2020-05-14 17:39:34 +02:00
|
|
|
Index: libgcrypt-1.8.2/cipher/rsa.c
|
|
|
|
===================================================================
|
|
|
|
--- libgcrypt-1.8.2.orig/cipher/rsa.c
|
|
|
|
+++ libgcrypt-1.8.2/cipher/rsa.c
|
2020-05-19 14:29:20 +02:00
|
|
|
@@ -159,27 +159,103 @@ test_keys (RSA_secret_key *sk, unsigned
|
2020-05-14 17:39:34 +02:00
|
|
|
/* 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;
|
|
|
|
+ gcry_mpi_t r_sig_mpi = NULL;
|
|
|
|
+ unsigned char *buf = NULL;
|
|
|
|
+ size_t buflen;
|
|
|
|
|
|
|
|
- /* 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. */
|
|
|
|
-
|
|
|
|
- /* 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. */
|
|
|
|
+ if (_gcry_md_open (&hd, GCRY_MD_SHA256, 0))
|
|
|
|
+ {
|
2020-05-19 14:29:20 +02:00
|
|
|
+ if (DBG_CIPHER)
|
|
|
|
+ log_debug ("gcry_pk_sign/open failed\n");
|
2020-05-14 17:39:34 +02:00
|
|
|
+ goto leave_hash;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ _gcry_mpi_aprint (GCRYMPI_FMT_STD, &buf, &buflen, plaintext);
|
|
|
|
+ _gcry_md_write (hd, buf, buflen);
|
|
|
|
+
|
|
|
|
+ xfree (buf);
|
2020-05-19 14:29:20 +02:00
|
|
|
+ buf = NULL;
|
2020-05-14 17:39:34 +02:00
|
|
|
+
|
|
|
|
+ /* 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))
|
|
|
|
+ {
|
2020-05-19 14:29:20 +02:00
|
|
|
+ if (DBG_CIPHER)
|
|
|
|
+ log_debug ("gcry_pk_sign failed\n");
|
2020-05-14 17:39:34 +02:00
|
|
|
+ goto leave_hash;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /* Check that the signature and the original plaintext differ. */
|
|
|
|
+ if (_gcry_sexp_extract_param (r_sig, "sig-val!rsa", "s", &r_sig_mpi, NULL))
|
|
|
|
+ {
|
2020-05-19 14:29:20 +02:00
|
|
|
+ if (DBG_CIPHER)
|
|
|
|
+ log_debug ("extracting signature data failed\n");
|
2020-05-14 17:39:34 +02:00
|
|
|
+ goto leave_hash;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (!mpi_cmp (r_sig_mpi, plaintext))
|
|
|
|
+ {
|
2020-05-19 14:29:20 +02:00
|
|
|
+ if (DBG_CIPHER)
|
|
|
|
+ log_debug ("Signature failed\n");
|
2020-05-14 17:39:34 +02:00
|
|
|
+ goto leave_hash; /* Signature and plaintext match but should not. */
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ _gcry_sexp_release (s_hash);
|
|
|
|
+ _gcry_md_close (hd);
|
|
|
|
+
|
|
|
|
+ /* 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))
|
2020-05-19 14:29:20 +02:00
|
|
|
+ {
|
|
|
|
+ if (DBG_CIPHER)
|
|
|
|
+ log_debug ("gcry_md_open failed\n");
|
|
|
|
+ }
|
2020-05-14 17:39:34 +02:00
|
|
|
+
|
|
|
|
+ _gcry_mpi_aprint (GCRYMPI_FMT_STD, &buf, &buflen, plaintext);
|
|
|
|
+ _gcry_md_write (hd, buf, buflen);
|
|
|
|
+
|
|
|
|
+ xfree (buf);
|
2020-05-19 14:29:20 +02:00
|
|
|
+ buf = NULL;
|
2020-05-14 17:39:34 +02:00
|
|
|
+
|
|
|
|
+ /* verify the signature */
|
|
|
|
+ if (_gcry_pk_verify_md (r_sig, hd, s_hash, s_pkey))
|
|
|
|
+ {
|
2020-05-19 14:29:20 +02:00
|
|
|
+ if (DBG_CIPHER)
|
|
|
|
+ log_debug ("gcry_pk_verify failed\n");
|
2020-05-14 17:39:34 +02:00
|
|
|
+ goto leave_hash; /* Signature does not match. */
|
|
|
|
+ }
|
|
|
|
|
|
|
|
result = 0; /* All tests succeeded. */
|
|
|
|
|
|
|
|
+ leave_hash:
|
|
|
|
+ _gcry_sexp_release (s_skey);
|
|
|
|
+ _gcry_sexp_release (s_pkey);
|
|
|
|
+ _gcry_sexp_release (s_hash);
|
|
|
|
+ _gcry_sexp_release (r_sig);
|
|
|
|
+ _gcry_md_close (hd);
|
|
|
|
+ _gcry_mpi_release (r_sig_mpi);
|
|
|
|
+
|
|
|
|
leave:
|
|
|
|
_gcry_mpi_release (signature);
|
|
|
|
_gcry_mpi_release (decr_plaintext);
|
|
|
|
_gcry_mpi_release (ciphertext);
|
|
|
|
_gcry_mpi_release (plaintext);
|
|
|
|
+
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2020-05-19 14:29:20 +02:00
|
|
|
@@ -1903,7 +1979,7 @@ selftest_encr_2048 (gcry_sexp_t pkey, gc
|
2020-05-14 17:39:34 +02:00
|
|
|
/* This sexp trickery is to prevent the use of blinding.
|
|
|
|
* The flag doesn't get inherited by encr, so we have to
|
|
|
|
* derive a new sexp from the ciphertext */
|
|
|
|
- char buf[1024];
|
|
|
|
+ unsigned char buf[1024];
|
|
|
|
memset(buf, 0, sizeof(buf));
|
|
|
|
err = _gcry_mpi_print (GCRYMPI_FMT_STD, buf, sizeof buf, NULL, ciphertext);
|
|
|
|
if (err)
|
2020-05-19 14:29:20 +02:00
|
|
|
@@ -2012,6 +2088,7 @@ selftests_rsa (selftest_report_func_t re
|
|
|
|
sexp_release (skey);
|
|
|
|
if (report)
|
|
|
|
report ("pubkey", GCRY_PK_RSA, what, errtxt);
|
|
|
|
+
|
|
|
|
return GPG_ERR_SELFTEST_FAILED;
|
|
|
|
}
|
|
|
|
|