[svn] gcry - r1306 - in trunk: . cipher doc src tests

svn author wk cvs at cvs.gnupg.org
Tue Aug 26 13:14:01 CEST 2008


Author: wk
Date: 2008-08-26 13:13:57 +0200 (Tue, 26 Aug 2008)
New Revision: 1306

Modified:
   trunk/NEWS
   trunk/TODO
   trunk/cipher/ChangeLog
   trunk/cipher/primegen.c
   trunk/cipher/pubkey.c
   trunk/cipher/rsa.c
   trunk/doc/gcrypt.texi
   trunk/src/ChangeLog
   trunk/src/cipher-proto.h
   trunk/src/cipher.h
   trunk/src/fips.c
   trunk/src/g10lib.h
   trunk/src/global.c
   trunk/tests/ChangeLog
   trunk/tests/basic.c
   trunk/tests/benchmark.c
Log:
Implemented transient-key flag as requested by the GNUNet folks.
Documentation cleanups.
Removed FIPS logging unless in double verbose state.


[The diff below has been truncated]

Modified: trunk/cipher/ChangeLog
===================================================================
--- trunk/cipher/ChangeLog	2008-08-25 11:15:35 UTC (rev 1305)
+++ trunk/cipher/ChangeLog	2008-08-26 11:13:57 UTC (rev 1306)
@@ -1,3 +1,17 @@
+2008-08-26  Werner Koch  <wk at g10code.com>
+
+	* pubkey.c (pubkey_generate): Add arg KEYGEN_FLAGS.
+	(gcry_pk_genkey): Implement new parameter "transient-key" and
+	pass it as flags to pubkey_generate.
+	(pubkey_generate): Make use of an ext_generate function.
+	* rsa.c (generate): Add new arg transient_key and pass appropriate
+	args to the prime generator.
+	(_gcry_rsa_generate): Factor all code out to ...
+	(rsa_generate): .. new func with extra arg KEYGEN_FLAGS.
+	(_gcry_pubkey_extraspec_ecdsa): Setup rsa_generate.
+	* primegen.c (_gcry_generate_secret_prime) 
+	(_gcry_generate_public_prime): Add new arg RANDOM_LEVEL.
+
 2008-08-21  Werner Koch  <wk at g10code.com>
 
 	* primegen.c (_gcry_generate_secret_prime)

Modified: trunk/src/ChangeLog
===================================================================
--- trunk/src/ChangeLog	2008-08-25 11:15:35 UTC (rev 1305)
+++ trunk/src/ChangeLog	2008-08-26 11:13:57 UTC (rev 1306)
@@ -1,3 +1,13 @@
+2008-08-26  Werner Koch  <wk at g10code.com>
+
+	* fips.c (fips_new_state): Print state transitions only at
+	verbosity level of 2.
+	(reporter): Likewise.
+
+	* cipher-proto.h (pk_ext_generate_t): New.
+	(pk_extra_spec): Add member ext_generate.
+	* cipher.h (PUBKEY_FLAG_TRANSIENT_KEY): New.
+
 2008-08-22  Werner Koch  <wk at g10code.com>
 
 	* hmac256.c (_gcry_hmac256_file): New.

Modified: trunk/tests/ChangeLog
===================================================================
--- trunk/tests/ChangeLog	2008-08-25 11:15:35 UTC (rev 1305)
+++ trunk/tests/ChangeLog	2008-08-26 11:13:57 UTC (rev 1306)
@@ -1,3 +1,10 @@
+2008-08-26  Werner Koch  <wk at g10code.com>
+
+	* basic.c (get_keys_new): Use transient-key flag. 
+	* benchmark.c (main): First check options then do the libgcrypt
+	initialization.
+	(rsa_bench): Use transient-key flag if not in fips mode.
+
 2008-08-20  Werner Koch  <wk at g10code.com>
 
 	* t-mpi-bit.c (test_lshift): New.

