Implemented transient-key flag as requested by the GNUNet folks.
authorWerner Koch <wk@gnupg.org>
Tue, 26 Aug 2008 11:13:57 +0000 (11:13 +0000)
committerWerner Koch <wk@gnupg.org>
Tue, 26 Aug 2008 11:13:57 +0000 (11:13 +0000)
Documentation cleanups.
Removed FIPS logging unless in double verbose state.

16 files changed:
NEWS
TODO
cipher/ChangeLog
cipher/primegen.c
cipher/pubkey.c
cipher/rsa.c
doc/gcrypt.texi
src/ChangeLog
src/cipher-proto.h
src/cipher.h
src/fips.c
src/g10lib.h
src/global.c
tests/ChangeLog
tests/basic.c
tests/benchmark.c

diff --git a/NEWS b/NEWS
index bb5d05e..8699939 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -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 @@ Noteworthy changes in version 1.4.2 (unreleased)
 
  * 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.
diff --git a/TODO b/TODO
index cc1cafb..4331027 100644 (file)
--- a/TODO
+++ b/TODO
@@ -66,16 +66,6 @@ What's left to do                                 -*- outline -*-
   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
index 6ae5312..60e7694 100644 (file)
@@ -1,3 +1,17 @@
+2008-08-26  Werner Koch  <wk@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@g10code.com>
 
        * primegen.c (_gcry_generate_secret_prime)
index 2c677b6..b9b31c6 100644 (file)
@@ -240,26 +240,29 @@ progress( int c )
  */
 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 @@ prime_generate_internal (int need_q_factor,
 }
 
 
-
+/* 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 @@ _gcry_generate_elg_prime (int mode, unsigned pbits, unsigned qbits,
   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)
index cf8a17c..8c35390 100644 (file)
@@ -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 @@ pubkey_get_nenc (int algorithm)
 
 /* 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_generate (int algorithm, unsigned int nbits, unsigned int qbits,
   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 @@ gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms)
   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 @@ gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms)
         }
     }
 
-  /* Handle the optional "curve" parameter. */
+  /* Parse the optional "curve" parameter. */
   l2 = gcry_sexp_find_token (list, "curve", 0);
   if (l2)
     {
@@ -2196,6 +2219,15 @@ gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms)
       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.  */
@@ -2227,7 +2259,7 @@ gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms)
     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 @@ gpg_error_t
 _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;
index 370a8f7..8ca8f31 100644 (file)
@@ -54,7 +54,8 @@ typedef struct
 
 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 @@ check_exponent (void *arg, gcry_mpi_t a)
  *       = 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,9 +126,18 @@ generate (RSA_secret_key *sk, unsigned int nbits, unsigned long use_e)
   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) )
