Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
20d9e39
Guard NULL in KDF capacity getter
danielinux Mar 10, 2026
b04e6c3
Reject AES keys for ChaCha20-Poly1305
danielinux Mar 10, 2026
04f5550
Fix EdDSA length handling on 64-bit
danielinux Mar 10, 2026
e9b00d2
Fix LMS and XMSS output lengths on 64-bit
danielinux Mar 10, 2026
44005a6
Zeroize AEAD keys before free
danielinux Mar 10, 2026
8cf6e69
Zeroize KDF secret buffers before free
danielinux Mar 10, 2026
7d6b0ac
Guard AEAD buffer growth overflow
danielinux Mar 10, 2026
3f80c28
Guard KDF buffer growth overflow
danielinux Mar 10, 2026
8070a3a
Free volatile key data on export rejection
danielinux Mar 10, 2026
003627c
Fix PQ key-type switch fallthrough
danielinux Mar 10, 2026
b964bd9
Fix RSA-PSS MGF and verify handling
danielinux Mar 10, 2026
8e947b8
Use constant-time compare for MAC verify
danielinux Mar 10, 2026
a826de8
Use constant-time compare for KDF verify
danielinux Mar 10, 2026
d500173
Use constant-time compare for RSA verify
danielinux Mar 10, 2026
b720999
Use constant-time compare for hash verify
danielinux Mar 10, 2026
ba7aea9
Use Dilithium export APIs for ML-DSA keys
danielinux Mar 10, 2026
4207379
Delay ML-DSA length outputs until both exports succeed
danielinux Mar 11, 2026
efd18ed
Zero old KDF buffers during reallocation
danielinux Mar 11, 2026
a6e0e55
Zero old AEAD buffers during reallocation
danielinux Mar 11, 2026
54d4600
Clarify Ed25519 length regression coverage
danielinux Mar 11, 2026
aceefeb
Fix ChaCha20/AES regression test intent
danielinux Mar 11, 2026
b818ba1
Report skipped PSA API tests and fix ChaCha regression check
danielinux Mar 11, 2026
32679bf
Provide misc helpers for NO_INLINE builds
danielinux Mar 11, 2026
a30c739
Harden KDF verify temp buffer handling
danielinux Mar 11, 2026
5be1b00
Validate append buffer pointers before dereference
danielinux Mar 11, 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
15 changes: 15 additions & 0 deletions src/misc_impl.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/* misc_impl.c
*
* Provide misc.c helper implementations for NO_INLINE builds.
*/

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <wolfssl/wolfcrypt/settings.h>

