[svn] gcry - r1189 - trunk/cipher

svn author wk cvs at cvs.gnupg.org
Wed Oct 25 20:28:50 CEST 2006


Author: wk
Date: 2006-10-25 20:28:49 +0200 (Wed, 25 Oct 2006)
New Revision: 1189

Modified:
   trunk/cipher/ChangeLog
   trunk/cipher/ac.c
   trunk/cipher/primegen.c
   trunk/cipher/pubkey.c
Log:
See ChangeLog.  There are still problems in ac.c.


Modified: trunk/cipher/ChangeLog
===================================================================
--- trunk/cipher/ChangeLog	2006-10-23 09:14:16 UTC (rev 1188)
+++ trunk/cipher/ChangeLog	2006-10-25 18:28:49 UTC (rev 1189)
@@ -1,3 +1,19 @@
+2006-10-25  Werner Koch  <wk at g10code.com>
+
+	* primegen.c (prime_generate_internal): Tweaked use of secure
+	memory and entropy use. Safe unused primes from the pool. Allocate
+	at least a pool of 30.
+	(save_pool_prime, get_pool_prime): New.
+
+2006-10-23  Werner Koch  <wk at g10code.com>
+
+	* ac.c (_gcry_ac_data_from_sexp): Reset sexp_tmp for failsafe
+	means.  Release sexp_cur if needed.  Reported by Dirk Stoecker.
+
+	* pubkey.c (pubkeys_registered_lock): Intialized it.  It is not
+	 realy needed because this is a mere initialization to 0 anyway.
+	 Noted by Victor Stinner.
+
 2006-10-17  Werner Koch  <wk at g10code.com>
 
 	* dsa.c (_gcry_dsa_generate2): New.
@@ -50,7 +66,7 @@
 	* blowfish.c (selftest): Cast string to usnigned char*.
 
 	* primegen.c (prime_generate_internal): Cast unsigned/char*
-	mismatch in calling m_out_od_n.
+	mismatch in calling m_out_of_n.
 	(is_prime): Changed COUNT to unsigned int *.
 
 	* ac.c (_gcry_ac_data_copy): Initialize DATA_MPIS.
@@ -3052,7 +3068,7 @@
 
 Mon Mar  2 19:21:46 1998  Werner Koch  (wk at isil.d.shuttle.de)
 
-	* gost.c, gost.h: Removed because they did only conatin trash.
+	* gost.c, gost.h: Removed because they did only contain trash.
 
 Sun Mar  1 16:42:29 1998  Werner Koch  (wk at isil.d.shuttle.de)
 

Modified: trunk/cipher/ac.c
===================================================================
--- trunk/cipher/ac.c	2006-10-23 09:14:16 UTC (rev 1188)
+++ trunk/cipher/ac.c	2006-10-25 18:28:49 UTC (rev 1189)
@@ -743,28 +743,32 @@
 
 	      /* Release old SEXP_CUR, in case it is not equal to the
 		 original SEXP.  */
-
 	      if (sexp_cur != sexp)
 		gcry_sexp_release (sexp_cur);
 
 	      /* Make SEXP_CUR point to the new current sublist.  */
 	      sexp_cur = sexp_tmp;
+              sexp_tmp = NULL;
 	    }
 	}
       if (err)
 	goto out;
 
       if (i)
-	/* We have at least one identifier in the list, this means the
-	   the list of named MPI values is prefixed, this means that
-	   we need to skip the first item (the list name), when
-	   processing the MPI values.  */
-	skip_name = 1;
+        {
+          /* We have at least one identifier in the list, this means
+             the the list of named MPI values is prefixed, this means
+             that we need to skip the first item (the list name), when
+             processing the MPI values.  */
+          skip_name = 1;
+        }
       else
-	/* Since there is no identifiers list, the list of named MPI
-	   values is not prefixed with a list name, therefore the
-	   offset to use is zero.  */
-	skip_name = 0;
+        {
+          /* Since there is no identifiers list, the list of named MPI
+             values is not prefixed with a list name, therefore the
+             offset to use is zero.  */
+          skip_name = 0;
+        }
     }
   else
     /* Since there is no identifiers list, the list of named MPI
@@ -821,7 +825,9 @@
       if (err)
 	break;
 
+/*       gcry_free (string); */
       string = NULL;
+/*       gcry_mpi_release (mpi); */
       mpi = NULL;
 
       gcry_sexp_release (sexp_tmp);
