diff --git a/doc/dox_comments/header_files/sha.h b/doc/dox_comments/header_files/sha.h index e6368fa4a48..5d9ae5269de 100644 --- a/doc/dox_comments/header_files/sha.h +++ b/doc/dox_comments/header_files/sha.h @@ -193,11 +193,15 @@ int wc_ShaFinalRaw(wc_Sha* sha, byte* hash); \param src Source SHA structure \param dst Destination SHA structure + (must be zeroed or previously initialized) _Example_ \code wc_Sha src, dst; - int ret = wc_ShaCopy(&src, &dst); + memset(&dst, 0, sizeof(dst)); + int ret = wc_InitSha(&src); + if (ret == 0) + ret = wc_ShaCopy(&src, &dst); \endcode \sa wc_InitSha diff --git a/doc/dox_comments/header_files/sha256.h b/doc/dox_comments/header_files/sha256.h index 3a94b797ba9..57f86be2dca 100644 --- a/doc/dox_comments/header_files/sha256.h +++ b/doc/dox_comments/header_files/sha256.h @@ -366,12 +366,16 @@ int wc_Sha256_Grow(wc_Sha256* sha256, const byte* in, int inSz); \return negative on error \param src Source SHA256 structure - \param dst Destination SHA256 structure + \param dst Destination SHA256 structure; + (must be zeroed or previously initialized) _Example_ \code wc_Sha256 src, dst; - int ret = wc_Sha256Copy(&src, &dst); + memset(&dst, 0, sizeof(dst)); + int ret = wc_InitSha256(&src); + if (ret == 0) + ret = wc_Sha256Copy(&src, &dst); \endcode \sa wc_InitSha256 @@ -534,11 +538,15 @@ int wc_Sha224GetHash(wc_Sha224* sha224, byte* hash); \param src Source SHA224 structure \param dst Destination SHA224 structure + (must be zeroed or previously initialized) _Example_ \code wc_Sha224 src, dst; - int ret = wc_Sha224Copy(&src, &dst); + memset(&dst, 0, sizeof(dst)); + int ret = wc_InitSha224(&src); + if (ret == 0) + ret = wc_Sha224Copy(&src, &dst); \endcode \sa wc_InitSha224 diff --git a/doc/dox_comments/header_files/sha3.h b/doc/dox_comments/header_files/sha3.h index 6389939f8ff..2707ee9aa10 100644 --- a/doc/dox_comments/header_files/sha3.h +++ b/doc/dox_comments/header_files/sha3.h @@ -162,11 +162,13 @@ int wc_Sha3_224_GetHash(wc_Sha3* sha3, byte* hash); \param sha3 pointer to the sha3 structure to copy \param dst pointer to the sha3 structure to copy into + (must be zeroed or previously initialized) _Example_ \code wc_Sha3 sha3[1]; wc_Sha3 sha3_dup[1]; + memset(sha3_dup, 0, sizeof(*sha3_dup)); if ((ret = wc_InitSha3_224(sha3, NULL, INVALID_DEVID)) != 0) { WOLFSSL_MSG("wc_InitSha3_224 failed"); } @@ -347,11 +349,13 @@ int wc_Sha3_256_GetHash(wc_Sha3* sha3, byte* hash); \param sha3 pointer to the sha3 structure to copy \param dst pointer to the sha3 structure to copy into + (must be zeroed or previously initialized) _Example_ \code wc_Sha3 sha3[1]; wc_Sha3 sha3_dup[1]; + memset(sha3_dup, 0, sizeof(*sha3_dup)); if ((ret = wc_InitSha3_256(sha3, NULL, INVALID_DEVID)) != 0) { WOLFSSL_MSG("wc_InitSha3_256 failed"); } @@ -532,11 +536,13 @@ int wc_Sha3_384_GetHash(wc_Sha3* sha3, byte* hash); \param sha3 pointer to the sha3 structure to copy \param dst pointer to the sha3 structure to copy into + (must be zeroed or previously initialized) _Example_ \code wc_Sha3 sha3[1]; wc_Sha3 sha3_dup[1]; + memset(sha3_dup, 0, sizeof(*sha3_dup)); if ((ret = wc_InitSha3_384(sha3, NULL, INVALID_DEVID)) != 0) { WOLFSSL_MSG("wc_InitSha3_384 failed"); } @@ -717,11 +723,13 @@ int wc_Sha3_512_GetHash(wc_Sha3* sha3, byte* hash); \param sha3 pointer to the sha3 structure to copy \param dst pointer to the sha3 structure to copy into + (must be zeroed or previously initialized) _Example_ \code wc_Sha3 sha3[1]; wc_Sha3 sha3_dup[1]; + memset(sha3_dup, 0, sizeof(*sha3_dup)); if ((ret = wc_InitSha3_512(sha3, NULL, INVALID_DEVID)) != 0) { WOLFSSL_MSG("wc_InitSha3_512 failed"); } @@ -972,11 +980,13 @@ int wc_Shake128_GetHash(wc_Shake* shake, byte* hash); \param shake pointer to the shake structure to copy \param dst pointer to the shake structure to copy into + (must be zeroed or previously initialized) _Example_ \code wc_Shake shake[1]; wc_Shake shake_dup[1]; + memset(shake_dup, 0, sizeof(*shake_dup)); if ((ret = wc_InitShake128(shake, NULL, INVALID_DEVID)) != 0) { WOLFSSL_MSG("wc_InitShake128 failed"); } @@ -1227,11 +1237,13 @@ int wc_Shake256_GetHash(wc_Shake* shake, byte* hash); \param shake pointer to the shake structure to copy \param dst pointer to the shake structure to copy into + (must be zeroed or previously initialized) _Example_ \code wc_Shake shake[1]; wc_Shake shake_dup[1]; + memset(shake_dup, 0, sizeof(*shake_dup)); if ((ret = wc_InitShake256(shake, NULL, INVALID_DEVID)) != 0) { WOLFSSL_MSG("wc_InitShake256 failed"); } diff --git a/doc/dox_comments/header_files/sha512.h b/doc/dox_comments/header_files/sha512.h index 0f9c129a479..84e43dbf66d 100644 --- a/doc/dox_comments/header_files/sha512.h +++ b/doc/dox_comments/header_files/sha512.h @@ -273,11 +273,15 @@ int wc_Sha512GetHash(wc_Sha512* sha512, byte* hash); \param src Source SHA512 structure \param dst Destination SHA512 structure + (must be zeroed or previously initialized) _Example_ \code wc_Sha512 src, dst; - int ret = wc_Sha512Copy(&src, &dst); + memset(&dst, 0, sizeof(dst)); + int ret = wc_InitSha512(&src); + if (ret == 0) + ret = wc_Sha512Copy(&src, &dst); \endcode \sa wc_InitSha512 @@ -521,11 +525,15 @@ int wc_Sha512_224GetHash(wc_Sha512* sha512, byte* hash); \param src Source SHA512 structure \param dst Destination SHA512 structure + (must be zeroed or previously initialized) _Example_ \code wc_Sha512 src, dst; - int ret = wc_Sha512_224Copy(&src, &dst); + memset(&dst, 0, sizeof(dst)); + int ret = wc_InitSha512_224(&src); + if (ret == 0) + ret = wc_Sha512_224Copy(&src, &dst); \endcode \sa wc_InitSha512_224 @@ -747,11 +755,15 @@ int wc_Sha512_256GetHash(wc_Sha512* sha512, byte* hash); \param src Source SHA512 structure \param dst Destination SHA512 structure + (must be zeroed or previously initialized) _Example_ \code wc_Sha512 src, dst; - int ret = wc_Sha512_256Copy(&src, &dst); + memset(&dst, 0, sizeof(dst)); + int ret = wc_InitSha512_256(&src); + if (ret == 0) + ret = wc_Sha512_256Copy(&src, &dst); \endcode \sa wc_InitSha512_256 @@ -911,11 +923,15 @@ int wc_Sha384GetHash(wc_Sha384* sha384, byte* hash); \param src Source SHA384 structure \param dst Destination SHA384 structure + (must be zeroed or previously initialized) _Example_ \code wc_Sha384 src, dst; - int ret = wc_Sha384Copy(&src, &dst); + memset(&dst, 0, sizeof(dst)); + int ret = wc_InitSha384(&src); + if (ret == 0) + ret = wc_Sha384Copy(&src, &dst); \endcode \sa wc_InitSha384 diff --git a/tests/api/test_aes.c b/tests/api/test_aes.c index ed4f762a610..6a830639746 100644 --- a/tests/api/test_aes.c +++ b/tests/api/test_aes.c @@ -93,6 +93,8 @@ static int test_wc_AesSetKey_BadArgs(Aes* aes, byte* key, word32 keyLen, WC_NO_ERR_TRACE(BAD_FUNC_ARG)); ExpectIntEQ(wc_AesSetKey(aes , key , 48 , iv, AES_ENCRYPTION), WC_NO_ERR_TRACE(BAD_FUNC_ARG)); + ExpectIntEQ(wc_AesSetKey(aes , NULL , 48 , iv, AES_ENCRYPTION), + WC_NO_ERR_TRACE(BAD_FUNC_ARG)); return EXPECT_RESULT(); } @@ -3262,13 +3264,15 @@ int test_wc_AesGcmEncryptDecrypt_Sizes(void) int sz; int i; WC_DECLARE_VAR(plain, byte, GCM_LEN, NULL); - WC_DECLARE_VAR(cipher, byte, GCM_LEN, NULL); + /* enlarged size is to accommodate devcrypto build which assumes + * space in buffer to append auth tag */ + WC_DECLARE_VAR(cipher, byte, GCM_LEN+WC_AES_BLOCK_SIZE, NULL); #ifdef HAVE_AES_DECRYPT WC_DECLARE_VAR(decrypted, byte, GCM_LEN, NULL); #endif WC_ALLOC_VAR(plain, byte, GCM_LEN, NULL); - WC_ALLOC_VAR(cipher, byte, GCM_LEN, NULL); + WC_ALLOC_VAR(cipher, byte, GCM_LEN+WC_AES_BLOCK_SIZE, NULL); #ifdef HAVE_AES_DECRYPT WC_ALLOC_VAR(decrypted, byte, GCM_LEN, NULL); #endif @@ -3288,7 +3292,7 @@ int test_wc_AesGcmEncryptDecrypt_Sizes(void) ExpectIntEQ(wc_AesGcmSetKey(&aes, key32, sizeof(key32)/sizeof(byte)), 0); for (sz = 0; sz < WC_AES_BLOCK_SIZE; sz++) { - XMEMSET(cipher, 0, GCM_LEN); + XMEMSET(cipher, 0, GCM_LEN + WC_AES_BLOCK_SIZE); ExpectIntEQ(wc_AesGcmEncrypt(&aes, cipher, plain, sz, iv, ivLen, tag, sizeof(tag), NULL, 0), 0); ExpectBufEQ(cipher, expected, sz); @@ -3304,7 +3308,7 @@ int test_wc_AesGcmEncryptDecrypt_Sizes(void) i = 0; for (sz = WC_AES_BLOCK_SIZE; sz <= GCM_LEN; sz *= 2) { - XMEMSET(cipher, 0, GCM_LEN); + XMEMSET(cipher, 0, GCM_LEN + WC_AES_BLOCK_SIZE); ExpectIntEQ(wc_AesGcmEncrypt(&aes, cipher, plain, sz, iv, ivLen, tag, sizeof(tag), NULL, 0), 0); ExpectBufEQ(tag, expTagLong[i], WC_AES_BLOCK_SIZE); @@ -3994,7 +3998,9 @@ int test_wc_AesGcmNonStdNonce(void) * and cannot exercise the GHASH-based counter derivation. */ #if !defined(NO_AES) && defined(HAVE_AESGCM) && \ !defined(HAVE_FIPS) && \ - !defined(WOLFSSL_AFALG) && !defined(WOLFSSL_KCAPI) + !defined(WOLFSSL_AFALG) && !defined(WOLFSSL_KCAPI) && \ + !defined(WOLFSSL_DEVCRYPTO_AES) + /* DEVCRYPTO does not support Non std Nonce */ /* ------------------------------------------------------------------ * Section 1: 1-byte IV, AES-128 diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index 79a2b0517e3..0ef7264bd76 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -5971,7 +5971,13 @@ static void AesSetKey_C(Aes* aes, const byte* key, word32 keySz, int dir) #if defined(WOLFSSL_DEVCRYPTO) && \ (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC)) - aes->ctx.cfd = -1; + /* Release any session already held. The session was created with the + * previous key, so re-keying must tear it down rather than just mark + * the context uninitialized, which would orphan the descriptor and + * leave the stale key in use. */ + wc_DevCryptoFree(&aes->ctx); + aes->ctx.inited = 0; + aes->ctx.cfd = -1; /* not set when no session was open */ #endif #ifdef WOLFSSL_IMX6_CAAM_BLOB #ifdef WOLFSSL_CHECK_MEM_ZERO @@ -15786,7 +15792,8 @@ int wc_AesInit(Aes* aes, void* heap, int devId) #endif #if defined(WOLFSSL_DEVCRYPTO) && \ (defined(WOLFSSL_DEVCRYPTO_AES) || defined(WOLFSSL_DEVCRYPTO_CBC)) - aes->ctx.cfd = -1; + aes->ctx.cfd = -1; + aes->ctx.inited = 0; #endif #if defined(WOLFSSL_IMXRT_DCP) DCPAesInit(aes); diff --git a/wolfcrypt/src/des3.c b/wolfcrypt/src/des3.c index f1beae1b60c..a3560a4ecda 100644 --- a/wolfcrypt/src/des3.c +++ b/wolfcrypt/src/des3.c @@ -1565,16 +1565,23 @@ for (i = 0; i < 16; i++) { /* key chunk for each iteration */ XMEMSET(ks, 0, 8); /* Clear key schedule */ - for (j = 0; j < 56; j++) /* rotate pc1 the right amount */ - pcr[j] = - pc1m[(l = j + totrot[i]) < (j < 28 ? 28 : 56) ? l : l-28]; - /* rotate left and right halves independently */ - for (j = 0; j < 48; j++) { /* select bits individually */ - if (pcr[pc2[j] - 1]) { /* check bit that goes to ks[j] */ - l= j % 6; /* mask it in if it's there */ - ks[j/6] |= (byte)(bytebit[l] >> 2); - } + for (j = 0; j < 28; j++) { /* rotate pc1 the right amount */ + l = (j + totrot[i]) % 28; + pcr[j] = pc1m[l]; + pcr[j + 28] = pc1m[l + 28]; + } + + for (j = 0; j < 48; j++) { /* select bits individually */ + byte bit; + byte mask; + bit = + (byte)(pcr[pc2[j] - 1]); /* all pcr values are either 0 + or 1 */ + mask = (byte)(0 - bit); /* mask is either 0xFF or 0x00 */ + /* only set to bytebit value if bit == 1 */ + ks[j/6] |= + (byte)((bytebit[j % 6] >> 2) & mask); } /* Now convert to odd/even interleaved form for use in F */ diff --git a/wolfcrypt/src/dsa.c b/wolfcrypt/src/dsa.c index 1561f2ad174..ae1a1a7a8a4 100644 --- a/wolfcrypt/src/dsa.c +++ b/wolfcrypt/src/dsa.c @@ -1151,6 +1151,13 @@ int wc_DsaVerify_ex(const byte* digest, word32 digestSz, const byte* sig, if (digest == NULL || sig == NULL || key == NULL || answer == NULL) return BAD_FUNC_ARG; + /* assign default value so verification is always failed on error */ + *answer = 0; + + /* Note the min allowed digestSz here is WC_MIN_DIGEST_SIZE_FOR_VERIFY, not + * WC_MIN_DIGEST_SIZE, to allow verify-only legacy DSA operations, as + * expressly allowed under FIPS 186-5, FIPS 140-3, and SP 800-131A. + */ if ((digestSz > WC_MAX_DIGEST_SIZE) || (digestSz < WC_MIN_DIGEST_SIZE_FOR_VERIFY)) { diff --git a/wolfcrypt/src/hmac.c b/wolfcrypt/src/hmac.c index e5267c1cbb3..0138fc13cc9 100644 --- a/wolfcrypt/src/hmac.c +++ b/wolfcrypt/src/hmac.c @@ -1536,7 +1536,8 @@ int wc_HmacInit(Hmac* hmac, void* heap, int devId) hmac->devCtx = NULL; #endif #if defined(WOLFSSL_DEVCRYPTO_HMAC) - hmac->ctx.cfd = -1; + hmac->ctx.inited = 0; + hmac->ctx.cfd = -1; #endif #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_HMAC) diff --git a/wolfcrypt/src/port/Espressif/esp_crt_bundle/esp_crt_bundle.c b/wolfcrypt/src/port/Espressif/esp_crt_bundle/esp_crt_bundle.c index c0baed81807..94ba64fe611 100644 --- a/wolfcrypt/src/port/Espressif/esp_crt_bundle/esp_crt_bundle.c +++ b/wolfcrypt/src/port/Espressif/esp_crt_bundle/esp_crt_bundle.c @@ -983,14 +983,12 @@ static CB_INLINE int wolfssl_ssl_conf_verify_cb_no_signer(int preverify, /* Clean up and exit */ if ((_crt_found == 0) && (bundle_cert != NULL)) { ESP_LOGW(TAG, "Cert not found, free bundle_cert"); + /* this_subject and this_issuer are a part of bundle_cert and will be + * freed here */ wolfSSL_X509_free(bundle_cert); bundle_cert = NULL; - /* this_subject and this_issuer are pointers into cert used. - * Don't free if the cert was found. */ - wolfSSL_X509_NAME_free(this_subject); - this_subject = NULL; - wolfSSL_X509_NAME_free(this_issuer); this_issuer = NULL; + this_subject = NULL; } /* We don't clean up the store_cert and x509 as we are in a callback, diff --git a/wolfcrypt/src/port/Renesas/renesas_fspsm_aes.c b/wolfcrypt/src/port/Renesas/renesas_fspsm_aes.c index 0dff415cbe6..c9d9dae0b94 100644 --- a/wolfcrypt/src/port/Renesas/renesas_fspsm_aes.c +++ b/wolfcrypt/src/port/Renesas/renesas_fspsm_aes.c @@ -411,9 +411,12 @@ int wc_fspsm_AesGcmEncrypt(struct Aes* aes, byte* out, key_server_aes = (FSPSM_AES_PWKEY)XMALLOC(sizeof(FSPSM_AES_WKEY), aes->heap, DYNAMIC_TYPE_AES); if (key_client_aes == NULL || key_server_aes == NULL) { - XFREE(plainBuf, aes->heap, DYNAMIC_TYPE_AES); - XFREE(cipherBuf, aes->heap, DYNAMIC_TYPE_AES); - XFREE(aTagBuf, aes->heap, DYNAMIC_TYPE_AES); + XFREE(key_client_aes, aes->heap, DYNAMIC_TYPE_AES); + XFREE(key_server_aes, aes->heap, DYNAMIC_TYPE_AES); + XFREE(plainBuf, aes->heap, DYNAMIC_TYPE_AES); + XFREE(cipherBuf, aes->heap, DYNAMIC_TYPE_AES); + XFREE(aTagBuf, aes->heap, DYNAMIC_TYPE_AES); + wc_fspsm_hw_unlock(); return MEMORY_E; } @@ -638,9 +641,12 @@ int wc_fspsm_AesGcmDecrypt(struct Aes* aes, byte* out, key_server_aes = (FSPSM_AES_PWKEY)XMALLOC(sizeof(FSPSM_AES_WKEY), aes->heap, DYNAMIC_TYPE_AES); if (key_client_aes == NULL || key_server_aes == NULL) { - XFREE(plainBuf, aes->heap, DYNAMIC_TYPE_AES); - XFREE(cipherBuf, aes->heap, DYNAMIC_TYPE_AES); - XFREE(aTagBuf, aes->heap, DYNAMIC_TYPE_AES); + XFREE(key_client_aes, aes->heap, DYNAMIC_TYPE_AES); + XFREE(key_server_aes, aes->heap, DYNAMIC_TYPE_AES); + XFREE(plainBuf, aes->heap, DYNAMIC_TYPE_AES); + XFREE(cipherBuf, aes->heap, DYNAMIC_TYPE_AES); + XFREE(aTagBuf, aes->heap, DYNAMIC_TYPE_AES); + wc_fspsm_hw_unlock(); return MEMORY_E; } diff --git a/wolfcrypt/src/port/Renesas/renesas_fspsm_sha.c b/wolfcrypt/src/port/Renesas/renesas_fspsm_sha.c index c543946a164..29a63c070b0 100644 --- a/wolfcrypt/src/port/Renesas/renesas_fspsm_sha.c +++ b/wolfcrypt/src/port/Renesas/renesas_fspsm_sha.c @@ -228,7 +228,7 @@ static int FSPSM_HashCopy(wolfssl_FSPSM_Hash* src, wolfssl_FSPSM_Hash* dst) * hash The FSPSM Hash object. * heap Buffer to hold heap if available * devId device Id - * return 0 on success, BAD_FUNC_ARG when has is NULL + * return 0 on success, BAD_FUNC_ARG when has is NULL or WC_HW_E on hw failure */ static int FSPSM_HashInit(wolfssl_FSPSM_Hash* hash, void* heap, int devId, word32 sha_type) @@ -281,6 +281,11 @@ static int FSPSM_HashInit(wolfssl_FSPSM_Hash* hash, void* heap, int devId, } wc_fspsm_hw_lock(); ret = Init(&hash->handle); + if (ret != FSP_SUCCESS) { + WOLFSSL_MSG("ShaInit operation failed"); + WOLFSSL_ERROR(WC_HW_E); + ret = WC_HW_E; + } wc_fspsm_hw_unlock(); return ret; #endif @@ -293,7 +298,7 @@ static int FSPSM_HashInit(wolfssl_FSPSM_Hash* hash, void* heap, int devId, * hash The FSPSM Hash object. * data Buffer to hold plain text for hash * sz Length of data - * return 0 on success, otherwise MEMORY_E or BAD_FUNC_ARG on failure + * return 0 on success, otherwise MEMORY_E, BAD_FUNC_ARG or WC_HW_E on failure */ static int FSPSM_HashUpdate(wolfssl_FSPSM_Hash* hash, const byte* data, word32 sz) @@ -370,6 +375,11 @@ static int FSPSM_HashUpdate(wolfssl_FSPSM_Hash* hash, } wc_fspsm_hw_lock(); ret = Update(&hash->handle, (byte*)data, sz); + if (ret != FSP_SUCCESS) { + WOLFSSL_MSG("ShaUpdate operation failed"); + WOLFSSL_ERROR(WC_HW_E); + ret = WC_HW_E; + } wc_fspsm_hw_unlock(); return ret; #endif @@ -382,7 +392,7 @@ static int FSPSM_HashUpdate(wolfssl_FSPSM_Hash* hash, * out Buffer to hold hashed text * outSz Length of out * return FSP_SUCCESS(0) on success, - * otherwise BAD_FUNC_ARG or FSP Error code on failure + * otherwise BAD_FUNC_ARG or WC_HW_E on failure */ static int FSPSM_HashFinal(wolfssl_FSPSM_Hash* hash, byte* out, word32 outSz) { @@ -418,21 +428,30 @@ static int FSPSM_HashFinal(wolfssl_FSPSM_Hash* hash, byte* out, word32 outSz) #endif wc_fspsm_hw_lock(); - if (Init(&handle) == FSP_SUCCESS) { - ret = Update(&handle, (uint8_t*)hash->msg, hash->used); - if (ret == FSP_SUCCESS) { - ret = Final(&handle, out, (uint32_t*)&sz); - if (ret != FSP_SUCCESS - #if defined(WOLFSSL_RENESAS_SCEPROTECT) - || sz != outSz - #endif - ) { - WOLFSSL_MSG("Sha operation failed"); - WOLFSSL_ERROR(WC_HW_E); - ret = WC_HW_E; - } + if ((ret = Init(&handle)) != FSP_SUCCESS) { + WOLFSSL_MSG("Sha init operation failed"); + WOLFSSL_ERROR(WC_HW_E); + ret = WC_HW_E; + } + else if ((ret = Update(&handle, (uint8_t*)hash->msg, hash->used)) + != FSP_SUCCESS) { + WOLFSSL_MSG("Sha update operation failed"); + WOLFSSL_ERROR(WC_HW_E); + ret = WC_HW_E; + } + else { + ret = Final(&handle, out, (uint32_t*)&sz); + if (ret != FSP_SUCCESS + #if defined(WOLFSSL_RENESAS_SCEPROTECT) + || sz != outSz + #endif + ) { + WOLFSSL_MSG("Sha operation failed"); + WOLFSSL_ERROR(WC_HW_E); + ret = WC_HW_E; } } + wc_fspsm_hw_unlock(); #elif defined(WOLFSSL_RENESAS_RSIP) @@ -475,11 +494,12 @@ static int FSPSM_HashFinal(wolfssl_FSPSM_Hash* hash, byte* out, word32 outSz) heap = hash->heap; FSPSM_HashFree(hash); - FSPSM_HashInit(hash, heap, 0, hash->sha_type); + ret = FSPSM_HashInit(hash, heap, 0, hash->sha_type); return ret; } -/* Hash operation to message and return a result */ +/* Hash operation to message and return a result or BAD_FUNC_ARG/WC_HW_E + * on error */ static int FSPSM_HashGet(wolfssl_FSPSM_Hash* hash, byte* out, word32 outSz) { int ret = FSP_SUCCESS; @@ -519,19 +539,27 @@ static int FSPSM_HashGet(wolfssl_FSPSM_Hash* hash, byte* out, word32 outSz) if (ret != 0) return ret; #endif wc_fspsm_hw_lock(); - if (Init(&handle) == FSP_SUCCESS) { - ret = Update(&handle, (uint8_t*)hash->msg, hash->used); - if (ret == FSP_SUCCESS) { - ret = Final(&handle, out, &sz); - if (ret != FSP_SUCCESS - #if defined(WOLFSSL_RENESAS_SCEPROTECT) - || sz != outSz - #endif - ) { - WOLFSSL_MSG("Sha operation failed"); - WOLFSSL_ERROR(WC_HW_E); - ret = WC_HW_E; - } + if ((ret = Init(&handle)) != FSP_SUCCESS) { + WOLFSSL_MSG("Sha init operation failed"); + WOLFSSL_ERROR(WC_HW_E); + ret = WC_HW_E; + } + else if ((ret = Update(&handle, (uint8_t*)hash->msg, hash->used)) + != FSP_SUCCESS) { + WOLFSSL_MSG("Sha update operation failed"); + WOLFSSL_ERROR(WC_HW_E); + ret = WC_HW_E; + } + else { + ret = Final(&handle, out, &sz); + if (ret != FSP_SUCCESS + #if defined(WOLFSSL_RENESAS_SCEPROTECT) + || sz != outSz + #endif + ) { + WOLFSSL_MSG("Sha operation failed"); + WOLFSSL_ERROR(WC_HW_E); + ret = WC_HW_E; } } wc_fspsm_hw_unlock(); @@ -567,7 +595,7 @@ static int FSPSM_HashGet(wolfssl_FSPSM_Hash* hash, byte* out, word32 outSz) if(FSPSM_HashCopy(hash, &hashCopy) != 0) { WOLFSSL_MSG("ShaCopy operation failed"); WOLFSSL_ERROR(WC_HW_E); - ret = WC_HW_E; + return WC_HW_E; } wc_fspsm_hw_lock(); ret = Final(&hashCopy.handle, out, (uint32_t*)&sz); diff --git a/wolfcrypt/src/port/caam/wolfcaam_hmac.c b/wolfcrypt/src/port/caam/wolfcaam_hmac.c index fb9c149a4d2..e6c54286aae 100644 --- a/wolfcrypt/src/port/caam/wolfcaam_hmac.c +++ b/wolfcrypt/src/port/caam/wolfcaam_hmac.c @@ -54,7 +54,7 @@ int wc_CAAM_Hmac(Hmac* hmac, int macType, const byte* msg, int msgSz, { int ret = 0; - if (hmac->ctx.cfd == -1 && hmac->keyLen > 0) { + if (hmac->ctx.inited == 0 && hmac->keyLen > 0) { ret = wc_DevCrypto_HmacSetKey(hmac, macType, hmac->keyRaw, hmac->keyLen); if (ret != 0) { diff --git a/wolfcrypt/src/port/devcrypto/devcrypto_aes.c b/wolfcrypt/src/port/devcrypto/devcrypto_aes.c index 62cd624f017..fe53360d584 100644 --- a/wolfcrypt/src/port/devcrypto/devcrypto_aes.c +++ b/wolfcrypt/src/port/devcrypto/devcrypto_aes.c @@ -49,7 +49,7 @@ int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) if (sz == 0) { return 0; } - if (aes->ctx.cfd == -1) { + if (aes->ctx.inited == 0) { ret = wc_DevCryptoCreate(&aes->ctx, CRYPTO_AES_CBC, (byte*)aes->devKey, aes->keylen); if (ret != 0) @@ -82,7 +82,7 @@ int wc_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz) } XMEMCPY(aes->tmp, in + sz - WC_AES_BLOCK_SIZE, WC_AES_BLOCK_SIZE); - if (aes->ctx.cfd == -1) { + if (aes->ctx.inited == 0) { ret = wc_DevCryptoCreate(&aes->ctx, CRYPTO_AES_CBC, (byte*)aes->devKey, aes->keylen); if (ret != 0) @@ -110,7 +110,7 @@ int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen, const word32 max_key_len = (AES_MAX_KEY_SIZE / 8); #endif - if (aes == NULL || + if (aes == NULL || userKey == NULL || !((keylen == 16) || (keylen == 24) || (keylen == 32))) { return BAD_FUNC_ARG; } @@ -128,7 +128,10 @@ int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen, defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) aes->left = 0; #endif - aes->ctx.cfd = -1; + /* release any session already held so re-keying does not orphan it */ + wc_DevCryptoFree(&aes->ctx); + aes->ctx.inited = 0; + aes->ctx.cfd = -1; /* not set when no session was open */ XMEMCPY(aes->devKey, userKey, keylen); (void)dir; @@ -151,7 +154,7 @@ static int wc_DevCrypto_AesDirect(Aes* aes, byte* out, const byte* in, return BAD_FUNC_ARG; } - if (aes->ctx.cfd == -1) { + if (aes->ctx.inited == 0) { ret = wc_DevCryptoCreate(&aes->ctx, CRYPTO_AES_ECB, (byte*)aes->devKey, aes->keylen); if (ret != 0) @@ -221,7 +224,7 @@ int wc_AesCtrEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) sz--; } - if (aes->ctx.cfd == -1) { + if (aes->ctx.inited == 0) { ret = wc_DevCryptoCreate(&aes->ctx, CRYPTO_AES_CTR, (byte*)aes->devKey, aes->keylen); if (ret != 0) @@ -284,8 +287,6 @@ int wc_AesGcmSetKey(Aes* aes, const byte* key, word32 len) return wc_AesSetKey(aes, key, len, NULL, AES_ENCRYPTION); } - - /* common code for AES-GCM encrypt/decrypt */ static int wc_DevCrypto_AesGcm(Aes* aes, byte* out, byte* in, word32 sz, const byte* iv, word32 ivSz, @@ -310,7 +311,7 @@ static int wc_DevCrypto_AesGcm(Aes* aes, byte* out, byte* in, word32 sz, in = scratch; XMEMSET(scratch, 0, WC_AES_BLOCK_SIZE); - if (aes->ctx.cfd == -1) { + if (aes->ctx.inited == 0) { ret = wc_DevCryptoCreate(&aes->ctx, CRYPTO_AES_GCM, (byte*)aes->devKey, aes->keylen); if (ret != 0) @@ -399,4 +400,3 @@ int wc_AesEcbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz) #endif /* HAVE_AES_ECB */ #endif /* WOLFSSL_DEVCRYPTO_AES */ #endif /* !NO_AES && WOLFSSL_DEVCRYPTO */ - diff --git a/wolfcrypt/src/port/devcrypto/devcrypto_hash.c b/wolfcrypt/src/port/devcrypto/devcrypto_hash.c index 37f9763fc2f..19e84b73504 100644 --- a/wolfcrypt/src/port/devcrypto/devcrypto_hash.c +++ b/wolfcrypt/src/port/devcrypto/devcrypto_hash.c @@ -135,20 +135,14 @@ int wc_Sha256Update(wc_Sha256* sha, const byte* in, word32 sz) #ifdef WOLFSSL_DEVCRYPTO_HASH_KEEP /* keep full message to hash at end instead of incremental updates */ if (sha->len < sha->used + sz) { - if (sha->msg == NULL) { - sha->msg = (byte*)XMALLOC(sha->used + sz, sha->heap, - DYNAMIC_TYPE_TMP_BUFFER); - } else { - byte* pt = (byte*)XREALLOC(sha->msg, sha->used + sz, sha->heap, - DYNAMIC_TYPE_TMP_BUFFER); - if (pt == NULL) { - return MEMORY_E; - } - sha->msg = pt; - } - if (sha->msg == NULL) { + byte* pt = (byte*)XREALLOC(sha->msg, sha->used + sz, sha->heap, + DYNAMIC_TYPE_TMP_BUFFER); + if (pt == NULL) { return MEMORY_E; } + + sha->msg = pt; + sha->len = sha->used + sz; } XMEMCPY(sha->msg + sha->used, in, sz); @@ -163,16 +157,23 @@ int wc_Sha256Update(wc_Sha256* sha, const byte* in, word32 sz) int wc_Sha256Final(wc_Sha256* sha, byte* hash) { int ret; + void* heap; if (sha == NULL || hash == NULL) { return BAD_FUNC_ARG; } + /* Cache the heap hint so the re-init below does not read it back out of a + * struct that wc_Sha256Free() has already torn down. */ + heap = sha->heap; + /* help static analysis tools out */ XMEMSET(hash, 0, WC_SHA256_DIGEST_SIZE); #ifdef WOLFSSL_DEVCRYPTO_HASH_KEEP /* keep full message to hash at end instead of incremental updates */ if ((ret = HashUpdate(sha, CRYPTO_SHA2_256, sha->msg, sha->used)) < 0) { + wc_Sha256Free(sha); + (void)wc_InitSha256_ex(sha, heap, 0); return ret; } XFREE(sha->msg, sha->heap, DYNAMIC_TYPE_TMP_BUFFER); @@ -180,11 +181,13 @@ int wc_Sha256Final(wc_Sha256* sha, byte* hash) #endif ret = GetDigest(sha, CRYPTO_SHA2_256, hash); if (ret != 0) { - return ret; + wc_Sha256Free(sha); + (void)wc_InitSha256_ex(sha, heap, 0); + return ret; } wc_Sha256Free(sha); - return wc_InitSha256_ex(sha, sha->heap, 0); + return wc_InitSha256_ex(sha, heap, 0); } @@ -198,9 +201,11 @@ int wc_Sha256GetHash(wc_Sha256* sha, byte* hash) { int ret; wc_Sha256 cpy; - wc_Sha256Copy(sha, &cpy); + XMEMSET(&cpy, 0, sizeof(cpy)); + ret = wc_Sha256Copy(sha, &cpy); - if ((ret = HashUpdate(&cpy, CRYPTO_SHA2_256, cpy.msg, cpy.used)) == 0) { + if (ret == 0 && (ret = HashUpdate(&cpy, + CRYPTO_SHA2_256, cpy.msg, cpy.used)) == 0) { /* help static analysis tools out */ XMEMSET(hash, 0, WC_SHA256_DIGEST_SIZE); ret = GetDigest(&cpy, CRYPTO_SHA2_256, hash); @@ -219,22 +224,40 @@ int wc_Sha256GetHash(wc_Sha256* sha, byte* hash) int wc_Sha256Copy(wc_Sha256* src, wc_Sha256* dst) { + int ret = 0; + if (src == NULL || dst == NULL) { return BAD_FUNC_ARG; } - wc_InitSha256_ex(dst, src->heap, 0); #ifdef WOLFSSL_DEVCRYPTO_HASH_KEEP + wc_Sha256Free(dst); + if ((ret = wc_InitSha256_ex(dst, src->heap, 0)) != 0) { + return ret; + } + + if (src->len > 0) { + dst->msg = (byte*)XMALLOC(src->len, dst->heap, DYNAMIC_TYPE_TMP_BUFFER); + if (dst->msg == NULL) { + wc_Sha256Free(dst); + return MEMORY_E; + } + XMEMCPY(dst->msg, src->msg, src->len); + } + dst->len = src->len; dst->used = src->used; - dst->msg = (byte*)XMALLOC(src->len, dst->heap, DYNAMIC_TYPE_TMP_BUFFER); - if (dst->msg == NULL) { - return MEMORY_E; - } - XMEMCPY(dst->msg, src->msg, src->len); -#endif - return 0; + return ret; +#else + /* dst is left untouched: nothing is copied or re-initialized here, so + * tearing it down would destroy a live caller object on a path that only + * reports "not supported". */ + (void)ret; + + WOLFSSL_MSG("Compile with WOLFSSL_DEVCRYPTO_HASH_KEEP for this feature"); + return NOT_COMPILED_IN; +#endif } #endif /* !NO_SHA256 */ diff --git a/wolfcrypt/src/port/devcrypto/devcrypto_hmac.c b/wolfcrypt/src/port/devcrypto/devcrypto_hmac.c index 7032181a982..e138b60ecfc 100644 --- a/wolfcrypt/src/port/devcrypto/devcrypto_hmac.c +++ b/wolfcrypt/src/port/devcrypto/devcrypto_hmac.c @@ -50,7 +50,9 @@ int wc_DevCrypto_HmacSetKey(Hmac* hmac, int t, const byte* key, word32 keySz) { int hType; - hmac->ctx.cfd = -1; + /* Re-keying releases any session already held, so it is not orphaned by + * the wc_DevCryptoCreate() below. */ + wc_DevCryptoFree(&hmac->ctx); hType = InternalTypeToDevcrypto(t); if (hType < 0) { return hType; diff --git a/wolfcrypt/src/port/devcrypto/devcrypto_rsa.c b/wolfcrypt/src/port/devcrypto/devcrypto_rsa.c index 4d118f80da8..a0fbd6c830e 100644 --- a/wolfcrypt/src/port/devcrypto/devcrypto_rsa.c +++ b/wolfcrypt/src/port/devcrypto/devcrypto_rsa.c @@ -264,7 +264,6 @@ static int _PublicOperation(const byte* in, word32 inlen, byte* out, dev = &key->ctx; - key->ctx.cfd = -1; if (wc_DevCryptoCreate(dev, CRYPTO_ASYM_RSA_PUBLIC, NULL, 0) != 0) { WOLFSSL_MSG("Error getting RSA public session"); return WC_DEVCRYPTO_E; @@ -439,7 +438,6 @@ int wc_DevCrypto_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng) byte eBuf[8]; int eBufSz; - key->ctx.cfd = -1; nSz = dSz = bSz; cSz = pSz = qSz = dpSz = dqSz = bSz/2; diff --git a/wolfcrypt/src/port/devcrypto/wc_devcrypto.c b/wolfcrypt/src/port/devcrypto/wc_devcrypto.c index e6d82dab4e6..db047b9b957 100644 --- a/wolfcrypt/src/port/devcrypto/wc_devcrypto.c +++ b/wolfcrypt/src/port/devcrypto/wc_devcrypto.c @@ -77,19 +77,25 @@ int wc_DevCryptoCreate(WC_CRYPTODEV* ctx, int type, byte* key, word32 keySz) return BAD_FUNC_ARG; } + /* Note: ctx is an out parameter and may be uninitialized stack memory, so + * it must not be inspected here. Callers that reuse a long lived ctx are + * responsible for calling wc_DevCryptoFree() before re-creating it. */ + /* sanity check on session type before creating descriptor */ XMEMSET(ctx, 0, sizeof(WC_CRYPTODEV)); + ctx->cfd = -1; + /* clone the master fd */ if (ioctl(fd, CRIOGET, &ctx->cfd) != 0) { WOLFSSL_MSG("Error cloning fd"); + ctx->cfd = -1; return WC_DEVCRYPTO_E; } if (fcntl(ctx->cfd, F_SETFD, 1) == -1) { WOLFSSL_MSG("Error setting F_SETFD with fcntl"); - (void)close(ctx->cfd); - return WC_DEVCRYPTO_E; + goto err_close; } /* set up session */ @@ -150,6 +156,7 @@ int wc_DevCryptoCreate(WC_CRYPTODEV* ctx, int type, byte* key, word32 keySz) default: WOLFSSL_MSG("Unknown / Unimplemented algorithm type"); (void)close(ctx->cfd); + ctx->cfd = -1; return BAD_FUNC_ARG; } @@ -158,17 +165,15 @@ int wc_DevCryptoCreate(WC_CRYPTODEV* ctx, int type, byte* key, word32 keySz) #if defined(DEBUG_DEVCRYPTO) perror("CIOGSESSION error "); #endif - (void)close(ctx->cfd); WOLFSSL_MSG("Error starting cryptodev session"); - return WC_DEVCRYPTO_E; + goto err_close; } #if defined(CIOCGSESSINFO) && defined(DEBUG_DEVCRYPTO) sesInfo.ses = ctx->sess.ses; if (ioctl(ctx->cfd, CIOCGSESSINFO, &sesInfo)) { - (void)close(ctx->cfd); WOLFSSL_MSG("Error getting session info"); - return WC_DEVCRYPTO_E; + goto err_close; } if (ctx->sess.cipher == 0) { printf("Using %s with driver %s\n", sesInfo.hash_info.cra_name, @@ -178,22 +183,30 @@ int wc_DevCryptoCreate(WC_CRYPTODEV* ctx, int type, byte* key, word32 keySz) sesInfo.cipher_info.cra_driver_name); } #endif + /* successful init */ + ctx->inited = 1; (void)key; (void)keySz; return 0; + +err_close: + (void)close(ctx->cfd); + ctx->cfd = -1; + return WC_DEVCRYPTO_E; } /* free up descriptor and session used with ctx */ void wc_DevCryptoFree(WC_CRYPTODEV* ctx) { - if (ctx != NULL && ctx->cfd >= 0) { + if (ctx != NULL && ctx->inited == 1) { if (ioctl(ctx->cfd, CIOCFSESSION, &ctx->sess.ses)) { WOLFSSL_MSG("Error stopping cryptodev session"); } (void)close(ctx->cfd); ctx->cfd = -1; + ctx->inited = 0; } } diff --git a/wolfcrypt/src/random.c b/wolfcrypt/src/random.c index 83dd85c8e08..f1b86e5ba44 100644 --- a/wolfcrypt/src/random.c +++ b/wolfcrypt/src/random.c @@ -385,26 +385,41 @@ static int sha256DrbgDisabled = 0; static int sha512DrbgDisabled = 0; #endif /* WOLFSSL_DRBG_SHA512 */ + #ifndef SINGLE_THREADED static wolfSSL_Mutex drbgStateMutex WOLFSSL_MUTEX_INITIALIZER_CLAUSE(drbgStateMutex); #ifndef WOLFSSL_MUTEX_INITIALIZER -static int drbgStateMutex_inited = 0; -#endif -#endif /* !SINGLE_THREADED */ +enum { + WC_DRBG_MUTEX_UNINITED, + WC_DRBG_MUTEX_INITED +}; +/* Ports with no static mutex initializer must create drbgStateMutex at run + * time, so its readiness is tracked here. + * + * wc_DrbgState_MutexInit and wc_DrbgState_MutexFree are called only from + * wolfCrypt_Init() and wolfCrypt_Cleanup(), inside the span serialized by the + * init-state machine, so this flag is not otherwise synchronized. */ +static int drbgStateMutex_inited = WC_DRBG_MUTEX_UNINITED; +#endif /* !defined(WOLFSSL_MUTEX_INITIALIZER) */ +#endif /* !defined(SINGLE_THREADED) */ + int wc_DrbgState_MutexInit(void) { #ifndef SINGLE_THREADED #ifndef WOLFSSL_MUTEX_INITIALIZER - if (!drbgStateMutex_inited) { + if (drbgStateMutex_inited == WC_DRBG_MUTEX_UNINITED) { int ret = wc_InitMutex(&drbgStateMutex); - if (ret != 0) + if (ret != 0) { + /* flag left unchanged because mutex was not inited */ return ret; - drbgStateMutex_inited = 1; + } + drbgStateMutex_inited = WC_DRBG_MUTEX_INITED; } -#endif -#endif + +#endif /* !defined(WOLFSSL_MUTEX_INITIALIZER) */ +#endif /* !defined(SINGLE_THREADED) */ return 0; } @@ -412,13 +427,17 @@ int wc_DrbgState_MutexFree(void) { #ifndef SINGLE_THREADED #ifndef WOLFSSL_MUTEX_INITIALIZER - if (drbgStateMutex_inited) { + if (drbgStateMutex_inited == WC_DRBG_MUTEX_INITED) { int ret = wc_FreeMutex(&drbgStateMutex); - drbgStateMutex_inited = 0; - return ret; + if (ret != 0) { + /* flag left unchanged because mutex was not freed */ + return ret; + } + drbgStateMutex_inited = WC_DRBG_MUTEX_UNINITED; } -#endif -#endif + +#endif /* !defined(WOLFSSL_MUTEX_INITIALIZER) */ +#endif /* !defined(SINGLE_THREADED) */ return 0; } @@ -3788,9 +3807,10 @@ static WC_INLINE int IntelRDseed64_r(word64* rnd) /* return 0 on success */ static int wc_GenerateSeed_IntelRD(OS_Seed* os, byte* output, word32 sz) { - int ret; + int ret = 0; word64 rndTmp; static int rdseed_sanity_status = 0; + word64 rndTmpLocal = 0; (void)os; @@ -3834,11 +3854,19 @@ static int wc_GenerateSeed_IntelRD(OS_Seed* os, byte* output, word32 sz) } for (; (sz / sizeof(word64)) > 0; sz -= sizeof(word64), - output += sizeof(word64)) { - ret = IntelRDseed64_r((word64*)output); - if (ret != 0) - return ret; + output += sizeof(word64)) { + ret = IntelRDseed64_r(&rndTmpLocal); + if (ret != 0) { + break; + } + writeUnalignedWord64(output, rndTmpLocal); } + + ForceZero(&rndTmpLocal, sizeof(rndTmpLocal)); + if (ret != 0) { + return ret; + } + if (sz == 0) return 0; @@ -3908,8 +3936,9 @@ static WC_INLINE int IntelRDrand64_r(word64 *rnd) /* return 0 on success */ static int wc_GenerateRand_IntelRD(OS_Seed* os, byte* output, word32 sz) { - int ret; word64 rndTmp; + int ret = 0; + word64 rndTmpLocal = 0; (void)os; @@ -3917,11 +3946,19 @@ static int wc_GenerateRand_IntelRD(OS_Seed* os, byte* output, word32 sz) return -1; for (; (sz / sizeof(word64)) > 0; sz -= sizeof(word64), - output += sizeof(word64)) { - ret = IntelRDrand64_r((word64 *)output); - if (ret != 0) - return ret; + output += sizeof(word64)) { + ret = IntelRDrand64_r(&rndTmpLocal); + if (ret != 0) { + break; + } + writeUnalignedWord64(output, rndTmpLocal); } + + ForceZero(&rndTmpLocal, sizeof(rndTmpLocal)); + if (ret != 0) { + return ret; + } + if (sz == 0) return 0; @@ -3931,6 +3968,7 @@ static int wc_GenerateRand_IntelRD(OS_Seed* os, byte* output, word32 sz) return ret; XMEMCPY(output, &rndTmp, sz); + ForceZero(&rndTmp, sizeof(rndTmp)); return 0; } diff --git a/wolfcrypt/src/siphash.c b/wolfcrypt/src/siphash.c index 28047be30b5..eecdaf2a378 100644 --- a/wolfcrypt/src/siphash.c +++ b/wolfcrypt/src/siphash.c @@ -80,7 +80,7 @@ * @param [in] a Little-endian byte array. * @return 16-bit number. */ -#define GET_U16(a) (*(const word16*)(a)) +#define GET_U16(a) readUnalignedWord16(a) /** * Encode 64-bit number to a little-endian byte array. * @@ -411,8 +411,8 @@ int wc_SipHash(const unsigned char* key, const unsigned char* in, word32 inSz, return BAD_FUNC_ARG; } - k0 = ((const word64*)key)[0]; - k1 = ((const word64*)key)[1]; + k0 = GET_U64(key); + k1 = GET_U64(key + 8); __asm__ __volatile__ ( "xorq %[k0], %[v0]\n\t" "xorq %[k1], %[v1]\n\t" @@ -640,8 +640,8 @@ int wc_SipHash(const unsigned char* key, const unsigned char* in, word32 inSz, return BAD_FUNC_ARG; } - k0 = ((word64*)key)[0]; - k1 = ((word64*)key)[1]; + k0 = GET_U64(key + 0); + k1 = GET_U64(key + 8); __asm__ __volatile__ ( "eor %[v0], %[v0], %[k0]\n\t" "eor %[v1], %[v1], %[k1]\n\t" diff --git a/wolfcrypt/src/wc_mlkem_poly.c b/wolfcrypt/src/wc_mlkem_poly.c index 56528414773..e8d0e57b521 100644 --- a/wolfcrypt/src/wc_mlkem_poly.c +++ b/wolfcrypt/src/wc_mlkem_poly.c @@ -5104,19 +5104,20 @@ static int mlkem_get_noise_k4_avx512(MLKEM_PRF_T* prf, sword16* vec1, * 17: e2 <- SamplePolyCBD_eta_2(PRF_eta_2(r, N)) * ... * - * @param [out] rand Random number byte array. + * @param [out] rand Random number word64 array. Used as the SHAKE-256 + * state - the random is squeezed into it in place. * @param [in] seed Seed to generate random from. * @param [in] o Offset of seed count. */ -static void mlkem_get_noise_x3_eta2_aarch64(byte* rand, byte* seed, byte o) +static void mlkem_get_noise_x3_eta2_aarch64(word64* rand, byte* seed, byte o) { - word64* state = (word64*)rand; + /* Only rand[i*25 + 4] is set here - the rest of the state is zeroed in + * registers by the assembly. */ + rand[0*25 + 4] = 0x1f00 + 0 + o; + rand[1*25 + 4] = 0x1f00 + 1 + o; + rand[2*25 + 4] = 0x1f00 + 2 + o; - state[0*25 + 4] = 0x1f00 + 0 + o; - state[1*25 + 4] = 0x1f00 + 1 + o; - state[2*25 + 4] = 0x1f00 + 2 + o; - - mlkem_shake256_blocksx3_seed_neon(state, seed); + mlkem_shake256_blocksx3_seed_neon(rand, seed); } #if defined(WOLFSSL_KYBER512) || defined(WOLFSSL_WC_ML_KEM_512) @@ -5139,6 +5140,8 @@ static void mlkem_get_noise_x3_eta2_aarch64(byte* rand, byte* seed, byte o) */ static void mlkem_get_noise_x3_eta3_aarch64(byte* rand, byte* seed, byte o) { + /* Only state[i*25 + 4] is read by the assembly - the rest of the state is + * zeroed in registers there. */ word64 state[3 * 25]; state[0*25 + 4] = 0x1f00 + 0 + o; @@ -5181,12 +5184,11 @@ static void mlkem_get_noise_x3_eta3_aarch64(byte* rand, byte* seed, byte o) */ static void mlkem_get_noise_eta3_aarch64(byte* rand, byte* seed, byte o) { + /* ETA3_RAND_SIZE is larger than the SHAKE-256 rate - two squeezes are + * needed, so the state cannot be squeezed in place over the output. */ word64 state[25]; - state[0] = ((word64*)seed)[0]; - state[1] = ((word64*)seed)[1]; - state[2] = ((word64*)seed)[2]; - state[3] = ((word64*)seed)[3]; + readUnalignedWords64(state, seed, 4); state[4] = 0x1f00 + o; XMEMSET(state + 5, 0, sizeof(*state) * (25 - 5)); state[16] = W64LIT(0x8000000000000000); @@ -5218,21 +5220,21 @@ static int mlkem_get_noise_k2_aarch64(sword16* vec1, sword16* vec2, sword16* poly, byte* seed) { int ret = 0; - byte rand[3 * 25 * 8]; + word64 rand[3 * 25]; - mlkem_get_noise_x3_eta3_aarch64(rand, seed, 0); - mlkem_cbd_eta3(vec1 , rand + 0 * ETA3_RAND_SIZE); - mlkem_cbd_eta3(vec1 + MLKEM_N, rand + 1 * ETA3_RAND_SIZE); + mlkem_get_noise_x3_eta3_aarch64((byte*)rand, seed, 0); + mlkem_cbd_eta3(vec1 , (byte*)rand + 0 * ETA3_RAND_SIZE); + mlkem_cbd_eta3(vec1 + MLKEM_N, (byte*)rand + 1 * ETA3_RAND_SIZE); if (poly == NULL) { - mlkem_cbd_eta3(vec2 , rand + 2 * ETA3_RAND_SIZE); - mlkem_get_noise_eta3_aarch64(rand, seed, 3); - mlkem_cbd_eta3(vec2 + MLKEM_N, rand ); + mlkem_cbd_eta3(vec2 , (byte*)rand + 2 * ETA3_RAND_SIZE); + mlkem_get_noise_eta3_aarch64((byte*)rand, seed, 3); + mlkem_cbd_eta3(vec2 + MLKEM_N, (byte*)rand ); } else { mlkem_get_noise_x3_eta2_aarch64(rand, seed, 2); - mlkem_cbd_eta2(vec2 , rand + 0 * 25 * 8); - mlkem_cbd_eta2(vec2 + MLKEM_N, rand + 1 * 25 * 8); - mlkem_cbd_eta2(poly , rand + 2 * 25 * 8); + mlkem_cbd_eta2(vec2 , (byte*)rand + 0 * 25 * 8); + mlkem_cbd_eta2(vec2 + MLKEM_N, (byte*)rand + 1 * 25 * 8); + mlkem_cbd_eta2(poly , (byte*)rand + 2 * 25 * 8); } /* rand holds secret noise. */ @@ -5257,23 +5259,18 @@ static int mlkem_get_noise_k2_aarch64(sword16* vec1, sword16* vec2, * 17: e2 <- SamplePolyCBD_eta_2(PRF_eta_2(r, N)) * ... * - * @param [out] rand Random number byte array. + * @param [out] rand Random number word64 array. * @param [in] seed Seed to generate random from. * @param [in] o Offset of seed count. */ -static void mlkem_get_noise_eta2_aarch64(byte* rand, byte* seed, byte o) +static void mlkem_get_noise_eta2_aarch64(word64* rand, byte* seed, byte o) { - word64* state = (word64*)rand; - - state[0] = ((word64*)seed)[0]; - state[1] = ((word64*)seed)[1]; - state[2] = ((word64*)seed)[2]; - state[3] = ((word64*)seed)[3]; + readUnalignedWords64(rand, seed, 4); /* Transposed value same as not. */ - state[4] = 0x1f00 + o; - XMEMSET(state + 5, 0, sizeof(*state) * (25 - 5)); - state[16] = W64LIT(0x8000000000000000); - BlockSha3(state); + rand[4] = 0x1f00 + o; + XMEMSET(rand + 5, 0, sizeof(*rand) * (25 - 5)); + rand[16] = W64LIT(0x8000000000000000); + BlockSha3(rand); } /* Get the noise/error by calculating random bytes and sampling to a binomial @@ -5288,19 +5285,19 @@ static void mlkem_get_noise_eta2_aarch64(byte* rand, byte* seed, byte o) static int mlkem_get_noise_k3_aarch64(sword16* vec1, sword16* vec2, sword16* poly, byte* seed) { - byte rand[3 * 25 * 8]; + word64 rand[3 * 25]; mlkem_get_noise_x3_eta2_aarch64(rand, seed, 0); - mlkem_cbd_eta2(vec1 , rand + 0 * 25 * 8); - mlkem_cbd_eta2(vec1 + 1 * MLKEM_N, rand + 1 * 25 * 8); - mlkem_cbd_eta2(vec1 + 2 * MLKEM_N, rand + 2 * 25 * 8); + mlkem_cbd_eta2(vec1 , (byte*)rand + 0 * 25 * 8); + mlkem_cbd_eta2(vec1 + 1 * MLKEM_N, (byte*)rand + 1 * 25 * 8); + mlkem_cbd_eta2(vec1 + 2 * MLKEM_N, (byte*)rand + 2 * 25 * 8); mlkem_get_noise_x3_eta2_aarch64(rand, seed, 3); - mlkem_cbd_eta2(vec2 , rand + 0 * 25 * 8); - mlkem_cbd_eta2(vec2 + 1 * MLKEM_N, rand + 1 * 25 * 8); - mlkem_cbd_eta2(vec2 + 2 * MLKEM_N, rand + 2 * 25 * 8); + mlkem_cbd_eta2(vec2 , (byte*)rand + 0 * 25 * 8); + mlkem_cbd_eta2(vec2 + 1 * MLKEM_N, (byte*)rand + 1 * 25 * 8); + mlkem_cbd_eta2(vec2 + 2 * MLKEM_N, (byte*)rand + 2 * 25 * 8); if (poly != NULL) { mlkem_get_noise_eta2_aarch64(rand, seed, 6); - mlkem_cbd_eta2(poly , rand + 0 * 25 * 8); + mlkem_cbd_eta2(poly , (byte*)rand + 0 * 25 * 8); } /* rand holds secret noise. */ @@ -5329,21 +5326,21 @@ static int mlkem_get_noise_k4_aarch64(sword16* vec1, sword16* vec2, sword16* poly, byte* seed) { int ret = 0; - byte rand[3 * 25 * 8]; + word64 rand[3 * 25]; mlkem_get_noise_x3_eta2_aarch64(rand, seed, 0); - mlkem_cbd_eta2(vec1 , rand + 0 * 25 * 8); - mlkem_cbd_eta2(vec1 + 1 * MLKEM_N, rand + 1 * 25 * 8); - mlkem_cbd_eta2(vec1 + 2 * MLKEM_N, rand + 2 * 25 * 8); + mlkem_cbd_eta2(vec1 , (byte*)rand + 0 * 25 * 8); + mlkem_cbd_eta2(vec1 + 1 * MLKEM_N, (byte*)rand + 1 * 25 * 8); + mlkem_cbd_eta2(vec1 + 2 * MLKEM_N, (byte*)rand + 2 * 25 * 8); mlkem_get_noise_x3_eta2_aarch64(rand, seed, 3); - mlkem_cbd_eta2(vec1 + 3 * MLKEM_N, rand + 0 * 25 * 8); - mlkem_cbd_eta2(vec2 , rand + 1 * 25 * 8); - mlkem_cbd_eta2(vec2 + 1 * MLKEM_N, rand + 2 * 25 * 8); + mlkem_cbd_eta2(vec1 + 3 * MLKEM_N, (byte*)rand + 0 * 25 * 8); + mlkem_cbd_eta2(vec2 , (byte*)rand + 1 * 25 * 8); + mlkem_cbd_eta2(vec2 + 1 * MLKEM_N, (byte*)rand + 2 * 25 * 8); mlkem_get_noise_x3_eta2_aarch64(rand, seed, 6); - mlkem_cbd_eta2(vec2 + 2 * MLKEM_N, rand + 0 * 25 * 8); - mlkem_cbd_eta2(vec2 + 3 * MLKEM_N, rand + 1 * 25 * 8); + mlkem_cbd_eta2(vec2 + 2 * MLKEM_N, (byte*)rand + 0 * 25 * 8); + mlkem_cbd_eta2(vec2 + 3 * MLKEM_N, (byte*)rand + 1 * 25 * 8); if (poly != NULL) { - mlkem_cbd_eta2(poly, rand + 2 * 25 * 8); + mlkem_cbd_eta2(poly, (byte*)rand + 2 * 25 * 8); } /* rand holds secret noise. */ diff --git a/wolfssl/wolfcrypt/port/devcrypto/wc_devcrypto.h b/wolfssl/wolfcrypt/port/devcrypto/wc_devcrypto.h index 47ee1b3f520..0a36b837dc6 100644 --- a/wolfssl/wolfcrypt/port/devcrypto/wc_devcrypto.h +++ b/wolfssl/wolfcrypt/port/devcrypto/wc_devcrypto.h @@ -38,6 +38,7 @@ typedef struct WC_CRYPTODEV { int cfd; + WC_BITFIELD inited : 1; /* is this object initialized (1) or not (0) */ struct session_op sess; } WC_CRYPTODEV;