Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
e5214e0
F-4941 - Reject PBKDF2 iteration count above INT_MAX
aidangarske Jul 10, 2026
e3bc98a
F-6670 - Encode both bytes of RSA-PSS salt length >= 256
aidangarske Jul 10, 2026
d163760
F-5922 - Commit ECDSA digest type only after validation
aidangarske Jul 10, 2026
f2e2c2d
F-5184 - Reject ECC private scalar outside [1, n-1] on import
aidangarske Jul 10, 2026
ef42fc0
F-5185 - Validate explicit DH domain parameters in param check
aidangarske Jul 10, 2026
350082a
F-6682 - Zeroize HMAC context on free
aidangarske Jul 10, 2026
84d51c8
F-5544 - Zeroize PBKDF1 key in PEM encrypt fallback
aidangarske Jul 10, 2026
3cbb1d8
F-5923 - Reset CCM TLS AAD length like the GCM path
aidangarske Jul 10, 2026
27eda91
F-5924 - Clear TLS ETM output length on bad padding
aidangarske Jul 10, 2026
ba77631
F-4940 - Cap PEM password callback length to buffer size
aidangarske Jul 10, 2026
a65d3bf
F-4938 - Cap EPKI decode password length to buffer size
aidangarske Jul 10, 2026
5fb013f
F-4826 - Cap encrypt-key password length to buffer size
aidangarske Jul 10, 2026
f7358e5
F-4937 - Cap RSA PKCS8 decode password length to buffer size
aidangarske Jul 10, 2026
d144a3a
F-4384 - Guard AES key wrap lengths against word32 truncation
aidangarske Jul 10, 2026
7625364
F-4698 - Cap DER BIO read accumulator against word32 overflow
aidangarske Jul 10, 2026
91cdeae
F-5805 - Pass original dispatch table to OSSL_LIB_CTX_new_child
aidangarske Jul 10, 2026
b1ae85e
F-5866 - Re-init urandom mutex in forked child
aidangarske Jul 10, 2026
d9009e0
F-4289 - Reject zero-length X25519/X448 private key import
aidangarske Jul 10, 2026
cb74265
F-5913 - Bound ECC group name compare to param length
aidangarske Jul 10, 2026
6294f5d
F-5918 - Bound DH group name compare and fix utf8 copy guard
aidangarske Jul 10, 2026
e24e797
F-4699 - Reject truncated PEM before header detection
aidangarske Jul 10, 2026
4491ee7
F-5925 - Pass record base pointer to TLS CBC decrypt
aidangarske Jul 10, 2026
d58dab1
F-5198 - Guard DES3 TLS record length before padding strip
aidangarske Jul 10, 2026
779e3b1
F-4291 - Reject HMAC key set without a digest
aidangarske Jul 10, 2026
858a695
F-4292 - Report KDF exchange dup as unsupported instead of empty
aidangarske Jul 10, 2026
8ec8493
F-5921 - Validate PKCS12 KDF diversifier id range
aidangarske Jul 10, 2026
51ae87b
F-4824 - Guard legacy PKCS8 DER-to-PEM size against word32 overflow
aidangarske Jul 10, 2026
4f2fd55
Guard unit.h AES_BLOCK_SIZE fallback against wolfSSL enum clash
aidangarske Jul 10, 2026
fc67e33
F-5185 - Reject explicit DH generator equal to p-1
aidangarske Jul 10, 2026
d1f0dfe
F-5918 - Copy exact UTF8 parameter length to avoid out-of-bounds read
aidangarske Jul 10, 2026
34e6771
F-5198 - Strip DES3 TLS padding using record base pointer
aidangarske Jul 10, 2026
3d4e193
F-4698 - Fix DER BIO overflow guard on 32-bit size_t
aidangarske Jul 10, 2026
b0b7125
F-4941 - Reject PKCS12 KDF iteration count above INT_MAX
aidangarske Jul 10, 2026
1bc900e
F-5184 - Clarify ECC private scalar range-check comment
aidangarske Jul 10, 2026
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
2 changes: 2 additions & 0 deletions src/wp_aes_aead.c
Original file line number Diff line number Diff line change
Expand Up @@ -1789,6 +1789,7 @@ static int wp_aesccm_init(wp_AeadCtx* ctx, const unsigned char *key,
}
if (ok) {
ctx->enc = enc;
ctx->tlsAadLen = UNINITIALISED_SIZET;
ok = wp_aead_set_ctx_params(ctx, params);
}

