File openssl-1_1-ossl-sli-016-PSS-length.patch of Package openssl-1_1

From c1eb9877a21d28fe8941b0d64692925a1843c9b2 Mon Sep 17 00:00:00 2001
From: Christopher Dickerman <chrisd@atsec.com>
Date: Fri, 2 Aug 2024 10:25:15 -0500
Subject: [PATCH] 1224275 PSS length

---
 crypto/fips/fips_sli.c            | 60 +++++++++++++++++++++++++++++++
 crypto/rsa/rsa_pss.c              |  8 ++++-
 include/internal/fips_sli_local.h |  3 ++
 3 files changed, 70 insertions(+), 1 deletion(-)

diff --git a/crypto/fips/fips_sli.c b/crypto/fips/fips_sli.c
index 898bdd5..f62d1ae 100644
--- a/crypto/fips/fips_sli.c
+++ b/crypto/fips/fips_sli.c
@@ -4,6 +4,8 @@
 #include "crypto/evp.h"
 #include "../evp/evp_local.h"
 #include "../hmac/hmac_local.h"
+#include "../rsa/rsa_local.h"
+#include <openssl/tls1.h>
 #include "internal/fips_sli_local.h"
 
 /* Main part of the FIPS Service Level Indicator
@@ -406,3 +417,66 @@ void fips_sli_check_padding_rsa_enc_EVP_PKEY_CTX(EVP_PKEY_CTX * ctx, int pad_mod
 void fips_sli_check_padding_rsa_dec_EVP_PKEY_CTX(EVP_PKEY_CTX * ctx, int pad_mode) {
     fips_sli_check_padding_rsa_enc_EVP_PKEY_CTX(ctx, pad_mode);
 }
+
+// approved range is only [0; hash output block length]
+static FIPS_STATUS get_fips_padding_rsa_pss_genver_status(EVP_MD_CTX * ctx, const int * res_salt_len) {
+    if (ctx == NULL)
+        return FIPS_ERROR;
+    EVP_PKEY_CTX * pkey_ctx = EVP_MD_CTX_pkey_ctx(ctx);
+    if (pkey_ctx == NULL)
+        return FIPS_ERROR;
+    EVP_PKEY * pkey = pkey_ctx->pkey;
+    if (pkey == NULL)
+        return FIPS_ERROR;
+    const EVP_MD * md = ctx->digest;
+
+    long sLen = ASN1_INTEGER_get(RSA_get0_pss_params(
+    EVP_PKEY_get1_RSA(pkey))->saltLength);
+
+    if (sLen >= 0) {
+        if (sLen > EVP_MD_block_size(md))
+            return FIPS_NONAPPROVED;
+        else
+            return FIPS_APPROVED;
+    }
+
+    // check the special values
+    if (pkey_ctx->operation & EVP_PKEY_OP_SIGN) {
+        switch (sLen) {
+        case RSA_PSS_SALTLEN_DIGEST:
+            return FIPS_APPROVED;
+        case RSA_PSS_SALTLEN_MAX:
+        case RSA_PSS_SALTLEN_MAX_SIGN:
+        default:
+            return FIPS_NONAPPROVED;
+        }
+    // need to access the resulting salt length for verification
+    } else if (pkey_ctx->operation & EVP_PKEY_OP_VERIFY) {
+        if (res_salt_len == NULL)
+            return FIPS_ERROR;
+        if (*res_salt_len > EVP_MD_block_size(md) || *res_salt_len < 0)
+            return FIPS_NONAPPROVED;
+        else
+            return FIPS_APPROVED;
+    }
+    return FIPS_NONAPPROVED;
+}
+
+void fips_sli_check_padding_rsa_siggen_EVP_MD_CTX(EVP_MD_CTX * ctx, int pad_mode) {
+    switch (pad_mode) {
+    case RSA_PKCS1_PSS_PADDING:
+        fips_sli_fsm_EVP_MD_CTX(ctx, get_fips_padding_rsa_pss_genver_status(ctx, NULL));
+    default:
+        fips_sli_fsm_EVP_MD_CTX(ctx, FIPS_ERROR);
+    }
+}
+
+// find a better way to access the actual salt length, maybe in ctx->data?
+void fips_sli_check_padding_rsa_sigver_EVP_MD_CTX(EVP_MD_CTX * ctx, int pad_mode, int res_salt_len) {
+    switch (pad_mode) {
+    case RSA_PKCS1_PSS_PADDING:
+        fips_sli_fsm_EVP_MD_CTX(ctx, get_fips_padding_rsa_pss_genver_status(ctx, &res_salt_len));
+    default:
+        fips_sli_fsm_EVP_MD_CTX(ctx, FIPS_ERROR);
+    }
+}
diff --git a/crypto/rsa/rsa_pss.c b/crypto/rsa/rsa_pss.c
index 40ce1c4..40b586c 100644
--- a/crypto/rsa/rsa_pss.c
+++ b/crypto/rsa/rsa_pss.c
@@ -14,6 +14,7 @@
 #include <openssl/evp.h>
 #include <openssl/rand.h>
 #include <openssl/sha.h>
+#include "internal/fips_sli_local.h"
 #include "rsa_local.h"
 
 static const unsigned char zeroes[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
@@ -35,7 +36,7 @@ int RSA_verify_PKCS1_PSS_mgf1(RSA *rsa, const unsigned char *mHash,
 {
     int i;
     int ret = 0;
-    int hLen, maskedDBLen, MSBits, emLen;
+    int hLen, maskedDBLen, MSBits, emLen, sLenRes;
     const unsigned char *H;
     unsigned char *DB = NULL;
     EVP_MD_CTX *ctx = EVP_MD_CTX_new();
@@ -118,6 +119,7 @@ int RSA_verify_PKCS1_PSS_mgf1(RSA *rsa, const unsigned char *mHash,
         if (!EVP_DigestUpdate(ctx, DB + i, maskedDBLen - i))
             goto err;
     }
+    sLenRes = maskedDBLen - i;
     if (!EVP_DigestFinal_ex(ctx, H_, NULL))
         goto err;
     if (memcmp(H_, H, hLen)) {
@@ -127,6 +129,8 @@ int RSA_verify_PKCS1_PSS_mgf1(RSA *rsa, const unsigned char *mHash,
         ret = 1;
     }
 
+    fips_sli_check_padding_rsa_sigver_EVP_MD_CTX(ctx, RSA_PKCS1_PSS_PADDING, sLenRes);
+    
  err:
     OPENSSL_free(DB);
     EVP_MD_CTX_free(ctx);
@@ -242,6 +246,8 @@ int RSA_padding_add_PKCS1_PSS_mgf1(RSA *rsa, unsigned char *EM,
 
     ret = 1;
 
+    fips_sli_check_padding_rsa_siggen_EVP_MD_CTX(ctx, RSA_PKCS1_PSS_PADDING);
+
  err:
     EVP_MD_CTX_free(ctx);
     OPENSSL_clear_free(salt, (size_t)sLen); /* salt != NULL implies sLen > 0 */
