File libgcrypt-PCT-DSA.patch of Package libgcrypt.14348
Index: libgcrypt-1.8.2/cipher/dsa.c
===================================================================
--- libgcrypt-1.8.2.orig/cipher/dsa.c
+++ libgcrypt-1.8.2/cipher/dsa.c
@@ -181,17 +181,63 @@ test_keys (DSA_secret_key *sk, unsigned
/* Create a random plaintext. */
_gcry_mpi_randomize (data, qbits, GCRY_WEAK_RANDOM);
- /* Sign DATA using the secret key. */
- sign (sig_a, sig_b, data, sk, 0, 0);
-
- /* Verify the signature using the public key. */
- if ( verify (sig_a, sig_b, data, &pk) )
- goto leave; /* Signature does not match. */
+ /* 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, data);
+ _gcry_md_write(hd, buf, buflen);
+
+ /* build DSA private key sexp in s_skey */
+ sexp_build(&s_skey, NULL, "(private-key (dsa(p %m)(q %m)(g %m)(y %m)(x %m)))", sk->p, sk->q, sk->g, sk->y, sk->x);
+ 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 (dsa(p %m)(q %m)(g %m)(y %m)))", pk.p, pk.q, pk.g, pk.y);
+ 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, data);
+ _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. */
+ }
+#if 0
+ TODO: use the _md api
/* Modify the data and check that the signing fails. */
mpi_add_ui (data, data, 1);
if ( !verify (sig_a, sig_b, data, &pk) )
goto leave; /* Signature matches but should not. */
+#endif
result = 0; /* The test succeeded. */
@@ -199,6 +252,11 @@ test_keys (DSA_secret_key *sk, unsigned
_gcry_mpi_release (sig_b);
_gcry_mpi_release (sig_a);
_gcry_mpi_release (data);
+ _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;
}