summaryrefslogtreecommitdiff
path: root/plugins/MirOTR/Libgcrypt/cipher/dsa.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/MirOTR/Libgcrypt/cipher/dsa.c')
-rw-r--r--plugins/MirOTR/Libgcrypt/cipher/dsa.c997
1 files changed, 557 insertions, 440 deletions
diff --git a/plugins/MirOTR/Libgcrypt/cipher/dsa.c b/plugins/MirOTR/Libgcrypt/cipher/dsa.c
index ceb94965c5..09cd9693ec 100644
--- a/plugins/MirOTR/Libgcrypt/cipher/dsa.c
+++ b/plugins/MirOTR/Libgcrypt/cipher/dsa.c
@@ -1,6 +1,7 @@
/* dsa.c - DSA signature algorithm
* Copyright (C) 1998, 2000, 2001, 2002, 2003,
* 2006, 2008 Free Software Foundation, Inc.
+ * Copyright (C) 2013 g10 Code GmbH.
*
* This file is part of Libgcrypt.
*
@@ -26,6 +27,8 @@
#include "g10lib.h"
#include "mpi.h"
#include "cipher.h"
+#include "pubkey-internal.h"
+
typedef struct
{
@@ -55,6 +58,14 @@ typedef struct
} dsa_domain_t;
+static const char *dsa_names[] =
+ {
+ "dsa",
+ "openpgp-dsa",
+ NULL,
+ };
+
+
/* A sample 1024 bit DSA key used for the selftests. */
static const char sample_secret_key[] =
"(private-key"
@@ -74,7 +85,7 @@ static const char sample_secret_key[] =
" 42CAA7DC289F0C5A9D155F02D3D551DB741A81695B74D4C8F477F9C7838EB0FB#)"
" (x #11D54E4ADBD3034160F2CED4B7CD292A4EBF3EC0#)))";
/* A sample 1024 bit DSA key used for the selftests (public only). */
-static const char sample_public_key[] =
+static const char sample_public_key[] =
"(public-key"
" (dsa"
" (p #00AD7C0025BA1A15F775F3F2D673718391D00456978D347B33D7B49E7F32EDAB"
@@ -94,7 +105,6 @@ static const char sample_public_key[] =
-static gcry_mpi_t gen_k (gcry_mpi_t q);
static int test_keys (DSA_secret_key *sk, unsigned int qbits);
static int check_secret_key (DSA_secret_key *sk);
static gpg_err_code_t generate (DSA_secret_key *sk,
@@ -103,10 +113,12 @@ static gpg_err_code_t generate (DSA_secret_key *sk,
int transient_key,
dsa_domain_t *domain,
gcry_mpi_t **ret_factors);
-static void sign (gcry_mpi_t r, gcry_mpi_t s, gcry_mpi_t input,
- DSA_secret_key *skey);
-static int verify (gcry_mpi_t r, gcry_mpi_t s, gcry_mpi_t input,
+static gpg_err_code_t sign (gcry_mpi_t r, gcry_mpi_t s, gcry_mpi_t input,
+ DSA_secret_key *skey, int flags, int hashalgo);
+static gpg_err_code_t verify (gcry_mpi_t r, gcry_mpi_t s, gcry_mpi_t input,
DSA_public_key *pkey);
+static unsigned int dsa_get_nbits (gcry_sexp_t parms);
+
static void (*progress_cb) (void *,const char *, int, int, int );
static void *progress_cb_data;
@@ -130,78 +142,15 @@ progress (int c)
}
-/*
- * Generate a random secret exponent k less than q.
- */
-static gcry_mpi_t
-gen_k( gcry_mpi_t q )
-{
- gcry_mpi_t k = mpi_alloc_secure( mpi_get_nlimbs(q) );
- unsigned int nbits = mpi_get_nbits(q);
- unsigned int nbytes = (nbits+7)/8;
- char *rndbuf = NULL;
-
- if ( DBG_CIPHER )
- log_debug("choosing a random k ");
- for (;;)
- {
- if( DBG_CIPHER )
- progress('.');
-
- if ( !rndbuf || nbits < 32 )
- {
- gcry_free(rndbuf);
- rndbuf = gcry_random_bytes_secure( (nbits+7)/8, GCRY_STRONG_RANDOM );
- }
- else
- { /* Change only some of the higher bits. We could improve
- this by directly requesting more memory at the first call
- to get_random_bytes() and use this the here maybe it is
- easier to do this directly in random.c. */
- char *pp = gcry_random_bytes_secure( 4, GCRY_STRONG_RANDOM );
- memcpy( rndbuf,pp, 4 );
- gcry_free(pp);
- }
- _gcry_mpi_set_buffer( k, rndbuf, nbytes, 0 );
- if ( mpi_test_bit( k, nbits-1 ) )
- mpi_set_highbit( k, nbits-1 );
- else
- {
- mpi_set_highbit( k, nbits-1 );
- mpi_clear_bit( k, nbits-1 );
- }
-
- if( !(mpi_cmp( k, q ) < 0) ) /* check: k < q */
- {
- if( DBG_CIPHER )
- progress('+');
- continue; /* no */
- }
- if( !(mpi_cmp_ui( k, 0 ) > 0) ) /* check: k > 0 */
- {
- if( DBG_CIPHER )
- progress('-');
- continue; /* no */
- }
- break; /* okay */
- }
- gcry_free(rndbuf);
- if( DBG_CIPHER )
- progress('\n');
-
- return k;
-}
-
-
/* Check that a freshly generated key actually works. Returns 0 on success. */
static int
test_keys (DSA_secret_key *sk, unsigned int qbits)
{
int result = -1; /* Default to failure. */
DSA_public_key pk;
- gcry_mpi_t data = gcry_mpi_new (qbits);
- gcry_mpi_t sig_a = gcry_mpi_new (qbits);
- gcry_mpi_t sig_b = gcry_mpi_new (qbits);
+ gcry_mpi_t data = mpi_new (qbits);
+ gcry_mpi_t sig_a = mpi_new (qbits);
+ gcry_mpi_t sig_b = mpi_new (qbits);
/* Put the relevant parameters into a public key structure. */
pk.p = sk->p;
@@ -210,26 +159,26 @@ test_keys (DSA_secret_key *sk, unsigned int qbits)
pk.y = sk->y;
/* Create a random plaintext. */
- gcry_mpi_randomize (data, qbits, GCRY_WEAK_RANDOM);
+ _gcry_mpi_randomize (data, qbits, GCRY_WEAK_RANDOM);
/* Sign DATA using the secret key. */
- sign (sig_a, sig_b, data, sk);
+ sign (sig_a, sig_b, data, sk, 0, 0);
/* Verify the signature using the public key. */
- if ( !verify (sig_a, sig_b, data, &pk) )
+ if ( verify (sig_a, sig_b, data, &pk) )
goto leave; /* Signature does not match. */
/* Modify the data and check that the signing fails. */
- gcry_mpi_add_ui (data, data, 1);
- if ( verify (sig_a, sig_b, data, &pk) )
+ mpi_add_ui (data, data, 1);
+ if ( !verify (sig_a, sig_b, data, &pk) )
goto leave; /* Signature matches but should not. */
result = 0; /* The test succeeded. */
leave:
- gcry_mpi_release (sig_b);
- gcry_mpi_release (sig_a);
- gcry_mpi_release (data);
+ _gcry_mpi_release (sig_b);
+ _gcry_mpi_release (sig_a);
+ _gcry_mpi_release (data);
return result;
}
@@ -247,6 +196,7 @@ static gpg_err_code_t
generate (DSA_secret_key *sk, unsigned int nbits, unsigned int qbits,
int transient_key, dsa_domain_t *domain, gcry_mpi_t **ret_factors )
{
+ gpg_err_code_t rc;
gcry_mpi_t p; /* the prime */
gcry_mpi_t q; /* the 160 bit prime factor */
gcry_mpi_t g; /* the generator */
@@ -298,7 +248,10 @@ generate (DSA_secret_key *sk, unsigned int nbits, unsigned int qbits,
else
{
/* Generate new domain parameters. */
- p = _gcry_generate_elg_prime (1, nbits, qbits, NULL, ret_factors);
+ rc = _gcry_generate_elg_prime (1, nbits, qbits, NULL, &p, ret_factors);
+ if (rc)
+ return rc;
+
/* Get q out of factors. */
q = mpi_copy ((*ret_factors)[0]);
gcry_assert (mpi_get_nbits (q) == qbits);
@@ -314,48 +267,55 @@ generate (DSA_secret_key *sk, unsigned int nbits, unsigned int qbits,
{
mpi_add_ui (h, h, 1);
/* g = h^e mod p */
- gcry_mpi_powm (g, h, e, p);
- }
+ mpi_powm (g, h, e, p);
+ }
while (!mpi_cmp_ui (g, 1)); /* Continue until g != 1. */
}
/* Select a random number X with the property:
* 0 < x < q-1
+ *
+ * FIXME: Why do we use the requirement x < q-1 ? It should be
+ * sufficient to test for x < q. FIPS-186-3 check x < q-1 but it
+ * does not check for 0 < x because it makes sure that Q is unsigned
+ * and finally adds one to the result so that 0 will never be
+ * returned. We should replace the code below with _gcry_dsa_gen_k.
+ *
* This must be a very good random number because this is the secret
* part. The random quality depends on the transient_key flag. */
random_level = transient_key ? GCRY_STRONG_RANDOM : GCRY_VERY_STRONG_RANDOM;
if (DBG_CIPHER)
- log_debug("choosing a random x%s", transient_key? " (transient-key)":"");
+ log_debug("choosing a random x%s\n", transient_key? " (transient-key)":"");
gcry_assert( qbits >= 160 );
x = mpi_alloc_secure( mpi_get_nlimbs(q) );
mpi_sub_ui( h, q, 1 ); /* put q-1 into h */
rndbuf = NULL;
- do
+ do
{
if( DBG_CIPHER )
progress('.');
if( !rndbuf )
- rndbuf = gcry_random_bytes_secure ((qbits+7)/8, random_level);
- else
+ rndbuf = _gcry_random_bytes_secure ((qbits+7)/8, random_level);
+ else
{ /* Change only some of the higher bits (= 2 bytes)*/
- char *r = gcry_random_bytes_secure (2, random_level);
+ char *r = _gcry_random_bytes_secure (2, random_level);
memcpy(rndbuf, r, 2 );
- gcry_free(r);
+ xfree(r);
}
_gcry_mpi_set_buffer( x, rndbuf, (qbits+7)/8, 0 );
mpi_clear_highbit( x, qbits+1 );
- }
+ }
while ( !( mpi_cmp_ui( x, 0 )>0 && mpi_cmp( x, h )<0 ) );
- gcry_free(rndbuf);
+ xfree(rndbuf);
mpi_free( e );
mpi_free( h );
/* y = g^x mod p */
y = mpi_alloc( mpi_get_nlimbs(p) );
- gcry_mpi_powm( y, g, x, p );
+ mpi_powm (y, g, x, p);
- if( DBG_CIPHER )
+ if( DBG_CIPHER )
{
progress('\n');
log_mpidump("dsa p", p );
@@ -375,11 +335,11 @@ generate (DSA_secret_key *sk, unsigned int nbits, unsigned int qbits,
/* Now we can test our keys (this should never fail!). */
if ( test_keys (sk, qbits) )
{
- gcry_mpi_release (sk->p); sk->p = NULL;
- gcry_mpi_release (sk->q); sk->q = NULL;
- gcry_mpi_release (sk->g); sk->g = NULL;
- gcry_mpi_release (sk->y); sk->y = NULL;
- gcry_mpi_release (sk->x); sk->x = NULL;
+ _gcry_mpi_release (sk->p); sk->p = NULL;
+ _gcry_mpi_release (sk->q); sk->q = NULL;
+ _gcry_mpi_release (sk->g); sk->g = NULL;
+ _gcry_mpi_release (sk->y); sk->y = NULL;
+ _gcry_mpi_release (sk->x); sk->x = NULL;
fips_signal_error ("self-test after key generation failed");
return GPG_ERR_SELFTEST_FAILED;
}
@@ -406,8 +366,8 @@ generate_fips186 (DSA_secret_key *sk, unsigned int nbits, unsigned int qbits,
const void *seed;
size_t seedlen;
} initial_seed = { NULL, NULL, 0 };
- gcry_mpi_t prime_q = NULL;
- gcry_mpi_t prime_p = NULL;
+ gcry_mpi_t prime_q = NULL;
+ gcry_mpi_t prime_p = NULL;
gcry_mpi_t value_g = NULL; /* The generator. */
gcry_mpi_t value_y = NULL; /* g^x mod p */
gcry_mpi_t value_x = NULL; /* The secret exponent. */
@@ -462,20 +422,20 @@ generate_fips186 (DSA_secret_key *sk, unsigned int nbits, unsigned int qbits,
/* Get an initial seed value. */
if (deriveparms)
{
- initial_seed.sexp = gcry_sexp_find_token (deriveparms, "seed", 0);
+ initial_seed.sexp = sexp_find_token (deriveparms, "seed", 0);
if (initial_seed.sexp)
- initial_seed.seed = gcry_sexp_nth_data (initial_seed.sexp, 1,
+ initial_seed.seed = sexp_nth_data (initial_seed.sexp, 1,
&initial_seed.seedlen);
}
-
+
/* Fixme: Enable 186-3 after it has been approved and after fixing
the generation function. */
/* if (use_fips186_2) */
(void)use_fips186_2;
- ec = _gcry_generate_fips186_2_prime (nbits, qbits,
- initial_seed.seed,
+ ec = _gcry_generate_fips186_2_prime (nbits, qbits,
+ initial_seed.seed,
initial_seed.seedlen,
- &prime_q, &prime_p,
+ &prime_q, &prime_p,
r_counter,
r_seed, r_seedlen);
/* else */
@@ -483,7 +443,7 @@ generate_fips186 (DSA_secret_key *sk, unsigned int nbits, unsigned int qbits,
/* &prime_q, &prime_p, */
/* r_counter, */
/* r_seed, r_seedlen, NULL); */
- gcry_sexp_release (initial_seed.sexp);
+ sexp_release (initial_seed.sexp);
if (ec)
goto leave;
@@ -493,33 +453,33 @@ generate_fips186 (DSA_secret_key *sk, unsigned int nbits, unsigned int qbits,
mpi_sub_ui (value_e, prime_p, 1);
mpi_fdiv_q (value_e, value_e, prime_q );
value_g = mpi_alloc_like (prime_p);
- value_h = mpi_alloc_set_ui (1);
+ value_h = mpi_alloc_set_ui (1);
do
{
mpi_add_ui (value_h, value_h, 1);
/* g = h^e mod p */
mpi_powm (value_g, value_h, value_e, prime_p);
- }
+ }
while (!mpi_cmp_ui (value_g, 1)); /* Continue until g != 1. */
}
/* Select a random number x with: 0 < x < q */
- value_x = gcry_mpi_snew (qbits);
- do
+ value_x = mpi_snew (qbits);
+ do
{
if( DBG_CIPHER )
progress('.');
- gcry_mpi_randomize (value_x, qbits, GCRY_VERY_STRONG_RANDOM);
+ _gcry_mpi_randomize (value_x, qbits, GCRY_VERY_STRONG_RANDOM);
mpi_clear_highbit (value_x, qbits+1);
- }
+ }
while (!(mpi_cmp_ui (value_x, 0) > 0 && mpi_cmp (value_x, prime_q) < 0));
/* y = g^x mod p */
value_y = mpi_alloc_like (prime_p);
- gcry_mpi_powm (value_y, value_g, value_x, prime_p);
+ mpi_powm (value_y, value_g, value_x, prime_p);
- if (DBG_CIPHER)
+ if (DBG_CIPHER)
{
progress('\n');
log_mpidump("dsa p", prime_p );
@@ -539,22 +499,22 @@ generate_fips186 (DSA_secret_key *sk, unsigned int nbits, unsigned int qbits,
*r_h = value_h; value_h = NULL;
leave:
- gcry_mpi_release (prime_p);
- gcry_mpi_release (prime_q);
- gcry_mpi_release (value_g);
- gcry_mpi_release (value_y);
- gcry_mpi_release (value_x);
- gcry_mpi_release (value_h);
- gcry_mpi_release (value_e);
+ _gcry_mpi_release (prime_p);
+ _gcry_mpi_release (prime_q);
+ _gcry_mpi_release (value_g);
+ _gcry_mpi_release (value_y);
+ _gcry_mpi_release (value_x);
+ _gcry_mpi_release (value_h);
+ _gcry_mpi_release (value_e);
/* As a last step test this keys (this should never fail of course). */
if (!ec && test_keys (sk, qbits) )
{
- gcry_mpi_release (sk->p); sk->p = NULL;
- gcry_mpi_release (sk->q); sk->q = NULL;
- gcry_mpi_release (sk->g); sk->g = NULL;
- gcry_mpi_release (sk->y); sk->y = NULL;
- gcry_mpi_release (sk->x); sk->x = NULL;
+ _gcry_mpi_release (sk->p); sk->p = NULL;
+ _gcry_mpi_release (sk->q); sk->q = NULL;
+ _gcry_mpi_release (sk->g); sk->g = NULL;
+ _gcry_mpi_release (sk->y); sk->y = NULL;
+ _gcry_mpi_release (sk->x); sk->x = NULL;
fips_signal_error ("self-test after key generation failed");
ec = GPG_ERR_SELFTEST_FAILED;
}
@@ -562,9 +522,9 @@ generate_fips186 (DSA_secret_key *sk, unsigned int nbits, unsigned int qbits,
if (ec)
{
*r_counter = 0;
- gcry_free (*r_seed); *r_seed = NULL;
+ xfree (*r_seed); *r_seed = NULL;
*r_seedlen = 0;
- gcry_mpi_release (*r_h); *r_h = NULL;
+ _gcry_mpi_release (*r_h); *r_h = NULL;
}
return ec;
@@ -582,7 +542,7 @@ check_secret_key( DSA_secret_key *sk )
int rc;
gcry_mpi_t y = mpi_alloc( mpi_get_nlimbs(sk->y) );
- gcry_mpi_powm( y, sk->g, sk->x, sk->p );
+ mpi_powm( y, sk->g, sk->x, sk->p );
rc = !mpi_cmp( y, sk->y );
mpi_free( y );
return rc;
@@ -591,20 +551,63 @@ check_secret_key( DSA_secret_key *sk )
/*
- Make a DSA signature from HASH and put it into r and s.
+ Make a DSA signature from INPUT and put it into r and s.
+
+ INPUT may either be a plain MPI or an opaque MPI which is then
+ internally converted to a plain MPI. FLAGS and HASHALGO may both
+ be 0 for standard operation mode.
+
+ The return value is 0 on success or an error code. Note that for
+ backward compatibility the function will not return any error if
+ FLAGS and HASHALGO are both 0 and INPUT is a plain MPI.
*/
-static void
-sign(gcry_mpi_t r, gcry_mpi_t s, gcry_mpi_t hash, DSA_secret_key *skey )
+static gpg_err_code_t
+sign (gcry_mpi_t r, gcry_mpi_t s, gcry_mpi_t input, DSA_secret_key *skey,
+ int flags, int hashalgo)
{
+ gpg_err_code_t rc;
+ gcry_mpi_t hash;
gcry_mpi_t k;
gcry_mpi_t kinv;
gcry_mpi_t tmp;
+ const void *abuf;
+ unsigned int abits, qbits;
+ int extraloops = 0;
+
+ qbits = mpi_get_nbits (skey->q);
- /* Select a random k with 0 < k < q */
- k = gen_k( skey->q );
+ /* Convert the INPUT into an MPI. */
+ rc = _gcry_dsa_normalize_hash (input, &hash, qbits);
+ if (rc)
+ return rc;
+
+ again:
+ /* Create the K value. */
+ if ((flags & PUBKEY_FLAG_RFC6979) && hashalgo)
+ {
+ /* Use Pornin's method for deterministic DSA. If this flag is
+ set, it is expected that HASH is an opaque MPI with the to be
+ signed hash. That hash is also used as h1 from 3.2.a. */
+ if (!mpi_is_opaque (input))
+ {
+ rc = GPG_ERR_CONFLICT;
+ goto leave;
+ }
+
+ abuf = mpi_get_opaque (input, &abits);
+ rc = _gcry_dsa_gen_rfc6979_k (&k, skey->q, skey->x,
+ abuf, (abits+7)/8, hashalgo, extraloops);
+ if (rc)
+ goto leave;
+ }
+ else
+ {
+ /* Select a random k with 0 < k < q */
+ k = _gcry_dsa_gen_k (skey->q, GCRY_STRONG_RANDOM);
+ }
/* r = (a^k mod p) mod q */
- gcry_mpi_powm( r, skey->g, k, skey->p );
+ mpi_powm( r, skey->g, k, skey->p );
mpi_fdiv_r( r, r, skey->q );
/* kinv = k^(-1) mod q */
@@ -620,24 +623,46 @@ sign(gcry_mpi_t r, gcry_mpi_t s, gcry_mpi_t hash, DSA_secret_key *skey )
mpi_free(k);
mpi_free(kinv);
mpi_free(tmp);
+
+ if (!mpi_cmp_ui (r, 0))
+ {
+ /* This is a highly unlikely code path. */
+ extraloops++;
+ goto again;
+ }
+
+ rc = 0;
+
+ leave:
+ if (hash != input)
+ mpi_free (hash);
+
+ return rc;
}
/*
Returns true if the signature composed from R and S is valid.
*/
-static int
-verify (gcry_mpi_t r, gcry_mpi_t s, gcry_mpi_t hash, DSA_public_key *pkey )
+static gpg_err_code_t
+verify (gcry_mpi_t r, gcry_mpi_t s, gcry_mpi_t input, DSA_public_key *pkey )
{
- int rc;
+ gpg_err_code_t rc = 0;
gcry_mpi_t w, u1, u2, v;
gcry_mpi_t base[3];
gcry_mpi_t ex[3];
+ gcry_mpi_t hash;
+ unsigned int nbits;
if( !(mpi_cmp_ui( r, 0 ) > 0 && mpi_cmp( r, pkey->q ) < 0) )
- return 0; /* assertion 0 < r < q failed */
+ return GPG_ERR_BAD_SIGNATURE; /* Assertion 0 < r < n failed. */
if( !(mpi_cmp_ui( s, 0 ) > 0 && mpi_cmp( s, pkey->q ) < 0) )
- return 0; /* assertion 0 < s < q failed */
+ return GPG_ERR_BAD_SIGNATURE; /* Assertion 0 < s < n failed. */
+
+ nbits = mpi_get_nbits (pkey->q);
+ rc = _gcry_dsa_normalize_hash (input, &hash, nbits);
+ if (rc)
+ return rc;
w = mpi_alloc( mpi_get_nlimbs(pkey->q) );
u1 = mpi_alloc( mpi_get_nlimbs(pkey->q) );
@@ -660,12 +685,25 @@ verify (gcry_mpi_t r, gcry_mpi_t s, gcry_mpi_t hash, DSA_public_key *pkey )
mpi_mulpowm( v, base, ex, pkey->p );
mpi_fdiv_r( v, v, pkey->q );
- rc = !mpi_cmp( v, r );
+ if (mpi_cmp( v, r ))
+ {
+ if (DBG_CIPHER)
+ {
+ log_mpidump (" i", input);
+ log_mpidump (" h", hash);
+ log_mpidump (" v", v);
+ log_mpidump (" r", r);
+ log_mpidump (" s", s);
+ }
+ rc = GPG_ERR_BAD_SIGNATURE;
+ }
mpi_free(w);
mpi_free(u1);
mpi_free(u2);
mpi_free(v);
+ if (hash != input)
+ mpi_free (hash);
return rc;
}
@@ -676,366 +714,458 @@ verify (gcry_mpi_t r, gcry_mpi_t s, gcry_mpi_t hash, DSA_public_key *pkey )
*********************************************/
static gcry_err_code_t
-dsa_generate_ext (int algo, unsigned int nbits, unsigned long evalue,
- const gcry_sexp_t genparms,
- gcry_mpi_t *skey, gcry_mpi_t **retfactors,
- gcry_sexp_t *r_extrainfo)
+dsa_generate (const gcry_sexp_t genparms, gcry_sexp_t *r_skey)
{
- gpg_err_code_t ec;
+ gpg_err_code_t rc;
+ unsigned int nbits;
+ gcry_sexp_t domainsexp;
DSA_secret_key sk;
gcry_sexp_t l1;
unsigned int qbits = 0;
gcry_sexp_t deriveparms = NULL;
gcry_sexp_t seedinfo = NULL;
- int transient_key = 0;
- int use_fips186_2 = 0;
- int use_fips186 = 0;
+ gcry_sexp_t misc_info = NULL;
+ int flags = 0;
dsa_domain_t domain;
-
- (void)algo; /* No need to check it. */
- (void)evalue; /* Not required for DSA. */
+ gcry_mpi_t *factors = NULL;
+ memset (&sk, 0, sizeof sk);
memset (&domain, 0, sizeof domain);
- if (genparms)
+ rc = _gcry_pk_util_get_nbits (genparms, &nbits);
+ if (rc)
+ return rc;
+
+ /* Parse the optional flags list. */
+ l1 = sexp_find_token (genparms, "flags", 0);
+ if (l1)
{
- gcry_sexp_t domainsexp;
-
- /* Parse the optional qbits element. */
- l1 = gcry_sexp_find_token (genparms, "qbits", 0);
- if (l1)
+ rc = _gcry_pk_util_parse_flaglist (l1, &flags, NULL);
+ sexp_release (l1);
+ if (rc)
+ return rc;\
+ }
+
+ /* Parse the optional qbits element. */
+ l1 = sexp_find_token (genparms, "qbits", 0);
+ if (l1)
+ {
+ char buf[50];
+ const char *s;
+ size_t n;
+
+ s = sexp_nth_data (l1, 1, &n);
+ if (!s || n >= DIM (buf) - 1 )
{
- char buf[50];
- const char *s;
- size_t n;
-
- s = gcry_sexp_nth_data (l1, 1, &n);
- if (!s || n >= DIM (buf) - 1 )
- {
- gcry_sexp_release (l1);
- return GPG_ERR_INV_OBJ; /* No value or value too large. */
- }
- memcpy (buf, s, n);
- buf[n] = 0;
- qbits = (unsigned int)strtoul (buf, NULL, 0);
- gcry_sexp_release (l1);
+ sexp_release (l1);
+ return GPG_ERR_INV_OBJ; /* No value or value too large. */
}
+ memcpy (buf, s, n);
+ buf[n] = 0;
+ qbits = (unsigned int)strtoul (buf, NULL, 0);
+ sexp_release (l1);
+ }
- /* Parse the optional transient-key flag. */
- l1 = gcry_sexp_find_token (genparms, "transient-key", 0);
+ /* Parse the optional transient-key flag. */
+ if (!(flags & PUBKEY_FLAG_TRANSIENT_KEY))
+ {
+ l1 = sexp_find_token (genparms, "transient-key", 0);
if (l1)
{
- transient_key = 1;
- gcry_sexp_release (l1);
+ flags |= PUBKEY_FLAG_TRANSIENT_KEY;
+ sexp_release (l1);
}
+ }
- /* Get the optional derive parameters. */
- deriveparms = gcry_sexp_find_token (genparms, "derive-parms", 0);
+ /* Get the optional derive parameters. */
+ deriveparms = sexp_find_token (genparms, "derive-parms", 0);
- /* Parse the optional "use-fips186" flags. */
- l1 = gcry_sexp_find_token (genparms, "use-fips186", 0);
+ /* Parse the optional "use-fips186" flags. */
+ if (!(flags & PUBKEY_FLAG_USE_FIPS186))
+ {
+ l1 = sexp_find_token (genparms, "use-fips186", 0);
if (l1)
{
- use_fips186 = 1;
- gcry_sexp_release (l1);
+ flags |= PUBKEY_FLAG_USE_FIPS186;
+ sexp_release (l1);
}
- l1 = gcry_sexp_find_token (genparms, "use-fips186-2", 0);
+ }
+ if (!(flags & PUBKEY_FLAG_USE_FIPS186_2))
+ {
+ l1 = sexp_find_token (genparms, "use-fips186-2", 0);
if (l1)
{
- use_fips186_2 = 1;
- gcry_sexp_release (l1);
+ flags |= PUBKEY_FLAG_USE_FIPS186_2;
+ sexp_release (l1);
}
+ }
- /* Check whether domain parameters are given. */
- domainsexp = gcry_sexp_find_token (genparms, "domain", 0);
- if (domainsexp)
+ /* Check whether domain parameters are given. */
+ domainsexp = sexp_find_token (genparms, "domain", 0);
+ if (domainsexp)
+ {
+ /* DERIVEPARMS can't be used together with domain parameters.
+ NBITS abnd QBITS may not be specified because there values
+ are derived from the domain parameters. */
+ if (deriveparms || qbits || nbits)
{
- /* DERIVEPARMS can't be used together with domain
- parameters. NBITS abnd QBITS may not be specified
- because there values are derived from the domain
- parameters. */
- if (deriveparms || qbits || nbits)
- {
- gcry_sexp_release (domainsexp);
- gcry_sexp_release (deriveparms);
- return GPG_ERR_INV_VALUE;
- }
-
- /* Put all domain parameters into the domain object. */
- l1 = gcry_sexp_find_token (domainsexp, "p", 0);
- domain.p = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
- gcry_sexp_release (l1);
- l1 = gcry_sexp_find_token (domainsexp, "q", 0);
- domain.q = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
- gcry_sexp_release (l1);
- l1 = gcry_sexp_find_token (domainsexp, "g", 0);
- domain.g = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
- gcry_sexp_release (l1);
- gcry_sexp_release (domainsexp);
-
- /* Check that all domain parameters are available. */
- if (!domain.p || !domain.q || !domain.g)
- {
- gcry_mpi_release (domain.p);
- gcry_mpi_release (domain.q);
- gcry_mpi_release (domain.g);
- gcry_sexp_release (deriveparms);
- return GPG_ERR_MISSING_VALUE;
- }
+ sexp_release (domainsexp);
+ sexp_release (deriveparms);
+ return GPG_ERR_INV_VALUE;
+ }
- /* Get NBITS and QBITS from the domain parameters. */
- nbits = mpi_get_nbits (domain.p);
- qbits = mpi_get_nbits (domain.q);
+ /* Put all domain parameters into the domain object. */
+ l1 = sexp_find_token (domainsexp, "p", 0);
+ domain.p = sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
+ sexp_release (l1);
+ l1 = sexp_find_token (domainsexp, "q", 0);
+ domain.q = sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
+ sexp_release (l1);
+ l1 = sexp_find_token (domainsexp, "g", 0);
+ domain.g = sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
+ sexp_release (l1);
+ sexp_release (domainsexp);
+
+ /* Check that all domain parameters are available. */
+ if (!domain.p || !domain.q || !domain.g)
+ {
+ _gcry_mpi_release (domain.p);
+ _gcry_mpi_release (domain.q);
+ _gcry_mpi_release (domain.g);
+ sexp_release (deriveparms);
+ return GPG_ERR_MISSING_VALUE;
}
+
+ /* Get NBITS and QBITS from the domain parameters. */
+ nbits = mpi_get_nbits (domain.p);
+ qbits = mpi_get_nbits (domain.q);
}
- if (deriveparms || use_fips186 || use_fips186_2 || fips_mode ())
+ if (deriveparms
+ || (flags & PUBKEY_FLAG_USE_FIPS186)
+ || (flags & PUBKEY_FLAG_USE_FIPS186_2)
+ || fips_mode ())
{
int counter;
void *seed;
size_t seedlen;
gcry_mpi_t h_value;
- ec = generate_fips186 (&sk, nbits, qbits, deriveparms, use_fips186_2,
+ rc = generate_fips186 (&sk, nbits, qbits, deriveparms,
+ !!(flags & PUBKEY_FLAG_USE_FIPS186_2),
&domain,
&counter, &seed, &seedlen, &h_value);
- gcry_sexp_release (deriveparms);
- if (!ec && h_value)
+ if (!rc && h_value)
{
/* Format the seed-values unless domain parameters are used
for which a H_VALUE of NULL is an indication. */
- ec = gpg_err_code (gcry_sexp_build
- (&seedinfo, NULL,
- "(seed-values(counter %d)(seed %b)(h %m))",
- counter, (int)seedlen, seed, h_value));
- if (ec)
- {
- gcry_mpi_release (sk.p); sk.p = NULL;
- gcry_mpi_release (sk.q); sk.q = NULL;
- gcry_mpi_release (sk.g); sk.g = NULL;
- gcry_mpi_release (sk.y); sk.y = NULL;
- gcry_mpi_release (sk.x); sk.x = NULL;
- }
- gcry_free (seed);
- gcry_mpi_release (h_value);
+ rc = sexp_build (&seedinfo, NULL,
+ "(seed-values(counter %d)(seed %b)(h %m))",
+ counter, (int)seedlen, seed, h_value);
+ xfree (seed);
+ _gcry_mpi_release (h_value);
}
}
else
{
- ec = generate (&sk, nbits, qbits, transient_key, &domain, retfactors);
+ rc = generate (&sk, nbits, qbits,
+ !!(flags & PUBKEY_FLAG_TRANSIENT_KEY),
+ &domain, &factors);
}
- gcry_mpi_release (domain.p);
- gcry_mpi_release (domain.q);
- gcry_mpi_release (domain.g);
-
- if (!ec)
+ if (!rc)
{
- skey[0] = sk.p;
- skey[1] = sk.q;
- skey[2] = sk.g;
- skey[3] = sk.y;
- skey[4] = sk.x;
-
- if (!r_extrainfo)
- {
- /* Old style interface - return the factors - if any - at
- retfactors. */
- }
- else if (!*retfactors && !seedinfo)
- {
- /* No factors and no seedinfo, thus there is nothing to return. */
- *r_extrainfo = NULL;
- }
+ /* Put the factors into MISC_INFO. Note that the factors are
+ not confidential thus we can store them in standard memory. */
+ int nfactors, i, j;
+ char *p;
+ char *format = NULL;
+ void **arg_list = NULL;
+
+ for (nfactors=0; factors && factors[nfactors]; nfactors++)
+ ;
+ /* Allocate space for the format string:
+ "(misc-key-info%S(pm1-factors%m))"
+ with one "%m" for each factor and construct it. */
+ format = xtrymalloc (50 + 2*nfactors);
+ if (!format)
+ rc = gpg_err_code_from_syserror ();
else
{
- /* Put the factors into extrainfo and set retfactors to NULL
- to make use of the new interface. Note that the factors
- are not confidential thus we can store them in standard
- memory. */
- int nfactors, i, j;
- char *p;
- char *format = NULL;
- void **arg_list = NULL;
-
- for (nfactors=0; *retfactors && (*retfactors)[nfactors]; nfactors++)
- ;
- /* Allocate space for the format string:
- "(misc-key-info%S(pm1-factors%m))"
- with one "%m" for each factor and construct it. */
- format = gcry_malloc (50 + 2*nfactors);
- if (!format)
- ec = gpg_err_code_from_syserror ();
- else
+ p = stpcpy (format, "(misc-key-info");
+ if (seedinfo)
+ p = stpcpy (p, "%S");
+ if (nfactors)
{
- p = stpcpy (format, "(misc-key-info");
- if (seedinfo)
- p = stpcpy (p, "%S");
- if (nfactors)
- {
- p = stpcpy (p, "(pm1-factors");
- for (i=0; i < nfactors; i++)
- p = stpcpy (p, "%m");
- p = stpcpy (p, ")");
- }
+ p = stpcpy (p, "(pm1-factors");
+ for (i=0; i < nfactors; i++)
+ p = stpcpy (p, "%m");
p = stpcpy (p, ")");
-
- /* Allocate space for the list of factors plus one for
- an S-expression plus an extra NULL entry for safety
- and fill it with the factors. */
- arg_list = gcry_calloc (nfactors+1+1, sizeof *arg_list);
- if (!arg_list)
- ec = gpg_err_code_from_syserror ();
- else
- {
- i = 0;
- if (seedinfo)
- arg_list[i++] = &seedinfo;
- for (j=0; j < nfactors; j++)
- arg_list[i++] = (*retfactors) + j;
- arg_list[i] = NULL;
-
- ec = gpg_err_code (gcry_sexp_build_array
- (r_extrainfo, NULL, format, arg_list));
- }
- }
-
- gcry_free (arg_list);
- gcry_free (format);
- for (i=0; i < nfactors; i++)
- {
- gcry_mpi_release ((*retfactors)[i]);
- (*retfactors)[i] = NULL;
}
- gcry_free (*retfactors);
- *retfactors = NULL;
- if (ec)
+ p = stpcpy (p, ")");
+
+ /* Allocate space for the list of factors plus one for the
+ seedinfo s-exp plus an extra NULL entry for safety and
+ fill it with the factors. */
+ arg_list = xtrycalloc (nfactors+1+1, sizeof *arg_list);
+ if (!arg_list)
+ rc = gpg_err_code_from_syserror ();
+ else
{
- for (i=0; i < 5; i++)
- {
- gcry_mpi_release (skey[i]);
- skey[i] = NULL;
- }
+ i = 0;
+ if (seedinfo)
+ arg_list[i++] = &seedinfo;
+ for (j=0; j < nfactors; j++)
+ arg_list[i++] = factors + j;
+ arg_list[i] = NULL;
+
+ rc = sexp_build_array (&misc_info, NULL, format, arg_list);
}
}
- }
-
- gcry_sexp_release (seedinfo);
- return ec;
-}
+ xfree (arg_list);
+ xfree (format);
+ }
-static gcry_err_code_t
-dsa_generate (int algo, unsigned int nbits, unsigned long evalue,
- gcry_mpi_t *skey, gcry_mpi_t **retfactors)
-{
- (void)evalue;
- return dsa_generate_ext (algo, nbits, 0, NULL, skey, retfactors, NULL);
+ if (!rc)
+ rc = sexp_build (r_skey, NULL,
+ "(key-data"
+ " (public-key"
+ " (dsa(p%m)(q%m)(g%m)(y%m)))"
+ " (private-key"
+ " (dsa(p%m)(q%m)(g%m)(y%m)(x%m)))"
+ " %S)",
+ sk.p, sk.q, sk.g, sk.y,
+ sk.p, sk.q, sk.g, sk.y, sk.x,
+ misc_info);
+
+
+ _gcry_mpi_release (sk.p);
+ _gcry_mpi_release (sk.q);
+ _gcry_mpi_release (sk.g);
+ _gcry_mpi_release (sk.y);
+ _gcry_mpi_release (sk.x);
+
+ _gcry_mpi_release (domain.p);
+ _gcry_mpi_release (domain.q);
+ _gcry_mpi_release (domain.g);
+
+ sexp_release (seedinfo);
+ sexp_release (misc_info);
+ sexp_release (deriveparms);
+ if (factors)
+ {
+ gcry_mpi_t *mp;
+ for (mp = factors; *mp; mp++)
+ mpi_free (*mp);
+ xfree (factors);
+ }
+ return rc;
}
static gcry_err_code_t
-dsa_check_secret_key (int algo, gcry_mpi_t *skey)
+dsa_check_secret_key (gcry_sexp_t keyparms)
{
- gcry_err_code_t err = GPG_ERR_NO_ERROR;
- DSA_secret_key sk;
+ gcry_err_code_t rc;
+ DSA_secret_key sk = {NULL, NULL, NULL, NULL, NULL};
- (void)algo;
+ rc = _gcry_sexp_extract_param (keyparms, NULL, "pqgyx",
+ &sk.p, &sk.q, &sk.g, &sk.y, &sk.x,
+ NULL);
+ if (rc)
+ goto leave;
- if ((! skey[0]) || (! skey[1]) || (! skey[2]) || (! skey[3]) || (! skey[4]))
- err = GPG_ERR_BAD_MPI;
- else
- {
- sk.p = skey[0];
- sk.q = skey[1];
- sk.g = skey[2];
- sk.y = skey[3];
- sk.x = skey[4];
- if (! check_secret_key (&sk))
- err = GPG_ERR_BAD_SECKEY;
- }
+ if (!check_secret_key (&sk))
+ rc = GPG_ERR_BAD_SECKEY;
- return err;
+ leave:
+ _gcry_mpi_release (sk.p);
+ _gcry_mpi_release (sk.q);
+ _gcry_mpi_release (sk.g);
+ _gcry_mpi_release (sk.y);
+ _gcry_mpi_release (sk.x);
+ if (DBG_CIPHER)
+ log_debug ("dsa_testkey => %s\n", gpg_strerror (rc));
+ return rc;
}
static gcry_err_code_t
-dsa_sign (int algo, gcry_mpi_t *resarr, gcry_mpi_t data, gcry_mpi_t *skey)
+dsa_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_data, gcry_sexp_t keyparms)
{
- gcry_err_code_t err = GPG_ERR_NO_ERROR;
- DSA_secret_key sk;
+ gcry_err_code_t rc;
+ struct pk_encoding_ctx ctx;
+ gcry_mpi_t data = NULL;
+ DSA_secret_key sk = {NULL, NULL, NULL, NULL, NULL};
+ gcry_mpi_t sig_r = NULL;
+ gcry_mpi_t sig_s = NULL;
+
+ _gcry_pk_util_init_encoding_ctx (&ctx, PUBKEY_OP_SIGN,
+ dsa_get_nbits (keyparms));
+
+ /* Extract the data. */
+ rc = _gcry_pk_util_data_to_mpi (s_data, &data, &ctx);
+ if (rc)
+ goto leave;
+ if (DBG_CIPHER)
+ log_mpidump ("dsa_sign data", data);
- (void)algo;
+ /* Extract the key. */
+ rc = _gcry_sexp_extract_param (keyparms, NULL, "pqgyx",
+ &sk.p, &sk.q, &sk.g, &sk.y, &sk.x, NULL);
+ if (rc)
+ goto leave;
+ if (DBG_CIPHER)
+ {
+ log_mpidump ("dsa_sign p", sk.p);
+ log_mpidump ("dsa_sign q", sk.q);
+ log_mpidump ("dsa_sign g", sk.g);
+ log_mpidump ("dsa_sign y", sk.y);
+ if (!fips_mode ())
+ log_mpidump ("dsa_sign x", sk.x);
+ }
- if ((! data)
- || (! skey[0]) || (! skey[1]) || (! skey[2])
- || (! skey[3]) || (! skey[4]))
- err = GPG_ERR_BAD_MPI;
- else
+ sig_r = mpi_new (0);
+ sig_s = mpi_new (0);
+ rc = sign (sig_r, sig_s, data, &sk, ctx.flags, ctx.hash_algo);
+ if (rc)
+ goto leave;
+ if (DBG_CIPHER)
{
- sk.p = skey[0];
- sk.q = skey[1];
- sk.g = skey[2];
- sk.y = skey[3];
- sk.x = skey[4];
- resarr[0] = mpi_alloc (mpi_get_nlimbs (sk.p));
- resarr[1] = mpi_alloc (mpi_get_nlimbs (sk.p));
- sign (resarr[0], resarr[1], data, &sk);
+ log_mpidump ("dsa_sign sig_r", sig_r);
+ log_mpidump ("dsa_sign sig_s", sig_s);
}
- return err;
+ rc = sexp_build (r_sig, NULL, "(sig-val(dsa(r%M)(s%M)))", sig_r, sig_s);
+
+ leave:
+ _gcry_mpi_release (sig_r);
+ _gcry_mpi_release (sig_s);
+ _gcry_mpi_release (sk.p);
+ _gcry_mpi_release (sk.q);
+ _gcry_mpi_release (sk.g);
+ _gcry_mpi_release (sk.y);
+ _gcry_mpi_release (sk.x);
+ _gcry_mpi_release (data);
+ _gcry_pk_util_free_encoding_ctx (&ctx);
+ if (DBG_CIPHER)
+ log_debug ("dsa_sign => %s\n", gpg_strerror (rc));
+ return rc;
}
+
static gcry_err_code_t
-dsa_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data, gcry_mpi_t *pkey,
- int (*cmp) (void *, gcry_mpi_t), void *opaquev)
+dsa_verify (gcry_sexp_t s_sig, gcry_sexp_t s_data, gcry_sexp_t s_keyparms)
{
- gcry_err_code_t err = GPG_ERR_NO_ERROR;
- DSA_public_key pk;
-
- (void)algo;
- (void)cmp;
- (void)opaquev;
+ gcry_err_code_t rc;
+ struct pk_encoding_ctx ctx;
+ gcry_sexp_t l1 = NULL;
+ gcry_mpi_t sig_r = NULL;
+ gcry_mpi_t sig_s = NULL;
+ gcry_mpi_t data = NULL;
+ DSA_public_key pk = { NULL, NULL, NULL, NULL };
+
+ _gcry_pk_util_init_encoding_ctx (&ctx, PUBKEY_OP_VERIFY,
+ dsa_get_nbits (s_keyparms));
+
+ /* Extract the data. */
+ rc = _gcry_pk_util_data_to_mpi (s_data, &data, &ctx);
+ if (rc)
+ goto leave;
+ if (DBG_CIPHER)
+ log_mpidump ("dsa_verify data", data);
+
+ /* Extract the signature value. */
+ rc = _gcry_pk_util_preparse_sigval (s_sig, dsa_names, &l1, NULL);
+ if (rc)
+ goto leave;
+ rc = _gcry_sexp_extract_param (l1, NULL, "rs", &sig_r, &sig_s, NULL);
+ if (rc)
+ goto leave;
+ if (DBG_CIPHER)
+ {
+ log_mpidump ("dsa_verify s_r", sig_r);
+ log_mpidump ("dsa_verify s_s", sig_s);
+ }
- if ((! data[0]) || (! data[1]) || (! hash)
- || (! pkey[0]) || (! pkey[1]) || (! pkey[2]) || (! pkey[3]))
- err = GPG_ERR_BAD_MPI;
- else
+ /* Extract the key. */
+ rc = _gcry_sexp_extract_param (s_keyparms, NULL, "pqgy",
+ &pk.p, &pk.q, &pk.g, &pk.y, NULL);
+ if (rc)
+ goto leave;
+ if (DBG_CIPHER)
{
- pk.p = pkey[0];
- pk.q = pkey[1];
- pk.g = pkey[2];
- pk.y = pkey[3];
- if (! verify (data[0], data[1], hash, &pk))
- err = GPG_ERR_BAD_SIGNATURE;
+ log_mpidump ("dsa_verify p", pk.p);
+ log_mpidump ("dsa_verify q", pk.q);
+ log_mpidump ("dsa_verify g", pk.g);
+ log_mpidump ("dsa_verify y", pk.y);
}
- return err;
+
+ /* Verify the signature. */
+ rc = verify (sig_r, sig_s, data, &pk);
+
+ leave:
+ _gcry_mpi_release (pk.p);
+ _gcry_mpi_release (pk.q);
+ _gcry_mpi_release (pk.g);
+ _gcry_mpi_release (pk.y);
+ _gcry_mpi_release (data);
+ _gcry_mpi_release (sig_r);
+ _gcry_mpi_release (sig_s);
+ sexp_release (l1);
+ _gcry_pk_util_free_encoding_ctx (&ctx);
+ if (DBG_CIPHER)
+ log_debug ("dsa_verify => %s\n", rc?gpg_strerror (rc):"Good");
+ return rc;
}
+/* Return the number of bits for the key described by PARMS. On error
+ * 0 is returned. The format of PARMS starts with the algorithm name;
+ * for example:
+ *
+ * (dsa
+ * (p <mpi>)
+ * (q <mpi>)
+ * (g <mpi>)
+ * (y <mpi>))
+ *
+ * More parameters may be given but we only need P here.
+ */
static unsigned int
-dsa_get_nbits (int algo, gcry_mpi_t *pkey)
+dsa_get_nbits (gcry_sexp_t parms)
{
- (void)algo;
-
- return mpi_get_nbits (pkey[0]);
+ gcry_sexp_t l1;
+ gcry_mpi_t p;
+ unsigned int nbits;
+
+ l1 = sexp_find_token (parms, "p", 1);
+ if (!l1)
+ return 0; /* Parameter P not found. */
+
+ p = sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
+ sexp_release (l1);
+ nbits = p? mpi_get_nbits (p) : 0;
+ _gcry_mpi_release (p);
+ return nbits;
}
-/*
+/*
Self-test section.
*/
static const char *
selftest_sign_1024 (gcry_sexp_t pkey, gcry_sexp_t skey)
{
- static const char sample_data[] =
- "(data (flags pkcs1)"
- " (hash sha1 #a0b1c2d3e4f500102030405060708090a1b2c3d4#))";
- static const char sample_data_bad[] =
- "(data (flags pkcs1)"
- " (hash sha1 #a0b1c2d3e4f510102030405060708090a1b2c3d4#))";
+ static const char sample_data[] =
+ "(data (flags raw)"
+ " (value #a0b1c2d3e4f500102030405060708090a1b2c3d4#))";
+ static const char sample_data_bad[] =
+ "(data (flags raw)"
+ " (value #a0b1c2d3e4f510102030405060708090a1b2c3d4#))";
const char *errtxt = NULL;
gcry_error_t err;
@@ -1043,30 +1173,29 @@ selftest_sign_1024 (gcry_sexp_t pkey, gcry_sexp_t skey)
gcry_sexp_t data_bad = NULL;
gcry_sexp_t sig = NULL;
- err = gcry_sexp_sscan (&data, NULL,
- sample_data, strlen (sample_data));
+ err = sexp_sscan (&data, NULL, sample_data, strlen (sample_data));
if (!err)
- err = gcry_sexp_sscan (&data_bad, NULL,
- sample_data_bad, strlen (sample_data_bad));
+ err = sexp_sscan (&data_bad, NULL,
+ sample_data_bad, strlen (sample_data_bad));
if (err)
{
errtxt = "converting data failed";
goto leave;
}
- err = gcry_pk_sign (&sig, data, skey);
+ err = _gcry_pk_sign (&sig, data, skey);
if (err)
{
errtxt = "signing failed";
goto leave;
}
- err = gcry_pk_verify (sig, data, pkey);
+ err = _gcry_pk_verify (sig, data, pkey);
if (err)
{
errtxt = "verify failed";
goto leave;
}
- err = gcry_pk_verify (sig, data_bad, pkey);
+ err = _gcry_pk_verify (sig, data_bad, pkey);
if (gcry_err_code (err) != GPG_ERR_BAD_SIGNATURE)
{
errtxt = "bad signature not detected";
@@ -1075,9 +1204,9 @@ selftest_sign_1024 (gcry_sexp_t pkey, gcry_sexp_t skey)
leave:
- gcry_sexp_release (sig);
- gcry_sexp_release (data_bad);
- gcry_sexp_release (data);
+ sexp_release (sig);
+ sexp_release (data_bad);
+ sexp_release (data);
return errtxt;
}
@@ -1093,22 +1222,21 @@ selftests_dsa (selftest_report_func_t report)
/* Convert the S-expressions into the internal representation. */
what = "convert";
- err = gcry_sexp_sscan (&skey, NULL,
- sample_secret_key, strlen (sample_secret_key));
+ err = sexp_sscan (&skey, NULL, sample_secret_key, strlen (sample_secret_key));
if (!err)
- err = gcry_sexp_sscan (&pkey, NULL,
- sample_public_key, strlen (sample_public_key));
+ err = sexp_sscan (&pkey, NULL,
+ sample_public_key, strlen (sample_public_key));
if (err)
{
- errtxt = gcry_strerror (err);
+ errtxt = _gcry_strerror (err);
goto failed;
}
what = "key consistency";
- err = gcry_pk_testkey (skey);
+ err = _gcry_pk_testkey (skey);
if (err)
{
- errtxt = gcry_strerror (err);
+ errtxt = _gcry_strerror (err);
goto failed;
}
@@ -1117,13 +1245,13 @@ selftests_dsa (selftest_report_func_t report)
if (errtxt)
goto failed;
- gcry_sexp_release (pkey);
- gcry_sexp_release (skey);
+ sexp_release (pkey);
+ sexp_release (skey);
return 0; /* Succeeded. */
failed:
- gcry_sexp_release (pkey);
- gcry_sexp_release (skey);
+ sexp_release (pkey);
+ sexp_release (skey);
if (report)
report ("pubkey", GCRY_PK_DSA, what, errtxt);
return GPG_ERR_SELFTEST_FAILED;
@@ -1146,7 +1274,7 @@ run_selftests (int algo, int extended, selftest_report_func_t report)
default:
ec = GPG_ERR_PUBKEY_ALGO;
break;
-
+
}
return ec;
}
@@ -1154,29 +1282,18 @@ run_selftests (int algo, int extended, selftest_report_func_t report)
-static const char *dsa_names[] =
- {
- "dsa",
- "openpgp-dsa",
- NULL,
- };
-
gcry_pk_spec_t _gcry_pubkey_spec_dsa =
{
- "DSA", dsa_names,
- "pqgy", "pqgyx", "", "rs", "pqgy",
+ GCRY_PK_DSA, { 0, 1 },
GCRY_PK_USAGE_SIGN,
+ "DSA", dsa_names,
+ "pqgy", "pqgyx", "", "rs", "pqgy",
dsa_generate,
dsa_check_secret_key,
NULL,
NULL,
dsa_sign,
dsa_verify,
- dsa_get_nbits
+ dsa_get_nbits,
+ run_selftests
};
-pk_extra_spec_t _gcry_pubkey_extraspec_dsa =
- {
- run_selftests,
- dsa_generate_ext
- };
-