chore: checkpoint before Python removal

This commit is contained in:
2026-03-26 22:33:59 +00:00
parent 683cec9307
commit e568ddf82a
29972 changed files with 11269302 additions and 2 deletions

View File

@@ -0,0 +1,137 @@
// Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved.
// Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) All rights reserved.
// SPDX-License-Identifier: Apache-2.0
#include <openssl/rsa.h>
#include <string.h>
#include <openssl/bn.h>
#include <openssl/mem.h>
#include <openssl/err.h>
#include "internal.h"
#include "../../internal.h"
#define BN_BLINDING_COUNTER 32
struct bn_blinding_st {
BIGNUM *A; // The base blinding factor, Montgomery-encoded.
BIGNUM *Ai; // The inverse of the blinding factor, Montgomery-encoded.
unsigned counter;
};
static int bn_blinding_create_param(BN_BLINDING *b, const BIGNUM *e,
const BN_MONT_CTX *mont, BN_CTX *ctx);
BN_BLINDING *BN_BLINDING_new(void) {
BN_BLINDING *ret = OPENSSL_zalloc(sizeof(BN_BLINDING));
if (ret == NULL) {
return NULL;
}
ret->A = BN_new();
if (ret->A == NULL) {
goto err;
}
ret->Ai = BN_new();
if (ret->Ai == NULL) {
goto err;
}
// The blinding values need to be created before this blinding can be used.
ret->counter = BN_BLINDING_COUNTER - 1;
return ret;
err:
BN_BLINDING_free(ret);
return NULL;
}
void BN_BLINDING_free(BN_BLINDING *r) {
if (r == NULL) {
return;
}
BN_free(r->A);
BN_free(r->Ai);
OPENSSL_free(r);
}
void BN_BLINDING_invalidate(BN_BLINDING *b) {
b->counter = BN_BLINDING_COUNTER - 1;
}
static int bn_blinding_update(BN_BLINDING *b, const BIGNUM *e,
const BN_MONT_CTX *mont, BN_CTX *ctx) {
if (++b->counter == BN_BLINDING_COUNTER) {
// re-create blinding parameters
if (!bn_blinding_create_param(b, e, mont, ctx)) {
goto err;
}
b->counter = 0;
} else {
if (!BN_mod_mul_montgomery(b->A, b->A, b->A, mont, ctx) ||
!BN_mod_mul_montgomery(b->Ai, b->Ai, b->Ai, mont, ctx)) {
goto err;
}
}
return 1;
err:
// |A| and |Ai| may be in an inconsistent state so they both need to be
// replaced the next time this blinding is used. Note that this is only
// sufficient because support for |BN_BLINDING_NO_UPDATE| and
// |BN_BLINDING_NO_RECREATE| was previously dropped.
b->counter = BN_BLINDING_COUNTER - 1;
return 0;
}
int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, const BIGNUM *e,
const BN_MONT_CTX *mont, BN_CTX *ctx) {
// |n| is not Montgomery-encoded and |b->A| is. |BN_mod_mul_montgomery|
// cancels one Montgomery factor, so the resulting value of |n| is unencoded.
if (!bn_blinding_update(b, e, mont, ctx) ||
!BN_mod_mul_montgomery(n, n, b->A, mont, ctx)) {
return 0;
}
return 1;
}
int BN_BLINDING_invert(BIGNUM *n, const BN_BLINDING *b, BN_MONT_CTX *mont,
BN_CTX *ctx) {
// |n| is not Montgomery-encoded and |b->A| is. |BN_mod_mul_montgomery|
// cancels one Montgomery factor, so the resulting value of |n| is unencoded.
return BN_mod_mul_montgomery(n, n, b->Ai, mont, ctx);
}
static int bn_blinding_create_param(BN_BLINDING *b, const BIGNUM *e,
const BN_MONT_CTX *mont, BN_CTX *ctx) {
int no_inverse;
if (!BN_rand_range_ex(b->A, 1, &mont->N) ||
// Compute |b->A|^-1 in Montgomery form. Note |BN_from_montgomery| +
// |BN_mod_inverse_blinded| is equivalent to, but more efficient than,
// |BN_mod_inverse_blinded| + |BN_to_montgomery|.
//
// We do not retry if |b->A| has no inverse. Finding a non-invertible
// value of |b->A| is equivalent to factoring |mont->N|. There is
// negligible probability of stumbling on one at random.
!BN_from_montgomery(b->Ai, b->A, mont, ctx) ||
!BN_mod_inverse_blinded(b->Ai, &no_inverse, b->Ai, mont, ctx) ||
// TODO(davidben): |BN_mod_exp_mont| internally computes the result in
// Montgomery form. Save a pair of Montgomery reductions and a
// multiplication by returning that value directly.
!BN_mod_exp_mont(b->A, b->A, e, &mont->N, ctx, mont) ||
!BN_to_montgomery(b->A, b->A, mont, ctx)) {
OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
return 0;
}
return 1;
}