Modified: trunk/NEWS
===================================================================
--- trunk/NEWS	2008-08-25 11:15:35 UTC (rev 1305)
+++ trunk/NEWS	2008-08-26 11:13:57 UTC (rev 1306)
@@ -1,8 +1,7 @@
 Noteworthy changes in version 1.4.2 (unreleased)
 ------------------------------------------------
 
- * The library may now be switched into a FIPS mode.  Note that this
-   mode is not yet fully working in 1.4.2rc1.
+ * The library may now be switched into a FIPS mode.
 
  * More runtime selftests.
 
@@ -14,6 +13,8 @@
 
  * The long missing gcry_mpi_lshift function has been added.
 
+ * RSA key generation now supports a "transient-key" flag.
+
  * Interface changes relative to the 1.3.0 release:
  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  GCRYCTL_OPERATIONAL_P   NEW.

Modified: trunk/TODO
===================================================================
--- trunk/TODO	2008-08-25 11:15:35 UTC (rev 1305)
+++ trunk/TODO	2008-08-26 11:13:57 UTC (rev 1306)
@@ -66,16 +66,6 @@
   collectros need to run that bunch of Unix utilities we don't waste
   their precious results.
 
-* Add transient flag to RSA key generation
- For short living keys it makes sense to allow generation using a PRNG.
- We could implement it this way:
-
- (genkey
-   (rsa
-     (nbits 4:1024)
-     (transient-key)))
-
-
 * Out of memory handler for secure memory should do proper logging
 
   There is no shortage of standard memory, so logging is most likely

Modified: trunk/cipher/primegen.c
===================================================================
--- trunk/cipher/primegen.c	2008-08-25 11:15:35 UTC (rev 1305)
+++ trunk/cipher/primegen.c	2008-08-26 11:13:57 UTC (rev 1306)
@@ -240,26 +240,29 @@
  */
 gcry_mpi_t
 _gcry_generate_secret_prime (unsigned int nbits,
+                             gcry_random_level_t random_level,
                              int (*extra_check)(void*, gcry_mpi_t),
                              void *extra_check_arg)
 {
   gcry_mpi_t prime;
 
-  prime = gen_prime (nbits, 1, GCRY_VERY_STRONG_RANDOM,
-                     extra_check, extra_check_arg);
+  prime = gen_prime (nbits, 1, random_level, extra_check, extra_check_arg);
   progress('\n');
   return prime;
 }
 
+
+/* Generate a prime number which may be public, i.e. not allocated in
+   secure memory.  */
 gcry_mpi_t
-_gcry_generate_public_prime( unsigned int nbits,
+_gcry_generate_public_prime (unsigned int nbits,
+                             gcry_random_level_t random_level,
                              int (*extra_check)(void*, gcry_mpi_t),
                              void *extra_check_arg)
 {
   gcry_mpi_t prime;
 
-  prime = gen_prime (nbits, 0, GCRY_VERY_STRONG_RANDOM,
-                     extra_check, extra_check_arg );
+  prime = gen_prime (nbits, 0, random_level, extra_check, extra_check_arg);
   progress('\n');
   return prime;
 }
@@ -730,7 +733,8 @@
 }
 
 
-
+/* Generate a prime used for discrete logarithm algorithms; i.e. this
+   prime will be public and no strong random is required.  */
 gcry_mpi_t
 _gcry_generate_elg_prime (int mode, unsigned pbits, unsigned qbits,
 			  gcry_mpi_t g, gcry_mpi_t **ret_factors)
@@ -745,6 +749,7 @@
   return prime;
 }
 
+
 static gcry_mpi_t
 gen_prime (unsigned int nbits, int secret, int randomlevel, 
            int (*extra_check)(void *, gcry_mpi_t), void *extra_check_arg)