@@ -834,6 +840,8 @@
 
  out:
 
+  if (sexp_cur != sexp)
+    gcry_sexp_release (sexp_cur);
   gcry_sexp_release (sexp_tmp);
   gcry_mpi_release (mpi);
   gcry_free (string);

Modified: trunk/cipher/primegen.c
===================================================================
--- trunk/cipher/primegen.c	2006-10-23 09:14:16 UTC (rev 1188)
+++ trunk/cipher/primegen.c	2006-10-25 18:28:49 UTC (rev 1189)
@@ -17,11 +17,6 @@
  * You should have received a copy of the GNU Lesser General Public
  * License along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- *
- * ***********************************************************************
- * The algorithm used to generate practically save primes is due to
- * Lim and Lee as described in the CRYPTO '97 proceedings (ISBN3540633847)
- * page 260.
  */
 
 #include <config.h>
@@ -35,6 +30,7 @@
 #include "g10lib.h"
 #include "mpi.h"
 #include "cipher.h"
+#include "ath.h"
 
 static gcry_mpi_t gen_prime (unsigned int nbits, int secret, int randomlevel, 
                              int (*extra_check)(void *, gcry_mpi_t),
@@ -133,6 +129,96 @@
 };
 static int no_of_small_prime_numbers = DIM (small_prime_numbers) - 1;
 
+
+
+/* An object and a list to build up a global pool of primes.  See
+   save_pool_prime and get_pool_prime. */
+struct primepool_s 
+{
+  struct primepool_s *next;
+  gcry_mpi_t prime;      /* If this is NULL the entry is not used. */
+  unsigned int nbits;
+  gcry_random_level_t randomlevel;
+};
+struct primepool_s *primepool;
+/* Mutex used to protect access to the primepool.  */
+static ath_mutex_t primepool_lock = ATH_MUTEX_INITIALIZER;
+
+
+
+/* Save PRIME which has been generated at RANDOMLEVEL for later
+   use. Needs to be called while primepool_lock is being hold.  Note
+   that PRIME should be considered released after calling this
+   function. */
+static void
+save_pool_prime (gcry_mpi_t prime, gcry_random_level_t randomlevel)
+{
+  struct primepool_s *item, *item2;
+  size_t n;
+
+  for (n=0, item = primepool; item; item = item->next, n++)
+    if (!item->prime)
+      break;
+  if (!item && n > 100)
+    {
+      /* Remove some of the entries.  Our strategy is removing
+         the last third from the list. */
+      int i;
+      
+      for (i=0, item2 = primepool; item2; item2 = item2->next)
+        {
+          if (i >= n/3*2)
+            {
+              gcry_mpi_release (item2->prime);
+              item2->prime = NULL;
+              if (!item)
+                item = item2;
+            }
+        }
+    }
+  if (!item)
+    {
+      item = gcry_calloc (1, sizeof *item);
+      if (!item)
+        {
+          /* Out of memory.  Silently giving up. */
+          gcry_mpi_release (prime);
+          return; 
+        }
+      item->next = primepool;
+      primepool = item;
+    }
+  item->prime = prime;
+  item->nbits = mpi_get_nbits (prime);
+  item->randomlevel = randomlevel;
+}
+
+
+/* Return a prime for the prime pool or NULL if none has been found.
+   The prime needs to match NBITS and randomlevel. This function needs
+   to be called why the primepool_look is being hold. */
+static gcry_mpi_t
+get_pool_prime (unsigned int nbits, gcry_random_level_t randomlevel)
+{
+  struct primepool_s *item;
+
+  for (item = primepool; item; item = item->next)
+    if (item->prime
+        && item->nbits == nbits && item->randomlevel == randomlevel)
+      {
+        gcry_mpi_t prime = item->prime;
+        item->prime = NULL;
+        assert (nbits == mpi_get_nbits (prime));
+        return prime;
+      }
+  return NULL;
+}
+
+
+
+
+
+
 void
 _gcry_register_primegen_progress ( void (*cb)(void *,const char*,int,int,int),
                                    void *cb_data )
@@ -178,18 +264,30 @@
 }
 
 