View File

@@ -0,0 +1,235 @@
// Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) All rights reserved.
// SPDX-License-Identifier: Apache-2.0
#ifndef OPENSSL_HEADER_RSA_INTERNAL_H
#define OPENSSL_HEADER_RSA_INTERNAL_H
#include <openssl/base.h>
#include <openssl/bn.h>
#include <openssl/rsa.h>
#if defined(__cplusplus)
extern "C" {
#endif
typedef struct bn_blinding_st BN_BLINDING;
struct rsa_meth_st {
void *app_data;
int (*init)(RSA *rsa);
int (*finish)(RSA *rsa);
// size returns the size of the RSA modulus in bytes.
size_t (*size)(const RSA *rsa);
// Set via |RSA_meth_set_sign|. The default behavior for |sign| is
// implemented in |RSA_sign|. If custom functionality is provided, |sign|
// will be invoked within |RSA_sign|.
int (*sign)(int type, const uint8_t *m, unsigned int m_length,
uint8_t *sigret, unsigned int *siglen, const RSA *rsa);
// Set via |RSA_meth_set_priv_enc|. |sign_raw| is equivalent to the
// |priv_enc| field of OpenSSL's |RSA_METHOD| struct. The default behavior
// for |sign_raw| is implemented in |RSA_sign_raw|. If custom
// functionality is provided, |sign_raw| will be invoked within
// |RSA_sign_raw|.
int (*sign_raw)(int max_out, const uint8_t *in, uint8_t *out, RSA *rsa,
int padding);
// Set via |RSA_meth_set_pub_dec|. |verify_raw| is equivalent to the
// |pub_dec| field of OpenSSL's |RSA_METHOD| struct. The default behavior
// for |verify_raw| is implemented in |RSA_verify_raw|. If custom
// functionality is provided, |verify_raw| will be invoked within
// |RSA_verify_raw|.
int (*verify_raw)(int max_out, const uint8_t *in, uint8_t *out, RSA *rsa,
int padding);
// Set via |RSA_meth_set_priv_dec|. |decrypt| is equivalent to the
// |priv_dec| field of OpenSSL's |RSA_METHOD| struct. The default behavior
// for |decrypt| is implemented in |RSA_decrypt|. If custom
// functionality is provided, |decrypt| will be invoked within
// |RSA_decrypt|.
int (*decrypt)(int max_out, const uint8_t *in, uint8_t *out, RSA *rsa,
int padding);
// Set via |RSA_meth_set_pub_enc|. |encrypt| is equivalent to the
// |pub_enc| field of OpenSSL's |RSA_METHOD| struct. The default behavior
// for |encrypt| is implemented in |RSA_encrypt|. If custom
// functionality is provided, |encrypt| will be invoked within
// |RSA_encrypt|.
int (*encrypt)(int max_out, const uint8_t *in, uint8_t *out, RSA *rsa,
int padding);
// private_transform takes a big-endian integer from |in|, calculates the
// d'th power of it, modulo the RSA modulus and writes the result as a
// big-endian integer to |out|. Both |in| and |out| are |len| bytes long and
// |len| is always equal to |RSA_size(rsa)|. If the result of the transform
// can be represented in fewer than |len| bytes, then |out| must be zero
// padded on the left.
//
// It returns one on success and zero otherwise.
//
// RSA decrypt and sign operations will call this, thus an ENGINE might wish
// to override it in order to avoid having to implement the padding
// functionality demanded by those, higher level, operations.
int (*private_transform)(RSA *rsa, uint8_t *out, const uint8_t *in,
size_t len);
int flags;
};
struct rsa_st {
const RSA_METHOD *meth;
BIGNUM *n;
BIGNUM *e;
BIGNUM *d;
BIGNUM *p;
BIGNUM *q;
BIGNUM *dmp1;
BIGNUM *dmq1;
BIGNUM *iqmp;
// If a PSS only key this contains the parameter restrictions.
RSASSA_PSS_PARAMS *pss;
// be careful using this if the RSA structure is shared
CRYPTO_EX_DATA ex_data;
CRYPTO_refcount_t references;
int flags;
CRYPTO_MUTEX lock;
// Used to cache montgomery values. The creation of these values is protected
// by |lock|.
BN_MONT_CTX *mont_n;
BN_MONT_CTX *mont_p;
BN_MONT_CTX *mont_q;
// The following fields are copies of |d|, |dmp1|, and |dmq1|, respectively,
// but with the correct widths to prevent side channels. These must use
// separate copies due to threading concerns caused by OpenSSL's API
// mistakes. See https://github.com/openssl/openssl/issues/5158 and
// the |freeze_private_key| implementation.
BIGNUM *d_fixed, *dmp1_fixed, *dmq1_fixed;
// iqmp_mont is q^-1 mod p in Montgomery form, using |mont_p|.
BIGNUM *iqmp_mont;
// num_blindings contains the size of the |blindings| and |blindings_inuse|
// arrays. This member and the |blindings_inuse| array are protected by
// |lock|.
size_t num_blindings;
// blindings is an array of BN_BLINDING structures that can be reserved by a
// thread by locking |lock| and changing the corresponding element in
// |blindings_inuse| from 0 to 1.
BN_BLINDING **blindings;
unsigned char *blindings_inuse;
uint64_t blinding_fork_generation;
// private_key_frozen is one if the key has been used for a private key
// operation and may no longer be mutated.
unsigned private_key_frozen:1;
};
#define RSA_PKCS1_PADDING_SIZE 11
// Default implementations of RSA operations.
size_t rsa_default_size(const RSA *rsa);
int rsa_default_sign_raw(RSA *rsa, size_t *out_len, uint8_t *out,
size_t max_out, const uint8_t *in, size_t in_len,
int padding);
int rsa_default_private_transform(RSA *rsa, uint8_t *out, const uint8_t *in,
size_t len);
BN_BLINDING *BN_BLINDING_new(void);
void BN_BLINDING_free(BN_BLINDING *b);
void BN_BLINDING_invalidate(BN_BLINDING *b);
int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, const BIGNUM *e,
const BN_MONT_CTX *mont_ctx, BN_CTX *ctx);
int BN_BLINDING_invert(BIGNUM *n, const BN_BLINDING *b, BN_MONT_CTX *mont_ctx,
BN_CTX *ctx);
int RSA_padding_add_PKCS1_type_1(uint8_t *to, size_t to_len,
const uint8_t *from, size_t from_len);
int RSA_padding_check_PKCS1_type_1(uint8_t *out, size_t *out_len,
size_t max_out, const uint8_t *from,
size_t from_len);
int RSA_padding_add_none(uint8_t *to, size_t to_len, const uint8_t *from,
size_t from_len);
// rsa_private_transform_no_self_test calls either the method-specific
// |private_transform| function (if given) or the generic one. See the comment
// for |private_transform| in |rsa_meth_st|.
int rsa_private_transform_no_self_test(RSA *rsa, uint8_t *out,
const uint8_t *in, size_t len);
// rsa_private_transform acts the same as |rsa_private_transform_no_self_test|
// but, in FIPS mode, performs an RSA self test before calling the default RSA
// implementation.
int rsa_private_transform(RSA *rsa, uint8_t *out, const uint8_t *in,
size_t len);
// rsa_invalidate_key is called after |rsa| has been mutated, to invalidate
// fields derived from the original structure. This function assumes exclusive
// access to |rsa|. In particular, no other thread may be concurrently signing,
// etc., with |rsa|.
void rsa_invalidate_key(RSA *rsa);
// This constant is exported for test purposes.
extern const BN_ULONG kBoringSSLRSASqrtTwo[];
extern const size_t kBoringSSLRSASqrtTwoLen;
// Functions that avoid self-tests.
//
// Self-tests need to call functions that don't try and ensure that the
// self-tests have passed. These functions, in turn, need to limit themselves
// to such functions too.
//
// These functions are the same as their public versions, but skip the self-test
// check.
int rsa_verify_no_self_test(int hash_nid, const uint8_t *digest,
size_t digest_len, const uint8_t *sig,
size_t sig_len, RSA *rsa);
int rsa_verify_raw_no_self_test(RSA *rsa, size_t *out_len, uint8_t *out,
size_t max_out, const uint8_t *in,
size_t in_len, int padding);
int rsa_sign_no_self_test(int hash_nid, const uint8_t *digest,
size_t digest_len, uint8_t *out, unsigned *out_len,
RSA *rsa);
// rsa_digestsign_no_self_test calculates the digest and calls
// |rsa_sign_no_self_test|, which doesn't try to run the self-test first. This
// is for use in the self tests themselves, to prevent an infinite loop.
int rsa_digestsign_no_self_test(const EVP_MD *md, const uint8_t *input,
size_t in_len, uint8_t *out, unsigned *out_len,
RSA *rsa);
// rsa_digestverify_no_self_test calculates the digest and calls
// |rsa_verify_no_self_test|, which doesn't try to run the self-test first. This
// is for use in the self tests themselves, to prevent an infinite loop.
int rsa_digestverify_no_self_test(const EVP_MD *md, const uint8_t *input,
size_t in_len, const uint8_t *sig,
size_t sig_len, RSA *rsa);
// Performs several checks on the public component of the given RSA key.
// See the implemetation in |rsa.c| for details.
int is_public_component_of_rsa_key_good(const RSA *key);
OPENSSL_EXPORT const RSASSA_PSS_PARAMS *RSA_get0_ssa_pss_params(const RSA *rsa);
#if defined(__cplusplus)
} // extern C
#endif
#endif // OPENSSL_HEADER_RSA_INTERNAL_H

