[svn] gcry - r1325 - trunk/cipher

svn author wk cvs at cvs.gnupg.org
Fri Sep 12 13:40:22 CEST 2008


Author: wk
Date: 2008-09-12 13:40:22 +0200 (Fri, 12 Sep 2008)
New Revision: 1325

Modified:
   trunk/cipher/ChangeLog
   trunk/cipher/dsa.c
   trunk/cipher/rsa.c
Log:
Improve selftest done after key generation.


Modified: trunk/cipher/ChangeLog
===================================================================
--- trunk/cipher/ChangeLog	2008-09-12 09:48:04 UTC (rev 1324)
+++ trunk/cipher/ChangeLog	2008-09-12 11:40:22 UTC (rev 1325)
@@ -3,6 +3,10 @@
 	* rsa.c (extract_a_from_sexp): New.
 	(selftest_encr_1024): Check that the ciphertext does not match the
 	plaintext.
+	(test_keys): Improve tests and return an error status.
+	(generate): Return an error if test_keys fails.
+	* dsa.c (test_keys): Add comments and return an error status.
+	(generate): Return an error if test_keys failed.
 
 2008-09-11  Werner Koch  <wk at g10code.com>
 

Modified: trunk/cipher/dsa.c
===================================================================
--- trunk/cipher/dsa.c	2008-09-12 09:48:04 UTC (rev 1324)
+++ trunk/cipher/dsa.c	2008-09-12 11:40:22 UTC (rev 1325)
@@ -87,7 +87,7 @@
 
 
 static gcry_mpi_t gen_k (gcry_mpi_t q);
-static void test_keys (DSA_secret_key *sk, unsigned qbits);
+static int test_keys (DSA_secret_key *sk, unsigned int qbits);
 static int check_secret_key (DSA_secret_key *sk);
 static gpg_err_code_t generate (DSA_secret_key *sk,
                                 unsigned int nbits,
@@ -183,27 +183,39 @@
 }
 
 
-static void
-test_keys( DSA_secret_key *sk, unsigned qbits )
+/* Check that a freshly generated key actually works.  Returns 0 on success. */
+static int
+test_keys (DSA_secret_key *sk, unsigned int qbits)
 {
+  int result = -1;  /* Default to failure.  */
   DSA_public_key pk;
-  gcry_mpi_t test = gcry_mpi_new ( qbits  );
-  gcry_mpi_t out1_a = gcry_mpi_new ( qbits );
-  gcry_mpi_t out1_b = gcry_mpi_new ( qbits );
+  gcry_mpi_t data  = gcry_mpi_new (qbits);
+  gcry_mpi_t sig_a = gcry_mpi_new (qbits);
+  gcry_mpi_t sig_b = gcry_mpi_new (qbits);
 
+  /* Put the relevant parameters into a public key structure.  */
   pk.p = sk->p;
   pk.q = sk->q;
   pk.g = sk->g;
   pk.y = sk->y;
-  gcry_mpi_randomize( test, qbits, GCRY_WEAK_RANDOM );
 
-  sign( out1_a, out1_b, test, sk );
-  if( !verify( out1_a, out1_b, test, &pk ) )
-    log_fatal("DSA:: sign, verify failed\n");
+  /* Create a random plaintext.  */
+  gcry_mpi_randomize (data, qbits, GCRY_WEAK_RANDOM);
 
-  gcry_mpi_release ( test );
-  gcry_mpi_release ( out1_a );
-  gcry_mpi_release ( out1_b );
+  /* Sign DATA using the secret key.  */
+  sign (sig_a, sig_b, data, sk);
+
+  /* Verify the signature using the public key.  */
+  if ( !verify (sig_a, sig_b, data, &pk) )
+    goto leave; /* Signature does not match.  */
+
+  result = 0; /* The test succeeded.  */
+
+ leave:
+  gcry_mpi_release (sig_b);
+  gcry_mpi_release (sig_a);
+  gcry_mpi_release (data);
+  return result;
 }
 
 
@@ -323,7 +335,15 @@
   sk->x = x;
 
   /* Now we can test our keys (this should never fail!). */
-  test_keys( sk, qbits );
+  if ( test_keys (sk, qbits) )
+    {
+      gcry_mpi_release (sk->p); sk->p = NULL;
+      gcry_mpi_release (sk->q); sk->q = NULL;
+      gcry_mpi_release (sk->g); sk->g = NULL;
+      gcry_mpi_release (sk->y); sk->y = NULL;
+      gcry_mpi_release (sk->x); sk->x = NULL;
+      return GPG_ERR_SELFTEST_FAILED;
+    }
   return 0;
 }
 

