summaryrefslogtreecommitdiff
path: root/cipher
diff options
context:
space:
mode:
authorJakub Jelen <jjelen@redhat.com>2022-08-08 15:58:16 +0200
committerNIIBE Yutaka <gniibe@fsij.org>2022-08-23 15:39:03 +0900
commit505f048cac8e5af92d3431bd97ade492d1a30bc2 (patch)
tree17d3a2150ff338d1376c1fa3af26ac9d8442ad4b /cipher
parent05a9c9d1ba1db6c1cd160fba979e9ddf4700a0c0 (diff)
downloadlibgcrypt-505f048cac8e5af92d3431bd97ade492d1a30bc2.tar.gz
rsa: Run PCT in FIPS mode also with digest step.
* cipher/rsa.c (test_keys_fips): New. (generate_fips): Call test_keys_fips. -- Signed-off-by: Jakub Jelen <jjelen@redhat.com>
Diffstat (limited to 'cipher')
-rw-r--r--cipher/rsa.c69
1 files changed, 68 insertions, 1 deletions
diff --git a/cipher/rsa.c b/cipher/rsa.c
index 34c8e490..73650ef1 100644
--- a/cipher/rsa.c
+++ b/cipher/rsa.c
@@ -177,6 +177,73 @@ test_keys (RSA_secret_key *sk, unsigned int nbits)
return result;
}
+static int
+test_keys_fips (RSA_secret_key *sk)
+{
+ int result = -1; /* Default to failure. */
+ char plaintext[128];
+ gcry_sexp_t sig = NULL;
+ gcry_sexp_t skey = NULL, pkey = NULL;
+ const char *data_tmpl = "(data (flags pkcs1) (hash %s %b))";
+ gcry_md_hd_t hd = NULL;
+ int ec;
+
+ /* Put the relevant parameters into a public key structure. */
+ ec = sexp_build (&pkey, NULL,
+ "(key-data"
+ " (public-key"
+ " (rsa(n%m)(e%m))))",
+ sk->n, sk->e);
+ if (ec)
+ goto leave;
+
+ /* Put the relevant parameters into a secret key structure. */
+ ec = sexp_build (&skey, NULL,
+ "(key-data"
+ " (public-key"
+ " (rsa(n%m)(e%m)))"
+ " (private-key"
+ " (rsa(n%m)(e%m)(d%m)(p%m)(q%m)(u%m))))",
+ sk->n, sk->e,
+ sk->n, sk->e, sk->d, sk->p, sk->q, sk->u);
+ if (ec)
+ goto leave;
+
+ /* Create a random plaintext. */
+ _gcry_randomize (plaintext, sizeof plaintext, GCRY_WEAK_RANDOM);
+
+ /* Open MD context and feed the random data in */
+ ec = _gcry_md_open (&hd, GCRY_MD_SHA256, 0);
+ if (ec)
+ goto leave;
+ _gcry_md_write (hd, plaintext, sizeof(plaintext));
+
+ /* Use the RSA secret function to create a signature of the plaintext. */
+ ec = _gcry_pk_sign_md (&sig, data_tmpl, hd, skey, NULL);
+ if (ec)
+ goto leave;
+
+ /* Use the RSA public function to verify this signature. */
+ ec = _gcry_pk_verify_md (sig, data_tmpl, hd, pkey, NULL);
+ if (ec)
+ goto leave;
+
+ /* Modify the data and check that the signing fails. */
+ _gcry_md_reset(hd);
+ plaintext[sizeof plaintext / 2] ^= 1;
+ _gcry_md_write (hd, plaintext, sizeof(plaintext));
+ ec = _gcry_pk_verify_md (sig, data_tmpl, hd, pkey, NULL);
+ if (ec != GPG_ERR_BAD_SIGNATURE)
+ goto leave; /* Signature verification worked on modified data */
+
+ result = 0; /* All tests succeeded. */
+ leave:
+ sexp_release (sig);
+ _gcry_md_close (hd);
+ sexp_release (pkey);
+ sexp_release (skey);
+ return result;
+}
/* Callback used by the prime generation to test whether the exponent
is suitable. Returns 0 if the test has been passed. */
@@ -648,7 +715,7 @@ generate_fips (RSA_secret_key *sk, unsigned int nbits, unsigned long use_e,
sk->u = u;
/* Now we can test our keys. */
- if (ec || (!testparms && test_keys (sk, nbits - 64)))
+ if (ec || (!testparms && test_keys_fips (sk)))
{
_gcry_mpi_release (sk->n); sk->n = NULL;
_gcry_mpi_release (sk->e); sk->e = NULL;