-/****************
- * We do not need to use the strongest RNG because we gain no extra
- * security from it - The prime number is public and we could also
- * offer the factors for those who are willing to check that it is
- * indeed a strong prime.  With ALL_FACTORS set to true all afcors of
- * prime-1 are returned in FACTORS.
- *
- * mode 0: Standard
- *	1: Make sure that at least one factor is of size qbits.
+/* Core prime generation function.  The algorithm used to generate
+   practically save primes is due to Lim and Lee as described in the
+   CRYPTO '97 proceedings (ISBN3540633847) page 260.
+
+   NEED_Q_FACTOR: If true make sure that at least one factor is of
+                  size qbits.  This is for example required for DSA.
+   PRIME_GENERATED: Adresss of a variable where the resulting prime
+                    number will be stored.
+   PBITS: Requested size of the prime number.  At least 48.
+   QBITS: One factor of the prime needs to be of this size.  Maybe 0
+          if this is not required.  See also MODE.
+   G: If not NULL an MPI which will receive a generator for the prime
+      for use with Elgamal.
+   RET_FACTORS: if not NULL, an array with all factors are stored at
+                that address.
+   ALL_FACTORS: If set to true all factors of prime-1 are returned.
+   RANDOMLEVEL:  How strong should the random numers be.
+   FLAGS: Prime generation bit flags. Currently supported:
+          GCRY_PRIME_FLAG_SECRET - The prime needs to be kept secret.
+   CB_FUNC, CB_ARG:  Callback to be used for extra checks.
+
  */
 static gcry_err_code_t
