forked from pool/libgcrypt
251 lines
9.6 KiB
Diff
251 lines
9.6 KiB
Diff
|
From 40d63d09b2d06631f4d2c3d1b167a620d50c99f8 Mon Sep 17 00:00:00 2001
|
||
|
From: Jakub Jelen <jjelen@redhat.com>
|
||
|
Date: Fri, 5 Nov 2021 14:19:23 +0100
|
||
|
Subject: [PATCH 198/200] rsa: Check keylen constraints for key operations.
|
||
|
|
||
|
* cipher/rsa.c (rsa_check_keysize): New.
|
||
|
(generate_fips): Factor out the bits check.
|
||
|
(rsa_encrypt): Add checking key length.
|
||
|
(rsa_decrypt, rsa_sign, rsa_verify): Likewise.
|
||
|
--
|
||
|
|
||
|
GnuPG-bug-id: 5512
|
||
|
Co-authored-by: NIIBE Yutaka <gniibe@fsij.org>
|
||
|
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
|
||
|
---
|
||
|
cipher/rsa.c | 58 ++++++++++++++++++++++++++++++++++++++--------------
|
||
|
1 file changed, 43 insertions(+), 15 deletions(-)
|
||
|
|
||
|
Index: libgcrypt-1.9.4/cipher/rsa.c
|
||
|
===================================================================
|
||
|
--- libgcrypt-1.9.4.orig/cipher/rsa.c
|
||
|
+++ libgcrypt-1.9.4/cipher/rsa.c
|
||
|
@@ -301,14 +301,6 @@ generate_std (RSA_secret_key *sk, unsign
|
||
|
gcry_mpi_t f;
|
||
|
gcry_random_level_t random_level;
|
||
|
|
||
|
- if (fips_mode ())
|
||
|
- {
|
||
|
- if (nbits < 1024)
|
||
|
- return GPG_ERR_INV_VALUE;
|
||
|
- if (transient_key)
|
||
|
- return GPG_ERR_INV_VALUE;
|
||
|
- }
|
||
|
-
|
||
|
/* The random quality depends on the transient_key flag. */
|
||
|
random_level = transient_key ? GCRY_STRONG_RANDOM : GCRY_VERY_STRONG_RANDOM;
|
||
|
|
||
|
@@ -437,6 +429,17 @@ generate_std (RSA_secret_key *sk, unsign
|
||
|
}
|
||
|
|
||
|
|
||
|
+/* Check the RSA key length is acceptable for key generation or usage */
|
||
|
+static gpg_err_code_t
|
||
|
+rsa_check_keysize (unsigned int nbits)
|
||
|
+{
|
||
|
+ if (fips_mode() && nbits < 2048)
|
||
|
+ 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.
|
||
|
@@ -466,12 +469,15 @@ generate_fips (RSA_secret_key *sk, unsig
|
||
|
unsigned int pbits = nbits/2;
|
||
|
unsigned int i;
|
||
|
int pqswitch;
|
||
|
- gpg_err_code_t ec = GPG_ERR_NO_PRIME;
|
||
|
+ gpg_err_code_t ec;
|
||
|
|
||
|
if (nbits < 1024 || (nbits & 0x1FF))
|
||
|
return GPG_ERR_INV_VALUE;
|
||
|
- if (fips_mode() && nbits < 2048)
|
||
|
- return GPG_ERR_INV_VALUE;
|
||
|
+ ec = rsa_check_keysize (nbits);
|
||
|
+ if (ec)
|
||
|
+ return ec;
|
||
|
+
|
||
|
+ ec = GPG_ERR_NO_PRIME;
|
||
|
|
||
|
/* The random quality depends on the transient_key flag. */
|
||
|
random_level = transient_key ? GCRY_STRONG_RANDOM : GCRY_VERY_STRONG_RANDOM;
|
||
|
@@ -1360,9 +1366,13 @@ rsa_encrypt (gcry_sexp_t *r_ciph, gcry_s
|
||
|
gcry_mpi_t data = NULL;
|
||
|
RSA_public_key pk = {NULL, NULL};
|
||
|
gcry_mpi_t ciph = NULL;
|
||
|
+ unsigned int nbits = rsa_get_nbits (keyparms);
|
||
|
+
|
||
|
+ rc = rsa_check_keysize (nbits);
|
||
|
+ if (rc)
|
||
|
+ return rc;
|
||
|
|
||
|
- _gcry_pk_util_init_encoding_ctx (&ctx, PUBKEY_OP_ENCRYPT,
|
||
|
- rsa_get_nbits (keyparms));
|
||
|
+ _gcry_pk_util_init_encoding_ctx (&ctx, PUBKEY_OP_ENCRYPT, nbits);
|
||
|
|
||
|
/* Extract the data. */
|
||
|
rc = _gcry_pk_util_data_to_mpi (s_data, &data, &ctx);
|
||
|
@@ -1432,9 +1442,13 @@ rsa_decrypt (gcry_sexp_t *r_plain, gcry_
|
||
|
gcry_mpi_t plain = NULL;
|
||
|
unsigned char *unpad = NULL;
|
||
|
size_t unpadlen = 0;
|
||
|
+ unsigned int nbits = rsa_get_nbits (keyparms);
|
||
|
|
||
|
- _gcry_pk_util_init_encoding_ctx (&ctx, PUBKEY_OP_DECRYPT,
|
||
|
- rsa_get_nbits (keyparms));
|
||
|
+ rc = rsa_check_keysize (nbits);
|
||
|
+ if (rc)
|
||
|
+ return rc;
|
||
|
+
|
||
|
+ _gcry_pk_util_init_encoding_ctx (&ctx, PUBKEY_OP_DECRYPT, nbits);
|
||
|
|
||
|
/* Extract the data. */
|
||
|
rc = _gcry_pk_util_preparse_encval (s_data, rsa_names, &l1, &ctx);
|
||
|
@@ -1477,7 +1491,7 @@ rsa_decrypt (gcry_sexp_t *r_plain, gcry_
|
||
|
mpi_fdiv_r (data, data, sk.n);
|
||
|
|
||
|
/* Allocate MPI for the plaintext. */
|
||
|
- plain = mpi_snew (ctx.nbits);
|
||
|
+ plain = mpi_snew (nbits);
|
||
|
|
||
|
/* We use blinding by default to mitigate timing attacks which can
|
||
|
be practically mounted over the network as shown by Brumley and
|
||
|
@@ -1485,7 +1499,7 @@ rsa_decrypt (gcry_sexp_t *r_plain, gcry_
|
||
|
if ((ctx.flags & PUBKEY_FLAG_NO_BLINDING))
|
||
|
secret (plain, data, &sk);
|
||
|
else
|
||
|
- secret_blinded (plain, data, &sk, ctx.nbits);
|
||
|
+ secret_blinded (plain, data, &sk, nbits);
|
||
|
|
||
|
if (DBG_CIPHER)
|
||
|
log_printmpi ("rsa_decrypt res", plain);
|
||
|
@@ -1494,7 +1508,7 @@ rsa_decrypt (gcry_sexp_t *r_plain, gcry_
|
||
|
switch (ctx.encoding)
|
||
|
{
|
||
|
case PUBKEY_ENC_PKCS1:
|
||
|
- rc = _gcry_rsa_pkcs1_decode_for_enc (&unpad, &unpadlen, ctx.nbits, plain);
|
||
|
+ rc = _gcry_rsa_pkcs1_decode_for_enc (&unpad, &unpadlen, nbits, plain);
|
||
|
mpi_free (plain);
|
||
|
plain = NULL;
|
||
|
if (!rc)
|
||
|
@@ -1503,7 +1517,7 @@ rsa_decrypt (gcry_sexp_t *r_plain, gcry_
|
||
|
|
||
|
case PUBKEY_ENC_OAEP:
|
||
|
rc = _gcry_rsa_oaep_decode (&unpad, &unpadlen,
|
||
|
- ctx.nbits, ctx.hash_algo,
|
||
|
+ nbits, ctx.hash_algo,
|
||
|
plain, ctx.label, ctx.labellen);
|
||
|
mpi_free (plain);
|
||
|
plain = NULL;
|
||
|
@@ -1548,9 +1562,13 @@ rsa_sign (gcry_sexp_t *r_sig, gcry_sexp_
|
||
|
RSA_public_key pk;
|
||
|
gcry_mpi_t sig = NULL;
|
||
|
gcry_mpi_t result = NULL;
|
||
|
+ unsigned int nbits = rsa_get_nbits (keyparms);
|
||
|
+
|
||
|
+ rc = rsa_check_keysize (nbits);
|
||
|
+ if (rc)
|
||
|
+ return rc;
|
||
|
|
||
|
- _gcry_pk_util_init_encoding_ctx (&ctx, PUBKEY_OP_SIGN,
|
||
|
- rsa_get_nbits (keyparms));
|
||
|
+ _gcry_pk_util_init_encoding_ctx (&ctx, PUBKEY_OP_SIGN, nbits);
|
||
|
|
||
|
/* Extract the data. */
|
||
|
rc = _gcry_pk_util_data_to_mpi (s_data, &data, &ctx);
|
||
|
@@ -1588,7 +1606,7 @@ rsa_sign (gcry_sexp_t *r_sig, gcry_sexp_
|
||
|
if ((ctx.flags & PUBKEY_FLAG_NO_BLINDING))
|
||
|
secret (sig, data, &sk);
|
||
|
else
|
||
|
- secret_blinded (sig, data, &sk, ctx.nbits);
|
||
|
+ secret_blinded (sig, data, &sk, nbits);
|
||
|
if (DBG_CIPHER)
|
||
|
log_printmpi ("rsa_sign res", sig);
|
||
|
|
||
|
@@ -1650,9 +1668,13 @@ rsa_verify (gcry_sexp_t s_sig, gcry_sexp
|
||
|
gcry_mpi_t data = NULL;
|
||
|
RSA_public_key pk = { NULL, NULL };
|
||
|
gcry_mpi_t result = NULL;
|
||
|
+ unsigned int nbits = rsa_get_nbits (keyparms);
|
||
|
+
|
||
|
+ rc = rsa_check_keysize (nbits);
|
||
|
+ if (rc)
|
||
|
+ return rc;
|
||
|
|
||
|
- _gcry_pk_util_init_encoding_ctx (&ctx, PUBKEY_OP_VERIFY,
|
||
|
- rsa_get_nbits (keyparms));
|
||
|
+ _gcry_pk_util_init_encoding_ctx (&ctx, PUBKEY_OP_VERIFY, nbits);
|
||
|
|
||
|
/* Extract the data. */
|
||
|
rc = _gcry_pk_util_data_to_mpi (s_data, &data, &ctx);
|
||
|
Index: libgcrypt-1.9.4/tests/basic.c
|
||
|
===================================================================
|
||
|
--- libgcrypt-1.9.4.orig/tests/basic.c
|
||
|
+++ libgcrypt-1.9.4/tests/basic.c
|
||
|
@@ -14172,6 +14172,62 @@ check_pubkey (void)
|
||
|
"\x4a\xa6\xf9\xeb\x23\xbf\xa9\x12\x2d\x5b" }
|
||
|
},
|
||
|
{
|
||
|
+ GCRY_PK_RSA, FLAG_CRYPT | FLAG_SIGN | FLAG_GRIP, /* 2k RSA */
|
||
|
+ {
|
||
|
+ "(private-key"
|
||
|
+ " (rsa"
|
||
|
+ " (n #009F56231A3D82E3E7D613D59D53E9AB921BEF9F08A782AED0B6E46ADBC853EC"
|
||
|
+ " 7C71C422435A3CD8FA0DB9EFD55CD3295BADC4E8E2E2B94E15AE82866AB8ADE8"
|
||
|
+ " 7E469FAE76DC3577DE87F1F419C4EB41123DFAF8D16922D5EDBAD6E9076D5A1C"
|
||
|
+ " 958106F0AE5E2E9193C6B49124C64C2A241C4075D4AF16299EB87A6585BAE917"
|
||
|
+ " DEF27FCDD165764D069BC18D16527B29DAAB549F7BBED4A7C6A842D203ED6613"
|
||
|
+ " 6E2411744E432CD26D940132F25874483DCAEECDFD95744819CBCF1EA810681C"
|
||
|
+ " 42907EBCB1C7EAFBE75C87EC32C5413EA10476545D3FC7B2ADB1B66B7F200918"
|
||
|
+ " 664B0E5261C2895AA28B0DE321E921B3F877172CCCAB81F43EF98002916156F6"
|
||
|
+ " CB#)\n"
|
||
|
+ " (e #010001#)\n"
|
||
|
+ " (d #07EF82500C403899934FE993AC5A36F14FF2DF38CF1EF315F205EE4C83EDAA19"
|
||
|
+ " 8890FC23DE9AA933CAFB37B6A8A8DBA675411958337287310D3FF2F1DDC0CB93"
|
||
|
+ " 7E70F57F75F833C021852B631D2B9A520E4431A03C5C3FCB5742DCD841D9FB12"
|
||
|
+ " 771AA1620DCEC3F1583426066ED9DC3F7028C5B59202C88FDF20396E2FA0EC4F"
|
||
|
+ " 5A22D9008F3043673931BC14A5046D6327398327900867E39CC61B2D1AFE2F48"
|
||
|
+ " EC8E1E3861C68D257D7425F4E6F99ABD77D61F10CA100EFC14389071831B33DD"
|
||
|
+ " 69CC8EABEF860D1DC2AAA84ABEAE5DFC91BC124DAF0F4C8EF5BBEA436751DE84"
|
||
|
+ " 3A8063E827A024466F44C28614F93B0732A100D4A0D86D532FE1E22C7725E401"
|
||
|
+ " #)\n"
|
||
|
+ " (p #00C29D438F115825779631CD665A5739367F3E128ADC29766483A46CA80897E0"
|
||
|
+ " 79B32881860B8F9A6A04C2614A904F6F2578DAE13EA67CD60AE3D0AA00A1FF9B"
|
||
|
+ " 441485E44B2DC3D0B60260FBFE073B5AC72FAF67964DE15C8212C389D20DB9CF"
|
||
|
+ " 54AF6AEF5C4196EAA56495DD30CF709F499D5AB30CA35E086C2A1589D6283F17"
|
||
|
+ " 83#)\n"
|
||
|
+ " (q #00D1984135231CB243FE959C0CBEF551EDD986AD7BEDF71EDF447BE3DA27AF46"
|
||
|
+ " 79C974A6FA69E4D52FE796650623DE70622862713932AA2FD9F2EC856EAEAA77"
|
||
|
+ " 88B4EA6084DC81C902F014829B18EA8B2666EC41586818E0589E18876065F97E"
|
||
|
+ " 8D22CE2DA53A05951EC132DCEF41E70A9C35F4ACC268FFAC2ADF54FA1DA110B9"
|
||
|
+ " 19#)\n"
|
||
|
+ " (u #67CF0FD7635205DD80FA814EE9E9C267C17376BF3209FB5D1BC42890D2822A04"
|
||
|
+ " 479DAF4D5B6ED69D0F8D1AF94164D07F8CD52ECEFE880641FA0F41DDAB1785E4"
|
||
|
+ " A37A32F997A516480B4CD4F6482B9466A1765093ED95023CA32D5EDC1E34CEE9"
|
||
|
+ " AF595BC51FE43C4BF810FA225AF697FB473B83815966188A4312C048B885E3F7"
|
||
|
+ " #)))\n",
|
||
|
+
|
||
|
+ "(public-key\n"
|
||
|
+ " (rsa\n"
|
||
|
+ " (n #009F56231A3D82E3E7D613D59D53E9AB921BEF9F08A782AED0B6E46ADBC853EC"
|
||
|
+ " 7C71C422435A3CD8FA0DB9EFD55CD3295BADC4E8E2E2B94E15AE82866AB8ADE8"
|
||
|
+ " 7E469FAE76DC3577DE87F1F419C4EB41123DFAF8D16922D5EDBAD6E9076D5A1C"
|
||
|
+ " 958106F0AE5E2E9193C6B49124C64C2A241C4075D4AF16299EB87A6585BAE917"
|
||
|
+ " DEF27FCDD165764D069BC18D16527B29DAAB549F7BBED4A7C6A842D203ED6613"
|
||
|
+ " 6E2411744E432CD26D940132F25874483DCAEECDFD95744819CBCF1EA810681C"
|
||
|
+ " 42907EBCB1C7EAFBE75C87EC32C5413EA10476545D3FC7B2ADB1B66B7F200918"
|
||
|
+ " 664B0E5261C2895AA28B0DE321E921B3F877172CCCAB81F43EF98002916156F6"
|
||
|
+ " CB#)\n"
|
||
|
+ " (e #010001#)))\n",
|
||
|
+
|
||
|
+ "\xe0\x08\x98\x9b\xb6\x44\xa2\x9a\x83\x37"
|
||
|
+ "\x47\xdd\x69\x55\xdb\x3a\xac\x89\x6e\x40"}
|
||
|
+ },
|
||
|
+ {
|
||
|
GCRY_PK_ELG, FLAG_SIGN | FLAG_CRYPT | FLAG_GRIP,
|
||
|
{
|
||
|
"(private-key\n"
|