-
Notifications
You must be signed in to change notification settings - Fork 1k
Fix: WolfCrypt Fenrir - 12 fixes #10786
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
84e553a
983e25d
f02c0b9
a5b0f26
6ed96c8
5cdc977
1241e7c
a6029ca
2b3617a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1570,11 +1570,15 @@ | |
| pc1m[(l = j + totrot[i]) < (j < 28 ? 28 : 56) ? l : l-28]; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔵 [Low] des3.c: secret-dependent ternary remains in the pc1 bit-extraction loop The PR removes the secret-dependent branch from the pc2 selection loop, but the loop fifteen lines above — which produces the very values it consumes — still branches on a secret key bit via Fix: Convert to arithmetic extraction so the whole key schedule is branchless by construction rather than by optimizer behaviour.
|
||
|
|
||
| /* 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 < 48; j++) { /* select bits individually */ | ||
| byte bit; | ||
| byte mask; | ||
| bit = | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔵 [Low] des3.c: new line exceeds the 80-column limit and will fail check-source-text Line 1577, added by this PR, is 87 characters. wolfSSL enforces 80 columns via testing/git-hooks/wolfssl-multi-test.sh check-source-text, wired into .github/workflows/check-source-text.yml, so this fails CI. The awkward statement splitting ( Fix: Reflow under 80 columns by moving comments above the statements, then run the repo's check-source-text lint before pushing. |
||
| (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 */ | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1128,6 +1128,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_SHA_DIGEST_SIZE, not | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔵 [Low] dsa.c: added comment misstates what WC_MIN_DIGEST_SIZE_FOR_VERIFY expands to The new comment claims 'the min allowed digestSz here is WC_SHA_DIGEST_SIZE, not WC_MIN_DIGEST_SIZE'. Per hash.h:272-287 both halves are wrong in the general case: in a non-FIPS build the macro is literally Fix: Reword to describe intent rather than a concrete value, and point at hash.h instead of restating it. |
||
| * 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)) | ||
| { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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"); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔵 [Low] esp_crt_bundle.c: missing space before comment terminator The fix is correct and I verified it thoroughly: Fix: Add the missing space before |
||
| /* 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, | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -410,10 +410,13 @@ int wc_fspsm_AesGcmEncrypt(struct Aes* aes, byte* out, | |
| aes->heap, DYNAMIC_TYPE_AES); | ||
| 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); | ||
| if (key_server_aes == NULL || key_client_aes == NULL) { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔵 [Low] Renesas FSPSM AES: inconsistent condition order and argument alignment between encrypt and decrypt The fix is correct and complete — I verified the lock is genuinely held ( Fix: Use client-then-server in both (matching declaration and allocation order) and align the XFREE arguments identically so the two blocks stay diffable.
|
||
| 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; | ||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -418,7 +418,7 @@ static int FSPSM_HashFinal(wolfssl_FSPSM_Hash* hash, byte* out, word32 outSz) | |
| #endif | ||
| wc_fspsm_hw_lock(); | ||
|
|
||
| if (Init(&handle) == FSP_SUCCESS) { | ||
| if ((ret = Init(&handle)) == FSP_SUCCESS) { | ||
| ret = Update(&handle, (uint8_t*)hash->msg, hash->used); | ||
| if (ret == FSP_SUCCESS) { | ||
| ret = Final(&handle, out, (uint32_t*)&sz); | ||
|
|
@@ -433,6 +433,10 @@ static int FSPSM_HashFinal(wolfssl_FSPSM_Hash* hash, byte* out, word32 outSz) | |
| } | ||
| } | ||
| } | ||
|
|
||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔵 [Low] FSPSM_HashFinal maps Init/Update failures to WC_HW_E without a WOLFSSL_ERROR trace The inner Final-failure path logs before converting ( Fix: Log before converting, matching the file's existing style, and apply the same to |
||
| if (ret != FSP_SUCCESS) | ||
| ret = WC_HW_E; | ||
|
|
||
| wc_fspsm_hw_unlock(); | ||
|
|
||
| #elif defined(WOLFSSL_RENESAS_RSIP) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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; | ||
| } | ||
|
|
@@ -129,6 +129,7 @@ int wc_AesSetKey(Aes* aes, const byte* userKey, word32 keylen, | |
| aes->left = 0; | ||
| #endif | ||
| aes->ctx.cfd = -1; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟠 [Medium] wc_AesSetKey clears the devcrypto context without releasing an already-open session The PR touches these exact two lines (adding Fix: Replace the two assignments with |
||
| aes->ctx.inited = 0; | ||
| XMEMCPY(aes->devKey, userKey, keylen); | ||
|
|
||
| (void)dir; | ||
|
|
@@ -151,7 +152,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 +222,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 +285,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 +309,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 +398,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 */ | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🔵 [Low] sha256.h doc: contract change documented only for wc_Sha256Copy, and the example leaves src uninitialized
The PR makes
wc_Sha256Free(dst)the first operation ondstand codifies 'must be zeroed/initialized' in the dox comment. I verified every in-tree caller already satisfies that contract — src/internal.c:7670 XMEMSETs*destination, src/tls13.c:12893 XMEMSETs theDigestunion, wolfcrypt/src/hmac.c:391 XMEMSETsdst->hashinsidewc_HmacCopy, src/ssl_crypto.c, evp.c:6155, wc_slhdsa.c and the tests — and the generic implementation in sha256.c already behaved this way, so the contract is consistent repo-wide. Two documentation gaps remain: the updated example still leavessrcuninitialized, and only the SHA-256 comment was touched thoughwc_ShaCopy,wc_Sha384Copy,wc_Sha512Copyandwc_Sm3Copycarry the identical contract.Fix: Fix the example to initialize
src, and propagate themust be zeroed/initializedwording to wc_ShaCopy / wc_Sha384Copy / wc_Sha512Copy / wc_Sm3Copy.