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)