-
Notifications
You must be signed in to change notification settings - Fork 26
CMAC refactor + deprecate cancellation #279
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: main
Are you sure you want to change the base?
Conversation
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.
Pull request overview
This PR refactors the CMAC implementation to use a stateless server pattern with client-held state, removes the unused cancellation API, and extends CMAC test coverage (including DMA paths) to follow wolfCrypt’s NIST test vectors and cached-key flows.
Changes:
- Redesigns CMAC request/response (including DMA) to carry only non-sensitive intermediate state, with AES subkeys re-derived on each server call using stack-allocated
Cmaccontexts. - Removes the cancellation API and all associated client/server/test wiring, simplifying the transport and error model.
- Updates the CMAC client and server crypto handlers plus tests to support cached keys (both RAM and NVM) for one-shot and incremental CMAC generate/verify in both non-DMA and DMA paths.
Reviewed changes
Copilot reviewed 14 out of 14 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
wolfhsm/wh_settings.h |
Removes the WOLFHSM_CFG_CANCEL_API configuration option from the public settings comments to match the removal of the cancellation feature. |
wolfhsm/wh_server.h |
Drops the per-algorithm algoCtx union (including server-side Cmac) and the cancelSeq field from whServerContext, aligning with stateless CMAC and no cancellation. |
wolfhsm/wh_message_crypto.h |
Introduces whMessageCrypto_CmacState and updates CMAC and CMAC DMA request/response structs to embed non-sensitive CMAC state, keeping request/response sizes aligned and documenting the new wire format. |
wolfhsm/wh_message.h |
Removes the WH_MESSAGE_GROUP_CANCEL message group since cancel messages are no longer supported. |
wolfhsm/wh_error.h |
Deletes WH_ERROR_CANCEL and WH_ERROR_CANCEL_LATE error codes to reflect that cancellation is no longer part of the API. |
wolfhsm/wh_client_crypto.h |
Removes the declaration and documentation of wh_Client_CmacCancelableResponse, consistent with dropping cancelable CMAC handling. |
wolfhsm/wh_client.h |
Strips the client-side cancel callback type, associated fields in whClientContext, config wiring, and public cancel APIs (EnableCancel, DisableCancel, Cancel*). |
test/wh_test_crypto.c |
Replaces the previous single CMAC KAT and cancellation tests with a suite of NIST SP 800-38B-based CMAC tests (128/192/256-bit keys; oneshot and incremental; cached and committed keys) and removes all cancel-related test harness plumbing. |
test/config/wolfhsm_cfg.h |
Stops enabling WOLFHSM_CFG_CANCEL_API in the POSIX test harness, fully disabling cancellation in test builds as well. |
src/wh_server_crypto.c |
Reimplements _HandleCmac and _HandleCmacDma to use stack-local Cmac contexts, reconstruct keys from inline bytes or keystore IDs, restore/persist only non-sensitive CMAC state, validate lengths, and remove the cancellation helper logic. |
src/wh_server.c |
Removes server-side canceled sequence getters/setters and the special-case response rewriting for canceled operations. |
src/wh_message_crypto.c |
Adds wh_MessageCrypto_TranslateCmacState and updates CMAC and CMAC DMA request/response translators to include the portable CMAC state plus the new DMA buffer layout, preserving endian correctness. |
src/wh_client_crypto.c |
Updates wh_Client_Cmac and wh_Client_CmacDma to pack/unpack the CMAC state in messages, reuse stashed raw keys for non-HSM incremental calls, enforce message size limits, and drop the cancelable-response path. |
src/wh_client.c |
Removes all client-side cancellation functions and associated context initialization, completing the cancellation API deprecation. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- refactor DMA CMAC to use client-supplied state vs state by reference - refactor to use stack allocated CMAC context - expand CMAC tests to mimic wolfCrypt tests but with cached keys - housekeeping, error checking
854738a to
2dedb29
Compare
Overview
Implementation Description
Refactors the server to be stateless*. The server no longer holds onto a CMAC session. Instead, the client carries all non-sensitive intermediate state and re-sends it with each request. The server re-derives the sensitive material (AES subkeys) from the key on every call, restores the portable state, processes new data, and returns updated state.
There are two locations for CMAC state:
Client-side: The wolfCrypt
Cmacstruct, which the caller owns. The client library uses specific fields within this struct to persist state between server round-trips:cmac->buffer[16]— partial block buffer (unprocessed leftover bytes)cmac->digest[16]— running CBC-MAC intermediate digestcmac->bufferSz— how many bytes are in the partial block buffercmac->totalSz— total bytes processed so farcmac->aes.devKey/cmac->aes.keylen— stashed copy of the raw key (for non-HSM keys)cmac->devCtx— the keyId (for HSM-stored keys)Server-side: The server is stateless with respect to CMAC. It does not persist any CMAC context between requests. Every request is self-contained. The client sends enough state for the server to reconstruct a working CMAC context, process the data, and return updated state.
What Gets Transmitted?
A message layer state struct (
whMessageCrypto_CmacState) carries only the non-sensitive fields:buffer,digest,bufferSz, andtotalSz. Critically, the AES subkeys (k1/k2) are never transmitted. The server re-derives them from the key on every request by callingwc_InitCmac_ex(). While I thought about only re-deriving on the finalize, there are other Init operations that must be invoked on every update, and it made the code more complicated. I figured the single AES operation and some bit shifting is fast enough that it could be done every operation.When Is The State Updated?
Cmacfields into the request'sresumeState.resumeStateback into its localCmacstruct.cmac->aes.devKeyso subsequent update/final calls can re-send the key without the caller needing to provide it again.DMA
The DMA path works exactly as the non-DMA path, except the input data is passed by reference. CMAC state and the result are still passed through the transport. The server handling performs the necessary address translations.