mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2026-07-07 04:50:48 +02:00
Merge pull request #10088 from anhu/new_various
Various security fixes and tests
This commit is contained in:
@@ -483,6 +483,38 @@ int wolfSSL_memsave_session_cache(void* mem, int sz)
|
||||
}
|
||||
|
||||
|
||||
#if !defined(SESSION_CACHE_DYNAMIC_MEM) && \
|
||||
(defined(HAVE_SESSION_TICKET) || \
|
||||
(defined(SESSION_CERTS) && defined(OPENSSL_EXTRA)))
|
||||
static void SessionSanityPointerSet(SessionRow* row)
|
||||
{
|
||||
int j;
|
||||
|
||||
/* Reset pointers to safe values after raw copy */
|
||||
for (j = 0; j < SESSIONS_PER_ROW; j++) {
|
||||
WOLFSSL_SESSION* s = &row->Sessions[j];
|
||||
#ifdef HAVE_SESSION_TICKET
|
||||
s->ticket = s->staticTicket;
|
||||
s->ticketLenAlloc = 0;
|
||||
if (s->ticketLen > SESSION_TICKET_LEN) {
|
||||
s->ticketLen = SESSION_TICKET_LEN;
|
||||
}
|
||||
#endif
|
||||
#if defined(WOLFSSL_TLS13) && defined(HAVE_SESSION_TICKET) && \
|
||||
defined(WOLFSSL_TICKET_NONCE_MALLOC) && \
|
||||
(!defined(HAVE_FIPS) || (defined(FIPS_VERSION_GE) && FIPS_VERSION_GE(5,3)))
|
||||
s->ticketNonce.data = s->ticketNonce.dataStatic;
|
||||
if (s->ticketNonce.len > MAX_TICKET_NONCE_STATIC_SZ) {
|
||||
s->ticketNonce.len = MAX_TICKET_NONCE_STATIC_SZ;
|
||||
}
|
||||
#endif
|
||||
#if defined(SESSION_CERTS) && defined(OPENSSL_EXTRA)
|
||||
s->peer = NULL;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Restore the persistent session cache from memory */
|
||||
int wolfSSL_memrestore_session_cache(const void* mem, int sz)
|
||||
{
|
||||
@@ -522,6 +554,11 @@ int wolfSSL_memrestore_session_cache(const void* mem, int sz)
|
||||
#endif
|
||||
|
||||
XMEMCPY(&SessionCache[i], row++, SIZEOF_SESSION_ROW);
|
||||
#if !defined(SESSION_CACHE_DYNAMIC_MEM) && \
|
||||
(defined(HAVE_SESSION_TICKET) || \
|
||||
(defined(SESSION_CERTS) && defined(OPENSSL_EXTRA)))
|
||||
SessionSanityPointerSet(&SessionCache[i]);
|
||||
#endif
|
||||
#ifdef ENABLE_SESSION_CACHE_ROW_LOCK
|
||||
SESSION_ROW_UNLOCK(&SessionCache[i]);
|
||||
#endif
|
||||
@@ -681,6 +718,11 @@ int wolfSSL_restore_session_cache(const char *fname)
|
||||
#endif
|
||||
|
||||
ret = (int)XFREAD(&SessionCache[i], SIZEOF_SESSION_ROW, 1, file);
|
||||
#if !defined(SESSION_CACHE_DYNAMIC_MEM) && \
|
||||
(defined(HAVE_SESSION_TICKET) || \
|
||||
(defined(SESSION_CERTS) && defined(OPENSSL_EXTRA)))
|
||||
SessionSanityPointerSet(&SessionCache[i]);
|
||||
#endif
|
||||
#ifdef ENABLE_SESSION_CACHE_ROW_LOCK
|
||||
SESSION_ROW_UNLOCK(&SessionCache[i]);
|
||||
#endif
|
||||
|
||||
@@ -9950,6 +9950,10 @@ static int TLSX_KeyShare_ProcessPqcClient_ex(WOLFSSL* ssl,
|
||||
}
|
||||
#endif
|
||||
|
||||
if (ret == 0 && keyShareEntry->keLen < ctSz) {
|
||||
WOLFSSL_MSG("PQC key share data too short for ciphertext.");
|
||||
ret = BUFFER_E;
|
||||
}
|
||||
if (ret == 0) {
|
||||
ret = wc_KyberKey_Decapsulate(kem, ssOutput,
|
||||
keyShareEntry->ke, ctSz);
|
||||
|
||||
+184
@@ -165,6 +165,19 @@
|
||||
#include <sys/uio.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_DILITHIUM
|
||||
#include <wolfssl/wolfcrypt/dilithium.h>
|
||||
#endif
|
||||
#if defined(WOLFSSL_HAVE_MLKEM)
|
||||
#include <wolfssl/wolfcrypt/mlkem.h>
|
||||
#endif
|
||||
#if defined(HAVE_PKCS7)
|
||||
#include <wolfssl/wolfcrypt/pkcs7.h>
|
||||
#endif
|
||||
#if !defined(NO_BIG_INT)
|
||||
#include <wolfssl/wolfcrypt/sp_int.h>
|
||||
#endif
|
||||
|
||||
/* include misc.c here regardless of NO_INLINE, because misc.c implementations
|
||||
* have default (hidden) visibility, and in the absence of visibility, it's
|
||||
* benign to mask out the library implementation.
|
||||
@@ -34758,6 +34771,47 @@ static int test_DhAgree_rejects_p_minus_1(void)
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
|
||||
/* ML-DSA HashML-DSA verify must reject hashLen > WC_MAX_DIGEST_SIZE */
|
||||
static int test_mldsa_verify_hash(void)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
#if defined(HAVE_DILITHIUM) && defined(WOLFSSL_WC_DILITHIUM) && \
|
||||
!defined(WOLFSSL_DILITHIUM_NO_MAKE_KEY) && \
|
||||
!defined(WOLFSSL_DILITHIUM_NO_VERIFY)
|
||||
dilithium_key key;
|
||||
WC_RNG rng;
|
||||
int res = 0;
|
||||
byte sig[4000];
|
||||
byte hash[4096]; /* larger than WC_MAX_DIGEST_SIZE */
|
||||
|
||||
XMEMSET(&key, 0, sizeof(key));
|
||||
XMEMSET(&rng, 0, sizeof(rng));
|
||||
XMEMSET(sig, 0x41, sizeof(sig));
|
||||
XMEMSET(hash, 'A', sizeof(hash));
|
||||
|
||||
ExpectIntEQ(wc_InitRng(&rng), 0);
|
||||
ExpectIntEQ(wc_dilithium_init(&key), 0);
|
||||
#ifndef WOLFSSL_NO_ML_DSA_65
|
||||
ExpectIntEQ(wc_dilithium_set_level(&key, WC_ML_DSA_65), 0);
|
||||
#elif !defined(WOLFSSL_NO_ML_DSA_44)
|
||||
ExpectIntEQ(wc_dilithium_set_level(&key, WC_ML_DSA_44), 0);
|
||||
#else
|
||||
ExpectIntEQ(wc_dilithium_set_level(&key, WC_ML_DSA_87), 0);
|
||||
#endif
|
||||
ExpectIntEQ(wc_dilithium_make_key(&key, &rng), 0);
|
||||
|
||||
/* hashLen=4096 must be rejected, not overflow the stack */
|
||||
ExpectIntEQ(wc_dilithium_verify_ctx_hash(sig, sizeof(sig), NULL, 0,
|
||||
WC_HASH_TYPE_SHA256, hash, sizeof(hash), &res, &key),
|
||||
WC_NO_ERR_TRACE(BAD_LENGTH_E));
|
||||
|
||||
wc_dilithium_free(&key);
|
||||
DoExpectIntEQ(wc_FreeRng(&rng), 0);
|
||||
#endif
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
/* Test: Ed448 must reject identity public key (0,1) */
|
||||
static int test_ed448_rejects_identity_key(void)
|
||||
{
|
||||
@@ -34936,6 +34990,133 @@ static int test_pkcs7_ori_oversized_oid(void)
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
/* Dilithium verify_ctx_msg must reject absurdly large msgLen */
|
||||
static int test_dilithium_hash(void)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
#if defined(HAVE_DILITHIUM) && defined(WOLFSSL_WC_DILITHIUM) && \
|
||||
!defined(WOLFSSL_DILITHIUM_NO_MAKE_KEY) && \
|
||||
!defined(WOLFSSL_DILITHIUM_NO_VERIFY)
|
||||
dilithium_key key;
|
||||
WC_RNG rng;
|
||||
int res = 0;
|
||||
byte sig[4000];
|
||||
byte msg[64];
|
||||
|
||||
XMEMSET(&key, 0, sizeof(key));
|
||||
XMEMSET(&rng, 0, sizeof(rng));
|
||||
XMEMSET(sig, 0, sizeof(sig));
|
||||
XMEMSET(msg, 'A', sizeof(msg));
|
||||
|
||||
ExpectIntEQ(wc_InitRng(&rng), 0);
|
||||
ExpectIntEQ(wc_dilithium_init(&key), 0);
|
||||
#ifndef WOLFSSL_NO_ML_DSA_65
|
||||
ExpectIntEQ(wc_dilithium_set_level(&key, WC_ML_DSA_65), 0);
|
||||
#elif !defined(WOLFSSL_NO_ML_DSA_44)
|
||||
ExpectIntEQ(wc_dilithium_set_level(&key, WC_ML_DSA_44), 0);
|
||||
#else
|
||||
ExpectIntEQ(wc_dilithium_set_level(&key, WC_ML_DSA_87), 0);
|
||||
#endif
|
||||
ExpectIntEQ(wc_dilithium_make_key(&key, &rng), 0);
|
||||
|
||||
ExpectIntEQ(wc_dilithium_verify_ctx_msg(sig, sizeof(sig), NULL, 0,
|
||||
msg, 0xFFFFFFC0, &res, &key), WC_NO_ERR_TRACE(BAD_FUNC_ARG));
|
||||
|
||||
wc_dilithium_free(&key);
|
||||
DoExpectIntEQ(wc_FreeRng(&rng), 0);
|
||||
#endif
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
/* PKCS7 CBC must validate all padding bytes */
|
||||
static int test_pkcs7_padding(void)
|
||||
{
|
||||
EXPECT_DECLS;
|
||||
#if defined(HAVE_PKCS7) && !defined(NO_AES) && defined(HAVE_AES_CBC) && \
|
||||
defined(WOLFSSL_AES_256) && !defined(NO_PKCS7_ENCRYPTED_DATA)
|
||||
PKCS7 pkcs7;
|
||||
byte key[32];
|
||||
byte plaintext[27]; /* 27 bytes -> padded to 32 -> padding = 05 05 05 05 05 */
|
||||
byte encoded[4096];
|
||||
byte output[256];
|
||||
byte modified[4096];
|
||||
int encodedSz = 0;
|
||||
int outSz;
|
||||
int ctOff = -1;
|
||||
int ctLen = 0;
|
||||
int i;
|
||||
|
||||
XMEMSET(key, 0xAA, sizeof(key));
|
||||
XMEMSET(plaintext, 'X', sizeof(plaintext));
|
||||
|
||||
/* Encode EncryptedData */
|
||||
XMEMSET(&pkcs7, 0, sizeof(pkcs7));
|
||||
ExpectIntEQ(wc_PKCS7_Init(&pkcs7, NULL, 0), 0);
|
||||
pkcs7.content = plaintext;
|
||||
pkcs7.contentSz = sizeof(plaintext);
|
||||
pkcs7.contentOID = DATA;
|
||||
pkcs7.encryptOID = AES256CBCb;
|
||||
pkcs7.encryptionKey = key;
|
||||
pkcs7.encryptionKeySz = sizeof(key);
|
||||
|
||||
ExpectIntGT(encodedSz = wc_PKCS7_EncodeEncryptedData(&pkcs7, encoded,
|
||||
sizeof(encoded)), 0);
|
||||
|
||||
/* Verify normal decrypt works */
|
||||
ExpectIntEQ(outSz = wc_PKCS7_DecodeEncryptedData(&pkcs7, encoded,
|
||||
(word32)encodedSz, output, sizeof(output)), (int)sizeof(plaintext));
|
||||
wc_PKCS7_Free(&pkcs7);
|
||||
|
||||
/* Find ciphertext block in encoded DER */
|
||||
if (EXPECT_SUCCESS()) {
|
||||
for (i = encodedSz - 10; i > 10; i--) {
|
||||
if (encoded[i] == 0x04 || encoded[i] == 0x80) {
|
||||
int len, lbytes;
|
||||
|
||||
if (encoded[i+1] < 0x80) {
|
||||
len = encoded[i+1]; lbytes = 1;
|
||||
}
|
||||
else if (encoded[i+1] == 0x81) {
|
||||
len = encoded[i+2]; lbytes = 2;
|
||||
}
|
||||
else {
|
||||
continue;
|
||||
}
|
||||
if (len > 0 && len % 16 == 0 &&
|
||||
i + 1 + lbytes + len <= encodedSz) {
|
||||
ctOff = i + 1 + lbytes;
|
||||
ctLen = len;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ExpectIntGT(ctOff, 0);
|
||||
ExpectIntGE(ctLen, 32);
|
||||
|
||||
/* Corrupt an interior padding byte via CBC bit-flip */
|
||||
if (EXPECT_SUCCESS()) {
|
||||
XMEMCPY(modified, encoded, (size_t)encodedSz);
|
||||
/* Flip byte in penultimate block to corrupt interior padding */
|
||||
modified[ctOff + ctLen - 32 + 11] ^= 0x42;
|
||||
|
||||
/* Decrypt modified ciphertext - must fail, not succeed */
|
||||
XMEMSET(&pkcs7, 0, sizeof(pkcs7));
|
||||
ExpectIntEQ(wc_PKCS7_Init(&pkcs7, NULL, 0), 0);
|
||||
pkcs7.encryptionKey = key;
|
||||
pkcs7.encryptionKeySz = sizeof(key);
|
||||
|
||||
outSz = wc_PKCS7_DecodeEncryptedData(&pkcs7, modified,
|
||||
(word32)encodedSz, output, sizeof(output));
|
||||
/* Must return an error - if it returns plaintext size, padding
|
||||
* oracle vulnerability exists */
|
||||
ExpectIntLT(outSz, 0);
|
||||
wc_PKCS7_Free(&pkcs7);
|
||||
}
|
||||
#endif
|
||||
return EXPECT_RESULT();
|
||||
}
|
||||
|
||||
TEST_CASE testCases[] = {
|
||||
TEST_DECL(test_fileAccess),
|
||||
|
||||
@@ -35754,11 +35935,14 @@ TEST_CASE testCases[] = {
|
||||
TEST_DECL(test_ed448_rejects_identity_key),
|
||||
TEST_DECL(test_pkcs7_decode_encrypted_outputsz),
|
||||
TEST_DECL(test_pkcs7_ori_oversized_oid),
|
||||
TEST_DECL(test_pkcs7_padding),
|
||||
|
||||
#if defined(WOLFSSL_SNIFFER) && defined(WOLFSSL_SNIFFER_CHAIN_INPUT)
|
||||
TEST_DECL(test_sniffer_chain_input_overflow),
|
||||
#endif
|
||||
|
||||
TEST_DECL(test_mldsa_verify_hash),
|
||||
TEST_DECL(test_dilithium_hash),
|
||||
/* This test needs to stay at the end to clean up any caches allocated. */
|
||||
TEST_DECL(test_wolfSSL_Cleanup)
|
||||
};
|
||||
|
||||
@@ -1113,10 +1113,12 @@ curve25519_key* wc_curve25519_new(void* heap, int devId, int *result_code)
|
||||
}
|
||||
|
||||
int wc_curve25519_delete(curve25519_key* key, curve25519_key** key_p) {
|
||||
void* heap;
|
||||
if (key == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
heap = key->heap;
|
||||
wc_curve25519_free(key);
|
||||
XFREE(key, key->heap, DYNAMIC_TYPE_CURVE25519);
|
||||
XFREE(key, heap, DYNAMIC_TYPE_CURVE25519);
|
||||
if (key_p != NULL)
|
||||
*key_p = NULL;
|
||||
return 0;
|
||||
|
||||
@@ -503,6 +503,9 @@ static int dilithium_hash256(wc_Shake* shake256, const byte* data1,
|
||||
word64* state = shake256->s;
|
||||
word8 *state8 = (word8*)state;
|
||||
|
||||
if (data2Len > (UINT32_MAX - data1Len)) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
if (data1Len + data2Len >= WC_SHA3_256_COUNT * 8) {
|
||||
XMEMCPY(state8, data1, data1Len);
|
||||
XMEMCPY(state8 + data1Len, data2, WC_SHA3_256_COUNT * 8 - data1Len);
|
||||
@@ -10554,6 +10557,10 @@ int wc_dilithium_verify_ctx_msg(const byte* sig, word32 sigLen, const byte* ctx,
|
||||
if ((ret == 0) && (ctx == NULL) && (ctxLen > 0)) {
|
||||
ret = BAD_FUNC_ARG;
|
||||
}
|
||||
/* Reject msgLen that would cause integer overflow in hash computations */
|
||||
if ((ret == 0) && (msgLen > UINT32_MAX / 2)) {
|
||||
ret = BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
#ifdef WOLF_CRYPTO_CB
|
||||
if (ret == 0) {
|
||||
@@ -10737,10 +10744,12 @@ dilithium_key* wc_dilithium_new(void* heap, int devId)
|
||||
|
||||
int wc_dilithium_delete(dilithium_key* key, dilithium_key** key_p)
|
||||
{
|
||||
void* heap;
|
||||
if (key == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
heap = key->heap;
|
||||
wc_dilithium_free(key);
|
||||
XFREE(key, key->heap, DYNAMIC_TYPE_DILITHIUM);
|
||||
XFREE(key, heap, DYNAMIC_TYPE_DILITHIUM);
|
||||
if (key_p != NULL)
|
||||
*key_p = NULL;
|
||||
|
||||
|
||||
@@ -1047,10 +1047,12 @@ ed25519_key* wc_ed25519_new(void* heap, int devId, int *result_code)
|
||||
}
|
||||
|
||||
int wc_ed25519_delete(ed25519_key* key, ed25519_key** key_p) {
|
||||
void* heap;
|
||||
if (key == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
heap = key->heap;
|
||||
wc_ed25519_free(key);
|
||||
XFREE(key, key->heap, DYNAMIC_TYPE_ED25519);
|
||||
XFREE(key, heap, DYNAMIC_TYPE_ED25519);
|
||||
if (key_p != NULL)
|
||||
*key_p = NULL;
|
||||
return 0;
|
||||
|
||||
+5
-4
@@ -318,6 +318,7 @@ int wolfSSL_EVP_PKEY_is_a(const WOLFSSL_EVP_PKEY *pkey, const char *name) {
|
||||
|
||||
#define WOLFSSL_EVP_PKEY_PRINT_LINE_WIDTH_MAX 80
|
||||
#define WOLFSSL_EVP_PKEY_PRINT_DIGITS_PER_LINE 15
|
||||
#define WOLFSSL_EVP_EXPONENT_PRINT_MAX 24
|
||||
|
||||
static unsigned int cipherType(const WOLFSSL_EVP_CIPHER *cipher);
|
||||
|
||||
@@ -11877,7 +11878,7 @@ static int PrintHexWithColon(WOLFSSL_BIO* out, const byte* input,
|
||||
static int PrintPubKeyRSA(WOLFSSL_BIO* out, const byte* pkey, int pkeySz,
|
||||
int indent, int bitlen, WOLFSSL_ASN1_PCTX* pctx)
|
||||
{
|
||||
byte buff[8] = { 0 };
|
||||
byte buff[WOLFSSL_EVP_EXPONENT_PRINT_MAX] = { 0 };
|
||||
int res = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
|
||||
word32 inOutIdx = 0;
|
||||
word32 nSz; /* size of modulus */
|
||||
@@ -12021,7 +12022,7 @@ static int PrintPubKeyEC(WOLFSSL_BIO* out, const byte* pkey, int pkeySz,
|
||||
{
|
||||
byte* pub = NULL;
|
||||
word32 pubSz = 0;
|
||||
byte buff[8] = { 0 };
|
||||
byte buff[WOLFSSL_EVP_EXPONENT_PRINT_MAX] = { 0 };
|
||||
int res = WOLFSSL_SUCCESS;
|
||||
word32 inOutIdx = 0;
|
||||
int curveId = 0;
|
||||
@@ -12210,7 +12211,7 @@ static int PrintPubKeyDSA(WOLFSSL_BIO* out, const byte* pkey, int pkeySz,
|
||||
int indent, int bitlen, WOLFSSL_ASN1_PCTX* pctx)
|
||||
{
|
||||
|
||||
byte buff[8] = { 0 };
|
||||
byte buff[WOLFSSL_EVP_EXPONENT_PRINT_MAX] = { 0 };
|
||||
int length;
|
||||
int res = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
|
||||
word32 inOutIdx = 0;
|
||||
@@ -12417,7 +12418,7 @@ static int PrintPubKeyDH(WOLFSSL_BIO* out, const byte* pkey, int pkeySz,
|
||||
int indent, int bitlen, WOLFSSL_ASN1_PCTX* pctx)
|
||||
{
|
||||
|
||||
byte buff[8] = { 0 };
|
||||
byte buff[WOLFSSL_EVP_EXPONENT_PRINT_MAX] = { 0 };
|
||||
int res = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
|
||||
word32 length;
|
||||
word32 inOutIdx;
|
||||
|
||||
+32
-5
@@ -12759,7 +12759,9 @@ int wc_PKCS7_DecodeEnvelopedData(wc_PKCS7* pkcs7, byte* in,
|
||||
byte* encryptedContent = NULL;
|
||||
int explicitOctet = 0;
|
||||
word32 localIdx = 0;
|
||||
byte tag = 0;
|
||||
byte tag = 0;
|
||||
byte padCheck = 0;
|
||||
int padIndex;
|
||||
|
||||
if (pkcs7 == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
@@ -13261,8 +13263,19 @@ int wc_PKCS7_DecodeEnvelopedData(wc_PKCS7* pkcs7, byte* in,
|
||||
|
||||
padLen = encryptedContent[encryptedContentSz-1];
|
||||
|
||||
/* copy plaintext to output */
|
||||
if (padLen > encryptedContentSz) {
|
||||
/* Constant-time padding check */
|
||||
padCheck |= ctMaskEq(padLen, 0);
|
||||
padCheck |= ctMaskGT(padLen, expBlockSz);
|
||||
padCheck |= ctMaskGT(padLen, encryptedContentSz);
|
||||
padCheck |= ctMaskGT(expBlockSz, encryptedContentSz);
|
||||
for (padIndex = encryptedContentSz < expBlockSz ? 0 :
|
||||
encryptedContentSz - expBlockSz;
|
||||
padIndex < encryptedContentSz; padIndex++) {
|
||||
byte inPad = ctMaskGTE(padIndex,
|
||||
encryptedContentSz - (int)padLen);
|
||||
padCheck |= inPad & (encryptedContent[padIndex] ^ padLen);
|
||||
}
|
||||
if (padCheck != 0) {
|
||||
ret = BUFFER_E;
|
||||
break;
|
||||
}
|
||||
@@ -15038,6 +15051,8 @@ int wc_PKCS7_DecodeEncryptedData(wc_PKCS7* pkcs7, byte* in, word32 inSz,
|
||||
byte* pkiMsg = in;
|
||||
word32 pkiMsgSz = inSz;
|
||||
byte tag = 0;
|
||||
byte padCheck = 0;
|
||||
int padIndex;
|
||||
|
||||
if (pkcs7 == NULL ||
|
||||
((pkcs7->encryptionKey == NULL || pkcs7->encryptionKeySz == 0) &&
|
||||
@@ -15315,8 +15330,20 @@ int wc_PKCS7_DecodeEncryptedData(wc_PKCS7* pkcs7, byte* in, word32 inSz,
|
||||
if (ret == 0) {
|
||||
padLen = encryptedContent[encryptedContentSz-1];
|
||||
|
||||
if (padLen > encryptedContentSz) {
|
||||
WOLFSSL_MSG("Bad padding size found");
|
||||
/* Constant-time padding check */
|
||||
padCheck |= ctMaskEq(padLen, 0);
|
||||
padCheck |= ctMaskGT(padLen, expBlockSz);
|
||||
padCheck |= ctMaskGT(padLen, encryptedContentSz);
|
||||
padCheck |= ctMaskGT(expBlockSz, encryptedContentSz);
|
||||
for (padIndex = encryptedContentSz < expBlockSz ? 0 :
|
||||
encryptedContentSz - expBlockSz;
|
||||
padIndex < encryptedContentSz; padIndex++) {
|
||||
byte inPad = ctMaskGTE(padIndex,
|
||||
encryptedContentSz - (int)padLen);
|
||||
padCheck |= inPad & (encryptedContent[padIndex] ^ padLen);
|
||||
}
|
||||
if (padCheck != 0) {
|
||||
WOLFSSL_MSG("Bad padding bytes found");
|
||||
ret = BUFFER_E;
|
||||
XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7);
|
||||
break;
|
||||
|
||||
@@ -2423,7 +2423,6 @@ enum Max_ASN {
|
||||
|
||||
#endif /* WOLFSSL_CERT_GEN */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user