File libgcrypt-FIPS-SLI-Differentiate-non-compliant-flags-in-the-SLI.patch of Package libgcrypt.37939
From b81e598c248826be6d8d518bd1e6a13a79f3c58c Mon Sep 17 00:00:00 2001
From: Lucas Mulling <lucas.mulling@suse.com>
Date: Fri, 7 Feb 2025 08:35:31 -0300
Subject: [PATCH 1/4] Fix non-compliant flags in the SLI
* cipher/pubkey-util.c (_gcry_pk_util_parse_flaglist): Differentiate use
of igninvflag.
Signed-off-by: Lucas Mulling <lucas.mulling@suse.com>
---
cipher/pubkey-util.c | 8 ++++++++
1 file changed, 8 insertions(+)
Index: libgcrypt-1.10.3/cipher/pubkey-util.c
===================================================================
--- libgcrypt-1.10.3.orig/cipher/pubkey-util.c
+++ libgcrypt-1.10.3/cipher/pubkey-util.c
@@ -200,6 +200,14 @@ _gcry_pk_util_parse_flaglist (gcry_sexp_
}
}
+ if (fips_mode () && igninvflag)
+ {
+ if (fips_check_rejection (GCRY_FIPS_FLAG_REJECT_PK))
+ rc = GPG_ERR_INV_FLAG;
+ else
+ fips_service_indicator_mark_non_compliant ();
+ }
+
if (r_flags)
*r_flags = flags;
if (r_encoding)
@@ -654,7 +662,6 @@ _gcry_pk_util_free_encoding_ctx (struct
xfree (ctx->label);
}
-
/* Take the hash value and convert into an MPI, suitable for
passing to the low level functions. We currently support the
old style way of passing just a MPI and the modern interface which
@@ -968,6 +975,18 @@ _gcry_pk_util_data_to_mpi (gcry_sexp_t i
list = sexp_find_token (ldata, "random-override", 0);
if (list)
{
+ if(fips_mode ())
+ {
+ if (fips_check_rejection (GCRY_FIPS_FLAG_REJECT_PK))
+ {
+ sexp_release (list);
+ rc = GPG_ERR_INV_FLAG;
+ goto leave;
+ }
+ else
+ fips_service_indicator_mark_non_compliant ();
+
+ }
s = sexp_nth_data (list, 1, &n);
if (!s)
rc = GPG_ERR_NO_OBJ;
@@ -1147,6 +1166,18 @@ _gcry_pk_util_data_to_mpi (gcry_sexp_t i
list = sexp_find_token (ldata, "random-override", 0);
if (list)
{
+ if(fips_mode ())
+ {
+ if (fips_check_rejection (GCRY_FIPS_FLAG_REJECT_PK))
+ {
+ sexp_release (list);
+ rc = GPG_ERR_INV_FLAG;
+ goto leave;
+ }
+ else
+ fips_service_indicator_mark_non_compliant ();
+
+ }
s = sexp_nth_data (list, 1, &n);
if (!s)
rc = GPG_ERR_NO_OBJ;
@@ -1246,6 +1277,18 @@ _gcry_pk_util_data_to_mpi (gcry_sexp_t i
list = sexp_find_token (ldata, "random-override", 0);
if (list)
{
+ if(fips_mode ())
+ {
+ if (fips_check_rejection (GCRY_FIPS_FLAG_REJECT_PK))
+ {
+ sexp_release (list);
+ rc = GPG_ERR_INV_FLAG;
+ goto leave;
+ }
+ else
+ fips_service_indicator_mark_non_compliant ();
+
+ }
s = sexp_nth_data (list, 1, &n);
if (!s)
rc = GPG_ERR_NO_OBJ;
Index: libgcrypt-1.10.3/cipher/rsa.c
===================================================================
--- libgcrypt-1.10.3.orig/cipher/rsa.c
+++ libgcrypt-1.10.3/cipher/rsa.c
@@ -1507,7 +1507,19 @@ rsa_decrypt (gcry_sexp_t *r_plain, gcry_
be practically mounted over the network as shown by Brumley and
Boney in 2003. */
if ((ctx.flags & PUBKEY_FLAG_NO_BLINDING))
- secret (plain, data, &sk);
+ {
+ if (fips_mode ())
+ {
+ if (fips_check_rejection (GCRY_FIPS_FLAG_REJECT_PK))
+ {
+ rc = GPG_ERR_INV_FLAG;
+ goto leave;
+ }
+ else
+ fips_service_indicator_mark_non_compliant ();
+ }
+ secret (plain, data, &sk);
+ }
else
secret_blinded (plain, data, &sk, nbits);
@@ -1621,8 +1633,22 @@ rsa_sign (gcry_sexp_t *r_sig, gcry_sexp_
/* Do RSA computation. */
sig = mpi_new (0);
+
if ((ctx.flags & PUBKEY_FLAG_NO_BLINDING))
- secret (sig, data, &sk);
+ {
+ if (fips_mode ())
+ {
+ if (fips_check_rejection (GCRY_FIPS_FLAG_REJECT_PK))
+ {
+ rc = GPG_ERR_INV_FLAG;
+ goto leave;
+ }
+ else
+ fips_service_indicator_mark_non_compliant ();
+ }
+
+ secret (sig, data, &sk);
+ }
else
secret_blinded (sig, data, &sk, nbits);
if (DBG_CIPHER)
Index: libgcrypt-1.10.3/src/visibility.c
===================================================================
--- libgcrypt-1.10.3.orig/src/visibility.c
+++ libgcrypt-1.10.3/src/visibility.c
@@ -1069,6 +1069,18 @@ gcry_pk_hash_verify (gcry_sexp_t sigval,
gcry_error_t
gcry_pk_random_override_new (gcry_ctx_t *r_ctx, const unsigned char *p, size_t len)
{
+ if (!fips_is_operational ())
+ return gpg_error (fips_not_operational ());
+ fips_service_indicator_init ();
+
+ if(fips_mode ())
+ {
+ if (fips_check_rejection (GCRY_FIPS_FLAG_REJECT_PK))
+ return GPG_ERR_INV_OP;
+ else
+ fips_service_indicator_mark_non_compliant ();
+
+ }
return gpg_error (_gcry_pk_random_override_new (r_ctx, p, len));
}
Index: libgcrypt-1.10.3/tests/basic.c
===================================================================
--- libgcrypt-1.10.3.orig/tests/basic.c
+++ libgcrypt-1.10.3/tests/basic.c
@@ -11648,7 +11648,7 @@ check_one_cipher (int algo, int mode, in
0, 61))
goto out;
}
- else if (mode == GCRY_CIPHER_MODE_CTR)
+ else if (mode == GCRY_CIPHER_MODE_CTR)
{
/* 32bit overflow test (big-endian counter) */
if (check_one_cipher_ctr_overflow (algo, mode, flags, key, 64, plain,
@@ -15381,7 +15381,7 @@ check_pubkey_sign (int n, gcry_sexp_t sk
" (hash sha1 #11223344556677889900AABBCCDDEEFF10203040#)\n"
" (random-override #4253647587980912233445566778899019283747#))\n",
GCRY_PK_RSA,
- 0 },
+ 0, FLAG_NOFIPS },
{ "(data\n (flags pss)\n"
" (hash-algo sha1)\n"
" (value #11223344556677889900AA#))\n",
@@ -15392,7 +15392,7 @@ check_pubkey_sign (int n, gcry_sexp_t sk
" (value #11223344556677889900AA#)\n"
" (random-override #4253647587980912233445566778899019283747#))\n",
GCRY_PK_RSA,
- 0 },
+ 0, FLAG_NOFIPS},
{ "(data\n (flags pss)\n"
" (hash-algo sha256)\n"
" (value #11223344556677889900AABBCCDDEEFF#)\n"
@@ -15400,7 +15400,7 @@ check_pubkey_sign (int n, gcry_sexp_t sk
" (random-override #42536475879809122334455667788990192837465564738291"
"00122334455667#))\n",
GCRY_PK_RSA,
- 0 },
+ 0, FLAG_NOFIPS },
{ "(data\n (flags pss)\n"
" (hash-algo sha256)\n"
" (value #11223344556677889900AABBCCDDEEFF#)\n"
@@ -15440,7 +15440,11 @@ check_pubkey_sign (int n, gcry_sexp_t sk
goto next;
}
if (gcry_err_code (rc) != datas[dataidx].expected_rc)
- fail ("gcry_pk_sign %d failed: %s\n", dataidx, gpg_strerror (rc));
+ {
+ show_sexp("hash: ", hash);
+ show_sexp("skey: ", skey);
+ fail ("gcry_pk_sign %d failed: %s\n", dataidx, gpg_strerror (rc));
+ }
if (!rc)
verify_one_signature (pkey, hash, badhash, sig);
@@ -15570,7 +15574,7 @@ check_pubkey_sign_ecdsa (int n, gcry_sex
goto next;
}
if (gcry_err_code (rc) != datas[dataidx].expected_rc)
- fail ("gcry_pk_sign failed: %s\n", gpg_strerror (rc));
+ fail ("gcry_pk_sign (%d) failed: %s\n", dataidx, gpg_strerror (rc));
if (!rc && verbose > 1)
show_sexp ("ECDSA signature:\n", sig);
@@ -15663,7 +15667,7 @@ check_pubkey_crypt (int n, gcry_sexp_t s
NULL,
1,
0,
- 0 },
+ 0, },
{ 0,
"(data\n (flags )\n" " (value #0090223344556677889900AA#))\n",
NULL,
@@ -15734,11 +15738,21 @@ check_pubkey_crypt (int n, gcry_sexp_t s
(datas[dataidx].flags & FLAG_NOFIPS)))
{
if (!rc)
- fail ("gcry_pk_encrypt did not fail as expected in FIPS mode\n");
+ {
+ show_sexp("data: ", data);
+ show_sexp("pkey: ", pkey);
+
+ fail ("gcry_pk_encrypt (%d) did not fail as expected in FIPS mode\n",
+ dataidx);
+ }
goto next;
}
if (gcry_err_code (rc) != datas[dataidx].encrypt_expected_rc)
- fail ("gcry_pk_encrypt failed: %s\n", gpg_strerror (rc));
+ {
+ show_sexp("data: ", data);
+ show_sexp("pkey: ", pkey);
+ fail ("gcry_pk_encrypt (%d) failed: %s\n", flags, gpg_strerror (rc));
+ }
if (!rc)
{
Index: libgcrypt-1.10.3/tests/pkcs1v2.c
===================================================================
--- libgcrypt-1.10.3.orig/tests/pkcs1v2.c
+++ libgcrypt-1.10.3/tests/pkcs1v2.c
@@ -337,6 +337,11 @@ check_pss (void)
err = gcry_pk_sign (&sig, sigtmpl, sec_key);
if (err)
{
+ if (in_fips_mode && gcry_err_code (err) == GPG_ERR_INV_FLAG)
+ {
+ gcry_sexp_release (sigtmpl);
+ continue;
+ }
show_sexp ("sigtmpl:\n", sigtmpl);
fail ("gcry_pk_sign failed: %s\n", gpg_strerror (err));
}
@@ -481,8 +486,15 @@ check_v15crypt (void)
}
else if (err)
{
- show_sexp ("plain:\n", ciph);
- fail ("gcry_pk_encrypt failed: %s\n", gpg_strerror (err));
+ /* SKIP the test in fips mode, random-override is not allowed */
+ if (in_fips_mode && gcry_err_code (err) == GPG_ERR_INV_FLAG)
+ {
+ gcry_sexp_release (plain);
+ continue;
+ }
+ show_sexp ("plain:\n", plain);
+ show_sexp ("pub_key:\n", pub_key);
+ fail ("gcry_pk_encrypt failed: (%d) %s\n", mno, gpg_strerror (err));
}
else
{
@@ -615,6 +627,11 @@ check_v15sign (void)
err = gcry_pk_sign (&sig, sigtmpl, sec_key);
if (err)
{
+ if (in_fips_mode && gcry_err_code (err) == GPG_ERR_INV_FLAG)
+ {
+ gcry_sexp_release (sigtmpl);
+ continue;
+ }
show_sexp ("sigtmpl:\n", sigtmpl);
fail ("gcry_pk_sign failed: %s\n", gpg_strerror (err));
}
Index: libgcrypt-1.10.3/tests/t-dsa.c
===================================================================
--- libgcrypt-1.10.3.orig/tests/t-dsa.c
+++ libgcrypt-1.10.3/tests/t-dsa.c
@@ -322,6 +322,10 @@ one_test_sexp (const char *sha_alg,
err = gcry_pk_random_override_new (&ctx, buffer2, buflen2);
if (err)
{
+ /* Setting rsa salt is not allowed in FIPS mode */
+ if (in_fips_mode && gpg_err_code (err) == GPG_ERR_INV_OP)
+ goto leave;
+
fail ("error setting salt for test: %s",
gpg_strerror (err));
goto leave;
Index: libgcrypt-1.10.3/tests/t-ecdsa.c
===================================================================
--- libgcrypt-1.10.3.orig/tests/t-ecdsa.c
+++ libgcrypt-1.10.3/tests/t-ecdsa.c
@@ -357,6 +357,10 @@ one_test_sexp (const char *curvename, co
err = gcry_pk_random_override_new (&ctx, buffer2, buflen2);
if (err)
{
+ /* Setting salt is not allowed in FIPS mode */
+ if (in_fips_mode && gpg_err_code (err) == GPG_ERR_INV_OP)
+ goto leave;
+
fail ("error setting salt for test: %s",
gpg_strerror (err));
goto leave;
Index: libgcrypt-1.10.3/tests/t-ed448.c
===================================================================
--- libgcrypt-1.10.3.orig/tests/t-ed448.c
+++ libgcrypt-1.10.3/tests/t-ed448.c
@@ -38,6 +38,7 @@ static int no_verify;
static int custom_data_file;
static int in_fips_mode;
+static int in_fips_mode;
static void
show_note (const char *format, ...)
Index: libgcrypt-1.10.3/tests/t-fips-service-ind.c
===================================================================
--- libgcrypt-1.10.3.orig/tests/t-fips-service-ind.c
+++ libgcrypt-1.10.3/tests/t-fips-service-ind.c
@@ -47,6 +47,9 @@ check_pk_g_t_n_c (int reject)
static struct {
const char *keyparms;
int expect_failure;
+ int expect_failure_testkey;
+ int expect_failure_nbits;
+ int expect_failure_curve;
} tv[] = {
{
"(genkey (ecc (curve nistp256)))",
@@ -54,8 +57,12 @@ check_pk_g_t_n_c (int reject)
},
{ /* non-compliant curve */
"(genkey (ecc (curve secp256k1)))",
- 1
- }
+ 1, 1, 1, 1
+ },
+ { /* non-compliant igninvflag */
+ "(genkey (ecc (curve nistp256) (flags igninvflag)))",
+ 1, 0, 0, 0
+ },
};
int tvidx;
gpg_error_t err;
@@ -138,14 +145,14 @@ check_pk_g_t_n_c (int reject)
goto next;
}
- if (in_fips_mode && !tv[tvidx].expect_failure && ec)
+ if (in_fips_mode && !tv[tvidx].expect_failure_testkey && ec)
{
/* Success with the FIPS service indicator == 0 expected, but != 0. */
fail ("gcry_pk_testkey test %d unexpectedly set the indicator in FIPS mode.\n",
tvidx);
goto next;
}
- else if (in_fips_mode && tv[tvidx].expect_failure && !ec)
+ else if (in_fips_mode && tv[tvidx].expect_failure_testkey && !ec)
{
/* Success with the FIPS service indicator != 0 expected, but == 0. */
fail ("gcry_pk_testkey test %d unexpectedly cleared the indicator in FIPS mode.\n",
@@ -169,14 +176,14 @@ check_pk_g_t_n_c (int reject)
goto next;
}
- if (in_fips_mode && !tv[tvidx].expect_failure && ec)
+ if (in_fips_mode && !tv[tvidx].expect_failure_nbits && ec)
{
/* Success with the FIPS service indicator == 0 expected, but != 0. */
fail ("gcry_pk_get_nbits test %d unexpectedly set the indicator in FIPS mode.\n",
tvidx);
goto next;
}
- else if (in_fips_mode && tv[tvidx].expect_failure && !ec)
+ else if (in_fips_mode && tv[tvidx].expect_failure_nbits && !ec)
{
/* Success with the FIPS service indicator != 0 expected, but == 0. */
fail ("gcry_pk_get_nbits test %d unexpectedly cleared the indicator in FIPS mode.\n",
@@ -200,14 +207,14 @@ check_pk_g_t_n_c (int reject)
goto next;
}
- if (in_fips_mode && !tv[tvidx].expect_failure && ec)
+ if (in_fips_mode && !tv[tvidx].expect_failure_curve && ec)
{
/* Success with the FIPS service indicator == 0 expected, but != 0. */
fail ("gcry_pk_get_curve test %d unexpectedly set the indicator in FIPS mode.\n",
tvidx);
goto next;
}
- else if (in_fips_mode && tv[tvidx].expect_failure && !ec)
+ else if (in_fips_mode && tv[tvidx].expect_failure_curve && !ec)
{
/* Success with the FIPS service indicator != 0 expected, but == 0. */
fail ("gcry_pk_get_curve test %d unexpectedly cleared the indicator in FIPS mode.\n",
@@ -404,6 +411,7 @@ check_pk_hash_sign_verify (void)
const char *k;
int expect_failure;
int expect_failure_hash;
+ int expect_failure_verify;
} tv[] = {
{ /* non-compliant hash */
GCRY_MD_BLAKE2B_512,
@@ -414,22 +422,43 @@ check_pk_hash_sign_verify (void)
"ce4014c68811f9a21a1fdb2c0e6113e06db7ca93b7404e78dc7ccd5ca89a4ca9#)))",
"(data(flags raw)(hash %s %b)(label %b))",
"94a1bbb14b906a61a280f245f9e93c7f3b4a6247824f5d33b9670787642a68de",
- 1, 1
+ 1, 1, 1
},
{ /* non-compliant curve */
GCRY_MD_SHA256,
"(private-key (ecc (curve secp256k1)"
" (d #c2cdf0a8b0a83b35ace53f097b5e6e6a0a1f2d40535eff1cf434f52a43d59d8f#)))",
-
"(public-key (ecc (curve secp256k1)"
" (q #046fcc37ea5e9e09fec6c83e5fbd7a745e3eee81d16ebd861c9e66f55518c19798"
"4e9f113c07f875691df8afc1029496fc4cb9509b39dcd38f251a83359cc8b4f7#)))",
"(data(flags raw)(hash %s %b)(label %b))",
"94a1bbb14b906a61a280f245f9e93c7f3b4a6247824f5d33b9670787642a68de",
+ 1, 0, 1
+ },
+ { /* non-compliant igninvflag */
+ GCRY_MD_SHA256,
+ "(private-key (ecc (curve nistp256) (flags igninvflag)"
+ " (d #519b423d715f8b581f4fa8ee59f4771a5b44c8130b4e3eacca54a56dda72b464#)))",
+ "(public-key (ecc (curve nistp256)"
+ " (q #041ccbe91c075fc7f4f033bfa248db8fccd3565de94bbfb12f3c59ff46c271bf83"
+ "ce4014c68811f9a21a1fdb2c0e6113e06db7ca93b7404e78dc7ccd5ca89a4ca9#)))",
+ "(data(flags raw)(hash %s %b)(label %b))",
+ "94a1bbb14b906a61a280f245f9e93c7f3b4a6247824f5d33b9670787642a68de",
1, 0
},
{
- GCRY_MD_SHA256,
+ GCRY_MD_SHA256, /* non-compliant label */
+ "(private-key (ecc (curve nistp256)"
+ " (d #519b423d715f8b581f4fa8ee59f4771a5b44c8130b4e3eacca54a56dda72b464#)))",
+ "(public-key (ecc (curve nistp256)"
+ " (q #041ccbe91c075fc7f4f033bfa248db8fccd3565de94bbfb12f3c59ff46c271bf83"
+ "ce4014c68811f9a21a1fdb2c0e6113e06db7ca93b7404e78dc7ccd5ca89a4ca9#)))",
+ "(data(flags raw)(hash %s %b)(label %b))",
+ "94a1bbb14b906a61a280f245f9e93c7f3b4a6247824f5d33b9670787642a68de",
+ 1, 0
+ },
+ {
+ GCRY_MD_GOSTR3411_94, /* non-compliant hash */
"(private-key (ecc (curve nistp256)"
" (d #519b423d715f8b581f4fa8ee59f4771a5b44c8130b4e3eacca54a56dda72b464#)))",
"(public-key (ecc (curve nistp256)"
@@ -437,7 +466,7 @@ check_pk_hash_sign_verify (void)
"ce4014c68811f9a21a1fdb2c0e6113e06db7ca93b7404e78dc7ccd5ca89a4ca9#)))",
"(data(flags raw)(hash %s %b)(label %b))",
"94a1bbb14b906a61a280f245f9e93c7f3b4a6247824f5d33b9670787642a68de",
- 0, 0
+ 1, 1, 1
}
};
int tvidx;
@@ -573,14 +602,14 @@ check_pk_hash_sign_verify (void)
goto next;
}
- if (in_fips_mode && !tv[tvidx].expect_failure && ec)
+ if (in_fips_mode && !tv[tvidx].expect_failure_verify && ec)
{
/* Success with the FIPS service indicator == 0 expected, but != 0. */
fail ("gcry_pk_hash test %d unexpectedly set the indicator in FIPS mode.\n",
tvidx);
goto next;
}
- else if (in_fips_mode && tv[tvidx].expect_failure && !ec)
+ else if (in_fips_mode && tv[tvidx].expect_failure_verify && !ec)
{
/* Success with the FIPS service indicator != 0 expected, but == 0. */
fail ("gcry_pk_hash_verify test %d unexpectedly cleared the indicator in FIPS mode.\n",
Index: libgcrypt-1.10.3/tests/t-rsa-pss.c
===================================================================
--- libgcrypt-1.10.3.orig/tests/t-rsa-pss.c
+++ libgcrypt-1.10.3/tests/t-rsa-pss.c
@@ -283,6 +283,10 @@ one_test_sexp (const char *n, const char
err = gcry_pk_random_override_new (&ctx, buffer2, buflen2);
if (err)
{
+ /* Setting rsa salt is not allowed in FIPS mode */
+ if (in_fips_mode && gpg_err_code (err) == GPG_ERR_INV_OP)
+ goto leave;
+
fail ("error setting salt for test: %s",
gpg_strerror (err));
goto leave;
Index: libgcrypt-1.10.3/cipher/ecc.c
===================================================================
--- libgcrypt-1.10.3.orig/cipher/ecc.c
+++ libgcrypt-1.10.3/cipher/ecc.c
@@ -792,7 +792,19 @@ ecc_sign (gcry_sexp_t *r_sig, gcry_sexp_
log_mpidump ("ecc_sign data", data);
if (ctx.label)
- rc = _gcry_mpi_scan (&k, GCRYMPI_FMT_USG, ctx.label, ctx.labellen, NULL);
+ {
+ if (fips_mode ())
+ {
+ if (fips_check_rejection (GCRY_FIPS_FLAG_REJECT_PK_ECC_K))
+ {
+ rc = GPG_ERR_INV_DATA;
+ goto leave;
+ }
+ else
+ fips_service_indicator_mark_non_compliant ();
+ }
+ rc = _gcry_mpi_scan (&k, GCRYMPI_FMT_USG, ctx.label, ctx.labellen, NULL);
+ }
if (rc)
goto leave;
Index: libgcrypt-1.10.3/src/gcrypt.h.in
===================================================================
--- libgcrypt-1.10.3.orig/src/gcrypt.h.in
+++ libgcrypt-1.10.3/src/gcrypt.h.in
@@ -1807,6 +1807,7 @@ char *gcry_get_config (int mode, const c
#define GCRY_FIPS_FLAG_REJECT_PK_GOST_SM2 (1 << 7)
#define GCRY_FIPS_FLAG_REJECT_CIPHER_MODE (1 << 8)
#define GCRY_FIPS_FLAG_REJECT_MD_SHA1 (1 << 9)
+#define GCRY_FIPS_FLAG_REJECT_PK_ECC_K (1 << 10)
#define GCRY_FIPS_FLAG_REJECT_MD \
(GCRY_FIPS_FLAG_REJECT_MD_MD5 | GCRY_FIPS_FLAG_REJECT_MD_OTHERS)