Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 75 additions & 0 deletions crypto/evp_extra/evp_extra_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2432,6 +2432,81 @@ TEST_P(EVPRsaPssBadKeyTest, InvalidSaltLength) {
INSTANTIATE_TEST_SUITE_P(All, EVPRsaPssBadKeyTest,
testing::ValuesIn(kBadPssKeyTestInputs));

// |kExampleRSAPSSKeyPKCS8| omits saltLength, so the RFC 4055 default of 20 is
// the restricted minimum.
TEST(EVPExtraTest, RestrictedPssAutoSaltlenHonorsMinimum) {
const uint8_t *p = kExampleRSAPSSKeyPKCS8;
bssl::UniquePtr<EVP_PKEY> pkey(
d2i_AutoPrivateKey(nullptr, &p, sizeof(kExampleRSAPSSKeyPKCS8)));
ASSERT_TRUE(pkey);
ASSERT_EQ(EVP_PKEY_RSA_PSS, EVP_PKEY_id(pkey.get()));

bssl::UniquePtr<EVP_PKEY_CTX> ctx(EVP_PKEY_CTX_new(pkey.get(), nullptr));
ASSERT_TRUE(ctx);
ASSERT_TRUE(EVP_PKEY_verify_init(ctx.get()));

int saltlen = 0;
ASSERT_TRUE(EVP_PKEY_CTX_get_rsa_pss_saltlen(ctx.get(), &saltlen));
EXPECT_EQ(20, saltlen);

EXPECT_FALSE(EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx.get(), 19));
ERR_clear_error();
EXPECT_TRUE(EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx.get(), 20));
EXPECT_TRUE(
EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx.get(), RSA_PSS_SALTLEN_DIGEST));
EXPECT_TRUE(
EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx.get(), RSA_PSS_SALTLEN_AUTO));

// |EVP_PKEY_CTX_dup| must keep the restriction.
bssl::UniquePtr<EVP_PKEY_CTX> ctx_copy(EVP_PKEY_CTX_dup(ctx.get()));
ASSERT_TRUE(ctx_copy);
EXPECT_FALSE(EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx_copy.get(), 19));
ERR_clear_error();
EXPECT_TRUE(
EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx_copy.get(), RSA_PSS_SALTLEN_AUTO));

bssl::UniquePtr<RSA> rsa(EVP_PKEY_get1_RSA(pkey.get()));
ASSERT_TRUE(rsa);
static const uint8_t kMsg[] = {'t', 'e', 's', 't'};
uint8_t digest[EVP_MAX_MD_SIZE];
unsigned digest_len = 0;
ASSERT_TRUE(EVP_Digest(kMsg, sizeof(kMsg), digest, &digest_len, EVP_sha256(),
nullptr));

// Sign through |rsa| directly, which is not subject to the restriction, so
// that we can produce salt lengths the restricted key would never pick.
auto sign_with_saltlen = [&](int salt_len) {
std::vector<uint8_t> sig(RSA_size(rsa.get()));
size_t sig_len = sig.size();
EXPECT_TRUE(RSA_sign_pss_mgf1(rsa.get(), &sig_len, sig.data(), sig.size(),
digest, digest_len, EVP_sha256(),
EVP_sha256(), salt_len));
sig.resize(sig_len);
return sig;
};

// |RSA_PSS_SALTLEN_AUTO| recovers the salt length, leaving the restricted
// minimum as its only constraint. 24 is included so that a check testing for
// equality with the minimum, rather than a floor, would still fail.
for (int salt_len : {0, 1, 19}) {
SCOPED_TRACE(salt_len);
const std::vector<uint8_t> sig = sign_with_saltlen(salt_len);
EXPECT_FALSE(
EVP_PKEY_verify(ctx.get(), sig.data(), sig.size(), digest, digest_len));
ERR_clear_error();
EXPECT_FALSE(EVP_PKEY_verify(ctx_copy.get(), sig.data(), sig.size(), digest,
digest_len));
ERR_clear_error();
}
for (int salt_len : {20, 24}) {
SCOPED_TRACE(salt_len);
const std::vector<uint8_t> sig = sign_with_saltlen(salt_len);
EXPECT_TRUE(
EVP_PKEY_verify(ctx.get(), sig.data(), sig.size(), digest, digest_len));
EXPECT_TRUE(EVP_PKEY_verify(ctx_copy.get(), sig.data(), sig.size(), digest,
digest_len));
}
}