Modified: trunk/cipher/pubkey.c
===================================================================
--- trunk/cipher/pubkey.c	2008-08-25 11:15:35 UTC (rev 1305)
+++ trunk/cipher/pubkey.c	2008-08-26 11:13:57 UTC (rev 1306)
@@ -29,6 +29,7 @@
 #include "cipher.h"
 #include "ath.h"
 
+
 static gcry_err_code_t pubkey_decrypt (int algo, gcry_mpi_t *result,
                                        gcry_mpi_t *data, gcry_mpi_t *skey,
                                        int flags);
@@ -530,18 +531,18 @@
 
 /* Generate a new public key with algorithm ALGORITHM of size NBITS
    and return it at SKEY. The use of the arguments QBITS, USE_E,
-   XVALUE and CURVE+_NAME depend onthe ALGORITHM.  RETFACTOR is used
+   XVALUE and CURVE_NAME depend on the ALGORITHM.  RETFACTOR is used
    by some algorithms to return certain additional information which
-   are in general not required.  
+   are in general not required.
 
-   The function returns ther error code number or 0 on success. */
+   The function returns the error code number or 0 on success. */
 static gcry_err_code_t
 pubkey_generate (int algorithm, unsigned int nbits, unsigned int qbits,
                  unsigned long use_e, gcry_mpi_t xvalue,
-                 const char *curve_name,
+                 const char *curve_name, unsigned int keygen_flags,
                  gcry_mpi_t *skey, gcry_mpi_t **retfactors)
 {
-  gcry_err_code_t err = GPG_ERR_PUBKEY_ALGO;
+  gcry_err_code_t ec = GPG_ERR_PUBKEY_ALGO;
   gcry_module_t pubkey;
 
   REGISTER_DEFAULT_PUBKEYS;
@@ -550,36 +551,57 @@
   pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
   if (pubkey)
     {
-      /* Hack to pass QBITS to the DSA generation.  */
-      if (qbits && pubkey->spec == &_gcry_pubkey_spec_dsa)
+      pk_extra_spec_t *extraspec = pubkey->extraspec;
+
+      if (keygen_flags && (!extraspec || !extraspec->ext_generate))
         {
-          err = _gcry_dsa_generate2
+          /* A keygen flag has been given but the module does not
+             provide an ext_generate function.  We don't want to
+             ignore such a condition as it might eventually be
+             security sensitive..  */
+          ec = GPG_ERR_INV_FLAG;
+        }
+      else if (qbits && pubkey->spec == &_gcry_pubkey_spec_dsa)
+        {
+          /* Hack to pass QBITS to the DSA generation.  fixme: We
+             should merge this into an ext_generate fucntion. */
+          ec = _gcry_dsa_generate2
             (algorithm, nbits, qbits, 0, skey, retfactors);
         }
 #ifdef USE_ELGAMAL
       else if (xvalue && pubkey->spec == &_gcry_pubkey_spec_elg)
         {
-          err = _gcry_elg_generate_using_x
+          /* Fixme: Merge this into an ext_generate fucntion.  */
+          ec = _gcry_elg_generate_using_x
             (algorithm, nbits, xvalue, skey, retfactors);
         }
 #endif /*USE_ELGAMAL*/
 #ifdef USE_ECC
       else if (curve_name && pubkey->spec == &_gcry_pubkey_spec_ecdsa)
         {
-          err = _gcry_ecc_generate
+          /* Fixme: Merge this into an ext_generate fucntion.  */
+          ec = _gcry_ecc_generate
             (algorithm, nbits, curve_name, skey, retfactors);
         }
 #endif /*USE_ECC*/
+      else if (extraspec && extraspec->ext_generate)
+        {
+          /* Use the extended generate function if available.  */
+          ec = extraspec->ext_generate (algorithm, nbits, use_e,
+                                        keygen_flags,
+                                        skey, retfactors);
+        }
       else
         {
-          err = ((gcry_pk_spec_t *) pubkey->spec)->generate 
+          /* Use the standard generate function.  */
+          ec = ((gcry_pk_spec_t *) pubkey->spec)->generate 
             (algorithm, nbits, use_e, skey, retfactors);
         }
       _gcry_module_release (pubkey);
     }
   ath_mutex_unlock (&pubkeys_registered_lock);
 
-  return err;
+  return ec;
 }
 
 static gcry_err_code_t