Expand Down Expand Up @@ -1914,6 +1915,7 @@ static int wp_aesccm_tls_cipher(wp_AeadCtx* ctx, unsigned char* out,
}

*outLen = olen;
ctx->tlsAadLen = UNINITIALISED_SIZET;
WOLFPROV_LEAVE(WP_LOG_COMP_AES, __FILE__ ":" WOLFPROV_STRINGIZE(__LINE__), ok);
return ok;
}
Expand Down
11 changes: 8 additions & 3 deletions src/wp_aes_block.c
Original file line number Diff line number Diff line change
Expand Up @@ -589,16 +589,20 @@ static int wp_aes_block_tls_dec_record(wp_AesBlockCtx *ctx,
gd = d - 1;
}
ivRecLen -= gd & ((size_t)padV + 1);
*outLen = ivRecLen;
/* No MAC to extract */
ctx->tlsmac = NULL;
ctx->tlsmacAlloced = 0;
/* With ETM/no-MAC, bad padding is a real error (the MAC was
* already verified by the record layer, so there is no padding
* oracle concern). Matches OpenSSL ssl3_cbc_copy_mac returning
* 0 when good==0 and mac_size==0. */
if (gd == 0)
if (gd == 0) {
ok = 0;
*outLen = 0;
}
else {
*outLen = ivRecLen;
}
}
else if (ok) {
/* 64-byte aligned buffer for cache-line-aware MAC rotation */
Expand Down Expand Up @@ -743,6 +747,7 @@ static int wp_aes_block_update(wp_AesBlockCtx *ctx, unsigned char *out,
int ok = 1;
size_t oLen = 0;
size_t nextBlocks;
unsigned char *outStart = out;

WOLFPROV_ENTER(WP_LOG_COMP_AES, "wp_aes_block_update");

Expand Down Expand Up @@ -808,7 +813,7 @@ static int wp_aes_block_update(wp_AesBlockCtx *ctx, unsigned char *out,
*outLen = oLen;
}
if (ok && (ctx->tls_version > 0) && (!ctx->enc)) {
ok = wp_aes_block_tls_dec_record(ctx, out, oLen, outLen);
ok = wp_aes_block_tls_dec_record(ctx, outStart, oLen, outLen);
}

WOLFPROV_LEAVE(WP_LOG_COMP_AES, __FILE__ ":" WOLFPROV_STRINGIZE(__LINE__), ok);
Expand Down
4 changes: 4 additions & 0 deletions src/wp_aes_wrap.c
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,10 @@ static int wp_aes_wrap_update(wp_AesWrapCtx *ctx, unsigned char *out,
ok = 0;
}

if (ok && ((inLen > UINT32_MAX) || (outSize > UINT32_MAX))) {
ok = 0;
}

if (ok && (inLen == 0)) {
*outLen = 0;
}
Expand Down
15 changes: 12 additions & 3 deletions src/wp_dec_epki2pki.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,9 +118,15 @@ static int wp_DecryptPKCS8Key(byte* input, word32 sz, const char* password,
EncryptedInfo info;
int algoId;

pem = OPENSSL_malloc(sz * 2);
if (pem == NULL) {
ret = MEMORY_E;
/* sz * 2 must not overflow word32 before allocating and encoding. */
if (sz > (0xFFFFFFFFU / 2)) {
ret = BAD_FUNC_ARG;
}
if (ret == 0) {
pem = OPENSSL_malloc((size_t)sz * 2);
if (pem == NULL) {
ret = MEMORY_E;
}
}
if (ret == 0) {
ret = wc_DerToPem(input, sz, pem, sz * 2, PKCS8_ENC_PRIVATEKEY_TYPE);
Expand Down Expand Up @@ -232,6 +238,9 @@ static int wp_epki2pki_decode(wp_Epki2Pki* ctx, OSSL_CORE_BIO* coreBio,
pwCbArg))) {
done = 1;
}
if ((!done) && ok && (passwordLen > sizeof(password))) {
ok = 0;
}
if ((!done) && ok) {
#if LIBWOLFSSL_VERSION_HEX >= 0x05000000
rc = wc_DecryptPKCS8Key(data, len, password, (int)passwordLen);
Expand Down
23 changes: 18 additions & 5 deletions src/wp_dec_pem2der.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,9 @@ static int wp_pem_password_cb(char* passwd, int sz, int rw, void* userdata)
if (!osslCb->cb(passwd, sz, &len, NULL, osslCb->cbArg)) {
ret = -1;
}
else if (len > (size_t)sz) {
ret = -1;
}
else {
ret = (int)len;
}
Expand Down Expand Up @@ -157,13 +160,19 @@ static int wp_pem2der_convert(const char* data, word32 len, DerBuffer** pDer,
WOLFPROV_ENTER(WP_LOG_COMP_PK, "wp_pem2der_convert");

/* Skip '-----BEGIN <name>-----\n'. */
base64Data = data + 16 + nameLen + 1;
base64Len = len - (16 + nameLen + 1);
footer = XSTRSTR(base64Data, "-----END ");
if (footer == NULL) {
if (len <= (word32)(16 + nameLen + 1)) {
info->consumed = len;
ok = 0;
}
if (ok) {
base64Data = data + 16 + nameLen + 1;
base64Len = len - (16 + nameLen + 1);
footer = XSTRSTR(base64Data, "-----END ");
if (footer == NULL) {
info->consumed = len;
ok = 0;
}
}
if (ok) {
/* Include footer and '\n'. */
info->consumed = (long)(footer - data) + 14 + nameLen + 1;
Expand Down Expand Up @@ -230,7 +239,11 @@ static int wp_pem2der_decode_data(const unsigned char* data, word32 len,

/* Identify the type of object by looking at the header. */
/* TODO: support more PEM headers. */
if (XMEMCMP(data, "-----BEGIN CERTIFICATE-----", 27) == 0) {
/* Header detection reads fixed-length prefixes; reject short input. */
if (len < 41) {
ok = 0;
}
else if (XMEMCMP(data, "-----BEGIN CERTIFICATE-----", 27) == 0) {
type = CERT_TYPE;
obj = OSSL_OBJECT_CERT;
}
Expand Down
9 changes: 7 additions & 2 deletions src/wp_des.c
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,7 @@ static int wp_des3_block_update(wp_Des3BlockCtx *ctx, unsigned char *out,
int ok = 1;
size_t oLen = 0;
size_t nextBlocks;
unsigned char *outStart = out;

WOLFPROV_ENTER(WP_LOG_COMP_DES, "wp_des3_block_update");

Expand Down Expand Up @@ -489,15 +490,19 @@ static int wp_des3_block_update(wp_Des3BlockCtx *ctx, unsigned char *out,
}
*outLen = oLen;
}
if (ok && (ctx->tls_version > 0) && (!ctx->enc) &&
(oLen < (size_t)(2 * DES_BLOCK_SIZE))) {
ok = 0;
}
if (ok && (ctx->tls_version > 0) && (!ctx->enc)) {
unsigned char pad = out[oLen-1];
unsigned char pad = outStart[oLen-1];
int padStart = DES_BLOCK_SIZE - pad - 1;
unsigned char invalid = (pad < DES_BLOCK_SIZE) - 1;
int i;

for (i = DES_BLOCK_SIZE - 1; i >= 0; i--) {
byte check = wp_ct_int_mask_gte(i, padStart);
check &= wp_ct_byte_mask_ne(out[oLen - DES_BLOCK_SIZE + i], pad);
check &= wp_ct_byte_mask_ne(outStart[oLen - DES_BLOCK_SIZE + i], pad);
invalid |= check;
}
*outLen = oLen - pad - 1 - DES_BLOCK_SIZE;
Expand Down
45 changes: 41 additions & 4 deletions src/wp_dh_kmgmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -1026,7 +1026,34 @@ static int wp_dh_validate(const wp_Dh* dh, int selection, int checkType)

if (((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) &&
(dh->id == 0)) {
/* TODO: check explicit parameters. */
int isPrime = 0;
int pm1Init = 0;
mp_int* p = (mp_int*)&dh->key.p;
mp_int* g = (mp_int*)&dh->key.g;
mp_int pm1;

/* Explicit domain parameters: p must be prime and g in [2, p-1). */
if (mp_init(&pm1) != 0) {
ok = 0;
}
else {
pm1Init = 1;
}
if (ok) {
rc = mp_prime_is_prime(p, 8, &isPrime);
if ((rc != 0) || (!isPrime)) {
ok = 0;
}
}
if (ok && (mp_sub_d(p, 1, &pm1) != 0)) {
ok = 0;
}
if (ok && ((mp_cmp_d(g, 2) == MP_LT) || (mp_cmp(g, &pm1) != MP_LT))) {
ok = 0;
}
if (pm1Init) {
mp_clear(&pm1);
}
}
if (ok && ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0)) {
#if LIBWOLFSSL_VERSION_HEX >= 0x05000000
Expand Down Expand Up @@ -1071,13 +1098,23 @@ static int wp_dh_import_group(wp_Dh* dh, const OSSL_PARAM params[])
int ok = 1;
const OSSL_PARAM* p;
const char* name = NULL;
char nameBuf[WP_MAX_DH_GROUP_NAME_SZ];

WOLFPROV_ENTER(WP_LOG_COMP_DH, "wp_dh_import_group");

/* Look for the group name first. */
if (!wp_params_get_utf8_string_ptr(params, OSSL_PKEY_PARAM_GROUP_NAME,
&name)) {
ok = 0;
p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_GROUP_NAME);
if (p != NULL) {
/* p->data may not be NUL-terminated; copy into a bounded buffer. */
if ((p->data_type != OSSL_PARAM_UTF8_STRING) || (p->data == NULL) ||
(p->data_size >= sizeof(nameBuf))) {
ok = 0;
}
else {
XMEMCPY(nameBuf, p->data, p->data_size);
nameBuf[p->data_size] = '\0';
name = nameBuf;
}
}
/* When name was found, set the parameters based on the mapping. */
if (ok && (name != NULL) && (!wp_dh_map_group_name(dh, name))) {
Expand Down
30 changes: 28 additions & 2 deletions src/wp_ecc_kmgmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -1101,12 +1101,18 @@ static int wp_ecc_import_group(wp_Ecc* ecc, const OSSL_PARAM params[])
p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_GROUP_NAME);
if (p != NULL) {
const char* name = NULL;
char nameBuf[WP_MAX_EC_GROUP_NAME_SZ];

if (p->data_type == OSSL_PARAM_UTF8_STRING) {
name = (const char*)p->data;
if (name == NULL) {
/* p->data may not be NUL-terminated; copy into a bounded buffer. */
if ((p->data == NULL) || (p->data_size >= sizeof(nameBuf))) {
ok = 0;
}
else {
XMEMCPY(nameBuf, p->data, p->data_size);
nameBuf[p->data_size] = '\0';
name = nameBuf;
}
}
else if (p->data_type == OSSL_PARAM_UTF8_PTR) {
if (!OSSL_PARAM_get_utf8_ptr(p, &name)) {
Expand Down Expand Up @@ -1150,6 +1156,26 @@ static int wp_ecc_import_keypair(wp_Ecc* ecc, const OSSL_PARAM params[],
NULL))) {
ok = 0;
}
if (ok && priv) {
int idx = wc_ecc_get_curve_idx(ecc->curveId);
const ecc_set_type* dp = (idx >= 0) ? wc_ecc_get_curve_params(idx) :
NULL;
mp_int order;
#if (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5,3)) && LIBWOLFSSL_VERSION_HEX >= 0x05006002
mp_int* d = wc_ecc_key_get_priv(&ecc->key);
#else
mp_int* d = &(ecc->key.k);
#endif

/* Reject a private scalar >= group order n (FIPS 186-4); d == 0 is caught by the private-key gate below. */
if ((dp != NULL) && (mp_init(&order) == MP_OKAY)) {
if ((mp_read_radix(&order, dp->order, 16) == MP_OKAY) &&
(mp_cmp(d, &order) != MP_LT)) {
ok = 0;
}
mp_clear(&order);
}
}
if (ok &&
#if (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5,3)) && LIBWOLFSSL_VERSION_HEX >= 0x05006002
(!mp_iszero(wc_ecc_key_get_priv(&ecc->key)))
Expand Down
33 changes: 12 additions & 21 deletions src/wp_ecdsa_sig.c
Original file line number Diff line number Diff line change
Expand Up @@ -487,42 +487,33 @@ static int wp_ecdsa_setup_md(wp_EcdsaSigCtx *ctx, const char *mdName,

if (mdName != NULL) {
int rc;
enum wc_HashType hashType;

#if LIBWOLFSSL_VERSION_HEX >= 0x05007004
ctx->hash.type = wp_name_to_wc_hash_type(ctx->libCtx, mdName, mdProps);
if ((ctx->hash.type == WC_HASH_TYPE_NONE) ||
(ctx->hash.type == WC_HASH_TYPE_MD5))
#else
ctx->hashType = wp_name_to_wc_hash_type(ctx->libCtx, mdName, mdProps);
if ((ctx->hashType == WC_HASH_TYPE_NONE) ||
(ctx->hashType == WC_HASH_TYPE_MD5))
#endif
{
hashType = wp_name_to_wc_hash_type(ctx->libCtx, mdName, mdProps);
if ((hashType == WC_HASH_TYPE_NONE) ||
(hashType == WC_HASH_TYPE_MD5)) {
ok = 0;
}
#ifdef HAVE_FIPS
#if LIBWOLFSSL_VERSION_HEX >= 0x05007004
if ((ctx->hash.type == WC_HASH_TYPE_SHA) && (op == EVP_PKEY_OP_SIGN))
#else
if ((ctx->hashType == WC_HASH_TYPE_SHA) && (op == EVP_PKEY_OP_SIGN))
#endif
{
if (ok && (hashType == WC_HASH_TYPE_SHA) &&
(op == EVP_PKEY_OP_SIGN)) {
ok = 0;
}
#endif

if (ok) {
#if LIBWOLFSSL_VERSION_HEX >= 0x05007004
rc = wc_HashInit_ex(&ctx->hash, ctx->hash.type, NULL, INVALID_DEVID);
#else
rc = wc_HashInit_ex(&ctx->hash, ctx->hashType, NULL, INVALID_DEVID);
#endif
rc = wc_HashInit_ex(&ctx->hash, hashType, NULL, INVALID_DEVID);
if (rc != 0) {
WOLFPROV_MSG_DEBUG_RETCODE(WP_LOG_LEVEL_DEBUG, "wc_HashInit_ex", rc);
ok = 0;
}
}
if (ok) {
#if LIBWOLFSSL_VERSION_HEX >= 0x05007004
ctx->hash.type = hashType;
#else
ctx->hashType = hashType;
#endif
OPENSSL_strlcpy(ctx->mdName, mdName, sizeof(ctx->mdName));
}
}
Expand Down
3 changes: 3 additions & 0 deletions src/wp_ecx_kmgmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -975,6 +975,9 @@ static int wp_ecx_import(wp_Ecx* ecx, int selection, const OSSL_PARAM params[])
&privData, &len)) {
ok = 0;
}
if (ok && (privData != NULL) && (len == 0)) {
ok = 0;
}
if (ok && (privData != NULL)) {
ecx->unclamped[0] = privData[0];
ecx->unclamped[1] = privData[len - 1];
Expand Down
19 changes: 14 additions & 5 deletions src/wp_hmac.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ static void wp_hmac_free(wp_HmacCtx* macCtx)
if (macCtx != NULL) {
wc_HmacFree(&macCtx->hmac);
OPENSSL_secure_clear_free(macCtx->key, macCtx->keyLen);
OPENSSL_free(macCtx);
OPENSSL_clear_free(macCtx, sizeof(*macCtx));
}
}

Expand All @@ -122,17 +122,26 @@ static int wp_hmac_set_key(wp_HmacCtx* macCtx, const unsigned char* key,
size_t keyLen, int restart)
{
int ok = 1;
word32 blockSize = wc_HashGetBlockSize(macCtx->type);
int blockSizeRet = wc_HashGetBlockSize(macCtx->type);
word32 blockSize = 0;

WOLFPROV_ENTER(WP_LOG_COMP_MAC, "wp_hmac_set_key");

WP_CHECK_FIPS_ALGO(WP_CAST_ALGO_HMAC);

if (macCtx->keyLen > 0) {
/* wc_HashGetBlockSize returns a negative error when no digest is set. */
if (blockSizeRet <= 0) {
ok = 0;
}
else {
blockSize = (word32)blockSizeRet;
}

if (ok && (macCtx->keyLen > 0)) {
OPENSSL_secure_clear_free(macCtx->key, macCtx->keyLen);
}

if (keyLen < blockSize) {
if (ok && (keyLen < blockSize)) {
/* wolfSSL FIPS needs a key that is at least block size in length with
* the unused parts zeroed out.
*/
Expand All @@ -145,7 +154,7 @@ static int wp_hmac_set_key(wp_HmacCtx* macCtx, const unsigned char* key,
ok = 0;
}
}
else {
else if (ok) {
macCtx->keyLen = keyLen;
macCtx->key = OPENSSL_secure_malloc(keyLen);
if (macCtx->key == NULL) {
Expand Down
Loading
Loading