import libgcrypt-1.10.0-5.el9_0
This commit is contained in:
parent
528206d53e
commit
4fdcbe4461
51
SOURCES/libgcrypt-1.10.0-allow-short-salt.patch
Normal file
51
SOURCES/libgcrypt-1.10.0-allow-short-salt.patch
Normal file
@ -0,0 +1,51 @@
|
||||
From 58c92098d053aae7c78cc42bdd7c80c13efc89bb Mon Sep 17 00:00:00 2001
|
||||
From: NIIBE Yutaka <gniibe@fsij.org>
|
||||
Date: Fri, 24 Jun 2022 08:59:31 +0900
|
||||
Subject: [PATCH] hmac,hkdf: Allow use of shorter salt for HKDF.
|
||||
|
||||
* cipher/md.c (prepare_macpads): Move the check to...
|
||||
* src/visibility.c (gcry_mac_setkey): ... here.
|
||||
* tests/t-kdf.c (check_hkdf): No failure is expected.
|
||||
|
||||
--
|
||||
|
||||
GnuPG-bug-id: 6039
|
||||
Fixes-commit: 76aad97dd312e83f2f9b8d086553f2b72ab6546f
|
||||
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
|
||||
---
|
||||
cipher/md.c | 3 ---
|
||||
src/visibility.c | 3 +++
|
||||
tests/t-kdf.c | 12 +-----------
|
||||
3 files changed, 4 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/cipher/md.c b/cipher/md.c
|
||||
index 4f4fc9bf..34336b5c 100644
|
||||
--- a/cipher/md.c
|
||||
+++ b/cipher/md.c
|
||||
@@ -903,9 +903,6 @@ prepare_macpads (gcry_md_hd_t a, const unsigned char *key, size_t keylen)
|
||||
{
|
||||
GcryDigestEntry *r;
|
||||
|
||||
- if (fips_mode () && keylen < 14)
|
||||
- return GPG_ERR_INV_VALUE;
|
||||
-
|
||||
if (!a->ctx->list)
|
||||
return GPG_ERR_DIGEST_ALGO; /* Might happen if no algo is enabled. */
|
||||
|
||||
diff --git a/src/visibility.c b/src/visibility.c
|
||||
index c98247d8..aee5bffb 100644
|
||||
--- a/src/visibility.c
|
||||
+++ b/src/visibility.c
|
||||
@@ -946,6 +946,9 @@ gcry_mac_setkey (gcry_mac_hd_t hd, const void *key, size_t keylen)
|
||||
if (!fips_is_operational ())
|
||||
return gpg_error (fips_not_operational ());
|
||||
|
||||
+ if (fips_mode () && keylen < 14)
|
||||
+ return GPG_ERR_INV_VALUE;
|
||||
+
|
||||
return gpg_error (_gcry_mac_setkey (hd, key, keylen));
|
||||
}
|
||||
|
||||
--
|
||||
2.37.1
|
||||
|
70
SOURCES/libgcrypt-1.10.0-allow-small-RSA-verify.patch
Normal file
70
SOURCES/libgcrypt-1.10.0-allow-small-RSA-verify.patch
Normal file
@ -0,0 +1,70 @@
|
||||
From ca2afc9fb64d9a9b2f8930ba505d9ab6c8a57667 Mon Sep 17 00:00:00 2001
|
||||
From: Jakub Jelen <jjelen@redhat.com>
|
||||
Date: Thu, 12 May 2022 10:56:47 +0200
|
||||
Subject: [PATCH] cipher: Allow verification of small RSA signatures in FIPS
|
||||
mode
|
||||
|
||||
* cipher/rsa.c (rsa_check_keysize): Formatting.
|
||||
(rsa_check_verify_keysize): New function.
|
||||
(rsa_verify): Allow using smaller keys for verification.
|
||||
--
|
||||
|
||||
GnuPG-bug-id: 5975
|
||||
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
|
||||
---
|
||||
cipher/rsa.c | 26 ++++++++++++++++++++++++--
|
||||
1 file changed, 24 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/cipher/rsa.c b/cipher/rsa.c
|
||||
index c6319b67..9f2b36e8 100644
|
||||
--- a/cipher/rsa.c
|
||||
+++ b/cipher/rsa.c
|
||||
@@ -352,13 +352,35 @@ generate_std (RSA_secret_key *sk, unsigned int nbits, unsigned long use_e,
|
||||
static gpg_err_code_t
|
||||
rsa_check_keysize (unsigned int nbits)
|
||||
{
|
||||
- if (fips_mode() && nbits < 2048)
|
||||
+ if (fips_mode () && nbits < 2048)
|
||||
return GPG_ERR_INV_VALUE;
|
||||
|
||||
return GPG_ERR_NO_ERROR;
|
||||
}
|
||||
|
||||
|
||||
+/* Check the RSA key length is acceptable for signature verification
|
||||
+ *
|
||||
+ * FIPS allows signature verification with RSA keys of size
|
||||
+ * 1024, 1280, 1536 and 1792 in legacy mode, but this is up to the
|
||||
+ * calling application to decide if the signature is legacy and
|
||||
+ * should be accepted.
|
||||
+ */
|
||||
+static gpg_err_code_t
|
||||
+rsa_check_verify_keysize (unsigned int nbits)
|
||||
+{
|
||||
+ if (fips_mode ())
|
||||
+ {
|
||||
+ if ((nbits >= 1024 && (nbits % 256) == 0) || nbits >= 2048)
|
||||
+ return GPG_ERR_NO_ERROR;
|
||||
+
|
||||
+ return GPG_ERR_INV_VALUE;
|
||||
+ }
|
||||
+
|
||||
+ return GPG_ERR_NO_ERROR;
|
||||
+}
|
||||
+
|
||||
+
|
||||
/****************
|
||||
* Generate a key pair with a key of size NBITS.
|
||||
* USE_E = 0 let Libcgrypt decide what exponent to use.
|
||||
@@ -1602,7 +1624,7 @@ rsa_verify (gcry_sexp_t s_sig, gcry_sexp_t s_data, gcry_sexp_t keyparms)
|
||||
gcry_mpi_t result = NULL;
|
||||
unsigned int nbits = rsa_get_nbits (keyparms);
|
||||
|
||||
- rc = rsa_check_keysize (nbits);
|
||||
+ rc = rsa_check_verify_keysize (nbits);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
--
|
||||
2.37.1
|
||||
|
151
SOURCES/libgcrypt-1.10.0-fips-disable-oaep.patch
Normal file
151
SOURCES/libgcrypt-1.10.0-fips-disable-oaep.patch
Normal file
@ -0,0 +1,151 @@
|
||||
From 34d8fc576b3a06dd205f45327a971eb6771e808c Mon Sep 17 00:00:00 2001
|
||||
From: Jakub Jelen <jjelen@redhat.com>
|
||||
Date: Wed, 17 Aug 2022 09:01:44 +0200
|
||||
Subject: [PATCH 1/2] Disable RSA-OAEP padding in FIPS mode
|
||||
|
||||
* cipher/pubkey-util.c (_gcry_pk_util_data_to_mpi): Block OAEP padding
|
||||
in FIPS mode for encryption
|
||||
* cipher/rsa.c (rsa_decrypt): Block OAEP padding in FIPS mode for
|
||||
decryption
|
||||
---
|
||||
|
||||
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
|
||||
---
|
||||
cipher/pubkey-util.c | 5 ++++-
|
||||
cipher/rsa.c | 3 ++-
|
||||
2 files changed, 6 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/cipher/pubkey-util.c b/cipher/pubkey-util.c
|
||||
index 4953caf3..244dd5d4 100644
|
||||
--- a/cipher/pubkey-util.c
|
||||
+++ b/cipher/pubkey-util.c
|
||||
@@ -1092,7 +1092,10 @@ _gcry_pk_util_data_to_mpi (gcry_sexp_t input, gcry_mpi_t *ret_mpi,
|
||||
const void * value;
|
||||
size_t valuelen;
|
||||
|
||||
- if ( !(value=sexp_nth_data (lvalue, 1, &valuelen)) || !valuelen )
|
||||
+ /* The RSA OAEP encryption requires some more assurances in FIPS */
|
||||
+ if (fips_mode ())
|
||||
+ rc = GPG_ERR_INV_FLAG;
|
||||
+ else if ( !(value=sexp_nth_data (lvalue, 1, &valuelen)) || !valuelen )
|
||||
rc = GPG_ERR_INV_OBJ;
|
||||
else
|
||||
{
|
||||
diff --git a/cipher/rsa.c b/cipher/rsa.c
|
||||
index 96dba090..87f57b55 100644
|
||||
--- a/cipher/rsa.c
|
||||
+++ b/cipher/rsa.c
|
||||
@@ -1457,7 +1457,8 @@ rsa_decrypt (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t keyparms)
|
||||
rc = GPG_ERR_INV_DATA;
|
||||
goto leave;
|
||||
}
|
||||
- if (fips_mode () && (ctx.encoding == PUBKEY_ENC_PKCS1))
|
||||
+ if (fips_mode () && (ctx.encoding == PUBKEY_ENC_PKCS1 ||
|
||||
+ ctx.encoding == PUBKEY_ENC_OAEP))
|
||||
{
|
||||
rc = GPG_ERR_INV_FLAG;
|
||||
goto leave;
|
||||
--
|
||||
2.37.1
|
||||
|
||||
|
||||
From c6d64e697c2748a49e875060aa753fc568c5f772 Mon Sep 17 00:00:00 2001
|
||||
From: Jakub Jelen <jjelen@redhat.com>
|
||||
Date: Wed, 17 Aug 2022 10:31:19 +0200
|
||||
Subject: [PATCH 2/2] tests: Expect the OEAP tests to fail in FIPS mode
|
||||
|
||||
* tests/basic.c (check_pubkey_crypt): Expect the OAEP padding encryption
|
||||
to fail in FIPS mode
|
||||
* tests/pkcs1v2.c (check_oaep): Expect the OAEP tests to fail in FIPS
|
||||
mode
|
||||
---
|
||||
|
||||
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
|
||||
---
|
||||
tests/basic.c | 14 +++++++++-----
|
||||
tests/pkcs1v2.c | 13 +++++++++++++
|
||||
2 files changed, 22 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/tests/basic.c b/tests/basic.c
|
||||
index 26980e15..b4102c9f 100644
|
||||
--- a/tests/basic.c
|
||||
+++ b/tests/basic.c
|
||||
@@ -16892,21 +16892,24 @@ check_pubkey_crypt (int n, gcry_sexp_t skey, gcry_sexp_t pkey, int algo,
|
||||
"(flags oaep)",
|
||||
1,
|
||||
0,
|
||||
- 0 },
|
||||
+ 0,
|
||||
+ FLAG_NOFIPS },
|
||||
{ GCRY_PK_RSA,
|
||||
"(data\n (flags oaep)\n (hash-algo sha1)\n"
|
||||
" (value #11223344556677889900AA#))\n",
|
||||
"(flags oaep)(hash-algo sha1)",
|
||||
1,
|
||||
0,
|
||||
- 0 },
|
||||
+ 0,
|
||||
+ FLAG_NOFIPS },
|
||||
{ GCRY_PK_RSA,
|
||||
"(data\n (flags oaep)\n (hash-algo sha1)\n (label \"test\")\n"
|
||||
" (value #11223344556677889900AA#))\n",
|
||||
"(flags oaep)(hash-algo sha1)(label \"test\")",
|
||||
1,
|
||||
0,
|
||||
- 0 },
|
||||
+ 0,
|
||||
+ FLAG_NOFIPS },
|
||||
{ GCRY_PK_RSA,
|
||||
"(data\n (flags oaep)\n (hash-algo sha1)\n (label \"test\")\n"
|
||||
" (value #11223344556677889900AA#)\n"
|
||||
@@ -16914,7 +16917,8 @@ check_pubkey_crypt (int n, gcry_sexp_t skey, gcry_sexp_t pkey, int algo,
|
||||
"(flags oaep)(hash-algo sha1)(label \"test\")",
|
||||
1,
|
||||
0,
|
||||
- 0 },
|
||||
+ 0,
|
||||
+ FLAG_NOFIPS },
|
||||
{ 0,
|
||||
"(data\n (flags )\n" " (value #11223344556677889900AA#))\n",
|
||||
NULL,
|
||||
@@ -16960,7 +16964,7 @@ check_pubkey_crypt (int n, gcry_sexp_t skey, gcry_sexp_t pkey, int algo,
|
||||
"(flags pkcs1)",
|
||||
1,
|
||||
0,
|
||||
- GPG_ERR_ENCODING_PROBLEM, FLAG_SPECIAL },
|
||||
+ GPG_ERR_ENCODING_PROBLEM, FLAG_SPECIAL | FLAG_NOFIPS },
|
||||
{ 0,
|
||||
"(data\n (flags pss)\n"
|
||||
" (value #11223344556677889900AA#))\n",
|
||||
diff --git a/tests/pkcs1v2.c b/tests/pkcs1v2.c
|
||||
index 6c7f3d81..2fd495d5 100644
|
||||
--- a/tests/pkcs1v2.c
|
||||
+++ b/tests/pkcs1v2.c
|
||||
@@ -186,11 +186,24 @@ check_oaep (void)
|
||||
err = gcry_pk_encrypt (&ciph, plain, pub_key);
|
||||
if (err)
|
||||
{
|
||||
+ if (in_fips_mode)
|
||||
+ {
|
||||
+ gcry_sexp_release (plain);
|
||||
+ plain = NULL;
|
||||
+ continue;
|
||||
+ }
|
||||
show_sexp ("plain:\n", ciph);
|
||||
fail ("gcry_pk_encrypt failed: %s\n", gpg_strerror (err));
|
||||
}
|
||||
else
|
||||
{
|
||||
+ if (in_fips_mode)
|
||||
+ {
|
||||
+ fail ("The OAEP encryption unexpectedly worked in FIPS mode\n");
|
||||
+ gcry_sexp_release (plain);
|
||||
+ plain = NULL;
|
||||
+ continue;
|
||||
+ }
|
||||
if (extract_cmp_data (ciph, "a", tbl[tno].m[mno].encr,
|
||||
tbl[tno].m[mno].desc))
|
||||
{
|
||||
--
|
||||
2.37.1
|
||||
|
41
SOURCES/libgcrypt-1.10.0-fips-getrandom.patch
Normal file
41
SOURCES/libgcrypt-1.10.0-fips-getrandom.patch
Normal file
@ -0,0 +1,41 @@
|
||||
From 0a5e608b8b18d4f41e4d7434c6262bf11507f859 Mon Sep 17 00:00:00 2001
|
||||
From: Jakub Jelen <jjelen@redhat.com>
|
||||
Date: Tue, 16 Aug 2022 15:30:43 +0200
|
||||
Subject: [PATCH] random: Use getrandom (GRND_RANDOM) in FIPS mode
|
||||
|
||||
The SP800-90C (clarified in IG D.K.) requires the following when
|
||||
different DRBGs are chained:
|
||||
* the parent needs to be reseeded before generate operation
|
||||
* the reseed & generate needs to be atomic
|
||||
|
||||
In RHEL, this is addressed by change in the kernel, that will do this
|
||||
automatically, when the getentropy () is called with GRND_RANDOM flag.
|
||||
|
||||
* random/rndgetentropy.c (_gcry_rndgetentropy_gather_random): Use
|
||||
GRND_RANDOM in FIPS Mode
|
||||
---
|
||||
|
||||
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
|
||||
---
|
||||
random/rndgetentropy.c | 5 ++++-
|
||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/random/rndgetentropy.c b/random/rndgetentropy.c
|
||||
index 7580873e..db4b09ed 100644
|
||||
--- a/random/rndgetentropy.c
|
||||
+++ b/random/rndgetentropy.c
|
||||
@@ -82,7 +82,10 @@ _gcry_rndgetentropy_gather_random (void (*add)(const void*, size_t,
|
||||
{
|
||||
nbytes = length < sizeof (buffer)? length : sizeof (buffer);
|
||||
_gcry_pre_syscall ();
|
||||
- ret = getentropy (buffer, nbytes);
|
||||
+ if (fips_mode ())
|
||||
+ ret = getrandom (buffer, nbytes, GRND_RANDOM);
|
||||
+ else
|
||||
+ ret = getentropy (buffer, nbytes);
|
||||
_gcry_post_syscall ();
|
||||
}
|
||||
while (ret == -1 && errno == EINTR);
|
||||
--
|
||||
2.37.1
|
||||
|
923
SOURCES/libgcrypt-1.10.0-fips-selftest.patch
Normal file
923
SOURCES/libgcrypt-1.10.0-fips-selftest.patch
Normal file
@ -0,0 +1,923 @@
|
||||
From e62829a907a7179ec6b0d9f47258185860f0a6c0 Mon Sep 17 00:00:00 2001
|
||||
From: Jakub Jelen <jjelen@redhat.com>
|
||||
Date: Tue, 2 Aug 2022 20:53:31 +0200
|
||||
Subject: [PATCH 1/6] Run digest&sign self tests for RSA and ECC in FIPS mode
|
||||
|
||||
* cipher/ecc.c (selftest_hash_sign): Implement digest & sign KAT
|
||||
(selftests_ecdsa): Run the original basic test only with extended tests
|
||||
(run_selftests): Pass-through the extended argument
|
||||
* cipher/rsa.c (selftest_hash_sign_2048): Implement digest & sign KAT
|
||||
(selftests_rsa): Run the original basic test only with extended tests
|
||||
(run_selftests): Pass-through the extended argument
|
||||
---
|
||||
|
||||
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
|
||||
---
|
||||
cipher/ecc.c | 138 ++++++++++++++++++++++++++++++++++++++++++++++++---
|
||||
cipher/rsa.c | 108 +++++++++++++++++++++++++++++++++++++---
|
||||
2 files changed, 234 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/cipher/ecc.c b/cipher/ecc.c
|
||||
index 9f0e7b11..63b0d05e 100644
|
||||
--- a/cipher/ecc.c
|
||||
+++ b/cipher/ecc.c
|
||||
@@ -1678,6 +1678,126 @@ _gcry_pk_ecc_get_sexp (gcry_sexp_t *r_sexp, int mode, mpi_ec_t ec)
|
||||
Self-test section.
|
||||
*/
|
||||
|
||||
+static const char *
|
||||
+selftest_hash_sign (gcry_sexp_t pkey, gcry_sexp_t skey)
|
||||
+{
|
||||
+ int md_algo = GCRY_MD_SHA256;
|
||||
+ gcry_md_hd_t hd = NULL;
|
||||
+ const char *data_tmpl = "(data (flags rfc6979) (hash %s %b))";
|
||||
+ /* Sample data from RFC 6979 section A.2.5, hash is of message "sample" */
|
||||
+ static const char sample_data[] = "sample";
|
||||
+ static const char sample_data_bad[] = "sbmple";
|
||||
+ static const char signature_r[] =
|
||||
+ "efd48b2aacb6a8fd1140dd9cd45e81d69d2c877b56aaf991c34d0ea84eaf3716";
|
||||
+ static const char signature_s[] =
|
||||
+ "f7cb1c942d657c41d436c7a1b6e29f65f3e900dbb9aff4064dc4ab2f843acda8";
|
||||
+
|
||||
+ const char *errtxt = NULL;
|
||||
+ gcry_error_t err;
|
||||
+ gcry_sexp_t sig = NULL;
|
||||
+ gcry_sexp_t l1 = NULL;
|
||||
+ gcry_sexp_t l2 = NULL;
|
||||
+ gcry_mpi_t r = NULL;
|
||||
+ gcry_mpi_t s = NULL;
|
||||
+ gcry_mpi_t calculated_r = NULL;
|
||||
+ gcry_mpi_t calculated_s = NULL;
|
||||
+ int cmp;
|
||||
+
|
||||
+ err = _gcry_md_open (&hd, md_algo, 0);
|
||||
+ if (err)
|
||||
+ {
|
||||
+ errtxt = "gcry_md_open failed";
|
||||
+ goto leave;
|
||||
+ }
|
||||
+
|
||||
+ _gcry_md_write (hd, sample_data, strlen(sample_data));
|
||||
+
|
||||
+ err = _gcry_mpi_scan (&r, GCRYMPI_FMT_HEX, signature_r, 0, NULL);
|
||||
+ if (!err)
|
||||
+ err = _gcry_mpi_scan (&s, GCRYMPI_FMT_HEX, signature_s, 0, NULL);
|
||||
+
|
||||
+ if (err)
|
||||
+ {
|
||||
+ errtxt = "converting data failed";
|
||||
+ goto leave;
|
||||
+ }
|
||||
+
|
||||
+ err = _gcry_pk_sign_md (&sig, data_tmpl, hd, skey, NULL);
|
||||
+ if (err)
|
||||
+ {
|
||||
+ errtxt = "signing failed";
|
||||
+ goto leave;
|
||||
+ }
|
||||
+
|
||||
+ /* check against known signature */
|
||||
+ errtxt = "signature validity failed";
|
||||
+ l1 = _gcry_sexp_find_token (sig, "sig-val", 0);
|
||||
+ if (!l1)
|
||||
+ goto leave;
|
||||
+ l2 = _gcry_sexp_find_token (l1, "ecdsa", 0);
|
||||
+ if (!l2)
|
||||
+ goto leave;
|
||||
+
|
||||
+ sexp_release (l1);
|
||||
+ l1 = l2;
|
||||
+
|
||||
+ l2 = _gcry_sexp_find_token (l1, "r", 0);
|
||||
+ if (!l2)
|
||||
+ goto leave;
|
||||
+ calculated_r = _gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
|
||||
+ if (!calculated_r)
|
||||
+ goto leave;
|
||||
+
|
||||
+ sexp_release (l2);
|
||||
+ l2 = _gcry_sexp_find_token (l1, "s", 0);
|
||||
+ if (!l2)
|
||||
+ goto leave;
|
||||
+ calculated_s = _gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
|
||||
+ if (!calculated_s)
|
||||
+ goto leave;
|
||||
+
|
||||
+ errtxt = "known sig check failed";
|
||||
+
|
||||
+ cmp = _gcry_mpi_cmp (r, calculated_r);
|
||||
+ if (cmp)
|
||||
+ goto leave;
|
||||
+ cmp = _gcry_mpi_cmp (s, calculated_s);
|
||||
+ if (cmp)
|
||||
+ goto leave;
|
||||
+
|
||||
+ errtxt = NULL;
|
||||
+
|
||||
+ /* verify generated signature */
|
||||
+ err = _gcry_pk_verify_md (sig, data_tmpl, hd, pkey, NULL);
|
||||
+ if (err)
|
||||
+ {
|
||||
+ errtxt = "verify failed";
|
||||
+ goto leave;
|
||||
+ }
|
||||
+
|
||||
+ _gcry_md_reset(hd);
|
||||
+ _gcry_md_write (hd, sample_data_bad, strlen(sample_data_bad));
|
||||
+ err = _gcry_pk_verify_md (sig, data_tmpl, hd, pkey, NULL);
|
||||
+ if (gcry_err_code (err) != GPG_ERR_BAD_SIGNATURE)
|
||||
+ {
|
||||
+ errtxt = "bad signature not detected";
|
||||
+ goto leave;
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+ leave:
|
||||
+ _gcry_md_close (hd);
|
||||
+ sexp_release (sig);
|
||||
+ sexp_release (l1);
|
||||
+ sexp_release (l2);
|
||||
+ mpi_release (r);
|
||||
+ mpi_release (s);
|
||||
+ mpi_release (calculated_r);
|
||||
+ mpi_release (calculated_s);
|
||||
+ return errtxt;
|
||||
+}
|
||||
+
|
||||
+
|
||||
static const char *
|
||||
selftest_sign (gcry_sexp_t pkey, gcry_sexp_t skey)
|
||||
{
|
||||
@@ -1798,7 +1918,7 @@ selftest_sign (gcry_sexp_t pkey, gcry_sexp_t skey)
|
||||
|
||||
|
||||
static gpg_err_code_t
|
||||
-selftests_ecdsa (selftest_report_func_t report)
|
||||
+selftests_ecdsa (selftest_report_func_t report, int extended)
|
||||
{
|
||||
const char *what;
|
||||
const char *errtxt;
|
||||
@@ -1826,8 +1946,16 @@ selftests_ecdsa (selftest_report_func_t report)
|
||||
goto failed;
|
||||
}
|
||||
|
||||
- what = "sign";
|
||||
- errtxt = selftest_sign (pkey, skey);
|
||||
+ if (extended)
|
||||
+ {
|
||||
+ what = "sign";
|
||||
+ errtxt = selftest_sign (pkey, skey);
|
||||
+ if (errtxt)
|
||||
+ goto failed;
|
||||
+ }
|
||||
+
|
||||
+ what = "digest sign";
|
||||
+ errtxt = selftest_hash_sign (pkey, skey);
|
||||
if (errtxt)
|
||||
goto failed;
|
||||
|
||||
@@ -1848,12 +1976,10 @@ selftests_ecdsa (selftest_report_func_t report)
|
||||
static gpg_err_code_t
|
||||
run_selftests (int algo, int extended, selftest_report_func_t report)
|
||||
{
|
||||
- (void)extended;
|
||||
-
|
||||
if (algo != GCRY_PK_ECC)
|
||||
return GPG_ERR_PUBKEY_ALGO;
|
||||
|
||||
- return selftests_ecdsa (report);
|
||||
+ return selftests_ecdsa (report, extended);
|
||||
}
|
||||
|
||||
|
||||
diff --git a/cipher/rsa.c b/cipher/rsa.c
|
||||
index 9f2b36e8..34c8e490 100644
|
||||
--- a/cipher/rsa.c
|
||||
+++ b/cipher/rsa.c
|
||||
@@ -1760,6 +1760,96 @@ compute_keygrip (gcry_md_hd_t md, gcry_sexp_t keyparam)
|
||||
Self-test section.
|
||||
*/
|
||||
|
||||
+static const char *
|
||||
+selftest_hash_sign_2048 (gcry_sexp_t pkey, gcry_sexp_t skey)
|
||||
+{
|
||||
+ int md_algo = GCRY_MD_SHA256;
|
||||
+ gcry_md_hd_t hd = NULL;
|
||||
+ const char *data_tmpl = "(data (flags pkcs1) (hash %s %b))";
|
||||
+ static const char sample_data[] =
|
||||
+ "11223344556677889900aabbccddeeff"
|
||||
+ "102030405060708090a0b0c0d0f01121";
|
||||
+ static const char sample_data_bad[] =
|
||||
+ "11223344556677889900aabbccddeeff"
|
||||
+ "802030405060708090a0b0c0d0f01121";
|
||||
+
|
||||
+ const char *errtxt = NULL;
|
||||
+ gcry_error_t err;
|
||||
+ gcry_sexp_t sig = NULL;
|
||||
+ /* raw signature data reference */
|
||||
+ const char ref_data[] =
|
||||
+ "518f41dea3ad884e93eefff8d7ca68a6f4c30d923632e35673651d675cebd652"
|
||||
+ "a44ed66f6879b18f3d48b2d235b1dd78f6189be1440352cc94231a55c1f93109"
|
||||
+ "84616b2841c42fe9a6e37be34cd188207209bd028e2fa93e721fbac40c31a068"
|
||||
+ "1253b312d4e07addb9c7f3d508fa89f218ea7c7f7b9f6a9b1e522c19fa1cd839"
|
||||
+ "93f9d4ca2f16c3d0b9abafe5e63e848152afc72ce7ee19ea45353116f85209ea"
|
||||
+ "b9de42129dbccdac8faa461e8e8cc2ae801101cc6add4ba76ccb752030b0e827"
|
||||
+ "7352b11cdecebae9cdc9a626c4701cd9c85cd287618888c5fae8b4d0ba48915d"
|
||||
+ "e5cc64e3aee2ba2862d04348ea71f65454f74f9fd1e3108005cc367ca41585a4";
|
||||
+ gcry_mpi_t ref_mpi = NULL;
|
||||
+ gcry_mpi_t sig_mpi = NULL;
|
||||
+
|
||||
+ err = _gcry_md_open (&hd, md_algo, 0);
|
||||
+ if (err)
|
||||
+ {
|
||||
+ errtxt = "gcry_md_open failed";
|
||||
+ goto leave;
|
||||
+ }
|
||||
+
|
||||
+ _gcry_md_write (hd, sample_data, sizeof(sample_data));
|
||||
+
|
||||
+ err = _gcry_pk_sign_md (&sig, data_tmpl, hd, skey, NULL);
|
||||
+ if (err)
|
||||
+ {
|
||||
+ errtxt = "signing failed";
|
||||
+ goto leave;
|
||||
+ }
|
||||
+
|
||||
+ err = _gcry_mpi_scan(&ref_mpi, GCRYMPI_FMT_HEX, ref_data, 0, NULL);
|
||||
+ if (err)
|
||||
+ {
|
||||
+ errtxt = "converting ref_data to mpi failed";
|
||||
+ goto leave;
|
||||
+ }
|
||||
+
|
||||
+ err = _gcry_sexp_extract_param(sig, "sig-val!rsa", "s", &sig_mpi, NULL);
|
||||
+ if (err)
|
||||
+ {
|
||||
+ errtxt = "extracting signature data failed";
|
||||
+ goto leave;
|
||||
+ }
|
||||
+
|
||||
+ if (mpi_cmp (sig_mpi, ref_mpi))
|
||||
+ {
|
||||
+ errtxt = "signature does not match reference data";
|
||||
+ goto leave;
|
||||
+ }
|
||||
+
|
||||
+ err = _gcry_pk_verify_md (sig, data_tmpl, hd, pkey, NULL);
|
||||
+ if (err)
|
||||
+ {
|
||||
+ errtxt = "verify failed";
|
||||
+ goto leave;
|
||||
+ }
|
||||
+
|
||||
+ _gcry_md_reset(hd);
|
||||
+ _gcry_md_write (hd, sample_data_bad, sizeof(sample_data_bad));
|
||||
+ err = _gcry_pk_verify_md (sig, data_tmpl, hd, pkey, NULL);
|
||||
+ if (gcry_err_code (err) != GPG_ERR_BAD_SIGNATURE)
|
||||
+ {
|
||||
+ errtxt = "bad signature not detected";
|
||||
+ goto leave;
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+ leave:
|
||||
+ sexp_release (sig);
|
||||
+ _gcry_md_close (hd);
|
||||
+ _gcry_mpi_release (ref_mpi);
|
||||
+ _gcry_mpi_release (sig_mpi);
|
||||
+ return errtxt;
|
||||
+}
|
||||
+
|
||||
static const char *
|
||||
selftest_sign_2048 (gcry_sexp_t pkey, gcry_sexp_t skey)
|
||||
{
|
||||
@@ -1996,7 +2086,7 @@ selftest_encr_2048 (gcry_sexp_t pkey, gcry_sexp_t skey)
|
||||
|
||||
|
||||
static gpg_err_code_t
|
||||
-selftests_rsa (selftest_report_func_t report)
|
||||
+selftests_rsa (selftest_report_func_t report, int extended)
|
||||
{
|
||||
const char *what;
|
||||
const char *errtxt;
|
||||
@@ -2024,8 +2114,16 @@ selftests_rsa (selftest_report_func_t report)
|
||||
goto failed;
|
||||
}
|
||||
|
||||
- what = "sign";
|
||||
- errtxt = selftest_sign_2048 (pkey, skey);
|
||||
+ if (extended)
|
||||
+ {
|
||||
+ what = "sign";
|
||||
+ errtxt = selftest_sign_2048 (pkey, skey);
|
||||
+ if (errtxt)
|
||||
+ goto failed;
|
||||
+ }
|
||||
+
|
||||
+ what = "digest sign";
|
||||
+ errtxt = selftest_hash_sign_2048 (pkey, skey);
|
||||
if (errtxt)
|
||||
goto failed;
|
||||
|
||||
@@ -2053,12 +2151,10 @@ run_selftests (int algo, int extended, selftest_report_func_t report)
|
||||
{
|
||||
gpg_err_code_t ec;
|
||||
|
||||
- (void)extended;
|
||||
-
|
||||
switch (algo)
|
||||
{
|
||||
case GCRY_PK_RSA:
|
||||
- ec = selftests_rsa (report);
|
||||
+ ec = selftests_rsa (report, extended);
|
||||
break;
|
||||
default:
|
||||
ec = GPG_ERR_PUBKEY_ALGO;
|
||||
--
|
||||
2.37.1
|
||||
|
||||
|
||||
From b386e9862e7c3c0f6623fb1c43b0cf0481bbebc7 Mon Sep 17 00:00:00 2001
|
||||
From: Jakub Jelen <jjelen@redhat.com>
|
||||
Date: Mon, 8 Aug 2022 13:50:15 +0200
|
||||
Subject: [PATCH 2/6] fips: Add function-name based FIPS indicator
|
||||
|
||||
* doc/gcrypt.texi: Document the new function-based fips indicator
|
||||
GCRYCTL_FIPS_SERVICE_INDICATOR_FUNCTION
|
||||
* src/fips.c (_gcry_fips_indicator_function): New function indicating
|
||||
non-approved functions.
|
||||
* src/gcrypt.h.in (enum gcry_ctl_cmds): New symbol
|
||||
GCRYCTL_FIPS_SERVICE_INDICATOR_FUNCTION
|
||||
* src/global.c (_gcry_vcontrol): Handle new FIPS indicator.
|
||||
---
|
||||
|
||||
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
|
||||
---
|
||||
doc/gcrypt.texi | 7 +++++++
|
||||
src/fips.c | 12 ++++++++++++
|
||||
src/g10lib.h | 1 +
|
||||
src/gcrypt.h.in | 3 ++-
|
||||
src/global.c | 7 +++++++
|
||||
5 files changed, 29 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/doc/gcrypt.texi b/doc/gcrypt.texi
|
||||
index f2c1cc94..b608dba2 100644
|
||||
--- a/doc/gcrypt.texi
|
||||
+++ b/doc/gcrypt.texi
|
||||
@@ -995,6 +995,13 @@ certification. If the KDF is approved, this function returns
|
||||
@code{GPG_ERR_NO_ERROR}. Otherwise @code{GPG_ERR_NOT_SUPPORTED}
|
||||
is returned.
|
||||
|
||||
+@item GCRYCTL_FIPS_SERVICE_INDICATOR_FUNCTION; Arguments: const char *
|
||||
+
|
||||
+Check if the given function is approved under the current FIPS 140-3
|
||||
+certification. If the function is approved, this function returns
|
||||
+@code{GPG_ERR_NO_ERROR} (other restrictions might still apply).
|
||||
+Otherwise @code{GPG_ERR_NOT_SUPPORTED} is returned.
|
||||
+
|
||||
@end table
|
||||
|
||||
@end deftypefun
|
||||
diff --git a/src/fips.c b/src/fips.c
|
||||
index a1958b14..9a524ea4 100644
|
||||
--- a/src/fips.c
|
||||
+++ b/src/fips.c
|
||||
@@ -390,6 +390,18 @@ _gcry_fips_indicator_kdf (va_list arg_ptr)
|
||||
}
|
||||
}
|
||||
|
||||
+int
|
||||
+_gcry_fips_indicator_function (va_list arg_ptr)
|
||||
+{
|
||||
+ const char *function = va_arg (arg_ptr, const char *);
|
||||
+
|
||||
+ if (strcmp (function, "gcry_sign") == 0 ||
|
||||
+ strcmp (function, "gcry_verify") == 0)
|
||||
+ return GPG_ERR_NOT_SUPPORTED;
|
||||
+
|
||||
+ return GPG_ERR_NO_ERROR;
|
||||
+}
|
||||
+
|
||||
|
||||
/* This is a test on whether the library is in the error or
|
||||
operational state. */
|
||||
diff --git a/src/g10lib.h b/src/g10lib.h
|
||||
index 8ba0a5c2..eff6295f 100644
|
||||
--- a/src/g10lib.h
|
||||
+++ b/src/g10lib.h
|
||||
@@ -468,6 +468,7 @@ void _gcry_fips_signal_error (const char *srcfile,
|
||||
|
||||
int _gcry_fips_indicator_cipher (va_list arg_ptr);
|
||||
int _gcry_fips_indicator_kdf (va_list arg_ptr);
|
||||
+int _gcry_fips_indicator_function (va_list arg_ptr);
|
||||
|
||||
int _gcry_fips_is_operational (void);
|
||||
|
||||
diff --git a/src/gcrypt.h.in b/src/gcrypt.h.in
|
||||
index 299261db..d6a1d516 100644
|
||||
--- a/src/gcrypt.h.in
|
||||
+++ b/src/gcrypt.h.in
|
||||
@@ -329,7 +329,8 @@ enum gcry_ctl_cmds
|
||||
GCRYCTL_SET_DECRYPTION_TAG = 80,
|
||||
GCRYCTL_FIPS_SERVICE_INDICATOR_CIPHER = 81,
|
||||
GCRYCTL_FIPS_SERVICE_INDICATOR_KDF = 82,
|
||||
- GCRYCTL_NO_FIPS_MODE = 83
|
||||
+ GCRYCTL_NO_FIPS_MODE = 83,
|
||||
+ GCRYCTL_FIPS_SERVICE_INDICATOR_FUNCTION = 84
|
||||
};
|
||||
|
||||
/* Perform various operations defined by CMD. */
|
||||
diff --git a/src/global.c b/src/global.c
|
||||
index 258ea4d1..debf6194 100644
|
||||
--- a/src/global.c
|
||||
+++ b/src/global.c
|
||||
@@ -797,6 +797,13 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, va_list arg_ptr)
|
||||
rc = _gcry_fips_indicator_kdf (arg_ptr);
|
||||
break;
|
||||
|
||||
+ case GCRYCTL_FIPS_SERVICE_INDICATOR_FUNCTION:
|
||||
+ /* Get FIPS Service Indicator for a given function from the API.
|
||||
+ * Returns GPG_ERR_NO_ERROR if the function is allowed or
|
||||
+ * GPG_ERR_NOT_SUPPORTED otherwise */
|
||||
+ rc = _gcry_fips_indicator_function (arg_ptr);
|
||||
+ break;
|
||||
+
|
||||
case PRIV_CTL_INIT_EXTRNG_TEST: /* Init external random test. */
|
||||
rc = GPG_ERR_NOT_SUPPORTED;
|
||||
break;
|
||||
--
|
||||
2.37.1
|
||||
|
||||
|
||||
From 756cdfaf30c2b12d2b2a931591089b1de22444f4 Mon Sep 17 00:00:00 2001
|
||||
From: Jakub Jelen <jjelen@redhat.com>
|
||||
Date: Mon, 8 Aug 2022 15:58:16 +0200
|
||||
Subject: [PATCH 4/6] rsa: Run PCT in FIPS mode also with digest step
|
||||
|
||||
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
|
||||
---
|
||||
cipher/rsa.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++-
|
||||
1 file changed, 68 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/cipher/rsa.c b/cipher/rsa.c
|
||||
index 6e7be8e8..78c26f2f 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;
|
||||
--
|
||||
2.37.1
|
||||
|
||||
|
||||
From de7ad6375be11a0cef45c6e9aa8119c4ce7a3258 Mon Sep 17 00:00:00 2001
|
||||
From: Jakub Jelen <jjelen@redhat.com>
|
||||
Date: Mon, 15 Aug 2022 19:55:33 +0200
|
||||
Subject: [PATCH 5/6] ecc: Run PCT also with the digest step
|
||||
|
||||
* cipher/ecc.c (test_keys_fips): New function
|
||||
(nist_generate_key): In FIPS mode, execute new PCT test
|
||||
---
|
||||
|
||||
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
|
||||
---
|
||||
cipher/ecc.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 81 insertions(+)
|
||||
|
||||
diff --git a/cipher/ecc.c b/cipher/ecc.c
|
||||
index 63b0d05e..783e249d 100644
|
||||
--- a/cipher/ecc.c
|
||||
+++ b/cipher/ecc.c
|
||||
@@ -101,6 +101,7 @@ static void *progress_cb_data;
|
||||
|
||||
/* Local prototypes. */
|
||||
static void test_keys (mpi_ec_t ec, unsigned int nbits);
|
||||
+static void test_keys_fips (mpi_ec_t ec, gcry_mpi_t x, gcry_mpi_t y);
|
||||
static void test_ecdh_only_keys (mpi_ec_t ec, unsigned int nbits, int flags);
|
||||
static unsigned int ecc_get_nbits (gcry_sexp_t parms);
|
||||
|
||||
@@ -255,6 +256,8 @@ nist_generate_key (mpi_ec_t ec, int flags,
|
||||
; /* User requested to skip the test. */
|
||||
else if (ec->model == MPI_EC_MONTGOMERY)
|
||||
test_ecdh_only_keys (ec, ec->nbits - 63, flags);
|
||||
+ else if (fips_mode ())
|
||||
+ test_keys_fips (ec, x, y);
|
||||
else
|
||||
test_keys (ec, ec->nbits - 64);
|
||||
|
||||
@@ -304,6 +307,84 @@ test_keys (mpi_ec_t ec, unsigned int nbits)
|
||||
mpi_free (test);
|
||||
}
|
||||
|
||||
+/* We should get here only with the NIST curves as they are the only ones
|
||||
+ * having the fips bit set in ecc_domain_parms_t struct so this is slightly
|
||||
+ * simpler than the whole ecc_generate function */
|
||||
+static void
|
||||
+test_keys_fips (mpi_ec_t ec, gcry_mpi_t Qx, gcry_mpi_t Qy)
|
||||
+{
|
||||
+ gcry_md_hd_t hd = NULL;
|
||||
+ const char *data_tmpl = "(data (flags rfc6979) (hash %s %b))";
|
||||
+ gcry_sexp_t skey = NULL, pkey = NULL;
|
||||
+ gcry_sexp_t curve_info = NULL;
|
||||
+ gcry_sexp_t sig = NULL;
|
||||
+ gcry_mpi_t public = NULL;
|
||||
+ char plaintext[128];
|
||||
+ int rc;
|
||||
+
|
||||
+ /* Build keys structures */
|
||||
+ if (ec->name)
|
||||
+ {
|
||||
+ rc = sexp_build (&curve_info, NULL, "(curve %s)", ec->name);
|
||||
+ if (rc)
|
||||
+ log_fatal ("ECDSA operation: failed to build curve_info\n");
|
||||
+ }
|
||||
+
|
||||
+ public = _gcry_ecc_ec2os (Qx, Qy, ec->p);
|
||||
+ rc = sexp_build (&pkey, NULL,
|
||||
+ "(key-data"
|
||||
+ " (public-key"
|
||||
+ " (ecc%S(q%m)))"
|
||||
+ " )",
|
||||
+ curve_info,
|
||||
+ public);
|
||||
+ if (rc)
|
||||
+ log_fatal ("ECDSA operation: failed to build public key: %s\n", gpg_strerror (rc));
|
||||
+ rc = sexp_build (&skey, NULL,
|
||||
+ "(key-data"
|
||||
+ " (private-key"
|
||||
+ " (ecc%S(q%m)(d%m)))"
|
||||
+ " )",
|
||||
+ curve_info,
|
||||
+ public, ec->d);
|
||||
+ if (rc)
|
||||
+ log_fatal ("ECDSA operation: failed to build private key: %s\n", gpg_strerror (rc));
|
||||
+
|
||||
+ /* Create a random plaintext. */
|
||||
+ _gcry_randomize (plaintext, sizeof plaintext, GCRY_WEAK_RANDOM);
|
||||
+
|
||||
+ /* Open MD context and feed the random data in */
|
||||
+ rc = _gcry_md_open (&hd, GCRY_MD_SHA256, 0);
|
||||
+ if (rc)
|
||||
+ log_fatal ("ECDSA operation: failed to initialize MD context: %s\n", gpg_strerror (rc));
|
||||
+ _gcry_md_write (hd, plaintext, sizeof(plaintext));
|
||||
+
|
||||
+ /* Sign the data */
|
||||
+ rc = _gcry_pk_sign_md (&sig, data_tmpl, hd, skey, NULL);
|
||||
+ if (rc)
|
||||
+ log_fatal ("ECDSA operation: signing failed: %s\n", gpg_strerror (rc));
|
||||
+
|
||||
+ /* Verify this signature. */
|
||||
+ rc = _gcry_pk_verify_md (sig, data_tmpl, hd, pkey, NULL);
|
||||
+ if (rc)
|
||||
+ log_fatal ("ECDSA operation: verification failed: %s\n", gpg_strerror (rc));
|
||||
+
|
||||
+ /* 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));
|
||||
+ rc = _gcry_pk_verify_md (sig, data_tmpl, hd, pkey, NULL);
|
||||
+ if (rc != GPG_ERR_BAD_SIGNATURE)
|
||||
+ log_fatal ("ECDSA operation: signature verification worked on modified data\n");
|
||||
+
|
||||
+ mpi_free (public);
|
||||
+ sexp_release (curve_info);
|
||||
+ _gcry_md_close (hd);
|
||||
+ sexp_release (pkey);
|
||||
+ sexp_release (skey);
|
||||
+ sexp_release (sig);
|
||||
+}
|
||||
+
|
||||
|
||||
static void
|
||||
test_ecdh_only_keys (mpi_ec_t ec, unsigned int nbits, int flags)
|
||||
--
|
||||
2.37.1
|
||||
|
||||
|
||||
From 2cca95e488d58ae79975dd867e7782504b155212 Mon Sep 17 00:00:00 2001
|
||||
From: Jakub Jelen <jjelen@redhat.com>
|
||||
Date: Tue, 16 Aug 2022 10:27:46 +0200
|
||||
Subject: [PATCH 6/6] Simplify the PCT for RSA and ECDSA
|
||||
|
||||
Could be squashed.
|
||||
|
||||
* cipher/ecc.c (test_keys_fips): Simplify to accept key in SEXP format
|
||||
(nist_generate_key): Skip call to test keys
|
||||
(ecc_generate): Call test keys in FIPS mode later, when we have
|
||||
complete SEXP key structure.
|
||||
* cipher/rsa.c (test_keys_fips): Simplify to accept key in SEXP format
|
||||
(generate_fips): Skip selftest at this stage
|
||||
(rsa_generate): Test the keys later when we already have key in SEXP
|
||||
format
|
||||
---
|
||||
|
||||
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
|
||||
---
|
||||
cipher/ecc.c | 50 ++++++++------------------------------------------
|
||||
cipher/rsa.c | 47 ++++++++++++-----------------------------------
|
||||
2 files changed, 20 insertions(+), 77 deletions(-)
|
||||
|
||||
diff --git a/cipher/ecc.c b/cipher/ecc.c
|
||||
index 783e249d..1e80200e 100644
|
||||
--- a/cipher/ecc.c
|
||||
+++ b/cipher/ecc.c
|
||||
@@ -101,7 +101,7 @@ static void *progress_cb_data;
|
||||
|
||||
/* Local prototypes. */
|
||||
static void test_keys (mpi_ec_t ec, unsigned int nbits);
|
||||
-static void test_keys_fips (mpi_ec_t ec, gcry_mpi_t x, gcry_mpi_t y);
|
||||
+static void test_keys_fips (gcry_sexp_t skey);
|
||||
static void test_ecdh_only_keys (mpi_ec_t ec, unsigned int nbits, int flags);
|
||||
static unsigned int ecc_get_nbits (gcry_sexp_t parms);
|
||||
|
||||
@@ -256,9 +256,7 @@ nist_generate_key (mpi_ec_t ec, int flags,
|
||||
; /* User requested to skip the test. */
|
||||
else if (ec->model == MPI_EC_MONTGOMERY)
|
||||
test_ecdh_only_keys (ec, ec->nbits - 63, flags);
|
||||
- else if (fips_mode ())
|
||||
- test_keys_fips (ec, x, y);
|
||||
- else
|
||||
+ else if (!fips_mode ())
|
||||
test_keys (ec, ec->nbits - 64);
|
||||
|
||||
return 0;
|
||||
@@ -311,45 +309,14 @@ test_keys (mpi_ec_t ec, unsigned int nbits)
|
||||
* having the fips bit set in ecc_domain_parms_t struct so this is slightly
|
||||
* simpler than the whole ecc_generate function */
|
||||
static void
|
||||
-test_keys_fips (mpi_ec_t ec, gcry_mpi_t Qx, gcry_mpi_t Qy)
|
||||
+test_keys_fips (gcry_sexp_t skey)
|
||||
{
|
||||
gcry_md_hd_t hd = NULL;
|
||||
const char *data_tmpl = "(data (flags rfc6979) (hash %s %b))";
|
||||
- gcry_sexp_t skey = NULL, pkey = NULL;
|
||||
- gcry_sexp_t curve_info = NULL;
|
||||
gcry_sexp_t sig = NULL;
|
||||
- gcry_mpi_t public = NULL;
|
||||
char plaintext[128];
|
||||
int rc;
|
||||
|
||||
- /* Build keys structures */
|
||||
- if (ec->name)
|
||||
- {
|
||||
- rc = sexp_build (&curve_info, NULL, "(curve %s)", ec->name);
|
||||
- if (rc)
|
||||
- log_fatal ("ECDSA operation: failed to build curve_info\n");
|
||||
- }
|
||||
-
|
||||
- public = _gcry_ecc_ec2os (Qx, Qy, ec->p);
|
||||
- rc = sexp_build (&pkey, NULL,
|
||||
- "(key-data"
|
||||
- " (public-key"
|
||||
- " (ecc%S(q%m)))"
|
||||
- " )",
|
||||
- curve_info,
|
||||
- public);
|
||||
- if (rc)
|
||||
- log_fatal ("ECDSA operation: failed to build public key: %s\n", gpg_strerror (rc));
|
||||
- rc = sexp_build (&skey, NULL,
|
||||
- "(key-data"
|
||||
- " (private-key"
|
||||
- " (ecc%S(q%m)(d%m)))"
|
||||
- " )",
|
||||
- curve_info,
|
||||
- public, ec->d);
|
||||
- if (rc)
|
||||
- log_fatal ("ECDSA operation: failed to build private key: %s\n", gpg_strerror (rc));
|
||||
-
|
||||
/* Create a random plaintext. */
|
||||
_gcry_randomize (plaintext, sizeof plaintext, GCRY_WEAK_RANDOM);
|
||||
|
||||
@@ -365,7 +332,7 @@ test_keys_fips (mpi_ec_t ec, gcry_mpi_t Qx, gcry_mpi_t Qy)
|
||||
log_fatal ("ECDSA operation: signing failed: %s\n", gpg_strerror (rc));
|
||||
|
||||
/* Verify this signature. */
|
||||
- rc = _gcry_pk_verify_md (sig, data_tmpl, hd, pkey, NULL);
|
||||
+ rc = _gcry_pk_verify_md (sig, data_tmpl, hd, skey, NULL);
|
||||
if (rc)
|
||||
log_fatal ("ECDSA operation: verification failed: %s\n", gpg_strerror (rc));
|
||||
|
||||
@@ -373,15 +340,11 @@ test_keys_fips (mpi_ec_t ec, gcry_mpi_t Qx, gcry_mpi_t Qy)
|
||||
_gcry_md_reset(hd);
|
||||
plaintext[sizeof plaintext / 2] ^= 1;
|
||||
_gcry_md_write (hd, plaintext, sizeof(plaintext));
|
||||
- rc = _gcry_pk_verify_md (sig, data_tmpl, hd, pkey, NULL);
|
||||
+ rc = _gcry_pk_verify_md (sig, data_tmpl, hd, skey, NULL);
|
||||
if (rc != GPG_ERR_BAD_SIGNATURE)
|
||||
log_fatal ("ECDSA operation: signature verification worked on modified data\n");
|
||||
|
||||
- mpi_free (public);
|
||||
- sexp_release (curve_info);
|
||||
_gcry_md_close (hd);
|
||||
- sexp_release (pkey);
|
||||
- sexp_release (skey);
|
||||
sexp_release (sig);
|
||||
}
|
||||
|
||||
@@ -714,6 +677,9 @@ ecc_generate (const gcry_sexp_t genparms, gcry_sexp_t *r_skey)
|
||||
log_debug ("ecgen result using Ed25519+EdDSA\n");
|
||||
}
|
||||
|
||||
+ if (!(flags & PUBKEY_FLAG_NO_KEYTEST) && fips_mode ())
|
||||
+ test_keys_fips (*r_skey);
|
||||
+
|
||||
leave:
|
||||
mpi_free (public);
|
||||
mpi_free (base);
|
||||
diff --git a/cipher/rsa.c b/cipher/rsa.c
|
||||
index 78c26f2f..9d14a474 100644
|
||||
--- a/cipher/rsa.c
|
||||
+++ b/cipher/rsa.c
|
||||
@@ -178,37 +178,15 @@ test_keys (RSA_secret_key *sk, unsigned int nbits)
|
||||
}
|
||||
|
||||
static int
|
||||
-test_keys_fips (RSA_secret_key *sk)
|
||||
+test_keys_fips (gcry_sexp_t skey)
|
||||
{
|
||||
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);
|
||||
|
||||
@@ -224,7 +202,7 @@ test_keys_fips (RSA_secret_key *sk)
|
||||
goto leave;
|
||||
|
||||
/* Use the RSA public function to verify this signature. */
|
||||
- ec = _gcry_pk_verify_md (sig, data_tmpl, hd, pkey, NULL);
|
||||
+ ec = _gcry_pk_verify_md (sig, data_tmpl, hd, skey, NULL);
|
||||
if (ec)
|
||||
goto leave;
|
||||
|
||||
@@ -232,7 +210,7 @@ test_keys_fips (RSA_secret_key *sk)
|
||||
_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);
|
||||
+ ec = _gcry_pk_verify_md (sig, data_tmpl, hd, skey, NULL);
|
||||
if (ec != GPG_ERR_BAD_SIGNATURE)
|
||||
goto leave; /* Signature verification worked on modified data */
|
||||
|
||||
@@ -240,8 +218,6 @@ test_keys_fips (RSA_secret_key *sk)
|
||||
leave:
|
||||
sexp_release (sig);
|
||||
_gcry_md_close (hd);
|
||||
- sexp_release (pkey);
|
||||
- sexp_release (skey);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -714,8 +690,7 @@ generate_fips (RSA_secret_key *sk, unsigned int nbits, unsigned long use_e,
|
||||
sk->d = d;
|
||||
sk->u = u;
|
||||
|
||||
- /* Now we can test our keys. */
|
||||
- if (ec || (!testparms && test_keys_fips (sk)))
|
||||
+ if (ec)
|
||||
{
|
||||
_gcry_mpi_release (sk->n); sk->n = NULL;
|
||||
_gcry_mpi_release (sk->e); sk->e = NULL;
|
||||
@@ -723,11 +698,6 @@ generate_fips (RSA_secret_key *sk, unsigned int nbits, unsigned long use_e,
|
||||
_gcry_mpi_release (sk->q); sk->q = NULL;
|
||||
_gcry_mpi_release (sk->d); sk->d = NULL;
|
||||
_gcry_mpi_release (sk->u); sk->u = NULL;
|
||||
- if (!ec)
|
||||
- {
|
||||
- fips_signal_error ("self-test after key generation failed");
|
||||
- return GPG_ERR_SELFTEST_FAILED;
|
||||
- }
|
||||
}
|
||||
|
||||
return ec;
|
||||
@@ -1306,7 +1276,7 @@ rsa_generate (const gcry_sexp_t genparms, gcry_sexp_t *r_skey)
|
||||
/**/ : NULL);
|
||||
|
||||
/* Generate. */
|
||||
- if (deriveparms || fips_mode())
|
||||
+ if (deriveparms || fips_mode ())
|
||||
{
|
||||
ec = generate_fips (&sk, nbits, evalue, deriveparms,
|
||||
!!(flags & PUBKEY_FLAG_TRANSIENT_KEY));
|
||||
@@ -1341,6 +1311,13 @@ rsa_generate (const gcry_sexp_t genparms, gcry_sexp_t *r_skey)
|
||||
mpi_free (sk.u);
|
||||
sexp_release (swap_info);
|
||||
|
||||
+ if (!ec && fips_mode () && test_keys_fips (*r_skey))
|
||||
+ {
|
||||
+ sexp_release (*r_skey); *r_skey = NULL;
|
||||
+ fips_signal_error ("self-test after key generation failed");
|
||||
+ return GPG_ERR_SELFTEST_FAILED;
|
||||
+ }
|
||||
+
|
||||
return ec;
|
||||
}
|
||||
|
||||
--
|
||||
2.37.1
|
@ -16,7 +16,7 @@ print(string.sub(hash, 0, 16))
|
||||
|
||||
Name: libgcrypt
|
||||
Version: 1.10.0
|
||||
Release: 4%{?dist}
|
||||
Release: 5%{?dist}
|
||||
URL: https://www.gnupg.org/
|
||||
Source0: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2
|
||||
Source1: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2.sig
|
||||
@ -24,6 +24,11 @@ Source2: wk@g10code.com
|
||||
Patch1: libgcrypt-1.10.0-disable-brainpool.patch
|
||||
Patch2: libgcrypt-1.10.0-fips-disable-pkcs1.5.patch
|
||||
Patch3: libgcrypt-1.10.0-ppc-hwf.patch
|
||||
Patch4: libgcrypt-1.10.0-allow-small-RSA-verify.patch
|
||||
Patch5: libgcrypt-1.10.0-allow-short-salt.patch
|
||||
Patch6: libgcrypt-1.10.0-fips-getrandom.patch
|
||||
Patch7: libgcrypt-1.10.0-fips-selftest.patch
|
||||
Patch8: libgcrypt-1.10.0-fips-disable-oaep.patch
|
||||
|
||||
%global gcrylibdir %{_libdir}
|
||||
%global gcrysoname libgcrypt.so.20
|
||||
@ -62,6 +67,11 @@ applications using libgcrypt.
|
||||
%patch1 -p1
|
||||
%patch2 -p1
|
||||
%patch3 -p1
|
||||
%patch4 -p1
|
||||
%patch5 -p1
|
||||
%patch6 -p1
|
||||
%patch7 -p1
|
||||
%patch8 -p1
|
||||
|
||||
%build
|
||||
# This package has a configure test which uses ASMs, but does not link the
|
||||
@ -180,6 +190,13 @@ mkdir -p -m 755 $RPM_BUILD_ROOT/etc/gcrypt
|
||||
%license COPYING
|
||||
|
||||
%changelog
|
||||
* Wed Aug 17 2022 Jakub Jelen <jjelen@redhat.com> - 1.10.0-5
|
||||
- Allow signature verification with smaller RSA keys (#2083846)
|
||||
- Allow short salt for KDF (#2114870)
|
||||
- Reseed the kernel DRBG by using GRND_RANDOM (#2118695)
|
||||
- Address FIPS review comments around selftests (#2118695)
|
||||
- Disable RSA-OAEP in FIPS mode (#2118695)
|
||||
|
||||
* Fri May 06 2022 Jakub Jelen <jjelen@redhat.com> - 1.10.0-4
|
||||
- Backport ppc hardware flags detection (#2051307)
|
||||
- Disable PKCS#1.5 encryption in FIPS mode (#2061328)
|
||||
|
Loading…
Reference in New Issue
Block a user