@@ -165,13 +177,15 @@ generate (RSA_secret_key *sk, unsigned int nbits, unsigned long use_e)
       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 @@ rsa_unblind (gcry_mpi_t x, gcry_mpi_t ri, gcry_mpi_t n)
  **************  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 @@ _gcry_rsa_generate (int algo, unsigned int nbits, unsigned long use_e,
 
   (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_rsa_generate (int algo, unsigned int nbits, unsigned long use_e,
 
 
 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 @@ gcry_pk_spec_t _gcry_pubkey_spec_rsa =
   };
 pk_extra_spec_t _gcry_pubkey_extraspec_rsa = 
   {
-    run_selftests
+    run_selftests,
+    rsa_generate
   };
 
index b13464c..ab1a704 100644 (file)
@@ -539,13 +539,15 @@ hardwired and does not depend on any configuration options.
 
 @item 
 If the applications requests FIPS mode using the control command
-@code{GCRYCTL_FORCE_FIPS_MODE}.  This may be done at any time.
+@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.
 
 
 
@@ -689,7 +691,8 @@ This command sets the verbosity of the logging.  A level of 0 disables
 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 @@ memory syncronization is done so the effect of this command might not
 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
+@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 @@ command may be used before the intialization has been finished but not
 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 @@ functions for doing memory allocation.
 @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 @@ This type is defined as: @code{void (*gcry_handler_log_t) (void *, int, const ch
 @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
+@code{gcry_check_version}.
 @end deftypefun
 
 @c **********************************************************
@@ -2621,6 +2627,13 @@ Note that in this case only the values for N, as given in the table,
 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 cryptograohic strength.
+
+
 @end table
 @c end table of parameters
 
index 7f54e74..26b304c 100644 (file)
@@ -1,3 +1,13 @@
+2008-08-26  Werner Koch  <wk@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@g10code.com>
 
        * hmac256.c (_gcry_hmac256_file): New.
index ae5492b..4ca76b5 100644 (file)
@@ -39,6 +39,16 @@ typedef gpg_err_code_t (*selftest_func_t)
      (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,
+      unsigned long use_e,
+      unsigned int keygen_flags, 
+      gcry_mpi_t *skey,
+      gcry_mpi_t **retfactors);
+
+
 /* Extra module specification structures.  These are used for internal
    modules which provide more functions than available through the
    public algorithm register APIs.  */
@@ -55,6 +65,7 @@ typedef struct md_extra_spec
 typedef struct pk_extra_spec
 {
   selftest_func_t selftest;
+  pk_ext_generate_t ext_generate;
 } pk_extra_spec_t;
 
 
index 91b5831..8a4c2de 100644 (file)
@@ -26,7 +26,8 @@
 
 #include "../random/random.h"
 
-#define PUBKEY_FLAG_NO_BLINDING (1 << 0)
+#define PUBKEY_FLAG_NO_BLINDING    (1 << 0)
+#define PUBKEY_FLAG_TRANSIENT_KEY  (1 << 1)
 
 #include "cipher-proto.h"
 
index 8f36797..3089f76 100644 (file)
@@ -292,6 +292,9 @@ _gcry_fips_test_operational (void)
 static void
 reporter (const char *domain, int algo, const char *what, const char *errtxt)
 {
+  if (!errtxt && !_gcry_log_verbosity (2))
+    return;
+
   log_info ("libgcrypt selftest: %s %s%s (%d): %s%s%s%s\n",
             !strcmp (domain, "hmac")? "digest":domain,
             !strcmp (domain, "hmac")? "HMAC-":"",
@@ -625,9 +628,10 @@ fips_new_state (enum module_states new_state)
 
   unlock_fsm ();
 
-  log_info ("libgcrypt state transition %s => %s %s\n",
-            state2str (last_state), state2str (new_state),
-            ok? "granted":"denied");
+  if (!ok || _gcry_log_verbosity (2))
+    log_info ("libgcrypt state transition %s => %s %s\n",
+              state2str (last_state), state2str (new_state),
+              ok? "granted":"denied");
   
   if (!ok)
     {
index 8670de4..668dc30 100644 (file)
@@ -155,13 +155,16 @@ const char *_gcry_mpi_get_hw_config (void);
 
 /*-- primegen.c --*/
 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 _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 _gcry_generate_elg_prime( int mode, unsigned pbits, unsigned qbits,
-                                          gcry_mpi_t g, gcry_mpi_t **factors );
+gcry_mpi_t _gcry_generate_elg_prime (int mode, 
+                                     unsigned int pbits, unsigned int qbits,
+                                     gcry_mpi_t g, gcry_mpi_t **factors);
 
 
 /* replacements of missing functions (missing-string.c)*/
index 2b7f0bc..894146e 100644 (file)
@@ -455,8 +455,9 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, va_list arg_ptr)
 
     case GCRYCTL_FORCE_FIPS_MODE:
       /* Performing 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.  */
+         the library has already been initialized into fips mode, a
+         selftest is triggered.  it is not possible to put the libraty
+         into fips mode after having passed the initialization. */
       if (!any_init_done)
         {
           /* Not yet intialized at all.  Set a flag so that we are put
index 8817632..52e4db9 100644 (file)
@@ -1,3 +1,10 @@
+2008-08-26  Werner Koch  <wk@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@g10code.com>
 
        * t-mpi-bit.c (test_lshift): New.
index 7ae2de2..a904554 100644 (file)
@@ -1861,7 +1861,9 @@ get_keys_new (gcry_sexp_t *pkey, gcry_sexp_t *skey)
   if (verbose)
     fprintf (stderr, "  generating RSA key:");  
   rc = gcry_sexp_new (&key_spec,
-                     "(genkey (rsa (nbits 4:1024)))", 0, 1);
+                     in_fips_mode ? "(genkey (rsa (nbits 4:1024)))"
+                      : "(genkey (rsa (nbits 4:1024)(transient-key)))", 
+                      0, 1);
   if (rc)
     die ("error creating S-expression: %s\n", gpg_strerror (rc));
   rc = gcry_pk_genkey (&key, key_spec);
@@ -2057,7 +2059,7 @@ main (int argc, char **argv)
         }
       else if (!strcmp (*argv, "--verbose"))
         {
-          verbose = 1;
+          verbose++;
           argc--; argv++;
         }
       else if (!strcmp (*argv, "--debug"))
@@ -2072,6 +2074,8 @@ main (int argc, char **argv)
         }
     }          
 
+  gcry_control (GCRYCTL_SET_VERBOSITY, (int)verbose);
+
   if (use_fips)
     gcry_control (GCRYCTL_FORCE_FIPS_MODE, 0);
 
index f428a15..7f218a6 100644 (file)
@@ -629,7 +629,10 @@ rsa_bench (int iterations, int print_header, int no_blinding)
       fflush (stdout);
 
       err = gcry_sexp_build (&key_spec, NULL,
-                             "(genkey (RSA (nbits %d)))", p_sizes[testno]);
+                             gcry_control (GCRYCTL_FIPS_MODE_P, 0)
+                             ? "(genkey (RSA (nbits %d)))"
+                             : "(genkey (RSA (nbits %d)(transient-key)))",
+                             p_sizes[testno]);
       if (err)
         die ("creating S-expression failed: %s\n", gcry_strerror (err));
 
@@ -987,24 +990,11 @@ main( int argc, char **argv )
 {
   int last_argc = -1;
   int no_blinding = 0;
-
+  int use_random_daemon = 0;
 
   if (argc)
     { argc--; argv++; }
 
-  if (!gcry_check_version (GCRYPT_VERSION))
-    {
-      fprintf (stderr, PGM ": version mismatch\n");
-      exit (1);
-    }
-  gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
-
-  if (argc && !strcmp (*argv, "--use-random-daemon"))
-    {
-      gcry_control (GCRYCTL_USE_RANDOM_DAEMON, 1);
-      argc--; argv++;
-    }
-
   while (argc && last_argc != argc )
     {
       last_argc = argc;
@@ -1022,12 +1012,12 @@ main( int argc, char **argv )
         }
       else if (!strcmp (*argv, "--verbose"))
         {
-          verbose = 1;
+          verbose++;
           argc--; argv++;
         }
       else if (!strcmp (*argv, "--use-random-daemon"))
         {
-          gcry_control (GCRYCTL_USE_RANDOM_DAEMON, 1);
+          use_random_daemon = 1;
           argc--; argv++;
         }
       else if (!strcmp (*argv, "--no-blinding"))
@@ -1052,11 +1042,26 @@ main( int argc, char **argv )
       else if (!strcmp (*argv, "--fips"))
         {
           argc--; argv++;
+          /* This command needs to be called before gcry_check_version.  */
           gcry_control (GCRYCTL_FORCE_FIPS_MODE, 0);
         }
     }          
+
+  gcry_control (GCRYCTL_SET_VERBOSITY, (int)verbose);
+
+  if (!gcry_check_version (GCRYPT_VERSION))
+    {
+      fprintf (stderr, PGM ": version mismatch\n");
+      exit (1);
+    }
+  gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
+
+  if (use_random_daemon)
+    gcry_control (GCRYCTL_USE_RANDOM_DAEMON, 1);
+
   gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
 
+
   if (cipher_repetitions < 1)
     cipher_repetitions = 1;