Blame SOURCES/0088-signature-Add-indicator-for-PSS-salt-length.patch

3da501
From a325a23bc83f4efd60130001c417ca5b96bdbff1 Mon Sep 17 00:00:00 2001
3da501
From: Clemens Lang <cllang@redhat.com>
3da501
Date: Thu, 17 Nov 2022 19:33:02 +0100
3da501
Subject: [PATCH 1/3] signature: Add indicator for PSS salt length
3da501
MIME-Version: 1.0
3da501
Content-Type: text/plain; charset=UTF-8
3da501
Content-Transfer-Encoding: 8bit
3da501
3da501
FIPS 186-4 section 5 "The RSA Digital Signature Algorithm", subsection
3da501
5.5 "PKCS #1" says: "For RSASSA-PSS […] the length (in bytes) of the
3da501
salt (sLen) shall satisfy 0 ≤ sLen ≤ hLen, where hLen is the length of
3da501
the hash function output block (in bytes)."
3da501
3da501
It is not exactly clear from this text whether hLen refers to the
3da501
message digest or the hash function used for the mask generation
3da501
function MGF1. PKCS#1 v2.1 suggests it is the former:
3da501
3da501
| Typical salt lengths in octets are hLen (the length of the output of
3da501
| the hash function Hash) and 0. In both cases the security of
3da501
| RSASSA-PSS can be closely related to the hardness of inverting RSAVP1.
3da501
| Bellare and Rogaway [4] give a tight lower bound for the security of
3da501
| the original RSA-PSS scheme, which corresponds roughly to the former
3da501
| case, while Coron [12] gives a lower bound for the related Full Domain
3da501
| Hashing scheme, which corresponds roughly to the latter case. In [13]
3da501
| Coron provides a general treatment with various salt lengths ranging
3da501
| from 0 to hLen; see [27] for discussion. See also [31], which adapts
3da501
| the security proofs in [4][13] to address the differences between the
3da501
| original and the present version of RSA-PSS as listed in Note 1 above.
3da501
3da501
Since OpenSSL defaults to creating signatures with the maximum salt
3da501
length, blocking the use of longer salts would probably lead to
3da501
significant problems in practice. Instead, introduce an explicit
3da501
indicator that can be obtained from the EVP_PKEY_CTX object using
3da501
EVP_PKEY_CTX_get_params() with the
3da501
  OSSL_SIGNATURE_PARAM_REDHAT_FIPS_INDICATOR
3da501
parameter.
3da501
3da501
Signed-off-by: Clemens Lang <cllang@redhat.com>
3da501
---
3da501
 include/openssl/core_names.h                  |  1 +
3da501
 include/openssl/evp.h                         |  4 ++++
3da501
 providers/implementations/signature/rsa_sig.c | 18 ++++++++++++++++++
3da501
 3 files changed, 23 insertions(+)
3da501
3da501
diff --git a/include/openssl/core_names.h b/include/openssl/core_names.h
3da501
index 94fab83193..69c59f0b46 100644
3da501
--- a/include/openssl/core_names.h
3da501
+++ b/include/openssl/core_names.h
3da501
@@ -453,6 +453,7 @@ extern "C" {
3da501
 #define OSSL_SIGNATURE_PARAM_MGF1_PROPERTIES    \
3da501
     OSSL_PKEY_PARAM_MGF1_PROPERTIES
3da501
 #define OSSL_SIGNATURE_PARAM_DIGEST_SIZE        OSSL_PKEY_PARAM_DIGEST_SIZE
3da501
+#define OSSL_SIGNATURE_PARAM_REDHAT_FIPS_INDICATOR "redhat-fips-indicator"
3da501
 
3da501
 /* Asym cipher parameters */
3da501
 #define OSSL_ASYM_CIPHER_PARAM_DIGEST                   OSSL_PKEY_PARAM_DIGEST
3da501
diff --git a/include/openssl/evp.h b/include/openssl/evp.h
3da501
index a5e78efd6e..f239200465 100644
3da501
--- a/include/openssl/evp.h
3da501
+++ b/include/openssl/evp.h
3da501
@@ -797,6 +797,10 @@ __owur int EVP_CipherFinal(EVP_CIPHER_CTX *ctx, unsigned char *outm,
3da501
 __owur int EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *outm,
3da501
                               int *outl);
3da501
 
3da501
+# define EVP_SIGNATURE_REDHAT_FIPS_INDICATOR_UNDETERMINED 0
3da501
+# define EVP_SIGNATURE_REDHAT_FIPS_INDICATOR_APPROVED     1
3da501
+# define EVP_SIGNATURE_REDHAT_FIPS_INDICATOR_NOT_APPROVED 2
3da501
+
3da501
 __owur int EVP_SignFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *s,
3da501
                          EVP_PKEY *pkey);
3da501
 __owur int EVP_SignFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *s,
3da501
diff --git a/providers/implementations/signature/rsa_sig.c b/providers/implementations/signature/rsa_sig.c
3da501
index 49e7f9158a..0c45008a00 100644
3da501
--- a/providers/implementations/signature/rsa_sig.c
3da501
+++ b/providers/implementations/signature/rsa_sig.c
3da501
@@ -1127,6 +1127,21 @@ static int rsa_get_ctx_params(void *vprsactx, OSSL_PARAM *params)
3da501
         }
3da501
     }
3da501
 
3da501
+#ifdef FIPS_MODULE
3da501
+    p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_REDHAT_FIPS_INDICATOR);
3da501
+    if (p != NULL) {
3da501
+        int fips_indicator = EVP_SIGNATURE_REDHAT_FIPS_INDICATOR_APPROVED;
3da501
+        if (prsactx->pad_mode == RSA_PKCS1_PSS_PADDING) {
3da501
+            if (prsactx->md == NULL) {
3da501
+                fips_indicator = EVP_SIGNATURE_REDHAT_FIPS_INDICATOR_UNDETERMINED;
3da501
+            } else if (rsa_pss_compute_saltlen(prsactx) > EVP_MD_get_size(prsactx->md)) {
3da501
+                fips_indicator = EVP_SIGNATURE_REDHAT_FIPS_INDICATOR_NOT_APPROVED;
3da501
+            }
3da501
+        }
3da501
+        return OSSL_PARAM_set_int(p, fips_indicator);
3da501
+    }
3da501
+#endif
3da501
+
3da501
     return 1;
3da501
 }
3da501
 
3da501
@@ -1136,6 +1151,9 @@ static const OSSL_PARAM known_gettable_ctx_params[] = {
3da501
     OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST, NULL, 0),
3da501
     OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_MGF1_DIGEST, NULL, 0),
3da501
     OSSL_PARAM_utf8_string(OSSL_SIGNATURE_PARAM_PSS_SALTLEN, NULL, 0),
3da501
+#ifdef FIPS_MODULE
3da501
+    OSSL_PARAM_int(OSSL_SIGNATURE_PARAM_REDHAT_FIPS_INDICATOR, NULL),
3da501
+#endif
3da501
     OSSL_PARAM_END
3da501
 };
3da501
 
3da501
-- 
3da501
2.38.1
3da501