diff --git a/tests/api/test_dsa.c b/tests/api/test_dsa.c index b645a57f45..cc56d78a03 100644 --- a/tests/api/test_dsa.c +++ b/tests/api/test_dsa.c @@ -426,9 +426,11 @@ int test_wc_DsaImportParamsRawCheck(void) /* null param pointers */ ExpectIntEQ(wc_DsaImportParamsRawCheck(&key, NULL, NULL, NULL, trusted, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG)); - /* illegal p length */ + /* illegal p length: the checked path now preserves the specific + * primality failure from p validation instead of overwriting it with + * BAD_FUNC_ARG during the later (L,N) size check. */ ExpectIntEQ(wc_DsaImportParamsRawCheck(&key, invalidP, q, g, trusted, NULL), - WC_NO_ERR_TRACE(BAD_FUNC_ARG)); + WC_NO_ERR_TRACE(DH_CHECK_PUB_E)); /* illegal q length */ ExpectIntEQ(wc_DsaImportParamsRawCheck(&key, p, invalidQ, g, trusted, NULL), WC_NO_ERR_TRACE(BAD_FUNC_ARG)); @@ -731,4 +733,3 @@ int test_wc_DsaCheckPubKey(void) #endif return EXPECT_RESULT(); } /* END test_wc_DsaCheckPubKey */ - diff --git a/wolfcrypt/src/curve25519.c b/wolfcrypt/src/curve25519.c index 12efe361f9..8e7afec540 100644 --- a/wolfcrypt/src/curve25519.c +++ b/wolfcrypt/src/curve25519.c @@ -977,7 +977,7 @@ int wc_curve25519_check_public(const byte* pub, word32 pubSz, int endian) /* Check for order-1 or higher. */ if (pub[0] == 0x7f) { for (i = 1; i < CURVE25519_KEYSIZE - 1; i++) { - if (pub[i] != 0) + if (pub[i] != 0xff) break; } if (i == CURVE25519_KEYSIZE - 1 && (pub[i] >= 0xec)) diff --git a/wolfcrypt/src/dh.c b/wolfcrypt/src/dh.c index 7da2173ac0..5a6daa9853 100644 --- a/wolfcrypt/src/dh.c +++ b/wolfcrypt/src/dh.c @@ -1013,6 +1013,13 @@ int wc_FreeDhKey(DhKey* key) #ifdef WOLFSSL_KCAPI_DH KcapiDh_Free(key); #endif + #ifdef WOLFSSL_CHECK_MEM_ZERO + /* Deregister any mem-zero entries covering this key (e.g. key->priv + * registered by wc_DhImportKeyPair) now that its fields are zeroed. + * Mirrors wc_FreeRsaKey(); mp_forcezero() alone does not remove the + * registration, so without this the entry leaks into later checks. */ + wc_MemZero_Check(key, sizeof(*key)); + #endif } return 0; } diff --git a/wolfcrypt/src/dsa.c b/wolfcrypt/src/dsa.c index 3ee03876fe..c9caf21306 100644 --- a/wolfcrypt/src/dsa.c +++ b/wolfcrypt/src/dsa.c @@ -546,13 +546,17 @@ static int _DsaImportParamsRaw(DsaKey* dsa, const char* p, const char* q, if (err == MP_OKAY) err = mp_read_radix(&dsa->g, g, MP_RADIX_HEX); - /* verify (L,N) pair bit lengths */ - pSz = mp_unsigned_bin_size(&dsa->p); - qSz = mp_unsigned_bin_size(&dsa->q); + /* verify (L,N) pair bit lengths - only when the reads above succeeded, so + * a more specific earlier error (e.g. DH_CHECK_PUB_E from the primality + * check) is not overwritten and qSz is not read from an unset q. */ + if (err == MP_OKAY) { + pSz = mp_unsigned_bin_size(&dsa->p); + qSz = mp_unsigned_bin_size(&dsa->q); - if (CheckDsaLN(pSz * WOLFSSL_BIT_SIZE, qSz * WOLFSSL_BIT_SIZE) != 0) { - WOLFSSL_MSG("Invalid DSA p or q parameter size"); - err = BAD_FUNC_ARG; + if (CheckDsaLN(pSz * WOLFSSL_BIT_SIZE, qSz * WOLFSSL_BIT_SIZE) != 0) { + WOLFSSL_MSG("Invalid DSA p or q parameter size"); + err = BAD_FUNC_ARG; + } } if (err != MP_OKAY) { diff --git a/wolfcrypt/src/random.c b/wolfcrypt/src/random.c index 5ca8ce20a1..daa7daef0c 100644 --- a/wolfcrypt/src/random.c +++ b/wolfcrypt/src/random.c @@ -2234,7 +2234,7 @@ int wc_InitRngNonce_ex(WC_RNG* rng, byte* nonce, word32 nonceSz, return _InitRng(rng, nonce, nonceSz, heap, devId); } -#ifdef HAVE_HASHDRBG +#if defined(HAVE_HASHDRBG) && !defined(CUSTOM_RAND_GENERATE_BLOCK) static int PollAndReSeed(WC_RNG* rng) { int ret = DRBG_NEED_RESEED; @@ -5320,7 +5320,10 @@ int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz) { int ret = 0; - if (os == NULL) { + /* Validate output before any entropy backend dereferences it: some + * (e.g. glibc's vDSO getrandom()) fault on a NULL buffer rather than + * returning an error. Mirrors wc_RNG_GenerateBlock's NULL check. */ + if (os == NULL || output == NULL) { return BAD_FUNC_ARG; } diff --git a/wolfcrypt/src/rsa.c b/wolfcrypt/src/rsa.c index cd66eab2ef..80b33c2075 100644 --- a/wolfcrypt/src/rsa.c +++ b/wolfcrypt/src/rsa.c @@ -5402,6 +5402,23 @@ int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng) #endif /* !WOLFSSL_CRYPTOCELL && !WOLFSSL_SE050 */ int err; +#if !defined(WOLFSSL_CRYPTOCELL) && \ + (!defined(WOLFSSL_SE050) || defined(WOLFSSL_SE050_NO_RSA)) && \ + !defined(WOLF_CRYPTO_CB_ONLY_RSA) && \ + !defined(WOLFSSL_MICROCHIP_TA100) && \ + !defined(WOLFSSL_SMALL_STACK) && defined(WOLFSSL_CHECK_MEM_ZERO) + /* Zero the stack temporaries so the mp_memzero_check() in the 'out' + * cleanup is safe even when an early argument/size check leaves via + * 'goto out' before these are mp_init'd - an uninitialized mp_int's size + * field would otherwise make the check scan an arbitrary stack range. + * Done here, after all declarations, to satisfy C89. */ + XMEMSET(&p_buf, 0, sizeof(p_buf)); + XMEMSET(&q_buf, 0, sizeof(q_buf)); + XMEMSET(&tmp1_buf, 0, sizeof(tmp1_buf)); + XMEMSET(&tmp2_buf, 0, sizeof(tmp2_buf)); + XMEMSET(&tmp3_buf, 0, sizeof(tmp3_buf)); +#endif + if (key == NULL || rng == NULL) { err = BAD_FUNC_ARG; goto out; diff --git a/wolfssl/wolfcrypt/fe_operations.h b/wolfssl/wolfcrypt/fe_operations.h index 65d0e1c904..88c785f2c3 100644 --- a/wolfssl/wolfcrypt/fe_operations.h +++ b/wolfssl/wolfcrypt/fe_operations.h @@ -40,6 +40,20 @@ #define CURVED25519_ASM_64BIT #define CURVED25519_ASM #endif + +/* The small (reduced-C) curve25519/ed25519 code and the Intel x64 assembly + * both provide the same fe_, sc_ and curve25519 symbols, so selecting both + * (for example a user_settings.h that keeps CURVE25519_SMALL/ED25519_SMALL + * while USE_INTEL_SPEEDUP enables the x64 assembly) produces duplicate-symbol + * link errors that are hard to diagnose. Detect the incompatible combination + * at compile time with a clear message instead. To keep the small + * implementation define NO_CURVED25519_X64; to use the assembly drop + * CURVE25519_SMALL / ED25519_SMALL. */ +#if defined(CURVED25519_X64) && \ + (defined(CURVE25519_SMALL) || defined(ED25519_SMALL)) + #error "CURVE25519_SMALL/ED25519_SMALL are incompatible with the Intel x64 curve25519/ed25519 assembly (CURVED25519_X64); define NO_CURVED25519_X64 to keep the small implementation, or remove the SMALL settings to use the assembly" +#endif + #if defined(WOLFSSL_ARMASM) #ifdef __aarch64__ #define CURVED25519_ASM_64BIT @@ -112,6 +126,13 @@ WOLFSSL_LOCAL int curve25519_nb(byte * q, const byte * n, const byte * p, WOLFSSL_LOCAL void fe_init(void); WOLFSSL_LOCAL int curve25519(byte * q, const byte * n, const byte * p); +#if defined(CURVED25519_X64) || (defined(WOLFSSL_ARMASM) && defined(__aarch64__)) +/* Fixed-base scalar multiply provided by the x64/aarch64 assembly + * (fe_x25519_asm.S, armv8-curve25519); declared here as no other header + * prototypes it, which otherwise breaks a strict C (implicit-declaration) + * build of curve25519.c. */ +WOLFSSL_LOCAL int curve25519_base(byte * q, const byte * n); +#endif #ifdef WOLFSSL_CURVE25519_BLINDING WOLFSSL_LOCAL int curve25519_blind(byte* q, const byte* n, const byte* mask, const byte* p, const byte* rz);