@@ -2075,6 +2097,7 @@
   unsigned int qbits;
   gcry_mpi_t xvalue = NULL;
   char *curve = NULL;
+  unsigned int keygen_flags = 0;
 
   skey[0] = NULL;
   *r_key = NULL;
@@ -2182,7 +2205,7 @@
         }
     }
 
-  /* Handle the optional "curve" parameter. */
+  /* Parse the optional "curve" parameter. */
   l2 = gcry_sexp_find_token (list, "curve", 0);
   if (l2)
     {
@@ -2196,7 +2219,16 @@
       l2 = NULL;
     }
 
+  /* Parse the optional "transient-key" flag. */
+  l2 = gcry_sexp_find_token (list, "transient-key", 0);
+  if (l2)
+    {
+      keygen_flags |= PUBKEY_FLAG_TRANSIENT_KEY;
+      gcry_sexp_release (l2);
+      l2 = NULL;
+    }
 
+
   /* Unless a curve name has been given, the "nbits" parameter is
      required.  */
   l2 = gcry_sexp_find_token (list, "nbits", 0);
@@ -2227,7 +2259,7 @@
     nbits = 0;
 
   rc = pubkey_generate (module->mod_id, nbits, qbits, use_e, xvalue,
-                        curve, skey, &factors);
+                        curve, keygen_flags, skey, &factors);
   if (rc)
     goto leave;
 
@@ -2693,7 +2725,7 @@
 _gcry_pk_selftest (int algo, selftest_report_func_t report)
 {
   gcry_module_t module = NULL;
-  cipher_extra_spec_t *extraspec = NULL;
+  pk_extra_spec_t *extraspec = NULL;
   gcry_err_code_t ec = 0;
 
   REGISTER_DEFAULT_PUBKEYS;

Modified: trunk/cipher/rsa.c
===================================================================
--- trunk/cipher/rsa.c	2008-08-25 11:15:35 UTC (rev 1305)
+++ trunk/cipher/rsa.c	2008-08-26 11:13:57 UTC (rev 1306)
@@ -54,7 +54,8 @@
 
 static void test_keys (RSA_secret_key *sk, unsigned nbits);
 static gpg_err_code_t generate (RSA_secret_key *sk,
-                                unsigned int nbits, unsigned long use_e);
+                                unsigned int nbits, unsigned long use_e,
+                                int transient_key);
 static int  check_secret_key (RSA_secret_key *sk);
 static void public (gcry_mpi_t output, gcry_mpi_t input, RSA_public_key *skey);
 static void secret (gcry_mpi_t output, gcry_mpi_t input, RSA_secret_key *skey);
@@ -109,10 +110,12 @@
  *       = 1 request the use of a "secure" exponent; this is required by some 
  *           specification to be 65537.
  *       > 2 Try starting at this value until a working exponent is found.
+ * TRANSIENT_KEY:  If true, generate the primes using the standard RNG.
  * Returns: 2 structures filled with all needed values
  */
 static gpg_err_code_t
-generate (RSA_secret_key *sk, unsigned int nbits, unsigned long use_e)
+generate (RSA_secret_key *sk, unsigned int nbits, unsigned long use_e,
+          int transient_key)
 {
   gcry_mpi_t p, q; /* the two primes */
   gcry_mpi_t d;    /* the private key */
@@ -123,10 +126,19 @@
   gcry_mpi_t phi;  /* helper: (p-1)(q-1) */
   gcry_mpi_t g;
   gcry_mpi_t f;
+  gcry_random_level_t random_level;
 
-  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;
+  }
 
