summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2008-12-05 18:53:06 +0000
committerWerner Koch <wk@gnupg.org>2008-12-05 18:53:06 +0000
commitbd5ca43389e2219b930d67ec51ad688650951e25 (patch)
tree3a7dc8c95a91fc0b7084b0c6199b68f47823ecb9
parentdb0387be06f205591870e882c8a4ae0e0ebf0846 (diff)
downloadlibgcrypt-bd5ca43389e2219b930d67ec51ad688650951e25.tar.gz
Allow (transient-key) for DSA.
Type fix. Made sure that gcry_free preserves ERRNO.
-rw-r--r--cipher/ChangeLog7
-rw-r--r--cipher/dsa.c42
-rw-r--r--doc/gcrypt.texi11
-rw-r--r--src/ChangeLog4
-rw-r--r--src/global.c13
-rw-r--r--src/stdmem.c4
-rw-r--r--tests/ChangeLog5
-rw-r--r--tests/pubkey.c22
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);