diff --git a/include/internal/fips_sli_local.h b/include/internal/fips_sli_local.h
index f8288e0..c5273f5 100644
--- a/include/internal/fips_sli_local.h
+++ b/include/internal/fips_sli_local.h
@@ -94,6 +94,9 @@ void fips_sli_check_key_ecdh_EVP_PKEY_CTX(EVP_PKEY_CTX *ctx, const EC_KEY *ecdh)
 void fips_sli_check_padding_rsa_enc_EVP_PKEY_CTX(EVP_PKEY_CTX * ctx, int pad_mode);
 void fips_sli_check_padding_rsa_dec_EVP_PKEY_CTX(EVP_PKEY_CTX * ctx, int pad_mode);
 
+void fips_sli_check_padding_rsa_sigver_EVP_MD_CTX(EVP_MD_CTX * ctx, int pad_mode, int res_salt_len);
+void fips_sli_check_padding_rsa_siggen_EVP_MD_CTX(EVP_MD_CTX * ctx, int pad_mode);
+
 FIPS_STATUS EVP_CIPHER_get_fips_status(const EVP_CIPHER *cipher);
 void fips_sli_check_cipher_EVP_CIPHER_CTX(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher);
 
-- 
2.39.3 (Apple Git-146)
openSUSE Build Service is sponsored by