+  /* The random quality depends on the transient_key flag.  */
+  random_level = transient_key ? GCRY_STRONG_RANDOM : GCRY_VERY_STRONG_RANDOM;
+
   /* Make sure that nbits is even so that we generate p, q of equal size. */
   if ( (nbits&1) )
     nbits++; 
@@ -165,13 +177,15 @@
       if (use_e)
         { /* Do an extra test to ensure that the given exponent is
              suitable. */
-          p = _gcry_generate_secret_prime (nbits/2, check_exponent, e);
-          q = _gcry_generate_secret_prime (nbits/2, check_exponent, e);
+          p = _gcry_generate_secret_prime (nbits/2, random_level,
+                                           check_exponent, e);
+          q = _gcry_generate_secret_prime (nbits/2, random_level,
+                                           check_exponent, e);
         }
       else
         { /* We check the exponent later. */
-          p = _gcry_generate_secret_prime (nbits/2, NULL, NULL);
-          q = _gcry_generate_secret_prime (nbits/2, NULL, NULL);
+          p = _gcry_generate_secret_prime (nbits/2, random_level, NULL, NULL);
+          q = _gcry_generate_secret_prime (nbits/2, random_level, NULL, NULL);
         }
       if (mpi_cmp (p, q) > 0 ) /* p shall be smaller than q (for calc of u)*/
         mpi_swap(p,q);
@@ -441,9 +455,10 @@
  **************  interface  ******************
  *********************************************/
 