// START KEM TESTS

Expand Down
22 changes: 11 additions & 11 deletions crypto/fipsmodule/evp/p_rsa.c
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ static int pkey_rsa_init(EVP_PKEY_CTX *ctx) {
} else {
rctx->pad_mode = RSA_PKCS1_PADDING;
}
rctx->saltlen = -2;
rctx->saltlen = RSA_PSS_SALTLEN_AUTO;
rctx->min_saltlen = NO_PSS_SALT_LEN_RESTRICTION;

ctx->data = rctx;
Expand All @@ -178,6 +178,7 @@ static int pkey_rsa_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) {
dctx->md = sctx->md;
dctx->mgf1md = sctx->mgf1md;
dctx->saltlen = sctx->saltlen;
dctx->min_saltlen = sctx->min_saltlen;
if (sctx->oaep_label) {
OPENSSL_free(dctx->oaep_label);
dctx->oaep_label = OPENSSL_memdup(sctx->oaep_label, sctx->oaep_labellen);
Expand Down Expand Up @@ -264,8 +265,9 @@ static int pkey_rsa_verify(EVP_PKEY_CTX *ctx, const uint8_t *sig,
return RSA_verify(EVP_MD_type(rctx->md), tbs, tbslen, sig, siglen, rsa);

case RSA_PKCS1_PSS_PADDING:
return RSA_verify_pss_mgf1(rsa, tbs, tbslen, rctx->md, rctx->mgf1md,
rctx->saltlen, sig, siglen);
return rsa_verify_pss_mgf1(rsa, tbs, tbslen, rctx->md, rctx->mgf1md,
rctx->saltlen, rctx->min_saltlen, sig,
Comment on lines +268 to +269

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: this passes rctx->min_saltlen, whose "no restriction" sentinel is NO_PSS_SALT_LEN_RESTRICTION (-1, top of this file), into a parameter documented against a different macro, RSA_PSS_NO_SALTLEN_MINIMUM (-1, fipsmodule/rsa/internal.h).

It is correct today, and robust rather than accidental, since the callee's doc says "like any negative value, imposes no minimum". But two names for one sentinel across the evp/rsa boundary invites drift. Could we either use the rsa/internal.h macro here, or note the correspondence at this call site?

siglen);

default:
return 0;
Expand Down Expand Up @@ -475,20 +477,18 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) {
if (type == EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN) {
*(int *)p2 = rctx->saltlen;
} else {
// |p1| can be |-2|, |-1| and non-negative.
// The functions of these values are mentioned in the API doc of
// |EVP_PKEY_CTX_set_rsa_pss_saltlen| in |evp.h|.
// Accordingly, |-2| is the smallest value that |p1| can be.
if (p1 < -2) {
// |p1| can be |RSA_PSS_SALTLEN_AUTO|, |RSA_PSS_SALTLEN_DIGEST|, or
// non-negative. See |EVP_PKEY_CTX_set_rsa_pss_saltlen|.
if (p1 != RSA_PSS_SALTLEN_AUTO && p1 != RSA_PSS_SALTLEN_DIGEST &&
p1 < 0) {
return 0;
}
int min_saltlen = rctx->min_saltlen;
if (min_saltlen != NO_PSS_SALT_LEN_RESTRICTION) {
// Check |min_saltlen| when |p1| is -1.
// |RSA_PSS_SALTLEN_AUTO| is checked against |min_saltlen| when the
// salt is recovered on verify.
if ((p1 == RSA_PSS_SALTLEN_DIGEST &&
(size_t)min_saltlen > EVP_MD_size(rctx->md)) ||
// Check |min_saltlen| when |p1| is the value gives the size of
// the salt in bytes.
(p1 >= 0 && p1 < min_saltlen)) {
OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PSS_SALTLEN);
return 0;
Expand Down
17 changes: 17 additions & 0 deletions crypto/fipsmodule/rsa/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,23 @@ int rsa_digestverify_no_self_test(const EVP_MD *md, const uint8_t *input,
// See the implemetation in |rsa.c| for details.
int is_public_component_of_rsa_key_good(const RSA *key);

// RSA_PSS_NO_SALTLEN_MINIMUM, like any negative value, imposes no minimum.
#define RSA_PSS_NO_SALTLEN_MINIMUM (-1)

// rsa_verify_PKCS1_PSS_mgf1 behaves like |RSA_verify_PKCS1_PSS_mgf1|, except
// that a non-negative |min_sLen| also requires the recovered salt to be at
// least |min_sLen| bytes. This only constrains |RSA_PSS_SALTLEN_AUTO|, since
// any other |sLen| is already checked exactly.
int rsa_verify_PKCS1_PSS_mgf1(const RSA *rsa, const uint8_t *mHash,
const EVP_MD *Hash, const EVP_MD *mgf1Hash,
const uint8_t *EM, int sLen, int min_sLen);

// rsa_verify_pss_mgf1 behaves like |RSA_verify_pss_mgf1|, with the same
// |min_sLen| meaning as |rsa_verify_PKCS1_PSS_mgf1|.
int rsa_verify_pss_mgf1(RSA *rsa, const uint8_t *digest, size_t digest_len,
const EVP_MD *md, const EVP_MD *mgf1_md, int salt_len,
int min_sLen, const uint8_t *sig, size_t sig_len);

OPENSSL_EXPORT const RSASSA_PSS_PARAMS *RSA_get0_ssa_pss_params(const RSA *rsa);

#if defined(__cplusplus)
Expand Down
38 changes: 26 additions & 12 deletions crypto/fipsmodule/rsa/padding.c
Original file line number Diff line number Diff line change
Expand Up @@ -158,9 +158,9 @@ int PKCS1_MGF1(uint8_t *out, size_t len, const uint8_t *seed, size_t seed_len,

static const uint8_t kPSSZeroes[] = {0, 0, 0, 0, 0, 0, 0, 0};

int RSA_verify_PKCS1_PSS_mgf1(const RSA *rsa, const uint8_t *mHash,
int rsa_verify_PKCS1_PSS_mgf1(const RSA *rsa, const uint8_t *mHash,
const EVP_MD *Hash, const EVP_MD *mgf1Hash,
const uint8_t *EM, int sLen) {
const uint8_t *EM, int sLen, int min_sLen) {
// We have to avoid the underlying SHA services updating the indicator
// state, so we lock the state here.
FIPS_service_indicator_lock_state();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: call to undeclared function 'FIPS_service_indicator_lock_state'; ISO C99 and later do not support implicit function declarations [clang-diagnostic-implicit-function-declaration]

  FIPS_service_indicator_lock_state();
  ^

Expand All @@ -175,14 +175,14 @@ int RSA_verify_PKCS1_PSS_mgf1(const RSA *rsa, const uint8_t *mHash,

// Negative sLen has special meanings:
// RSA_PSS_SALTLEN_DIGEST sLen == hLen
// -2 salt length is autorecovered from signature
// -N reserved
// RSA_PSS_SALTLEN_AUTO salt length is autorecovered from signature
// -N reserved
size_t hLen = EVP_MD_size(Hash);
if (sLen == RSA_PSS_SALTLEN_DIGEST) {
sLen = (int)hLen;
} else if (sLen == -2) {
sLen = -2;
} else if (sLen < -2) {
} else if (sLen == RSA_PSS_SALTLEN_AUTO) {
sLen = RSA_PSS_SALTLEN_AUTO;
} else if (sLen < RSA_PSS_SALTLEN_AUTO) {
OPENSSL_PUT_ERROR(RSA, RSA_R_SLEN_CHECK_FAILED);
goto err;
}
Expand All @@ -197,7 +197,8 @@ int RSA_verify_PKCS1_PSS_mgf1(const RSA *rsa, const uint8_t *mHash,
EM++;
emLen--;
}
// |sLen| may be -2 for the non-standard salt length recovery mode.
// |sLen| may be |RSA_PSS_SALTLEN_AUTO| for the non-standard salt length
// recovery mode.
if (emLen < hLen + 2 ||
(sLen >= 0 && emLen < hLen + (size_t)sLen + 2)) {
OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE);
Expand Down Expand Up @@ -237,8 +238,14 @@ OPENSSL_END_ALLOW_DEPRECATED
goto err;
}
salt_start++;
size_t recovered_sLen = maskedDBLen - salt_start;
// If a salt length was specified, check it matches.
if (sLen >= 0 && maskedDBLen - salt_start != (size_t)sLen) {
if (sLen >= 0 && recovered_sLen != (size_t)sLen) {
OPENSSL_PUT_ERROR(RSA, RSA_R_SLEN_CHECK_FAILED);
goto err;
}
// A restricted |EVP_PKEY_RSA_PSS| key also sets a minimum salt length.
if (min_sLen >= 0 && recovered_sLen < (size_t)min_sLen) {
Comment on lines +247 to +248

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The floor here is correct, but it makes an invariant load-bearing that is currently spelled out three separate times.

AUTO on a restricted key must produce a salt >= min_saltlen when signing, or we would emit PSS signatures that this new check then refuses. That holds only because the "maximum PSS salt length" computation agrees everywhere it appears:

Site Formula Decrement condition
p_rsa.c:106-108 (pkey_pss_init) RSA_size(rsa) - EVP_MD_size(md) - 2 (RSA_bits(rsa) & 0x7) == 1
padding.c:304-325 (RSA_padding_add_PKCS1_PSS_mgf1, AUTO) emLen - hLen - 2, emLen = RSA_size(rsa) MSBits == 0, MSBits = (BN_num_bits(rsa->n) - 1) & 0x7
x509/rsa_pss.c:169-172 (x509_rsa_ctx_to_pss, AUTO) EVP_PKEY_size(pk) - EVP_MD_size(sigmd) - 2 ((EVP_PKEY_bits(pk) - 1) & 0x7) == 0

All three are the same predicate -- bits = 1 (mod 8) -- in three different spellings, so they do agree today and "signing is unaffected" is accurate as written. Before this PR a divergence was a cosmetic inconsistency; now it would mean producing signatures we cannot verify.

Could we collapse them into one helper? Something like this in crypto/fipsmodule/rsa/internal.h, defined once in this file:

// rsa_pss_max_saltlen returns the maximum PSS salt length usable with |rsa| and
// a |hLen|-byte digest, or a negative value if |rsa| is too small. This is the
// value |RSA_PSS_SALTLEN_AUTO| resolves to when signing.
int rsa_pss_max_saltlen(const RSA *rsa, size_t hLen);

pkey_pss_init and the AUTO branch here are both inside the module boundary, so sharing between them costs nothing. x509_rsa_ctx_to_pss is outside it and works from an EVP_PKEY *, so folding that one in is optional -- a TODO pointing at the helper would already be an improvement.

If you would rather keep this PR tight, the alternative is a round-trip case in the new test: EVP_PKEY_sign_init + EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, RSA_PSS_SALTLEN_AUTO) + sign + verify with AUTO on the same restricted key. That pins the behaviour even if the formulas stay duplicated. The new test is thorough but it only signs via RSA_sign_pss_mgf1 at the RSA layer -- the EVP sign path with AUTO, which is what the "unaffected" claim is about, is never exercised.

OPENSSL_PUT_ERROR(RSA, RSA_R_SLEN_CHECK_FAILED);
goto err;
}
Expand All @@ -264,6 +271,13 @@ OPENSSL_END_ALLOW_DEPRECATED
return ret;
}

int RSA_verify_PKCS1_PSS_mgf1(const RSA *rsa, const uint8_t *mHash,
const EVP_MD *Hash, const EVP_MD *mgf1Hash,
const uint8_t *EM, int sLen) {
return rsa_verify_PKCS1_PSS_mgf1(rsa, mHash, Hash, mgf1Hash, EM, sLen,
RSA_PSS_NO_SALTLEN_MINIMUM);
}

int RSA_padding_add_PKCS1_PSS_mgf1(const RSA *rsa, unsigned char *EM,
const unsigned char *mHash,
const EVP_MD *Hash, const EVP_MD *mgf1Hash,
Expand Down Expand Up @@ -302,12 +316,12 @@ int RSA_padding_add_PKCS1_PSS_mgf1(const RSA *rsa, unsigned char *EM,

// Negative sLenRequested has special meanings:
// RSA_PSS_SALTLEN_DIGEST sLen == hLen
// -2 salt length is maximized
// -N reserved
// RSA_PSS_SALTLEN_AUTO salt length is maximized
// -N reserved
size_t sLen;
if (sLenRequested == RSA_PSS_SALTLEN_DIGEST) {
sLen = hLen;
} else if (sLenRequested == -2) {
} else if (sLenRequested == RSA_PSS_SALTLEN_AUTO) {
sLen = emLen - hLen - 2;
} else if (sLenRequested < 0) {
OPENSSL_PUT_ERROR(RSA, RSA_R_SLEN_CHECK_FAILED);
Expand Down
14 changes: 11 additions & 3 deletions crypto/fipsmodule/rsa/rsa.c
Original file line number Diff line number Diff line change
Expand Up @@ -964,9 +964,9 @@ int RSA_verify(int hash_nid, const uint8_t *digest, size_t digest_len,
rsa);
}

int RSA_verify_pss_mgf1(RSA *rsa, const uint8_t *digest, size_t digest_len,
int rsa_verify_pss_mgf1(RSA *rsa, const uint8_t *digest, size_t digest_len,
const EVP_MD *md, const EVP_MD *mgf1_md, int salt_len,
const uint8_t *sig, size_t sig_len) {
int min_sLen, const uint8_t *sig, size_t sig_len) {
SET_DIT_AUTO_RESET;
if (digest_len != EVP_MD_size(md)) {
OPENSSL_PUT_ERROR(RSA, RSA_R_INVALID_MESSAGE_LENGTH);
Expand All @@ -989,13 +989,21 @@ int RSA_verify_pss_mgf1(RSA *rsa, const uint8_t *digest, size_t digest_len,
goto err;
}

ret = RSA_verify_PKCS1_PSS_mgf1(rsa, digest, md, mgf1_md, em, salt_len);
ret = rsa_verify_PKCS1_PSS_mgf1(rsa, digest, md, mgf1_md, em, salt_len,
min_sLen);

err:
OPENSSL_free(em);
return ret;
}

int RSA_verify_pss_mgf1(RSA *rsa, const uint8_t *digest, size_t digest_len,
const EVP_MD *md, const EVP_MD *mgf1_md, int salt_len,
const uint8_t *sig, size_t sig_len) {
return rsa_verify_pss_mgf1(rsa, digest, digest_len, md, mgf1_md, salt_len,
RSA_PSS_NO_SALTLEN_MINIMUM, sig, sig_len);
}

int rsa_private_transform_no_self_test(RSA *rsa, uint8_t *out,
const uint8_t *in, size_t len) {
if (rsa->meth && rsa->meth->private_transform) {
Expand Down
3 changes: 2 additions & 1 deletion crypto/rsa_extra/rsassa_pss_asn1.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <openssl/digest.h>
#include <openssl/err.h>
#include <openssl/mem.h>
#include <openssl/rsa.h>

#include "../internal.h"
#include "internal.h"
Expand Down Expand Up @@ -421,7 +422,7 @@ static int pss_saltlen_create(int saltlen, RSA_INTEGER **out) {
int RSASSA_PSS_PARAMS_create(const EVP_MD *sigmd, const EVP_MD *mgf1md,
int saltlen, RSASSA_PSS_PARAMS **out) {
// If all parameters are not changed after |pkey_rsa_init|, don't create pss.
if (sigmd == NULL && mgf1md == NULL && saltlen == -2) {
if (sigmd == NULL && mgf1md == NULL && saltlen == RSA_PSS_SALTLEN_AUTO) {
return 1;
}
RSASSA_PSS_PARAMS *pss = RSASSA_PSS_PARAMS_new();
Expand Down
8 changes: 5 additions & 3 deletions crypto/x509/rsa_pss.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/obj.h>
#include <openssl/rsa.h>

#include "internal.h"

Expand Down Expand Up @@ -160,17 +161,18 @@ int x509_rsa_ctx_to_pss(EVP_MD_CTX *ctx, X509_ALGOR *algor) {
}

EVP_PKEY *pk = EVP_PKEY_CTX_get0_pkey(ctx->pctx);
if (saltlen == -1) {
if (saltlen == RSA_PSS_SALTLEN_DIGEST) {
saltlen = EVP_MD_size(sigmd);
} else if (saltlen == -2) {
} else if (saltlen == RSA_PSS_SALTLEN_AUTO) {
// TODO(davidben): Forbid this mode. The world has largely standardized on
// salt length matching hash length.
saltlen = EVP_PKEY_size(pk) - EVP_MD_size(sigmd) - 2;
if (((EVP_PKEY_bits(pk) - 1) & 0x7) == 0) {
saltlen--;
}
} else if (saltlen != (int)EVP_MD_size(sigmd)) {
// We only allow salt length matching hash length and, for now, the -2 case.
// We only allow salt length matching hash length and, for now, the
// |RSA_PSS_SALTLEN_AUTO| case.
OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS);
return 0;
}
Expand Down
20 changes: 14 additions & 6 deletions include/openssl/evp.h
Original file line number Diff line number Diff line change
Expand Up @@ -881,16 +881,24 @@ OPENSSL_EXPORT int EVP_PKEY_CTX_get_rsa_padding(EVP_PKEY_CTX *ctx,
int *out_padding);

// EVP_PKEY_CTX_set_rsa_pss_saltlen sets the length of the salt in a PSS-padded
// signature. A value of -1 cause the salt to be the same length as the digest
// in the signature. A value of -2 causes the salt to be the maximum length
// that will fit when signing and recovered from the signature when verifying.
// Otherwise the value gives the size of the salt in bytes.
// signature. A value of |RSA_PSS_SALTLEN_DIGEST| (-1) causes the salt to be the
// same length as the digest in the signature. A value of |RSA_PSS_SALTLEN_AUTO|
// (-2) causes the salt to be the maximum length that will fit when signing and
// recovered from the signature when verifying. Otherwise the value gives the
// size of the salt in bytes.
//
// If unsure, use -1.
// For |EVP_PKEY_RSA_PSS| keys that carry a restricted salt length, a value
// below that minimum is rejected. |RSA_PSS_SALTLEN_AUTO| is allowed, but verify
// then requires the recovered salt to be at least that minimum. Note OpenSSL
// instead rejects |RSA_PSS_SALTLEN_AUTO| here for a verify operation, and so
// accepts only a salt of exactly the minimum.
//
// If unsure, use |RSA_PSS_SALTLEN_DIGEST|.
//
// Returns one on success or zero on error.
//
// TODO(davidben): The default is currently -2. Switch it to -1.
// TODO(davidben): The default is currently |RSA_PSS_SALTLEN_AUTO|. Switch it to
// |RSA_PSS_SALTLEN_DIGEST|.
OPENSSL_EXPORT int EVP_PKEY_CTX_set_rsa_pss_saltlen(EVP_PKEY_CTX *ctx,
int salt_len);

Expand Down
Loading
Loading