forked from rpms/openssl
477d91adec
Resolves: rhbz#2129063
154 lines
6.5 KiB
Diff
154 lines
6.5 KiB
Diff
From 39a91c33e2b89a0fe42e3791d3dc304519a52182 Mon Sep 17 00:00:00 2001
|
|
From: Clemens Lang <cllang@redhat.com>
|
|
Date: Fri, 18 Nov 2022 12:35:33 +0100
|
|
Subject: [PATCH] signature: Clamp PSS salt len to MD len
|
|
|
|
Since FIPS 186-4 subsection 5.5 limits the acceptable PSS salt length to
|
|
the size of the message digest, change the default automatic behavior
|
|
when signing to use at most the digest size as salt length. Shorter
|
|
values are still possible when long hashes are used with short keys.
|
|
|
|
Signed-off-by: Clemens Lang <cllang@redhat.com>
|
|
---
|
|
crypto/rsa/rsa_ameth.c | 19 +++++++++++++++++--
|
|
crypto/rsa/rsa_pss.c | 11 +++++++++++
|
|
doc/man3/EVP_PKEY_CTX_ctrl.pod | 4 +++-
|
|
providers/implementations/signature/rsa_sig.c | 18 ++++++++++++++++--
|
|
4 files changed, 47 insertions(+), 5 deletions(-)
|
|
|
|
diff --git a/crypto/rsa/rsa_ameth.c b/crypto/rsa/rsa_ameth.c
|
|
index b1580ca..dc81627 100644
|
|
--- a/crypto/rsa/rsa_ameth.c
|
|
+++ b/crypto/rsa/rsa_ameth.c
|
|
@@ -449,6 +449,7 @@ static RSA_PSS_PARAMS *rsa_ctx_to_pss(EVP_PKEY_CTX *pkctx)
|
|
const EVP_MD *sigmd, *mgf1md;
|
|
EVP_PKEY *pk = EVP_PKEY_CTX_get0_pkey(pkctx);
|
|
int saltlen;
|
|
+ int saltlenMax = -1;
|
|
|
|
if (EVP_PKEY_CTX_get_signature_md(pkctx, &sigmd) <= 0)
|
|
return NULL;
|
|
@@ -456,14 +457,28 @@ static RSA_PSS_PARAMS *rsa_ctx_to_pss(EVP_PKEY_CTX *pkctx)
|
|
return NULL;
|
|
if (EVP_PKEY_CTX_get_rsa_pss_saltlen(pkctx, &saltlen) <= 0)
|
|
return NULL;
|
|
- if (saltlen == -1) {
|
|
+ if (saltlen == RSA_PSS_SALTLEN_DIGEST) {
|
|
saltlen = EVP_MD_get_size(sigmd);
|
|
- } else if (saltlen == -2 || saltlen == -3) {
|
|
+ } else if (saltlen == RSA_PSS_SALTLEN_AUTO) {
|
|
+ /* FIPS 186-4 section 5 "The RSA Digital Signature Algorithm",
|
|
+ * subsection 5.5 "PKCS #1" says: "For RSASSA-PSS […] the length (in
|
|
+ * bytes) of the salt (sLen) shall satisfy 0 ≤ sLen ≤ hLen, where hLen
|
|
+ * is the length of the hash function output block (in bytes)."
|
|
+ *
|
|
+ * Switch the meaning of RSA_PSS_SALTLEN_AUTO to use at most the digest
|
|
+ * length in FIPS mode, so that the default does not violate FIPS
|
|
+ * 186-4. */
|
|
+ saltlen = RSA_PSS_SALTLEN_MAX;
|
|
+ saltlenMax = EVP_MD_get_size(sigmd);
|
|
+ }
|
|
+ if (saltlen == RSA_PSS_SALTLEN_MAX) {
|
|
saltlen = EVP_PKEY_get_size(pk) - EVP_MD_get_size(sigmd) - 2;
|
|
if ((EVP_PKEY_get_bits(pk) & 0x7) == 1)
|
|
saltlen--;
|
|
if (saltlen < 0)
|
|
return NULL;
|
|
+ if (saltlenMax >= 0 && saltlen > saltlenMax)
|
|
+ saltlen = saltlenMax;
|
|
}
|
|
|
|
return ossl_rsa_pss_params_create(sigmd, mgf1md, saltlen);
|
|
diff --git a/crypto/rsa/rsa_pss.c b/crypto/rsa/rsa_pss.c
|
|
index e8681b0..d8f9207 100644
|
|
--- a/crypto/rsa/rsa_pss.c
|
|
+++ b/crypto/rsa/rsa_pss.c
|
|
@@ -168,6 +168,7 @@ int RSA_padding_add_PKCS1_PSS_mgf1(RSA *rsa, unsigned char *EM,
|
|
int hLen, maskedDBLen, MSBits, emLen;
|
|
unsigned char *H, *salt = NULL, *p;
|
|
EVP_MD_CTX *ctx = NULL;
|
|
+ int sLenMax = -1;
|
|
|
|
if (mgf1Hash == NULL)
|
|
mgf1Hash = Hash;
|
|
@@ -190,10 +191,18 @@ int RSA_padding_add_PKCS1_PSS_mgf1(RSA *rsa, unsigned char *EM,
|
|
* -3 same as above (on signing)
|
|
* -N reserved
|
|
*/
|
|
+ /* FIPS 186-4 section 5 "The RSA Digital Signature Algorithm", subsection
|
|
+ * 5.5 "PKCS #1" says: "For RSASSA-PSS […] the length (in bytes) of the
|
|
+ * salt (sLen) shall satisfy 0 ≤ sLen ≤ hLen, where hLen is the length of
|
|
+ * the hash function output block (in bytes)."
|
|
+ *
|
|
+ * Switch the meaning of RSA_PSS_SALTLEN_AUTO to use at most the digest
|
|
+ * length in FIPS mode, so that the default does not violate FIPS 186-4. */
|
|
if (sLen == RSA_PSS_SALTLEN_DIGEST) {
|
|
sLen = hLen;
|
|
} else if (sLen == RSA_PSS_SALTLEN_MAX_SIGN) {
|
|
sLen = RSA_PSS_SALTLEN_MAX;
|
|
+ sLenMax = hLen;
|
|
} else if (sLen < RSA_PSS_SALTLEN_MAX) {
|
|
ERR_raise(ERR_LIB_RSA, RSA_R_SLEN_CHECK_FAILED);
|
|
goto err;
|
|
@@ -211,6 +220,8 @@ int RSA_padding_add_PKCS1_PSS_mgf1(RSA *rsa, unsigned char *EM,
|
|
}
|
|
if (sLen == RSA_PSS_SALTLEN_MAX) {
|
|
sLen = emLen - hLen - 2;
|
|
+ if (sLenMax >= 0 && sLen > sLenMax)
|
|
+ sLen = sLenMax;
|
|
} else if (sLen > emLen - hLen - 2) {
|
|
ERR_raise(ERR_LIB_RSA, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
|
|
goto err;
|
|
diff --git a/doc/man3/EVP_PKEY_CTX_ctrl.pod b/doc/man3/EVP_PKEY_CTX_ctrl.pod
|
|
index 3075eaa..5463472 100644
|
|
--- a/doc/man3/EVP_PKEY_CTX_ctrl.pod
|
|
+++ b/doc/man3/EVP_PKEY_CTX_ctrl.pod
|
|
@@ -287,7 +287,9 @@ sets the salt length to the maximum permissible value.
|
|
|
|
causes the salt length to be automatically determined based on the
|
|
B<PSS> block structure when verifying. When signing, it has the same
|
|
-meaning as B<RSA_PSS_SALTLEN_MAX>.
|
|
+meaning as B<RSA_PSS_SALTLEN_MAX> up to a maximum of the digest length to
|
|
+comply with FIPS 186-4 section 5.5. This maximum is specific to Red Hat,
|
|
+upstream also uses larger values.
|
|
|
|
=back
|
|
|
|
diff --git a/providers/implementations/signature/rsa_sig.c b/providers/implementations/signature/rsa_sig.c
|
|
index 3ce5efd..519c6a2 100644
|
|
--- a/providers/implementations/signature/rsa_sig.c
|
|
+++ b/providers/implementations/signature/rsa_sig.c
|
|
@@ -200,13 +200,27 @@ static void *rsa_newctx(void *provctx, const char *propq)
|
|
static int rsa_pss_compute_saltlen(PROV_RSA_CTX *ctx)
|
|
{
|
|
int saltlen = ctx->saltlen;
|
|
-
|
|
+ int saltlenMax = -1;
|
|
+
|
|
+ /* FIPS 186-4 section 5 "The RSA Digital Signature Algorithm", subsection
|
|
+ * 5.5 "PKCS #1" says: "For RSASSA-PSS […] the length (in bytes) of the
|
|
+ * salt (sLen) shall satisfy 0 ≤ sLen ≤ hLen, where hLen is the length of
|
|
+ * the hash function output block (in bytes)."
|
|
+ *
|
|
+ * Switch the meaning of RSA_PSS_SALTLEN_AUTO to use at most the digest
|
|
+ * length in FIPS mode, so that the default does not violate FIPS 186-4. */
|
|
if (saltlen == RSA_PSS_SALTLEN_DIGEST) {
|
|
saltlen = EVP_MD_get_size(ctx->md);
|
|
- } else if (saltlen == RSA_PSS_SALTLEN_AUTO || saltlen == RSA_PSS_SALTLEN_MAX) {
|
|
+ } else if (saltlen == RSA_PSS_SALTLEN_AUTO) {
|
|
+ saltlen = RSA_PSS_SALTLEN_MAX;
|
|
+ saltlenMax = EVP_MD_get_size(ctx->md);
|
|
+ }
|
|
+ if (saltlen == RSA_PSS_SALTLEN_MAX) {
|
|
saltlen = RSA_size(ctx->rsa) - EVP_MD_get_size(ctx->md) - 2;
|
|
if ((RSA_bits(ctx->rsa) & 0x7) == 1)
|
|
saltlen--;
|
|
+ if (saltlenMax >= 0 && saltlen > saltlenMax)
|
|
+ saltlen = saltlenMax;
|
|
}
|
|
if (saltlen < 0) {
|
|
ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR);
|
|
--
|
|
2.38.1
|
|
|