From c7709f7b23848abf4ba65cb99cb2a9e9c7ebdefc Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 1 Apr 2022 18:29:08 +0200 Subject: [PATCH 1/3] Do not allow PKCS #1.5 padding for encryption in FIPS * cipher/pubkey-util.c (_gcry_pk_util_data_to_mpi): Block PKCS #1.5 padding for encryption in FIPS mode * cipher/rsa.c (rsa_decrypt): Block PKCS #1.5 decryption in FIPS mode -- GnuPG-bug-id: 5918 Signed-off-by: Jakub Jelen --- cipher/pubkey-util.c | 5 ++++- cipher/rsa.c | 5 +++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/cipher/pubkey-util.c b/cipher/pubkey-util.c index 68defea6..4953caf3 100644 --- a/cipher/pubkey-util.c +++ b/cipher/pubkey-util.c @@ -957,7 +957,10 @@ _gcry_pk_util_data_to_mpi (gcry_sexp_t input, gcry_mpi_t *ret_mpi, void *random_override = NULL; size_t random_override_len = 0; - if ( !(value=sexp_nth_data (lvalue, 1, &valuelen)) || !valuelen ) + /* The RSA PKCS#1.5 encryption is no longer supported by 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 771413b3..c6319b67 100644 --- a/cipher/rsa.c +++ b/cipher/rsa.c @@ -1391,6 +1391,11 @@ 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)) + { + rc = GPG_ERR_INV_FLAG; + goto leave; + } /* Extract the key. */ rc = sexp_extract_param (keyparms, NULL, "nedp?q?u?", -- 2.34.1 From 299e2f93415984919181e0ee651719bbf83bdd2f Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 1 Apr 2022 18:31:05 +0200 Subject: [PATCH 2/3] tests: Replace custom bit with more generic flags * tests/basic.c (global): New flag FLAG_SPECIAL (check_pubkey_crypt): Change to use bitfield flags -- GnuPG-bug-id: 5918 Signed-off-by: Jakub Jelen --- tests/basic.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/tests/basic.c b/tests/basic.c index a0ad33eb..1c6cb40b 100644 --- a/tests/basic.c +++ b/tests/basic.c @@ -55,11 +55,12 @@ typedef struct test_spec_pubkey } test_spec_pubkey_t; -#define FLAG_CRYPT (1 << 0) -#define FLAG_SIGN (1 << 1) -#define FLAG_GRIP (1 << 2) -#define FLAG_NOFIPS (1 << 3) -#define FLAG_CFB8 (1 << 4) +#define FLAG_CRYPT (1 << 0) +#define FLAG_SIGN (1 << 1) +#define FLAG_GRIP (1 << 2) +#define FLAG_NOFIPS (1 << 3) +#define FLAG_CFB8 (1 << 4) +#define FLAG_SPECIAL (1 << 5) static int in_fips_mode; @@ -15558,7 +15559,7 @@ check_pubkey_crypt (int n, gcry_sexp_t skey, gcry_sexp_t pkey, int algo, int unpadded; int encrypt_expected_rc; int decrypt_expected_rc; - int special; + int flags; } datas[] = { { GCRY_PK_RSA, @@ -15642,14 +15643,14 @@ check_pubkey_crypt (int n, gcry_sexp_t skey, gcry_sexp_t pkey, int algo, "(flags oaep)", 1, 0, - GPG_ERR_ENCODING_PROBLEM, 1 }, + GPG_ERR_ENCODING_PROBLEM, FLAG_SPECIAL }, { GCRY_PK_RSA, "(data\n (flags oaep)\n" " (value #11223344556677889900AA#))\n", "(flags pkcs1)", 1, 0, - GPG_ERR_ENCODING_PROBLEM, 1 }, + GPG_ERR_ENCODING_PROBLEM, FLAG_SPECIAL }, { 0, "(data\n (flags pss)\n" " (value #11223344556677889900AA#))\n", @@ -15725,7 +15726,7 @@ check_pubkey_crypt (int n, gcry_sexp_t skey, gcry_sexp_t pkey, int algo, ciph = list; } rc = gcry_pk_decrypt (&plain, ciph, skey); - if (!rc && datas[dataidx].special == 1) + if (!rc && (datas[dataidx].flags & FLAG_SPECIAL)) { /* It may happen that OAEP formatted data which is decrypted as pkcs#1 data returns a valid pkcs#1 -- 2.34.1 From f736f3c70182d9c948f9105eb769c47c5578df35 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 1 Apr 2022 18:34:42 +0200 Subject: [PATCH 3/3] tests: Expect the RSA PKCS #1.5 encryption to fail in FIPS mode * tests/basic.c (check_pubkey_crypt): Expect RSA PKCS #1.5 encryption to fail in FIPS mode. Expect failure when wrong padding is selected * tests/pkcs1v2.c (check_v15crypt): Expect RSA PKCS #1.5 encryption to fail in FIPS mode -- GnuPG-bug-id: 5918 Signed-off-by: Jakub Jelen --- tests/basic.c | 11 +++++++---- tests/pkcs1v2.c | 14 +++++++++++++- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/tests/basic.c b/tests/basic.c index 1c6cb40b..85764591 100644 --- a/tests/basic.c +++ b/tests/basic.c @@ -15568,14 +15568,16 @@ check_pubkey_crypt (int n, gcry_sexp_t skey, gcry_sexp_t pkey, int algo, NULL, 0, 0, - 0 }, + 0, + FLAG_NOFIPS }, { GCRY_PK_RSA, "(data\n (flags pkcs1)\n" " (value #11223344556677889900AA#))\n", "(flags pkcs1)", 1, 0, - 0 }, + 0, + FLAG_NOFIPS }, { GCRY_PK_RSA, "(data\n (flags oaep)\n" " (value #11223344556677889900AA#))\n", @@ -15677,7 +15679,8 @@ check_pubkey_crypt (int n, gcry_sexp_t skey, gcry_sexp_t pkey, int algo, die ("converting data failed: %s\n", gpg_strerror (rc)); rc = gcry_pk_encrypt (&ciph, data, pkey); - if (in_fips_mode && (flags & FLAG_NOFIPS)) + if (in_fips_mode && ((flags & FLAG_NOFIPS) || + (datas[dataidx].flags & FLAG_NOFIPS))) { if (!rc) fail ("gcry_pk_encrypt did not fail as expected in FIPS mode\n"); @@ -15726,7 +15729,7 @@ check_pubkey_crypt (int n, gcry_sexp_t skey, gcry_sexp_t pkey, int algo, ciph = list; } rc = gcry_pk_decrypt (&plain, ciph, skey); - if (!rc && (datas[dataidx].flags & FLAG_SPECIAL)) + if ((!rc || in_fips_mode) && (datas[dataidx].flags & FLAG_SPECIAL)) { /* It may happen that OAEP formatted data which is decrypted as pkcs#1 data returns a valid pkcs#1 diff --git a/tests/pkcs1v2.c b/tests/pkcs1v2.c index f26e779b..6c7f3d81 100644 --- a/tests/pkcs1v2.c +++ b/tests/pkcs1v2.c @@ -454,7 +454,19 @@ check_v15crypt (void) gcry_free (seed); err = gcry_pk_encrypt (&ciph, plain, pub_key); - if (err) + if (in_fips_mode) + { + if (!err) + { + fail ("gcry_pk_encrypt should have failed in FIPS mode:\n"); + } + gcry_sexp_release (plain); + plain = NULL; + gcry_sexp_release (ciph); + ciph = NULL; + continue; + } + else if (err) { show_sexp ("plain:\n", ciph); fail ("gcry_pk_encrypt failed: %s\n", gpg_strerror (err)); -- 2.34.1