forked from pool/libgcrypt
* Add --enable-marvin-workaround to spec to enable workaround * Fix timing based side-channel in RSA implementation ( Marvin attack ) * Add libgcrypt-CVE-2024-2236.patch OBS-URL: https://build.opensuse.org/package/show/devel:libraries:c_c++/libgcrypt?expand=0&rev=193
283 lines
9.1 KiB
Diff
283 lines
9.1 KiB
Diff
From 53c97483b17fee280e24f595bc0d82d9b362ffde Mon Sep 17 00:00:00 2001
|
|
From: NIIBE Yutaka <gniibe@fsij.org>
|
|
Date: Thu, 26 Dec 2024 11:12:48 +0900
|
|
Subject: [PATCH 18/19] fips,ecc: Check DATA in gcry_pk_sign/verify in FIPS
|
|
mode.
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
* src/gcrypt.h.in (GCRY_FIPS_FLAG_REJECT_PK_MD): New.
|
|
(GCRY_FIPS_FLAG_REJECT_PK_GOST_SM2): New.
|
|
|
|
* cipher/ecc.c (ecc_sign): Check if GOST or SM2. Check if hash is
|
|
compliant.
|
|
(ecc_verify): Likewise.
|
|
* tests/t-fips-service-ind.c (check_pk_s_v): Modify tests including
|
|
hash compliance.
|
|
|
|
--
|
|
|
|
GnuPG-bug-id: 7338
|
|
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
|
|
Signed-off-by: Lucas Mülling <lucas.mulling@suse.com>
|
|
---
|
|
cipher/ecc.c | 70 +++++++++++++++++++++++++++++++++++---
|
|
src/gcrypt.h.in | 4 ++-
|
|
tests/t-fips-service-ind.c | 52 ++++++++++++++++++++--------
|
|
3 files changed, 107 insertions(+), 19 deletions(-)
|
|
|
|
diff --git a/cipher/ecc.c b/cipher/ecc.c
|
|
index 8896afd0..525523ed 100644
|
|
--- a/cipher/ecc.c
|
|
+++ b/cipher/ecc.c
|
|
@@ -941,6 +941,18 @@ ecc_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_data, gcry_sexp_t keyparms)
|
|
if (rc)
|
|
goto leave;
|
|
|
|
+ if (fips_mode ()
|
|
+ && ((ctx.flags & PUBKEY_FLAG_GOST) || (ctx.flags & PUBKEY_FLAG_SM2)))
|
|
+ {
|
|
+ if (fips_check_rejection (GCRY_FIPS_FLAG_REJECT_PK_GOST_SM2))
|
|
+ {
|
|
+ rc = GPG_ERR_INV_DATA;
|
|
+ goto leave;
|
|
+ }
|
|
+ else
|
|
+ fips_service_indicator_mark_non_compliant ();
|
|
+ }
|
|
+
|
|
/* Hash algo is determined by curve in EdDSA. */
|
|
if ((ctx.flags & PUBKEY_FLAG_EDDSA))
|
|
{
|
|
@@ -953,10 +965,12 @@ ecc_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_data, gcry_sexp_t keyparms)
|
|
&& ctx.hash_algo != GCRY_MD_SHAKE256)))
|
|
{
|
|
if (fips_check_rejection (GCRY_FIPS_FLAG_REJECT_PK))
|
|
- rc = GPG_ERR_DIGEST_ALGO;
|
|
+ {
|
|
+ rc = GPG_ERR_DIGEST_ALGO;
|
|
+ goto leave;
|
|
+ }
|
|
else
|
|
fips_service_indicator_mark_non_compliant ();
|
|
- goto leave;
|
|
}
|
|
}
|
|
else
|
|
@@ -967,6 +981,23 @@ ecc_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_data, gcry_sexp_t keyparms)
|
|
ctx.hash_algo = GCRY_MD_SHAKE256;
|
|
}
|
|
}
|
|
+ else
|
|
+ {
|
|
+ if (fips_mode ())
|
|
+ {
|
|
+ if (_gcry_md_algo_info (ctx.hash_algo, GCRYCTL_TEST_ALGO, NULL, NULL)
|
|
+ || ctx.hash_algo == GCRY_MD_SHA1)
|
|
+ {
|
|
+ if (fips_check_rejection (GCRY_FIPS_FLAG_REJECT_PK_MD))
|
|
+ {
|
|
+ rc = GPG_ERR_DIGEST_ALGO;
|
|
+ goto leave;
|
|
+ }
|
|
+ else
|
|
+ fips_service_indicator_mark_non_compliant ();
|
|
+ }
|
|
+ }
|
|
+ }
|
|
|
|
sig_r = mpi_new (0);
|
|
sig_s = mpi_new (0);
|
|
@@ -1066,6 +1097,18 @@ ecc_verify (gcry_sexp_t s_sig, gcry_sexp_t s_data, gcry_sexp_t s_keyparms)
|
|
if (DBG_CIPHER)
|
|
log_mpidump ("ecc_verify data", data);
|
|
|
|
+ if (fips_mode ()
|
|
+ && ((ctx.flags & PUBKEY_FLAG_GOST) || (ctx.flags & PUBKEY_FLAG_SM2)))
|
|
+ {
|
|
+ if (fips_check_rejection (GCRY_FIPS_FLAG_REJECT_PK_GOST_SM2))
|
|
+ {
|
|
+ rc = GPG_ERR_INV_DATA;
|
|
+ goto leave;
|
|
+ }
|
|
+ else
|
|
+ fips_service_indicator_mark_non_compliant ();
|
|
+ }
|
|
+
|
|
/* Hash algo is determined by curve in EdDSA. */
|
|
if ((ctx.flags & PUBKEY_FLAG_EDDSA))
|
|
{
|
|
@@ -1078,10 +1121,12 @@ ecc_verify (gcry_sexp_t s_sig, gcry_sexp_t s_data, gcry_sexp_t s_keyparms)
|
|
&& ctx.hash_algo != GCRY_MD_SHAKE256)))
|
|
{
|
|
if (fips_check_rejection (GCRY_FIPS_FLAG_REJECT_PK))
|
|
- rc = GPG_ERR_DIGEST_ALGO;
|
|
+ {
|
|
+ rc = GPG_ERR_DIGEST_ALGO;
|
|
+ goto leave;
|
|
+ }
|
|
else
|
|
fips_service_indicator_mark_non_compliant ();
|
|
- goto leave;
|
|
}
|
|
}
|
|
else
|
|
@@ -1092,6 +1137,23 @@ ecc_verify (gcry_sexp_t s_sig, gcry_sexp_t s_data, gcry_sexp_t s_keyparms)
|
|
ctx.hash_algo = GCRY_MD_SHAKE256;
|
|
}
|
|
}
|
|
+ else
|
|
+ {
|
|
+ if (fips_mode ())
|
|
+ {
|
|
+ if (_gcry_md_algo_info (ctx.hash_algo, GCRYCTL_TEST_ALGO, NULL, NULL)
|
|
+ || ctx.hash_algo == GCRY_MD_SHA1)
|
|
+ {
|
|
+ if (fips_check_rejection (GCRY_FIPS_FLAG_REJECT_PK_MD))
|
|
+ {
|
|
+ rc = GPG_ERR_DIGEST_ALGO;
|
|
+ goto leave;
|
|
+ }
|
|
+ else
|
|
+ fips_service_indicator_mark_non_compliant ();
|
|
+ }
|
|
+ }
|
|
+ }
|
|
|
|
/*
|
|
* Extract the signature value.
|
|
diff --git a/src/gcrypt.h.in b/src/gcrypt.h.in
|
|
index 7bee45e9..fcb6a327 100644
|
|
--- a/src/gcrypt.h.in
|
|
+++ b/src/gcrypt.h.in
|
|
@@ -1986,11 +1986,13 @@ char *gcry_get_config (int mode, const char *what);
|
|
#define GCRY_FIPS_FLAG_REJECT_MAC (1 << 3)
|
|
#define GCRY_FIPS_FLAG_REJECT_CIPHER (1 << 4)
|
|
#define GCRY_FIPS_FLAG_REJECT_PK (1 << 5)
|
|
+#define GCRY_FIPS_FLAG_REJECT_PK_MD (1 << 6)
|
|
+#define GCRY_FIPS_FLAG_REJECT_PK_GOST_SM2 (1 << 7)
|
|
|
|
#define GCRY_FIPS_FLAG_REJECT_MD \
|
|
(GCRY_FIPS_FLAG_REJECT_MD_MD5 | GCRY_FIPS_FLAG_REJECT_MD_OTHERS)
|
|
|
|
-/* Note: Don't reject MD5 */
|
|
+/* Note: Don't reject MD5, PK MD, PK GOST and PK SM2 */
|
|
#define GCRY_FIPS_FLAG_REJECT_COMPAT110 \
|
|
(GCRY_FIPS_FLAG_REJECT_MD_OTHERS \
|
|
| GCRY_FIPS_FLAG_REJECT_MAC \
|
|
diff --git a/tests/t-fips-service-ind.c b/tests/t-fips-service-ind.c
|
|
index 90d92c70..fe963fa5 100644
|
|
--- a/tests/t-fips-service-ind.c
|
|
+++ b/tests/t-fips-service-ind.c
|
|
@@ -228,6 +228,7 @@ check_pk_s_v (int reject)
|
|
static struct {
|
|
const char *prvkey;
|
|
const char *pubkey;
|
|
+ const char *data;
|
|
int expect_failure;
|
|
} tv[] = {
|
|
{
|
|
@@ -236,6 +237,8 @@ check_pk_s_v (int reject)
|
|
"(public-key (ecc (curve nistp256)"
|
|
" (q #041ccbe91c075fc7f4f033bfa248db8fccd3565de94bbfb12f3c59ff46c271bf83"
|
|
"ce4014c68811f9a21a1fdb2c0e6113e06db7ca93b7404e78dc7ccd5ca89a4ca9#)))",
|
|
+ "(data (flags raw)(hash sha256 "
|
|
+ "#00112233445566778899AABBCCDDEEFF000102030405060708090A0B0C0D0E0F#))",
|
|
0
|
|
},
|
|
{ /* non-compliant curve */
|
|
@@ -244,28 +247,40 @@ check_pk_s_v (int reject)
|
|
"(public-key (ecc (curve secp256k1)"
|
|
" (q #046fcc37ea5e9e09fec6c83e5fbd7a745e3eee81d16ebd861c9e66f55518c19798"
|
|
"4e9f113c07f875691df8afc1029496fc4cb9509b39dcd38f251a83359cc8b4f7#)))",
|
|
+ "(data (flags raw)(hash sha256 "
|
|
+ "#00112233445566778899AABBCCDDEEFF000102030405060708090A0B0C0D0E0F#))",
|
|
1
|
|
- }
|
|
+ },
|
|
+ { /* non-compliant hash */
|
|
+ "(private-key (ecc (curve nistp256)"
|
|
+ " (d #519b423d715f8b581f4fa8ee59f4771a5b44c8130b4e3eacca54a56dda72b464#)))",
|
|
+ "(public-key (ecc (curve nistp256)"
|
|
+ " (q #041ccbe91c075fc7f4f033bfa248db8fccd3565de94bbfb12f3c59ff46c271bf83"
|
|
+ "ce4014c68811f9a21a1fdb2c0e6113e06db7ca93b7404e78dc7ccd5ca89a4ca9#)))",
|
|
+ "(data (flags raw)(hash ripemd160 "
|
|
+ "#00112233445566778899AABBCCDDEEFF00010203#))",
|
|
+ 1
|
|
+ },
|
|
+ { /* non-compliant hash for signing */
|
|
+ "(private-key (ecc (curve nistp256)"
|
|
+ " (d #519b423d715f8b581f4fa8ee59f4771a5b44c8130b4e3eacca54a56dda72b464#)))",
|
|
+ "(public-key (ecc (curve nistp256)"
|
|
+ " (q #041ccbe91c075fc7f4f033bfa248db8fccd3565de94bbfb12f3c59ff46c271bf83"
|
|
+ "ce4014c68811f9a21a1fdb2c0e6113e06db7ca93b7404e78dc7ccd5ca89a4ca9#)))",
|
|
+ "(data (flags raw)(hash sha1 "
|
|
+ "#00112233445566778899AABBCCDDEEFF00010203#))",
|
|
+ 1
|
|
+ },
|
|
};
|
|
int tvidx;
|
|
gpg_error_t err;
|
|
gpg_err_code_t ec;
|
|
- const char *data = "(data (flags raw)"
|
|
- "(hash sha256 #00112233445566778899AABBCCDDEEFF000102030405060708090A0B0C0D0E0F#))";
|
|
- gcry_sexp_t s_data = NULL;
|
|
-
|
|
- err = gcry_sexp_build (&s_data, NULL, data);
|
|
- if (err)
|
|
- {
|
|
- fail ("error building SEXP for test, %s: %s",
|
|
- "data", gpg_strerror (err));
|
|
- return;
|
|
- }
|
|
|
|
for (tvidx=0; tvidx < DIM(tv); tvidx++)
|
|
{
|
|
gcry_sexp_t s_pk = NULL;
|
|
gcry_sexp_t s_sk = NULL;
|
|
+ gcry_sexp_t s_data = NULL;
|
|
gcry_sexp_t s_sig= NULL;
|
|
|
|
if (verbose)
|
|
@@ -287,6 +302,14 @@ check_pk_s_v (int reject)
|
|
goto next;
|
|
}
|
|
|
|
+ err = gcry_sexp_build (&s_data, NULL, tv[tvidx].data);
|
|
+ if (err)
|
|
+ {
|
|
+ fail ("error building SEXP for test, %s: %s",
|
|
+ "data", gpg_strerror (err));
|
|
+ goto next;
|
|
+ }
|
|
+
|
|
err = gcry_pk_sign (&s_sig, s_data, s_sk);
|
|
if (err)
|
|
{
|
|
@@ -363,11 +386,10 @@ check_pk_s_v (int reject)
|
|
|
|
next:
|
|
gcry_sexp_release (s_sig);
|
|
+ gcry_sexp_release (s_data);
|
|
gcry_sexp_release (s_pk);
|
|
gcry_sexp_release (s_sk);
|
|
}
|
|
-
|
|
- gcry_sexp_release (s_data);
|
|
}
|
|
|
|
/* Check gcry_pk_hash_sign, gcry_pk_hash_verify API. */
|
|
@@ -1461,6 +1483,8 @@ main (int argc, char **argv)
|
|
|
|
xgcry_control ((GCRYCTL_FIPS_REJECT_NON_FIPS,
|
|
(GCRY_FIPS_FLAG_REJECT_MD_MD5
|
|
+ | GCRY_FIPS_FLAG_REJECT_PK_MD
|
|
+ | GCRY_FIPS_FLAG_REJECT_PK_GOST_SM2
|
|
| GCRY_FIPS_FLAG_REJECT_COMPAT110)));
|
|
|
|
check_md_o_w_r_c (1);
|
|
--
|
|
2.49.0
|
|
|