-gcry_err_code_t
-_gcry_rsa_generate (int algo, unsigned int nbits, unsigned long use_e,
-                    gcry_mpi_t *skey, gcry_mpi_t **retfactors)
+static gcry_err_code_t
+rsa_generate (int algo, unsigned int nbits, unsigned long use_e,
+              unsigned int keygen_flags,
+              gcry_mpi_t *skey, gcry_mpi_t **retfactors)
 {
   RSA_secret_key sk;
   gpg_err_code_t ec;
@@ -451,7 +466,8 @@
 
   (void)algo;
 
-  ec = generate (&sk, nbits, use_e);
+  ec = generate (&sk, nbits, use_e,
+                 !!(keygen_flags & PUBKEY_FLAG_TRANSIENT_KEY) );
   if (!ec)
     {
       skey[0] = sk.n;
@@ -481,6 +497,14 @@
 
 
 gcry_err_code_t
+_gcry_rsa_generate (int algo, unsigned int nbits, unsigned long use_e,
+                    gcry_mpi_t *skey, gcry_mpi_t **retfactors)
+{
+  return rsa_generate (algo, nbits, use_e, 0, skey, retfactors);
+}
+
+
+gcry_err_code_t
 _gcry_rsa_check_secret_key( int algo, gcry_mpi_t *skey )
 {
   gcry_err_code_t err = GPG_ERR_NO_ERROR;
@@ -736,6 +760,7 @@
   };
 pk_extra_spec_t _gcry_pubkey_extraspec_rsa = 
   {
-    run_selftests
+    run_selftests,
+    rsa_generate
   };
 

Modified: trunk/doc/gcrypt.texi
===================================================================
--- trunk/doc/gcrypt.texi	2008-08-25 11:15:35 UTC (rev 1305)
+++ trunk/doc/gcrypt.texi	2008-08-26 11:13:57 UTC (rev 1306)
@@ -539,16 +539,18 @@
 
 @item 
 If the applications requests FIPS mode using the control command
- at code{GCRYCTL_FORCE_FIPS_MODE}.  This may be done at any time.
+ at code{GCRYCTL_FORCE_FIPS_MODE}.  This must be done prior to any
+initialization (i.e. before @code{gcry_check_version}).
 
 @end itemize
 
 Note that once Libgcrypt has been put into FIPS mode, it is not possible
 to switch back to standard mode without terminating the process first.
+If the log verbosity level of Libgcrypt has been set to at least 2, the
+state transitions and the selftests are logged.
 
 
 
-
 @c **********************************************************
 @c *******************  General  ****************************
 @c **********************************************************
@@ -689,7 +691,8 @@
 all extra logging whereas positive numbers enable more verbose logging.
 The level may be changed at any time but be aware that no memory
 syncronization is done so the effect of this command might not
-immediately show up in other threads.
+immediately show up in other threads.  This command may even be used
+prioe to @code{gcry_check_version}.
 
 @item GCRYCTL_SET_DEBUG_FLAGS; Arguments: unsigned int flags
 Set the debug flag bits as given by the argument.  Be aware that that no
@@ -697,12 +700,14 @@
 immediately show up in other threads.  The debug flags are not
 considered part of the API and thus may change without notice.  As of
 now bit 0 enables debugging of cipher functions and bit 1 debugging of
-multi-precision-integers.
+multi-precision-integers.  This command may even be used prioe to
+ at code{gcry_check_version}.
 
 @item GCRYCTL_CLEAR_DEBUG_FLAGS; Arguments: unsigned int flags
 Set the debug flag bits as given by the argument.  Be aware that that no
 memory syncronization is done so the effect of this command might not
-immediately show up in other threads.
+immediately show up in other threads.  This command may even be used
+prioe to @code{gcry_check_version}.
 
 @item GCRYCTL_DISABLE_INTERNAL_LOCKING; Arguments: none
 This command does nothing.  It exists only for backward compatibility.
@@ -758,12 +763,12 @@
 before a gcry_version_check.
 
 @item GCRYCTL_FORCE_FIPS_MODE; Arguments: none
-Running this command puts the library into FIPS mode.  If the library
-has already been initialized or is already in FIPS mode, a selftest is
-triggered and thus the library will be put into operational state.  This
-command may even be used before a call to gcry_check_version and that is
-actually the recommended way to let an application switch the library
-into FIPS mode.
+Running this command puts the library into FIPS mode.  If the library is
+already in FIPS mode, a selftest is triggered and thus the library will
+be put into operational state.  This command may be used before a call
+to gcry_check_version and that is actually the recommended way to let an
+application switch the library into FIPS mode.  Note that Libgcrypt will
+reject an attempt to switch to fips mode during or after the intialization.
 
 
 @end table
@@ -1279,8 +1284,8 @@
 @section Error handler
 
 The following functions may be used to register handler functions that
-are called by Libgcrypt in case certain error conditions
-occur.
+are called by Libgcrypt in case certain error conditions occur.  They
+may and should be registered prior to calling @code{gcry_check_version}.
 
 @deftp {Data type} gcry_handler_no_mem_t
 This type is defined as: @code{void (*gcry_handler_no_mem_t) (void *, size_t, unsigned int)}
@@ -1308,9 +1313,10 @@
 @end deftp
 
 @deftypefun void gcry_set_log_handler (gcry_handler_log_t @var{func_log}, void *@var{cb_data})
-This function registers @var{func_log} as `logging handler', which
-means that it will be called in case Libgcrypt wants to log
-a message.
+This function registers @var{func_log} as `logging handler', which means
+that it will be called in case Libgcrypt wants to log a message.  This
+function may and should be used prior to calling
+ at code{gcry_check_version}.
 @end deftypefun
 
 @c **********************************************************
@@ -2621,6 +2627,13 @@
 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.
 
+ at 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 cryptograohic strength.
+
+
 @end table
 @c end table of parameters
 

Modified: trunk/src/cipher-proto.h
===================================================================
--- trunk/src/cipher-proto.h	2008-08-25 11:15:35 UTC (rev 1305)
+++ trunk/src/cipher-proto.h	2008-08-26 11:13:57 UTC (rev 1306)
@@ -39,6 +39,16 @@
      (int algo, selftest_report_func_t report);
 
 
+/* An extended type of the generate function.  */
+typedef gcry_err_code_t (*pk_ext_generate_t)
+     (int algo,
+      unsigned int nbits,




More information about the Gnupg-commits mailing list