#if defined(WOLFSSL_PSA_ENGINE) && defined(NO_INLINE)
#define WOLFSSL_MISC_INCLUDED
#include <wolfcrypt/src/misc.c>
#endif
11 changes: 9 additions & 2 deletions src/psa_aead.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,18 @@ static psa_status_t wolfpsa_aead_append(uint8_t **buf, size_t *len,
{
uint8_t *new_buf;

if (buf == NULL || len == NULL) {
return PSA_ERROR_INVALID_ARGUMENT;
}
if (data == NULL && data_length > 0) {
return PSA_ERROR_INVALID_ARGUMENT;
}
if (data_length == 0) {
return PSA_SUCCESS;
}
if (*len > SIZE_MAX - data_length) {
return PSA_ERROR_INSUFFICIENT_MEMORY;
}

new_buf = (uint8_t *)XMALLOC(*len + data_length, NULL,
DYNAMIC_TYPE_TMP_BUFFER);
Expand All @@ -81,6 +87,7 @@ static psa_status_t wolfpsa_aead_append(uint8_t **buf, size_t *len,

if (*buf != NULL) {
XMEMCPY(new_buf, *buf, *len);
wc_ForceZero(*buf, *len);
XFREE(*buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
}

Expand Down Expand Up @@ -124,8 +131,7 @@ static psa_status_t wolfpsa_aead_check_key(psa_key_id_t key,
}
}
else if (PSA_ALG_AEAD_EQUAL(alg, PSA_ALG_CHACHA20_POLY1305)) {
if (attributes->type != PSA_KEY_TYPE_CHACHA20 &&
attributes->type != PSA_KEY_TYPE_AES) {
if (attributes->type != PSA_KEY_TYPE_CHACHA20) {
wolfpsa_free_key_data(*key_data);
*key_data = NULL;
*key_data_length = 0;
Expand Down Expand Up @@ -859,6 +865,7 @@ psa_status_t psa_aead_abort(psa_aead_operation_t *operation)
XFREE(ctx->input, NULL, DYNAMIC_TYPE_TMP_BUFFER);
}
if (ctx->key != NULL) {
wc_ForceZero(ctx->key, ctx->key_length);
XFREE(ctx->key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
}
XFREE(ctx, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Expand Down
50 changes: 40 additions & 10 deletions src/psa_ed25519_ed448.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ psa_status_t psa_asymmetric_sign_ed25519(psa_key_type_t key_type,
{
int ret;
ed25519_key ed_key;
word32 sig_len32;

if (alg != PSA_ALG_ED25519 && alg != PSA_ALG_ED25519PH) {
return PSA_ERROR_NOT_SUPPORTED;
Expand All @@ -85,22 +86,25 @@ psa_status_t psa_asymmetric_sign_ed25519(psa_key_type_t key_type,
}

/* Sign message */
sig_len32 = (word32)signature_size;
if (alg == PSA_ALG_ED25519PH) {
/* Sign hash */
ret = wc_ed25519ph_sign_hash(hash, (word32)hash_length, signature,
(word32*)signature_length, &ed_key, NULL, 0);
&sig_len32, &ed_key, NULL, 0);
}
else if (alg == PSA_ALG_ED25519) {
/* Sign message */
ret = wc_ed25519_sign_msg(hash, (word32)hash_length, signature,
(word32*)signature_length, &ed_key);
&sig_len32, &ed_key);
}

wc_ed25519_free(&ed_key);

if (ret != 0) {
return wc_error_to_psa_status(ret);
}

*signature_length = (size_t)sig_len32;

return PSA_SUCCESS;
}
Expand Down Expand Up @@ -184,6 +188,8 @@ psa_status_t psa_asymmetric_generate_key_ed25519(psa_key_type_t key_type,
int ret;
ed25519_key ed_key;
WC_RNG rng;
word32 priv_len32;
word32 pub_len32;

/* Check if key type is ED25519 key pair */
if (key_type != PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_TWISTED_EDWARDS) ||
Expand Down Expand Up @@ -213,15 +219,17 @@ psa_status_t psa_asymmetric_generate_key_ed25519(psa_key_type_t key_type,
}

/* Export private key */
ret = wc_ed25519_export_private_only(&ed_key, private_key, (word32*)private_key_length);
priv_len32 = (word32)private_key_size;
ret = wc_ed25519_export_private_only(&ed_key, private_key, &priv_len32);
if (ret != 0) {
wc_FreeRng(&rng);
wc_ed25519_free(&ed_key);
return wc_error_to_psa_status(ret);
}

/* Export public key */
ret = wc_ed25519_export_public(&ed_key, public_key, (word32*)public_key_length);
pub_len32 = (word32)public_key_size;
ret = wc_ed25519_export_public(&ed_key, public_key, &pub_len32);
if (ret != 0) {
wc_FreeRng(&rng);
wc_ed25519_free(&ed_key);
Expand All @@ -230,6 +238,9 @@ psa_status_t psa_asymmetric_generate_key_ed25519(psa_key_type_t key_type,

wc_FreeRng(&rng);
wc_ed25519_free(&ed_key);

*private_key_length = (size_t)priv_len32;
*public_key_length = (size_t)pub_len32;

return PSA_SUCCESS;
}
Expand All @@ -245,6 +256,7 @@ psa_status_t psa_asymmetric_export_public_key_ed25519(psa_key_type_t key_type,
{
int ret;
ed25519_key ed_key;
word32 out_len32;

/* Check if key type is ED25519 */
if ((key_type != PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_TWISTED_EDWARDS) &&
Expand Down Expand Up @@ -274,13 +286,16 @@ psa_status_t psa_asymmetric_export_public_key_ed25519(psa_key_type_t key_type,
}

/* Export public key */
ret = wc_ed25519_export_public(&ed_key, output, (word32*)output_length);
out_len32 = (word32)output_size;
ret = wc_ed25519_export_public(&ed_key, output, &out_len32);

wc_ed25519_free(&ed_key);

if (ret != 0) {
return wc_error_to_psa_status(ret);
}

*output_length = (size_t)out_len32;

return PSA_SUCCESS;
}
Expand All @@ -301,6 +316,7 @@ psa_status_t psa_asymmetric_sign_ed448(psa_key_type_t key_type,
{
int ret;
ed448_key ed_key;
word32 sig_len32;

if (alg != PSA_ALG_ED448 && alg != PSA_ALG_ED448PH) {
return PSA_ERROR_NOT_SUPPORTED;
Expand All @@ -327,22 +343,25 @@ psa_status_t psa_asymmetric_sign_ed448(psa_key_type_t key_type,
}

/* Sign message */
sig_len32 = (word32)signature_size;
if (alg == PSA_ALG_ED448PH) {
/* Sign hash */
ret = wc_ed448ph_sign_hash(hash, (word32)hash_length, signature,
(word32*)signature_length, &ed_key, NULL, 0);
&sig_len32, &ed_key, NULL, 0);
}
else if (alg == PSA_ALG_ED448) {
/* Sign message */
ret = wc_ed448_sign_msg(hash, (word32)hash_length, signature,
(word32*)signature_length, &ed_key, NULL, 0);
&sig_len32, &ed_key, NULL, 0);
}

wc_ed448_free(&ed_key);

if (ret != 0) {
return wc_error_to_psa_status(ret);
}

*signature_length = (size_t)sig_len32;

return PSA_SUCCESS;
}
Expand Down Expand Up @@ -426,6 +445,8 @@ psa_status_t psa_asymmetric_generate_key_ed448(psa_key_type_t key_type,
int ret;
ed448_key ed_key;
WC_RNG rng;
word32 priv_len32;
word32 pub_len32;

/* Check if key type is ED448 key pair */
if (key_type != PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_TWISTED_EDWARDS) ||
Expand Down Expand Up @@ -455,15 +476,17 @@ psa_status_t psa_asymmetric_generate_key_ed448(psa_key_type_t key_type,
}

/* Export private key */
ret = wc_ed448_export_private_only(&ed_key, private_key, (word32*)private_key_length);
priv_len32 = (word32)private_key_size;
ret = wc_ed448_export_private_only(&ed_key, private_key, &priv_len32);
if (ret != 0) {
wc_FreeRng(&rng);
wc_ed448_free(&ed_key);
return wc_error_to_psa_status(ret);
}

/* Export public key */
ret = wc_ed448_export_public(&ed_key, public_key, (word32*)public_key_length);
pub_len32 = (word32)public_key_size;
ret = wc_ed448_export_public(&ed_key, public_key, &pub_len32);
if (ret != 0) {
wc_FreeRng(&rng);
wc_ed448_free(&ed_key);
Expand All @@ -472,6 +495,9 @@ psa_status_t psa_asymmetric_generate_key_ed448(psa_key_type_t key_type,

wc_FreeRng(&rng);
wc_ed448_free(&ed_key);

*private_key_length = (size_t)priv_len32;
*public_key_length = (size_t)pub_len32;

return PSA_SUCCESS;
}
Expand All @@ -487,6 +513,7 @@ psa_status_t psa_asymmetric_export_public_key_ed448(psa_key_type_t key_type,
{
int ret;
ed448_key ed_key;
word32 out_len32;

/* Check if key type is ED448 */
if ((key_type != PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_TWISTED_EDWARDS) &&
Expand Down Expand Up @@ -516,13 +543,16 @@ psa_status_t psa_asymmetric_export_public_key_ed448(psa_key_type_t key_type,
}

/* Export public key */
ret = wc_ed448_export_public(&ed_key, output, (word32*)output_length);
out_len32 = (word32)output_size;
ret = wc_ed448_export_public(&ed_key, output, &out_len32);

wc_ed448_free(&ed_key);

if (ret != 0) {
return wc_error_to_psa_status(ret);
}

*output_length = (size_t)out_len32;

return PSA_SUCCESS;
}
Expand Down
9 changes: 7 additions & 2 deletions src/psa_hash_engine.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@
#include <wolfssl/wolfcrypt/logging.h>
#include <wolfssl/wolfcrypt/error-crypt.h>
#include <wolfssl/wolfcrypt/mem_track.h>
#include <wolfssl/wolfcrypt/misc.h>
#ifndef NO_INLINE
#define WOLFSSL_MISC_INCLUDED
#include <wolfcrypt/src/misc.c>
#endif

#ifdef WOLFSSL_MD5
#include <wolfssl/wolfcrypt/md5.h>
Expand Down Expand Up @@ -642,7 +647,7 @@ psa_status_t psa_hash_verify(psa_hash_operation_t *operation,
return PSA_ERROR_INVALID_SIGNATURE;
}

if (XMEMCMP(computed_hash, hash, computed_hash_length) != 0) {
if (ConstantCompare(computed_hash, hash, (int)computed_hash_length) != 0) {
return PSA_ERROR_INVALID_SIGNATURE;
}

Expand Down Expand Up @@ -865,7 +870,7 @@ psa_status_t psa_hash_compare(psa_algorithm_t alg,
}

/* Compare the computed hash with the reference hash */
if (XMEMCMP(computed_hash, hash, computed_hash_length) != 0) {
if (ConstantCompare(computed_hash, hash, (int)computed_hash_length) != 0) {
return PSA_ERROR_INVALID_SIGNATURE;
}

Expand Down
27 changes: 25 additions & 2 deletions src/psa_key_derivation.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include <config.h>
#endif

#include <limits.h>
#include <wolfssl/wolfcrypt/settings.h>

#if defined(WOLFSSL_PSA_ENGINE)
Expand All @@ -36,6 +37,11 @@
#include <wolfssl/wolfcrypt/pwdbased.h>
#include <wolfssl/wolfcrypt/mem_track.h>
#include <wolfssl/wolfcrypt/cmac.h>
#include <wolfssl/wolfcrypt/misc.h>
#ifndef NO_INLINE
#define WOLFSSL_MISC_INCLUDED
#include <wolfcrypt/src/misc.c>
#endif

typedef struct wolfpsa_kdf_ctx {
psa_algorithm_t alg;
Expand Down Expand Up @@ -82,6 +88,7 @@ static wolfpsa_kdf_ctx_t* wolfpsa_kdf_get_ctx(psa_key_derivation_operation_t *op
static void wolfpsa_kdf_free_buf(uint8_t **buf, size_t *len)
{
if (buf != NULL && *buf != NULL) {
wc_ForceZero(*buf, len != NULL ? *len : 0);
XFREE(*buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
*buf = NULL;
}
Expand All @@ -95,13 +102,19 @@ static psa_status_t wolfpsa_kdf_append(uint8_t **buf, size_t *len,
{
uint8_t *new_buf;

if (buf == NULL || len == NULL) {
return PSA_ERROR_INVALID_ARGUMENT;
}
if (data == NULL && data_length > 0) {
return PSA_ERROR_INVALID_ARGUMENT;
}

if (data_length == 0) {
return PSA_SUCCESS;
}
if (*len > SIZE_MAX - data_length) {
return PSA_ERROR_INSUFFICIENT_MEMORY;
}

new_buf = (uint8_t *)XMALLOC(*len + data_length, NULL,
DYNAMIC_TYPE_TMP_BUFFER);
Expand All @@ -111,6 +124,7 @@ static psa_status_t wolfpsa_kdf_append(uint8_t **buf, size_t *len,

if (*buf != NULL) {
XMEMCPY(new_buf, *buf, *len);
wc_ForceZero(*buf, *len);
XFREE(*buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
}

Expand Down Expand Up @@ -440,12 +454,13 @@ psa_status_t psa_key_derivation_set_capacity(psa_key_derivation_operation_t *ope
psa_status_t psa_key_derivation_get_capacity(const psa_key_derivation_operation_t *operation,
size_t *capacity)
{
const wolfpsa_kdf_ctx_t *ctx = (const wolfpsa_kdf_ctx_t *)(uintptr_t)operation->opaque;
const wolfpsa_kdf_ctx_t *ctx;

if (operation == NULL || capacity == NULL) {
return PSA_ERROR_INVALID_ARGUMENT;
}

ctx = (const wolfpsa_kdf_ctx_t *)(uintptr_t)operation->opaque;
if (ctx == NULL) {
return PSA_ERROR_BAD_STATE;
}
Expand Down Expand Up @@ -1094,17 +1109,25 @@ psa_status_t psa_key_derivation_verify_bytes(psa_key_derivation_operation_t *ope

status = psa_key_derivation_output_bytes(operation, buffer, expected_length);
if (status != PSA_SUCCESS) {
wc_ForceZero(buffer, expected_length);
XFREE(buffer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
return status;
}

if (XMEMCMP(buffer, expected, expected_length) != 0) {
if (expected_length > INT_MAX) {
wc_ForceZero(buffer, expected_length);
XFREE(buffer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
return PSA_ERROR_INVALID_ARGUMENT;
}

if (ConstantCompare(buffer, expected, (int)expected_length) != 0) {
status = PSA_ERROR_INVALID_SIGNATURE;
}
else {
status = PSA_SUCCESS;
}

wc_ForceZero(buffer, expected_length);
XFREE(buffer, NULL, DYNAMIC_TYPE_TMP_BUFFER);
return status;
}
Expand Down
Loading
Loading