-prime_generate_internal (int mode,
+prime_generate_internal (int need_q_factor,
 			 gcry_mpi_t *prime_generated, unsigned int pbits,
 			 unsigned int qbits, gcry_mpi_t g,
 			 gcry_mpi_t **ret_factors,
@@ -201,7 +299,9 @@
   gcry_mpi_t *factors_new = NULL; /* Factors to return to the
 				     caller.  */
   gcry_mpi_t *factors = NULL;	/* Current factors.  */
+  gcry_random_level_t poolrandomlevel; /* Random level used for pool primes. */
   gcry_mpi_t *pool = NULL;	/* Pool of primes.  */
+  int *pool_in_use = NULL;      /* Array with currently used POOL elements. */
   unsigned char *perms = NULL;	/* Permutations of POOL.  */
   gcry_mpi_t q_factor = NULL;	/* Used if QBITS is non-zero.  */
   unsigned int fbits = 0;	/* Length of prime factors.  */
@@ -212,6 +312,7 @@
   unsigned int nprime = 0;	/* Bits of PRIME.  */
   unsigned int req_qbits;       /* The original QBITS value.  */
   gcry_mpi_t val_2;             /* For check_prime().  */
+  int is_locked = 0;            /* Flag to help unlocking the primepool. */
   unsigned int is_secret = (flags & GCRY_PRIME_FLAG_SECRET);
   unsigned int count1 = 0, count2 = 0;
   unsigned int i = 0, j = 0;
@@ -219,28 +320,33 @@
   if (pbits < 48)
     return GPG_ERR_INV_ARG;
 
+  /* We won't use a too strong random elvel for the pooled subprimes. */
+  poolrandomlevel = (randomlevel > GCRY_STRONG_RANDOM?
+                     GCRY_STRONG_RANDOM : randomlevel);
+
+
   /* If QBITS is not given, assume a reasonable value. */
   if (!qbits)
     qbits = pbits / 3;
 
   req_qbits = qbits;
 
-  /* Find number of needed prime factors.  */
+  /* Find number of needed prime factors N.  */
   for (n = 1; (pbits - qbits - 1) / n  >= qbits; n++)
     ;
   n--;
 
   val_2 = mpi_alloc_set_ui (2);
 
-  if ((! n) || ((mode == 1) && (n < 2)))
+  if ((! n) || ((need_q_factor) && (n < 2)))
     {
       err = GPG_ERR_INV_ARG;
       goto leave;
     }
 
-  if (mode == 1)
+  if (need_q_factor)
     {
-      n--;
+      n--;  /* Need one factor less because we want a specific Q-FACTOR. */
       fbits = (pbits - 2 * req_qbits -1) / n;
       qbits =  pbits - req_qbits - n * fbits;
     }
@@ -254,28 +360,45 @@
     log_debug ("gen prime: pbits=%u qbits=%u fbits=%u/%u n=%d\n",
                pbits, req_qbits, qbits, fbits, n);
 
+  /* Allocate an integer to old the new prime. */
   prime = gcry_mpi_new (pbits);
 
   /* Generate first prime factor.  */
   q = gen_prime (qbits, is_secret, randomlevel, NULL, NULL);
-  
-  if (mode == 1)
+
+  /* Generate a specific Q-Factor if requested. */
+  if (need_q_factor)
     q_factor = gen_prime (req_qbits, is_secret, randomlevel, NULL, NULL);
   
-  /* Allocate an array to hold the factors + 2 for later usage.  */
+  /* Allocate an array to hold all factors + 2 for later usage.  */
   factors = gcry_calloc (n + 2, sizeof (*factors));
   if (!factors)
     {
       err = gpg_err_code_from_errno (errno);
       goto leave;
     }
+
+  /* Allocate an array to track pool usage. */
+  pool_in_use = gcry_malloc (n * sizeof *pool_in_use);
+  if (!pool_in_use)
+    {
+      err = gpg_err_code_from_errno (errno);
+      goto leave;
+    }
+  for (i=0; i < n; i++)
+    pool_in_use[i] = -1;
       
-  /* Make a pool of 3n+5 primes (this is an arbitrary value).  */
+  /* Make a pool of 3n+5 primes (this is an arbitrary value).  We
+     require at least 30 primes for are useful selection process. 
+     
+     FIXME: We need to do some reseacrh on the best formula for sizing
+     the pool.
+  */
   m = n * 3 + 5;
-  if (mode == 1) /* Need some more (for e.g. DSA).  */
+  if (need_q_factor) /* Need some more in this case. */
     m += 5;
-  if (m < 25)
-    m = 25;
+  if (m < 30)
+    m = 30;
   pool = gcry_calloc (m , sizeof (*pool));
   if (! pool)
     {
@@ -283,14 +406,19 @@
       goto leave;
     }
 
-  /* Permutate over the pool of primes.  */
+  /* Permutate over the pool of primes until we find a prime of the
+     requested length.  */
   do
     {
     next_try:
-      if (! perms)
+      for (i=0; i < n; i++)
+        pool_in_use[i] = -1;
+
+      if (!perms)
         {
-          /* Allocate new primes.  */
-          for(i = 0; i < m; i++)
+          /* Allocate new primes.  This is done right at the beginning
+             of the loop and if we have later run out of primes. */
+          for (i = 0; i < m; i++)
             {
               mpi_free (pool[i]);
               pool[i] = NULL;
@@ -298,44 +426,110 @@
 
           /* Init m_out_of_n().  */
           perms = gcry_calloc (1, m);
-          if (! perms)
+          if (!perms)
             {
               err = gpg_err_code_from_errno (errno);
               goto leave;
             }
-          for(i = 0; i < n; i++)
+
+          if (ath_mutex_lock (&primepool_lock))
             {
-              perms[i] = 1;
-              pool[i] = gen_prime (fbits, is_secret,
-                                   randomlevel, NULL, NULL);
+              err = GPG_ERR_INTERNAL;
+              goto leave;
+            }
+          is_locked = 1;
+          for (i = 0; i < n; i++)
+            {
+              perms[i] = 1; 
+              /* At a maximum we use strong random for the factors.
+                 This saves us a lot of entropy. Given that Q and
+                 possible Q-factor are also used in the final prime
+                 this should be acceptable.  We also don't allocate in
+                 secure memory to save on that scare resource too.  If
+                 Q has been allocated in secure memory, the final
+                 prime will be saved there anyway.  This is because
+                 our MPI routines take care of that.  GnuPG has worked
+                 this way ever since.  */
+              pool[i] = NULL;
+              if (is_locked)
+                {
+                  pool[i] = get_pool_prime (fbits, poolrandomlevel);
+                  if (!pool[i])
+                    {
+                      if (ath_mutex_unlock (&primepool_lock))
+                        {
+                          err = GPG_ERR_INTERNAL;
+                          goto leave;
+                        }
+                      is_locked = 0;
+                    }
+                }
+              if (!pool[i])
+                pool[i] = gen_prime (fbits, 0, poolrandomlevel, NULL, NULL);
+              pool_in_use[i] = i;
               factors[i] = pool[i];
             }
+          if (is_locked && ath_mutex_unlock (&primepool_lock))
+            {
+              err = GPG_ERR_INTERNAL;
+              goto leave;
+            }
+          is_locked = 0;
         }
       else
         {
+          /* Get next permutation. */
           m_out_of_n ( (char*)perms, n, m);
+          if (ath_mutex_lock (&primepool_lock))
+            {
+              err = GPG_ERR_INTERNAL;
+              goto leave;
+            }
+          is_locked = 1;
           for (i = j = 0; (i < m) && (j < n); i++)
             if (perms[i])
               {
-                if(! pool[i])
-                  pool[i] = gen_prime (fbits, 0, 1, NULL, NULL);
+                /* If the subprime has not yet beed generated do it now. */
+                if (!pool[i] && is_locked)
+                  {
+                    pool[i] = get_pool_prime (fbits, poolrandomlevel);
+                    if (!pool[i])
+                      {
+                        if (ath_mutex_unlock (&primepool_lock))
+                          {
+                            err = GPG_ERR_INTERNAL;
+                            goto leave;
+                          }
+                        is_locked = 0;
+                      }
+                  }
+                if (!pool[i])
+                  pool[i] = gen_prime (fbits, 0, poolrandomlevel, NULL, NULL);
+                pool_in_use[j] = i;
                 factors[j++] = pool[i];
               }
+          if (is_locked && ath_mutex_unlock (&primepool_lock))
+            {
+              err = GPG_ERR_INTERNAL;
+              goto leave;
+            }
+          is_locked = 0;
           if (i == n)
             {
+              /* Ran out of permutations: Allocate new primes.  */
               gcry_free (perms);
               perms = NULL;
               progress ('!');
-              goto next_try;	/* Allocate new primes.  */
+              goto next_try;	
             }
         }
 
 	/* Generate next prime candidate:
 	   p = 2 * q [ * q_factor] * factor_0 * factor_1 * ... * factor_n + 1. 
-        */
+         */
 	mpi_set (prime, q);
 	mpi_mul_ui (prime, prime, 2);
-	if (mode == 1)
+	if (need_q_factor)
 	  mpi_mul (prime, prime, q_factor);
 	for(i = 0; i < n; i++)
 	  mpi_mul (prime, prime, factors[i]);
@@ -350,7 +544,7 @@
 		qbits++;
 		progress('>');
 		mpi_free (q);
-		q = gen_prime (qbits, 0, 0, NULL, NULL);
+		q = gen_prime (qbits, is_secret, randomlevel, NULL, NULL);
 		goto next_try;
 	      }
 	  }
@@ -365,7 +559,7 @@
 		qbits--;
 		progress('<');
 		mpi_free (q);
-		q = gen_prime (qbits, 0, 0, NULL, NULL);
+		q = gen_prime (qbits, is_secret, randomlevel, NULL, NULL);
 		goto next_try;
 	      }
 	  }
