Repository navigation
Add support for SHAKE - #523
padelsbach wants to merge 10 commits into
Conversation
a7b236f to
c242d8b
Compare
wolfSSL-Fenrir-bot
left a comment
There was a problem hiding this comment.
Fenrir Automated Review — PR #523
Scan targets checked: wolfhsm-core-bugs, wolfhsm-crypto-bugs, wolfhsm-src
Findings: 5
5 finding(s) posted as inline comments (see file-level comments below)
This review was generated automatically by Fenrir. Reported findings require changes before merge.
|
@padelsbach plz investigate fenrir issues and resolve + assign me back the bot if ready to go. That said we don't want to merge unless the upstream wolfCrypt stuff is all in first |
d767420 to
e8f26b1
Compare
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Missing-server responses are not consistently converted into software fallback signals, causing SHAKE operations to fail in mixed-feature deployments.
Review effort: Balanced
Findings: 1
Open (1)
What changed in this PR
Adds SHAKE128/256 offload support following the existing SHA3 client/server architecture.
Changes:
- Adds SHAKE wire messages, client APIs, callbacks, and server handling.
- Adds extensive functional, validation, and fallback tests.
- Adds SHAKE build variants and updates the wolfSSL dependency revision.
| File | Description |
|---|---|
wolfhsm/wh_message_crypto.h |
Defines SHAKE wire formats and limits. |
wolfhsm/wh_client_crypto.h |
Declares SHAKE client APIs. |
src/wh_message_crypto.c |
Implements message translation. |
src/wh_client_crypto.c |
Implements SHAKE client offload. |
src/wh_client_cryptocb.c |
Adds wolfCrypt callback dispatch. |
src/wh_server_crypto.c |
Adds server-side SHAKE processing. |
test-refactor/client-server/wh_test_crypto_shake.c |
Adds comprehensive SHAKE tests. |
test-refactor/wh_test_list.c |
Registers the new tests. |
test-refactor/posix/Makefile |
Adds SHAKE build variants. |
test/config/user_settings.h |
Configures SHAKE and dependent algorithms. |
test/Makefile |
Configures wolfCrypt certificate paths. |
test/wh_test_check_struct_padding.c |
Checks new message padding. |
test-refactor/misc/wh_test_check_struct_padding.c |
Checks refactored-build padding. |
.github/workflows/build-and-test-refactor.yml |
Tests individual SHAKE configurations. |
.github/actions/checkout-wolfssl/action.yml |
Pins the required wolfSSL revision. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
9b2cb26 to
ee8fea0
Compare
ee8fea0 to
0455f93
Compare
Frauschi
left a comment
There was a problem hiding this comment.
Looks good overall. Main issue is the silent software fallback for large outputs; a few smaller things inline.
| #endif | ||
| } | ||
| /* Output too big for one response; let software produce it */ | ||
| if (ret == WH_ERROR_NOSPACE) { |
There was a problem hiding this comment.
Output above WH_MESSAGE_CRYPTO_SHAKE_MAX_INLINE_OUTPUT_SZ turns into CRYPTOCB_UNAVAILABLE here, so the hash silently finishes in software. We don't want a silent fallback on the offload path; this should either run on the HSM or fail. Absorb plus the chunked squeeze you already added could produce long outputs on the server.
There was a problem hiding this comment.
Dropped the fallback
|
|
||
| capacity = _ShakeUpdatePerCallCapacity(sha, v); | ||
| if (inLen > capacity) { | ||
| return WH_ERROR_BADARGS; |
There was a problem hiding this comment.
Other hash UpdateRequests return WH_ERROR_REQUEST_SIZE for an oversized inLen; SHAKE returns BADARGS. These SHAKE helpers are mostly copies of the SHA3 ones and already drifting, could they be shared since wc_Shake is a wc_Sha3?
There was a problem hiding this comment.
Yep, added helper _Sha3PackUpdate
| res.outSz = req.outSz; | ||
| } | ||
|
|
||
| ops.freeFn(shake); |
There was a problem hiding this comment.
shake, req and res hold sponge state derived from secret input (ML-DSA/ML-KEM seeds) and aren't zeroed. Can we wc_ForceZero them before returning, like the client side does?
There was a problem hiding this comment.
Yes, good catch. Refactored _HandleShake to cleanup at the end
| return WH_ERROR_BADARGS; | ||
| } | ||
| if ((op != WH_MESSAGE_CRYPTO_SHAKE_OP_ABSORB) && | ||
| ((out == NULL) || (outSz == 0))) { |
There was a problem hiding this comment.
Rejecting out == NULL before receiving leaves the server's reply in the comm buffer, so the next request reads a stale response. Validate in the request path instead.
There was a problem hiding this comment.
Reworked to receive the reply first, then reject
| /* Save state so a software fallback does not absorb input twice */ | ||
| _ShakeSaveState(sha, &saved); | ||
|
|
||
| ret = _ShakeUpdateAll(ctx, sha, v, in, inLen); |
There was a problem hiding this comment.
Move the outSz limit check before _ShakeUpdateAll, otherwise a too-large output streams all of in to the server first and then throws it away.
There was a problem hiding this comment.
Limit and check is only on the server now
| memcpy(out, (uint8_t*)(res + 1), outSz); | ||
| } | ||
| if (op == WH_MESSAGE_CRYPTO_SHAKE_OP_HASH) { | ||
| ret = v->resetFn(sha); |
There was a problem hiding this comment.
Minor: SHA3 resets with v->initFn, SHAKE with wc_Shake*_Reset, which frees and re-inits and can dispatch a FREE back into the callback. Using initFn would keep them consistent.
There was a problem hiding this comment.
Switched to v->initFn
|
|
||
| #if defined(WOLF_CRYPTO_CB_SHAKE_XOF) && \ | ||
| (defined(WOLFSSL_SHAKE128) || defined(WOLFSSL_SHAKE256)) | ||
| /* Declining an unknown op is safe as the wc_Shake state is still current */ |
There was a problem hiding this comment.
Nit: some new comments explain reasoning rather than code (this one, "Additive to avoid unsigned wrap", "A silent decline would still match software..."). I'd drop or shorten them.
There was a problem hiding this comment.
I usually comment about "why" and let the code describe "how". But these have been cleaned up
…ffer and comment cleanup

Follows patterns from SHA3