diff options
author | Werner Koch <wk@gnupg.org> | 2008-12-05 18:53:06 +0000 |
---|---|---|
committer | Werner Koch <wk@gnupg.org> | 2008-12-05 18:53:06 +0000 |
commit | bd5ca43389e2219b930d67ec51ad688650951e25 (patch) | |
tree | 3a7dc8c95a91fc0b7084b0c6199b68f47823ecb9 | |
parent | db0387be06f205591870e882c8a4ae0e0ebf0846 (diff) | |
download | libgcrypt-bd5ca43389e2219b930d67ec51ad688650951e25.tar.gz |
Allow (transient-key) for DSA.
Type fix.
Made sure that gcry_free preserves ERRNO.
-rw-r--r-- | cipher/ChangeLog | 7 | ||||
-rw-r--r-- | cipher/dsa.c | 42 | ||||
-rw-r--r-- | doc/gcrypt.texi | 11 | ||||
-rw-r--r-- | src/ChangeLog | 4 | ||||
-rw-r--r-- | src/global.c | 13 | ||||
-rw-r--r-- | src/stdmem.c | 4 | ||||
-rw-r--r-- | tests/ChangeLog | 5 | ||||
-rw-r--r-- | tests/pubkey.c | 22 |
8 files changed, 85 insertions, 23 deletions
diff --git a/cipher/ChangeLog b/cipher/ChangeLog index 84b9d4f4..c6371f48 100644 --- a/cipher/ChangeLog +++ b/cipher/ChangeLog @@ -1,3 +1,10 @@ +2008-12-05 Werner Koch <wk@g10code.com> + + * dsa.c (generate): Add arg TRANSIENT_KEY and use it to detrmine + the RNG quality needed. + (dsa_generate_ext): Parse the transient-key flag und pass it to + generate. + 2008-11-28 Werner Koch <wk@g10code.com> * dsa.c (generate_fips186): Add arg DERIVEPARMS and use the seed diff --git a/cipher/dsa.c b/cipher/dsa.c index b5f4ba07..d11a7d0d 100644 --- a/cipher/dsa.c +++ b/cipher/dsa.c @@ -91,6 +91,7 @@ static int check_secret_key (DSA_secret_key *sk); static gpg_err_code_t generate (DSA_secret_key *sk, unsigned int nbits, unsigned int qbits, + int transient_key, gcry_mpi_t **ret_factors); static void sign (gcry_mpi_t r, gcry_mpi_t s, gcry_mpi_t input, DSA_secret_key *skey); @@ -225,13 +226,16 @@ test_keys (DSA_secret_key *sk, unsigned int qbits) /* - Generate a DSA key pair with a key of size NBITS. + Generate a DSA key pair with a key of size NBITS. If transient_key + is true the key is generated using the standard RNG and not the + very secure one. + Returns: 2 structures filled with all needed values and an array with the n-1 factors of (p-1) */ static gpg_err_code_t generate (DSA_secret_key *sk, unsigned int nbits, unsigned int qbits, - gcry_mpi_t **ret_factors ) + int transient_key, gcry_mpi_t **ret_factors ) { gcry_mpi_t p; /* the prime */ gcry_mpi_t q; /* the 160 bit prime factor */ @@ -240,6 +244,7 @@ generate (DSA_secret_key *sk, unsigned int nbits, unsigned int qbits, gcry_mpi_t x; /* the secret exponent */ gcry_mpi_t h, e; /* helper */ unsigned char *rndbuf; + gcry_random_level_t random_level; if (qbits) ; /* Caller supplied qbits. Use this value. */ @@ -261,9 +266,15 @@ generate (DSA_secret_key *sk, unsigned int nbits, unsigned int qbits, if (nbits < 2*qbits || nbits > 15360) return GPG_ERR_INV_VALUE; - if (nbits < 1024 && fips_mode ()) - return GPG_ERR_INV_VALUE; + if (fips_mode ()) + { + if (nbits < 1024) + return GPG_ERR_INV_VALUE; + if (transient_key) + return GPG_ERR_INV_VALUE; + } + /* Generate the primes. */ p = _gcry_generate_elg_prime( 1, nbits, qbits, NULL, ret_factors ); /* get q out of factors */ q = mpi_copy((*ret_factors)[0]); @@ -289,8 +300,10 @@ generate (DSA_secret_key *sk, unsigned int nbits, unsigned int qbits, * 0 < x < q-1 * This must be a very good random number because this * is the secret part. */ - if( DBG_CIPHER ) - log_debug("choosing a random x "); + /* 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)":""); gcry_assert( qbits >= 160 ); x = mpi_alloc_secure( mpi_get_nlimbs(q) ); mpi_sub_ui( h, q, 1 ); /* put q-1 into h */ @@ -300,11 +313,10 @@ generate (DSA_secret_key *sk, unsigned int nbits, unsigned int qbits, if( DBG_CIPHER ) progress('.'); if( !rndbuf ) - rndbuf = gcry_random_bytes_secure( (qbits+7)/8, - GCRY_VERY_STRONG_RANDOM ); + 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, GCRY_VERY_STRONG_RANDOM); + char *r = gcry_random_bytes_secure (2, random_level); memcpy(rndbuf, r, 2 ); gcry_free(r); } @@ -633,6 +645,7 @@ dsa_generate_ext (int algo, unsigned int nbits, unsigned long evalue, 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; @@ -662,6 +675,15 @@ dsa_generate_ext (int algo, unsigned int nbits, unsigned long evalue, gcry_sexp_release (l1); } + /* Parse the optional transient-key flag. */ + l1 = gcry_sexp_find_token (genparms, "transient-key", 0); + if (l1) + { + transient_key = 1; + gcry_sexp_release (l1); + } + + /* Get the optional derive parameters. */ deriveparms = gcry_sexp_find_token (genparms, "derive-parms", 0); /* Parse the optional "use-fips186" flags. */ @@ -709,7 +731,7 @@ dsa_generate_ext (int algo, unsigned int nbits, unsigned long evalue, } else { - ec = generate (&sk, nbits, qbits, retfactors); + ec = generate (&sk, nbits, qbits, transient_key, retfactors); } if (!ec) { diff --git a/doc/gcrypt.texi b/doc/gcrypt.texi index 9569c81b..4ccaae89 100644 --- a/doc/gcrypt.texi +++ b/doc/gcrypt.texi @@ -2708,10 +2708,11 @@ are allowed. When specifying Q all values of N in the range 512 to 15680 are valid as long as they are multiples of 8. @item transient-key -This is only meaningful for RSA keys. This is a flag with no value. If -given the RSA key is created using a faster and a somewhat less secure -random number generator. This flag may be used for keys which are only -used for a short time and do not require full cryptographic strength. +This is only meaningful for RSA and DSA keys. This is a flag with no +value. If given the RSA or DSA key is created using a faster and a +somewhat less secure random number generator. This flag may be used +for keys which are only used for a short time and do not require full +cryptographic strength. @item domain This is only meaningful for DLP algorithms. If specified keys are @@ -5563,7 +5564,7 @@ DSA key generation refuses to create a key with a keysize other than 1024 bits. @item -The @code{transient-key} flag for RSA key generation is ignored. +The @code{transient-key} flag for RSA and DSA key generation is ignored. @item Support for the VIA Padlock engine is disabled. diff --git a/src/ChangeLog b/src/ChangeLog index beda9b28..389ebba3 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,7 @@ +2008-12-05 Werner Koch <wk@g10code.com> + + * global.c (gcry_free): Save and restore ERRNO if set. + 2008-11-24 Werner Koch <wk@g10code.com> * sexp.c (get_internal_buffer): New. diff --git a/src/global.c b/src/global.c index d2361de5..a69513e7 100644 --- a/src/global.c +++ b/src/global.c @@ -810,15 +810,24 @@ gcry_realloc (void *a, size_t n) } void -gcry_free( void *p ) +gcry_free (void *p) { - if( !p ) + int save_errno; + + if (!p) return; + /* In case ERRNO is set we better save it so that the free machinery + may not accidently change ERRNO. We restore it only if it was + already set to comply with the usual C semantic for ERRNO. */ + save_errno = errno; if (free_func) free_func (p); else _gcry_private_free (p); + + if (save_errno) + errno = save_errno; } void * diff --git a/src/stdmem.c b/src/stdmem.c index 231a541d..bb8adeab 100644 --- a/src/stdmem.c +++ b/src/stdmem.c @@ -207,12 +207,12 @@ _gcry_private_check_heap (const void *a) /* - * Free a memory block allocated by this opr the secmem module + * Free a memory block allocated by this or the secmem module */ void _gcry_private_free (void *a) { - byte *p = a; + unsigned char *p = a; if (!p) return; diff --git a/tests/ChangeLog b/tests/ChangeLog index 5b8f7dff..1da5666e 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,3 +1,8 @@ +2008-12-05 Werner Koch <wk@g10code.com> + + * pubkey.c (get_dsa_key_new): Add arg transient_key. + (check_run): Use it. + 2008-12-03 Werner Koch <wk@g10code.com> * fipsdrv.c (run_dsa_pqg_gen): Facor code out into .. diff --git a/tests/pubkey.c b/tests/pubkey.c index 0e6efd9b..f02d7a34 100644 --- a/tests/pubkey.c +++ b/tests/pubkey.c @@ -351,14 +351,18 @@ get_elg_key_new (gcry_sexp_t *pkey, gcry_sexp_t *skey, int fixed_x) *skey = sec_key; } + static void -get_dsa_key_new (gcry_sexp_t *pkey, gcry_sexp_t *skey) +get_dsa_key_new (gcry_sexp_t *pkey, gcry_sexp_t *skey, int transient_key) { gcry_sexp_t key_spec, key, pub_key, sec_key; int rc; - rc = gcry_sexp_new - (&key_spec, "(genkey (dsa (nbits 4:1024)))", 0, 1); + rc = gcry_sexp_new (&key_spec, + transient_key + ? "(genkey (dsa (nbits 4:1024)(transient-key)))" + : "(genkey (dsa (nbits 4:1024)))", + 0, 1); if (rc) die ("error creating S-expression: %s\n", gcry_strerror (rc)); rc = gcry_pk_genkey (&key, key_spec); @@ -467,11 +471,21 @@ check_run (void) if (verbose) fprintf (stderr, "Generating DSA key.\n"); - get_dsa_key_new (&pkey, &skey); + get_dsa_key_new (&pkey, &skey, 0); /* Fixme: Add a check function for DSA keys. */ gcry_sexp_release (pkey); gcry_sexp_release (skey); + if (!gcry_fips_mode_active ()) + { + if (verbose) + fprintf (stderr, "Generating transient DSA key.\n"); + get_dsa_key_new (&pkey, &skey, 1); + /* Fixme: Add a check function for DSA keys. */ + gcry_sexp_release (pkey); + gcry_sexp_release (skey); + } + if (verbose) fprintf (stderr, "Generating DSA key (FIPS 186).\n"); get_dsa_key_fips186_new (&pkey, &skey); |