Modified: trunk/cipher/rsa.c
===================================================================
--- trunk/cipher/rsa.c	2008-09-12 09:48:04 UTC (rev 1324)
+++ trunk/cipher/rsa.c	2008-09-12 11:40:22 UTC (rev 1325)
@@ -84,7 +84,7 @@
 
 
 
-static void test_keys (RSA_secret_key *sk, unsigned nbits);
+static int 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,
                                 int transient_key);
@@ -93,29 +93,57 @@
 static void secret (gcry_mpi_t output, gcry_mpi_t input, RSA_secret_key *skey);
 
 
-static void
-test_keys( RSA_secret_key *sk, unsigned nbits )
+/* Check that a freshly generated key actually works.  Returns 0 on success. */
+static int
+test_keys (RSA_secret_key *sk, unsigned int nbits)
 {
+  int result = -1; /* Default to failure.  */
   RSA_public_key pk;
-  gcry_mpi_t test = gcry_mpi_new ( nbits );
-  gcry_mpi_t out1 = gcry_mpi_new ( nbits );
-  gcry_mpi_t out2 = gcry_mpi_new ( nbits );
+  gcry_mpi_t plaintext = gcry_mpi_new (nbits);
+  gcry_mpi_t ciphertext = gcry_mpi_new (nbits);
+  gcry_mpi_t decr_plaintext = gcry_mpi_new (nbits);
+  gcry_mpi_t signature = gcry_mpi_new (nbits);
 
+  /* Put the relevant parameters into a public key structure.  */
   pk.n = sk->n;
   pk.e = sk->e;
-  gcry_mpi_randomize( test, nbits, GCRY_WEAK_RANDOM );
 
-  public( out1, test, &pk );
-  secret( out2, out1, sk );
-  if( mpi_cmp( test, out2 ) )
-    log_fatal("RSA operation: public, secret failed\n");
-  secret( out1, test, sk );
-  public( out2, out1, &pk );
-  if( mpi_cmp( test, out2 ) )
-    log_fatal("RSA operation: secret, public failed\n");
-  gcry_mpi_release ( test );
-  gcry_mpi_release ( out1 );
-  gcry_mpi_release ( out2 );
+  /* Create a random plaintext.  */
+  gcry_mpi_randomize (plaintext, nbits, GCRY_WEAK_RANDOM);
+
+  /* Encrypt using the public key.  */
+  public (ciphertext, plaintext, &pk);
+
+  /* Check that the cipher text does not match the plaintext.  */
+  if (!gcry_mpi_cmp (ciphertext, plaintext))
+    goto leave; /* Ciphertext is identical to the plaintext.  */
+
+  /* Decrypt using the secret key.  */
+  secret (decr_plaintext, ciphertext, sk);
+
+  /* Check that the decrypted plaintext matches the original plaintext.  */
+  if (gcry_mpi_cmp (decr_plaintext, plaintext))
+    goto leave; /* Plaintext does not match.  */
+
+  /* Create another random plaintext as data for signature checking.  */
+  gcry_mpi_randomize (plaintext, nbits, GCRY_WEAK_RANDOM);
+
+  /* Use the RSA secret function to create a signature of the plaintext.  */
+  secret (signature, plaintext, sk);
+  
+  /* Use the RSA public function to verify this signature.  */
+  public (decr_plaintext, signature, &pk);
+  if (gcry_mpi_cmp (decr_plaintext, plaintext))
+    goto leave; /* Signature does not match.  */
+
+  result = 0; /* All tests succeeded.  */
+
+ leave:
+  gcry_mpi_release (signature);
+  gcry_mpi_release (decr_plaintext);
+  gcry_mpi_release (ciphertext);
+  gcry_mpi_release (plaintext);
+  return result;
 }
 
 
@@ -279,8 +307,17 @@
   sk->d = d;
   sk->u = u;
 
-  /* now we can test our keys (this should never fail!) */
-  test_keys( sk, nbits - 64 );
+  /* Now we can test our keys. */
+  if (test_keys (sk, nbits - 64))
+    {
+      gcry_mpi_release (sk->n); sk->n = NULL;
+      gcry_mpi_release (sk->e); sk->e = NULL;
+      gcry_mpi_release (sk->p); sk->p = NULL;
+      gcry_mpi_release (sk->q); sk->q = NULL;
+      gcry_mpi_release (sk->d); sk->d = NULL;
+      gcry_mpi_release (sk->u); sk->u = NULL;
+      return GPG_ERR_SELFTEST_FAILED;
+    }
 
   return 0;
 }




More information about the Gnupg-commits mailing list