@@ -380,13 +574,13 @@
       progress ('\n');
       log_mpidump ("prime    : ", prime);
       log_mpidump ("factor  q: ", q);
-      if (mode == 1)
+      if (need_q_factor)
         log_mpidump ("factor q0: ", q_factor);
       for (i = 0; i < n; i++)
         log_mpidump ("factor pi: ", factors[i]);
       log_debug ("bit sizes: prime=%u, q=%u",
                  mpi_get_nbits (prime), mpi_get_nbits (q));
-      if (mode == 1)
+      if (need_q_factor)
         log_debug (", q0=%u", mpi_get_nbits (q_factor));
       for (i = 0; i < n; i++)
         log_debug (", p%d=%u", i, mpi_get_nbits (factors[i]));
@@ -408,7 +602,7 @@
           i = 0;
           factors_new[i++] = gcry_mpi_set_ui (NULL, 2);
           factors_new[i++] = mpi_copy (q);
-          if (mode == 1)
+          if (need_q_factor)
             factors_new[i++] = mpi_copy (q_factor);
           for(j=0; j < n; j++)
             factors_new[i++] = mpi_copy (factors[j]);
@@ -416,7 +610,7 @@
       else
         {
           i = 0;
-          if (mode == 1)
+          if (need_q_factor)
             {
               factors_new[i++] = mpi_copy (q_factor);
               for (; i <= n; i++)
@@ -435,7 +629,7 @@
       gcry_mpi_t b = mpi_alloc (mpi_get_nlimbs (prime));
       gcry_mpi_t pmin1 = mpi_alloc (mpi_get_nlimbs (prime));
       
-      if (mode == 1)
+      if (need_q_factor)
         err = GPG_ERR_NOT_IMPLEMENTED;
       else
         {
@@ -482,10 +676,29 @@
  leave:
   if (pool)
     {
+      is_locked = !ath_mutex_lock (&primepool_lock);
       for(i = 0; i < m; i++)
-	mpi_free (pool[i]);
+        {
+          if (pool[i])
+            {
+              for (j=0; j < n; j++)
+                if (pool_in_use[j] == i)
+                  break;
+              if (j == n && is_locked)
+                {
+                  /* This pooled subprime has not been used. */
+                  save_pool_prime (pool[i], poolrandomlevel);
+                }
+              else
+                mpi_free (pool[i]);
+            }
+        }
+      if (is_locked && ath_mutex_unlock (&primepool_lock))
+        err = GPG_ERR_INTERNAL;
+      is_locked = 0;
       gcry_free (pool);
     }
+  gcry_free (pool_in_use);
   if (factors)
     gcry_free (factors);  /* Factors are shallow copies.  */
   if (perms)
@@ -515,6 +728,8 @@
   return err;
 }
 
+
+
 gcry_mpi_t
 _gcry_generate_elg_prime (int mode, unsigned pbits, unsigned qbits,
 			  gcry_mpi_t g, gcry_mpi_t **ret_factors)
@@ -522,7 +737,7 @@
   gcry_err_code_t err = GPG_ERR_NO_ERROR;
   gcry_mpi_t prime = NULL;
   
-  err = prime_generate_internal (mode, &prime, pbits, qbits, g,
+  err = prime_generate_internal ((mode == 1), &prime, pbits, qbits, g,
 				 ret_factors, GCRY_WEAK_RANDOM, 0, 0,
                                  NULL, NULL);
 
@@ -765,6 +980,21 @@
 }
 
 
+/* Given ARRAY of size N with M elements set to true produce a
+   modified array with the next permutation of M elements.  Note, that
+   ARRAY is used in a one-bit-per-byte approach.  To detected the last
+   permutation it is useful to intialize the array with the first M
+   element set to true and use this test:
+       m_out_of_n (array, m, n);
+       for (i = j = 0; i < n && j < m; i++)
+         if (array[i])
+           j++;
+       if (j == m)
+         goto ready;
+     
+   This code is based on the algorithm 452 from the "Collected
+   Algorithms From ACM, Volume II" by C. N. Liu and D. T. Tang.
+*/
 static void
 m_out_of_n ( char *array, int m, int n )
 {
@@ -773,12 +1003,12 @@
   if( !m || m >= n )
     return;
 
+  /* Need to handle this simple case separately. */
   if( m == 1 )
     { 
-      /* Special case. */
       for (i=0; i < n; i++ )
         {
-          if( array[i] )
+          if ( array[i] )
             {
               array[i++] = 0;
               if( i >= n )
@@ -790,6 +1020,7 @@
       BUG();
     }
 
+
   for (j=1; j < n; j++ )
     {
       if ( array[n-1] == array[n-j-1])
@@ -866,6 +1097,7 @@
       k2 = n + 1 - m;
     }
  leave:
+  /* Now complement the two selected bits. */
   array[k1-1] = !array[k1-1];
   array[k2-1] = !array[k2-1];
 }
@@ -897,7 +1129,7 @@
     mode = 1;
 
   /* Generate.  */
-  err = prime_generate_internal (mode, &prime_generated, prime_bits,
+  err = prime_generate_internal ((mode==1), &prime_generated, prime_bits,
 				 factor_bits, NULL,
                                  factors? &factors_generated : NULL,
 				 random_level, flags, 1,

Modified: trunk/cipher/pubkey.c
===================================================================
--- trunk/cipher/pubkey.c	2006-10-23 09:14:16 UTC (rev 1188)
+++ trunk/cipher/pubkey.c	2006-10-25 18:28:49 UTC (rev 1189)
@@ -66,7 +66,7 @@
 static gcry_module_t pubkeys_registered;
 
 /* This is the lock protecting PUBKEYS_REGISTERED.  */
-static ath_mutex_t pubkeys_registered_lock;
+static ath_mutex_t pubkeys_registered_lock = ATH_MUTEX_INITIALIZER;;
 
 /* Flag to check wether the default pubkeys have already been
    registered.  */




More information about the Gnupg-commits mailing list