File libgcrypt-PCT-RSA.patch of Package libgcrypt.14348

Index: libgcrypt-1.8.2/cipher/rsa.c
===================================================================
--- libgcrypt-1.8.2.orig/cipher/rsa.c
+++ libgcrypt-1.8.2/cipher/rsa.c
@@ -159,19 +159,65 @@ test_keys (RSA_secret_key *sk, unsigned
   /* 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 gcry_pk_sign_md API in order to comply with FIPS 140-2,
+   * which requires full signature operation for PCT (hashing +
+   * asymmetric operation */
+  gcry_sexp_t s_skey = NULL;
+  gcry_sexp_t s_pkey = NULL;
+  gcry_sexp_t r_sig = NULL;
+  gcry_sexp_t s_hash = NULL;
+  gcry_md_hd_t hd = NULL;
+  unsigned char *buf = NULL;
+  size_t buflen;
+
+  if (_gcry_md_open(&hd, GCRY_MD_SHA256, 0))
+    {
+      log_debug("gcry_pk_sign failed\n");
+      goto leave;
+    }
+
+  _gcry_mpi_aprint(GCRYMPI_FMT_STD, &buf, &buflen, plaintext);
+  _gcry_md_write(hd, buf, buflen);
+
+  /* build RSA private key sexp in s_skey */
+  sexp_build(&s_skey, NULL, "(private-key (rsa(n %m)(e %m)(d %m)(p %m)(q %m)))", sk->n, sk->e, sk->d, sk->p, sk->q);
+  sexp_build(&s_hash, NULL, "(data (flags pkcs1)(hash-algo sha256))");
+  if (_gcry_pk_sign_md(&r_sig, hd, s_hash, s_skey))
+    {
+      log_debug("gcry_pk_sign failed\n");
+      goto leave;
+    }
+
+  _gcry_sexp_release(s_hash);
+  _gcry_md_close(hd);
+  xfree(buf);
+
+  /* build RSA public key sexp in s_pkey */
+  sexp_build(&s_pkey, NULL, "(public-key (rsa(n %m)(e %m)))", pk.n, pk.e);
+  sexp_build(&s_hash, NULL, "(data (flags pkcs1)(hash-algo sha256))");
+
+  if (_gcry_md_open(&hd, GCRY_MD_SHA256, 0))
+    log_debug("gcry_md_open failed\n");
+
+  _gcry_mpi_aprint(GCRYMPI_FMT_STD, &buf, &buflen, plaintext);
+  _gcry_md_write(hd, buf, buflen);
+
+  /* verify the signature */
+  if (_gcry_pk_verify_md(r_sig, hd, s_hash, s_pkey))
+    {
+      log_debug("gcry_pk_verify failed\n");
+      goto leave; /* Signature does not match.  */
+    }
 
-  /* Use the RSA public function to verify this signature.  */
-  public (decr_plaintext, signature, &pk);
-  if (mpi_cmp (decr_plaintext, plaintext))
-    goto leave; /* Signature does not match.  */
 
+#if 0
+  TODO: use the _md api
   /* Modify the signature and check that the signing fails.  */
   mpi_add_ui (signature, signature, 1);
   public (decr_plaintext, signature, &pk);
   if (!mpi_cmp (decr_plaintext, plaintext))
     goto leave; /* Signature matches but should not.  */
+#endif
 
   result = 0; /* All tests succeeded.  */
 
@@ -180,6 +252,11 @@ test_keys (RSA_secret_key *sk, unsigned
   _gcry_mpi_release (decr_plaintext);
   _gcry_mpi_release (ciphertext);
   _gcry_mpi_release (plaintext);
+  _gcry_sexp_release(s_skey);
+  _gcry_sexp_release(s_pkey);
+  _gcry_sexp_release(s_hash);
+  _gcry_sexp_release(r_sig);
+  _gcry_md_close (hd);
   return result;
 }
openSUSE Build Service is sponsored by