View File

@@ -0,0 +1,378 @@
// Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project 2005.
// Copyright (c) 2005 The OpenSSL Project. All rights reserved.
// SPDX-License-Identifier: Apache-2.0
#include <openssl/rsa.h>
#include <assert.h>
#include <limits.h>
#include <string.h>
#include <openssl/bn.h>
#include <openssl/digest.h>
#include <openssl/err.h>
#include <openssl/mem.h>
#include <openssl/rand.h>
#include <openssl/sha.h>
#include "internal.h"
#include "../../internal.h"
int RSA_padding_add_PKCS1_type_1(uint8_t *to, size_t to_len,
const uint8_t *from, size_t from_len) {
// See RFC 8017, section 9.2.
if (to_len < RSA_PKCS1_PADDING_SIZE) {
OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL);
return 0;
}
if (from_len > to_len - RSA_PKCS1_PADDING_SIZE) {
OPENSSL_PUT_ERROR(RSA, RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY);
return 0;
}
to[0] = 0;
to[1] = 1;
OPENSSL_memset(to + 2, 0xff, to_len - 3 - from_len);
to[to_len - from_len - 1] = 0;
OPENSSL_memcpy(to + to_len - from_len, from, from_len);
return 1;
}
int RSA_padding_check_PKCS1_type_1(uint8_t *out, size_t *out_len,
size_t max_out, const uint8_t *from,
size_t from_len) {
// See RFC 8017, section 9.2. This is part of signature verification and thus
// does not need to run in constant-time.
if (from_len < 2) {
OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_SMALL);
return 0;
}
// Check the header.
if (from[0] != 0 || from[1] != 1) {
OPENSSL_PUT_ERROR(RSA, RSA_R_BLOCK_TYPE_IS_NOT_01);
return 0;
}
// Scan over padded data, looking for the 00.
size_t pad;
for (pad = 2 /* header */; pad < from_len; pad++) {
if (from[pad] == 0x00) {
break;
}
if (from[pad] != 0xff) {
OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_FIXED_HEADER_DECRYPT);
return 0;
}
}
if (pad == from_len) {
OPENSSL_PUT_ERROR(RSA, RSA_R_NULL_BEFORE_BLOCK_MISSING);
return 0;
}
if (pad < 2 /* header */ + 8) {
OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_PAD_BYTE_COUNT);
return 0;
}
// Skip over the 00.
pad++;
if (from_len - pad > max_out) {
OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE);
return 0;
}
OPENSSL_memcpy(out, from + pad, from_len - pad);
*out_len = from_len - pad;
return 1;
}
int RSA_padding_add_none(uint8_t *to, size_t to_len, const uint8_t *from,
size_t from_len) {
if (from_len > to_len) {
OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
return 0;
}
if (from_len < to_len) {
OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_SMALL);
return 0;
}
OPENSSL_memcpy(to, from, from_len);
return 1;
}
int PKCS1_MGF1(uint8_t *out, size_t len, const uint8_t *seed, size_t seed_len,
const EVP_MD *md) {
// We have to avoid the underlying SHA services updating the indicator
// state, so we lock the state here.
FIPS_service_indicator_lock_state();
int ret = 0;
EVP_MD_CTX ctx;
EVP_MD_CTX_init(&ctx);
size_t md_len = EVP_MD_size(md);
for (uint32_t i = 0; len > 0; i++) {
uint8_t counter[4];
counter[0] = (uint8_t)(i >> 24);
counter[1] = (uint8_t)(i >> 16);
counter[2] = (uint8_t)(i >> 8);
counter[3] = (uint8_t)i;
if (!EVP_DigestInit_ex(&ctx, md, NULL) ||
!EVP_DigestUpdate(&ctx, seed, seed_len) ||
!EVP_DigestUpdate(&ctx, counter, sizeof(counter))) {
goto err;
}
if (md_len <= len) {
if (!EVP_DigestFinal_ex(&ctx, out, NULL)) {
goto err;
}
out += md_len;
len -= md_len;
} else {
uint8_t digest[EVP_MAX_MD_SIZE];
if (!EVP_DigestFinal_ex(&ctx, digest, NULL)) {
goto err;
}
OPENSSL_memcpy(out, digest, len);
len = 0;
}
}
ret = 1;
err:
EVP_MD_CTX_cleanup(&ctx);
FIPS_service_indicator_unlock_state();
return ret;
}
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,
const EVP_MD *Hash, const EVP_MD *mgf1Hash,
const uint8_t *EM, int sLen) {
// We have to avoid the underlying SHA services updating the indicator
// state, so we lock the state here.
FIPS_service_indicator_lock_state();
if (mgf1Hash == NULL) {
mgf1Hash = Hash;
}
int ret = 0;
uint8_t *DB = NULL;
EVP_MD_CTX ctx;
EVP_MD_CTX_init(&ctx);
// Negative sLen has special meanings:
// RSA_PSS_SALTLEN_DIGEST sLen == hLen
// -2 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) {
OPENSSL_PUT_ERROR(RSA, RSA_R_SLEN_CHECK_FAILED);
goto err;
}
unsigned MSBits = (BN_num_bits(rsa->n) - 1) & 0x7;
size_t emLen = RSA_size(rsa);
if (EM[0] & (0xFF << MSBits)) {
OPENSSL_PUT_ERROR(RSA, RSA_R_FIRST_OCTET_INVALID);
goto err;
}
if (MSBits == 0) {
EM++;
emLen--;
}
// |sLen| may be -2 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);
goto err;
}
if (EM[emLen - 1] != 0xbc) {
OPENSSL_PUT_ERROR(RSA, RSA_R_LAST_OCTET_INVALID);
goto err;
}
size_t maskedDBLen = emLen - hLen - 1;
const uint8_t *H = EM + maskedDBLen;
DB = OPENSSL_malloc(maskedDBLen);
if (!DB) {
goto err;
}
OPENSSL_BEGIN_ALLOW_DEPRECATED
if (!PKCS1_MGF1(DB, maskedDBLen, H, hLen, mgf1Hash)) {
goto err;
}
OPENSSL_END_ALLOW_DEPRECATED
for (size_t i = 0; i < maskedDBLen; i++) {
DB[i] ^= EM[i];
}
if (MSBits) {
DB[0] &= 0xFF >> (8 - MSBits);
}
// This step differs slightly from EMSA-PSS-VERIFY (RFC 8017) step 10 because
// it accepts a non-standard salt recovery flow. DB should be some number of
// zeros, a one, then the salt.
size_t salt_start;
for (salt_start = 0; DB[salt_start] == 0 && salt_start < maskedDBLen - 1;
salt_start++) {
;
}
if (DB[salt_start] != 0x1) {
OPENSSL_PUT_ERROR(RSA, RSA_R_SLEN_RECOVERY_FAILED);
goto err;
}
salt_start++;
// If a salt length was specified, check it matches.
if (sLen >= 0 && maskedDBLen - salt_start != (size_t)sLen) {
OPENSSL_PUT_ERROR(RSA, RSA_R_SLEN_CHECK_FAILED);
goto err;
}
uint8_t H_[EVP_MAX_MD_SIZE];
if (!EVP_DigestInit_ex(&ctx, Hash, NULL) ||
!EVP_DigestUpdate(&ctx, kPSSZeroes, sizeof(kPSSZeroes)) ||
!EVP_DigestUpdate(&ctx, mHash, hLen) ||
!EVP_DigestUpdate(&ctx, DB + salt_start, maskedDBLen - salt_start) ||
!EVP_DigestFinal_ex(&ctx, H_, NULL)) {
goto err;
}
if (OPENSSL_memcmp(H_, H, hLen) != 0) {
OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_SIGNATURE);
goto err;
}
ret = 1;
err:
OPENSSL_free(DB);
EVP_MD_CTX_cleanup(&ctx);
FIPS_service_indicator_unlock_state();
return ret;
}
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,
int sLenRequested) {
// We have to avoid the underlying SHA services updating the indicator
// state, so we lock the state here.
FIPS_service_indicator_lock_state();
int ret = 0;
size_t maskedDBLen, MSBits, emLen;
size_t hLen;
unsigned char *H, *salt = NULL, *p;
if (mgf1Hash == NULL) {
mgf1Hash = Hash;
}
hLen = EVP_MD_size(Hash);
if (BN_is_zero(rsa->n)) {
OPENSSL_PUT_ERROR(RSA, RSA_R_EMPTY_PUBLIC_KEY);
goto err;
}
MSBits = (BN_num_bits(rsa->n) - 1) & 0x7;
emLen = RSA_size(rsa);
if (MSBits == 0) {
assert(emLen >= 1);
*EM++ = 0;
emLen--;
}
if (emLen < hLen + 2) {
OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
goto err;
}
// Negative sLenRequested has special meanings:
// RSA_PSS_SALTLEN_DIGEST sLen == hLen
// -2 salt length is maximized
// -N reserved
size_t sLen;
if (sLenRequested == RSA_PSS_SALTLEN_DIGEST) {
sLen = hLen;
} else if (sLenRequested == -2) {
sLen = emLen - hLen - 2;
} else if (sLenRequested < 0) {
OPENSSL_PUT_ERROR(RSA, RSA_R_SLEN_CHECK_FAILED);
goto err;
} else {
sLen = (size_t)sLenRequested;
}
if (emLen - hLen - 2 < sLen) {
OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
goto err;
}
if (sLen > 0) {
salt = OPENSSL_malloc(sLen);
if (!salt) {
goto err;
}
AWSLC_ABORT_IF_NOT_ONE(RAND_bytes(salt, sLen));
}
maskedDBLen = emLen - hLen - 1;
H = EM + maskedDBLen;
EVP_MD_CTX ctx;
EVP_MD_CTX_init(&ctx);
int digest_ok = EVP_DigestInit_ex(&ctx, Hash, NULL) &&
EVP_DigestUpdate(&ctx, kPSSZeroes, sizeof(kPSSZeroes)) &&
EVP_DigestUpdate(&ctx, mHash, hLen) &&
EVP_DigestUpdate(&ctx, salt, sLen) &&
EVP_DigestFinal_ex(&ctx, H, NULL);
EVP_MD_CTX_cleanup(&ctx);
if (!digest_ok) {
goto err;
}
OPENSSL_BEGIN_ALLOW_DEPRECATED
// Generate dbMask in place then perform XOR on it
if (!PKCS1_MGF1(EM, maskedDBLen, H, hLen, mgf1Hash)) {
goto err;
}
OPENSSL_END_ALLOW_DEPRECATED
p = EM;
// Initial PS XORs with all zeroes which is a NOP so just update
// pointer. Note from a test above this value is guaranteed to
// be non-negative.
p += emLen - sLen - hLen - 2;
*p++ ^= 0x1;
if (sLen > 0) {
for (size_t i = 0; i < sLen; i++) {
*p++ ^= salt[i];
}
}
if (MSBits) {
EM[0] &= 0xFF >> (8 - MSBits);
}
// H is already in place so just set final 0xbc
EM[emLen - 1] = 0xbc;
ret = 1;
err:
OPENSSL_free(salt);
FIPS_service_indicator_unlock_state();
return ret;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff