Open
Conversation
Frauschi
commented
Apr 24, 2026
Owner
Author
Frauschi
left a comment
There was a problem hiding this comment.
Support for devCtx as well asl PRIVATE_KEY_ID and LABEL is missing
3f1a1b3 to
093d67a
Compare
Groundwork for routing LMS / HSS (RFC 8554) and XMSS / XMSS^MT
(RFC 8391, both profiled in NIST SP 800-208) through the
WOLF_CRYPTO_CB framework so that the wolfSSL PKCS#11 provider and the
wolfHSM client can later host stateful hash-based keys on a device.
No HSM-side or PKCS#11-provider code is in scope; this commit only
adds the wolfSSL-side dispatcher layer, the per-key device binding,
and the helpers a backend needs to answer the request.
Dispatcher surface (modelled on wc_CryptoCb_PqcSign* used for
Dilithium and Falcon):
WC_PK_TYPE_PQC_STATEFUL_SIG_KEYGEN
WC_PK_TYPE_PQC_STATEFUL_SIG_SIGN
WC_PK_TYPE_PQC_STATEFUL_SIG_VERIFY
WC_PK_TYPE_PQC_STATEFUL_SIG_SIGS_LEFT
A new discriminator enum wc_PqcStatefulSignatureType
(WC_PQC_STATEFUL_SIG_TYPE_LMS / _XMSS) tells the callback how to
interpret the void* key. The dispatcher functions are
wc_CryptoCb_PqcStatefulSig{KeyGen,Sign,Verify,SigsLeft} plus the
wc_CryptoCb_PqcStatefulSigGetDevId helper. XMSS vs XMSS^MT is
discriminated inside the callback via the existing
XmssKey::is_xmssmt field.
Mapping to PKCS#11 v3.1 / v3.2:
wc_LmsKey_MakeKey -> CKM_HSS_KEY_PAIR_GEN
wc_LmsKey_Sign -> CKM_HSS (sign)
wc_LmsKey_Verify -> CKM_HSS (verify)
wc_LmsKey_SigsLeft -> CKA_HSS_KEYS_REMAINING attribute
wc_XmssKey_MakeKey -> CKM_XMSS_KEY_PAIR_GEN / CKM_XMSSMT_KEY_PAIR_GEN
wc_XmssKey_Sign -> CKM_XMSS / CKM_XMSSMT (sign)
wc_XmssKey_Verify -> CKM_XMSS / CKM_XMSSMT (verify)
wc_XmssKey_SigsLeft -> XMSS remaining-sigs attribute
Public API additions:
- LmsKey / XmssKey gain (under WOLF_CRYPTO_CB) int devId and
void* devCtx, and (under WOLF_PRIVATE_KEY_ID) byte id[],
int idLen, char label[], int labelLen, with LMS_MAX_ID_LEN,
LMS_MAX_LABEL_LEN, XMSS_MAX_ID_LEN, XMSS_MAX_LABEL_LEN constants
defaulting to 32 and overridable.
- wc_LmsKey_InitId / wc_LmsKey_InitLabel and the XMSS equivalents,
gated on WOLF_PRIVATE_KEY_ID, mirror wc_InitRsaKey_Id /
wc_InitRsaKey_Label.
- wc_LmsKey_HashMsg / wc_XmssKey_HashMsg compute the digest dictated
by the parameter set (SHA-256 / SHA-256-192 / SHAKE256 / SHAKE256-192
for LMS; SHA-256 / SHA-512 / SHAKE128 / SHAKE256 for XMSS) so a
PKCS#11-style backend can produce the digest from inside the
callback. wolfHSM-style backends ignore the helper and consume
msg / msgSz directly.
Behaviour notes:
- The CryptoCb dispatch in wc_*Key_MakeKey / Sign runs before the
software write/read/context callback validation so a device-backed
key does not need dummy software callbacks. On CRYPTOCB_UNAVAILABLE
the software validations are re-applied.
- wc_*Key_Verify rejects negative msgSz before widening to word32 for
the dispatcher, and surfaces validity through int* res in the
dispatcher, translating res != 1 back to SIG_VERIFY_E for the
wolfSSL caller.
- wc_*Key_SigsLeft uses word32* sigsLeft so a key at the 2^32 PKCS#11
limit can be expressed unambiguously; the public int-returning API
clamps at 0x7FFFFFFF and emits WOLFSSL_MSG instead of swallowing
device errors.
- wc_*Key_Reload short-circuits for HSM-backed keys; wc_LmsKey_GetKid
warns that priv_raw may be uninitialised; wc_*Key_ExportPub
preserves the source key's devId so the verify-only copy keeps
dispatching through the same device.
Test coverage:
myCryptoDevCb gains four new handlers that bounce each operation
back into the software API by clearing devId and restoring it; both
Sign and Verify go through the dispatcher, so the produced signatures
self-verify within the harness. lms_test and xmss_test are invoked
inside cryptocb_test to exercise the full round trip.
Builds verified:
--enable-lms --enable-xmss --enable-cryptocb (primary)
--enable-lms --enable-xmss --enable-cryptocb CPPFLAGS=-DWOLF_PRIVATE_KEY_ID
--enable-lms --enable-xmss
--enable-cryptocb
A doc/LMS_XMSS_CryptoCb.md document covers the rationale, the
PKCS#11 mapping, the public API, and the design notes.
093d67a to
03833f6
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Groundwork for routing LMS/HSS (RFC 8554) and XMSS/XMSS^MT (RFC 8391) through the
WOLF_CRYPTO_CBframework, so that the PKCS#11 provider and wolfHSM client can later host stateful hash-based keys on a device. No HSM-side or PKCS#11-provider code is in scope here — this PR adds only the wolfSSL-side dispatcher layer.The dispatcher surface mirrors the operations PKCS#11 v3.1 and v3.2 expose for these algorithms:
wc_LmsKey_MakeKeyCKM_HSS_KEY_PAIR_GENwc_CryptoCb_LmsKeyGenwc_LmsKey_SignCKM_HSS(sign)wc_CryptoCb_LmsSignwc_LmsKey_VerifyCKM_HSS(verify)wc_CryptoCb_LmsVerifywc_LmsKey_SigsLeftCKA_HSS_KEYS_REMAININGwc_CryptoCb_LmsSigsLeftwc_XmssKey_MakeKeyCKM_XMSS_KEY_PAIR_GEN/CKM_XMSSMT_KEY_PAIR_GENwc_CryptoCb_XmssKeyGenwc_XmssKey_SignCKM_XMSS/CKM_XMSSMT(sign)wc_CryptoCb_XmssSignwc_XmssKey_VerifyCKM_XMSS/CKM_XMSSMT(verify)wc_CryptoCb_XmssVerifywc_XmssKey_SigsLeftwc_CryptoCb_XmssSigsLeftXMSS vs XMSSMT is discriminated inside the callback via the existing
XmssKey::is_xmssmtfield, so the dispatcher interface stays unified.Reload/GetKid/ExportPuband the external-backend variants (ext_lms.c,ext_xmss.c, selected by--with-liblms/--with-libxmss) are intentionally out of scope.Design choices
WC_PK_TYPE_LMS_*andWC_PK_TYPE_XMSS_*enums, dedicatedwc_CryptoInfo.pkunion members, and dedicatedwc_CryptoCb_*functions. Rejected the sharedwc_HashSigTypedispatcher style (Dilithium/Falcon) because LMS and XMSS have very different key structs and novoid*erasure benefit.wc_lms.c,wc_xmss.c).ext_lms.c/ext_xmss.ccarry an inline comment noting they do not route through CryptoCb.XmssKeygains adevIdfield underWOLF_CRYPTO_CB;wc_XmssKey_Initnow stores it (previously(void)devId;).LmsKeyalready had the field.write_private_key/read_private_key/contextvalidations so HSM-backed keys don't need dummy software callbacks. OnCRYPTOCB_UNAVAILABLEthe software path still revisits those checks.Reloadshort-circuits for HSM-backed keys (state lives in the device).GetKidlogs a warning becausepriv_rawmay be uninitialised on HSM-backed keys.Commit breakdown
types.h,devIdfield onXmssKey,wc_CryptoInfo.pkunion entries, eightwc_CryptoCb_*declarations and bodies.wc_lms.candwc_xmss.c, plus thewc_XmssKey_InitdevId-store fix.myCryptoDevCbhandlers andlms_test/xmss_testinvoked insidecryptocb_test.int* reson verify dispatchers,word32*sigs-left counts, safer SigsLeft fallback, flattenedmyCryptoDevCbelse-chain, reordered CryptoCb dispatch, HSM-awareReload/GetKid, doc and include cleanups.Test plan
./configure --enable-lms --enable-xmss --enable-cryptocb && make && ./wolfcrypt/test/testwolfcrypt— passes, LMS and XMSS tests exercise the CryptoCb round-trip../configure --enable-lms --enable-xmss && make && ./wolfcrypt/test/testwolfcrypt— new code fully#ifdef-elided, passes../configure --enable-cryptocb && make && ./wolfcrypt/test/testwolfcrypt— LMS/XMSS-less build, passes.testwolfcryptoutput md5 is bit-identical before and after the change under the primary config (801f0730eb597e486ec370f29a6259ce).https://claude.ai/code/session_01MixzJP9kPWkS8bhfDDDBnX
Generated by Claude Code