Support RFC 9802 LMS and XMSS in X.509 certificate and CSR generation#21
Open
Frauschi wants to merge 3 commits into
Open
Support RFC 9802 LMS and XMSS in X.509 certificate and CSR generation#21Frauschi wants to merge 3 commits into
Frauschi wants to merge 3 commits into
Conversation
Builds on the existing RFC 9802 LMS/XMSS X.509 verification support by
wiring HSS/LMS and XMSS/XMSS^MT keys into the certificate and PKCS#10
certificate-request generation API. LMS/XMSS now follow the same
"sign the message directly, no pre-hash" pattern already used for
Falcon / ML-DSA / SLH-DSA.
Public API:
- New CertType values LMS_TYPE, XMSS_TYPE, XMSSMT_TYPE accepted by
wc_MakeCert_ex, wc_SignCert_ex and wc_MakeCertReq_ex.
- New cert_enums values LMS_KEY, XMSS_KEY, XMSSMT_KEY.
- New wc_LmsKey_PublicKeyToDer / wc_XmssKey_PublicKeyToDer encoders that
emit the RFC 9802 SubjectPublicKeyInfo via the existing
SetAsymKeyDerPublic helper and the already-registered HSS_LMSk /
XMSSk / XMSSMTk key OIDs.
- Callers set cert->sigType to CTC_HSS_LMS / CTC_XMSS / CTC_XMSSMT.
Implementation:
- Thread LmsKey*/XmssKey* through EncodePublicKey, MakeAnyCert,
MakeCertReq, MakeSignature and SignCert (ASN.1 template path).
- SignCert sizes the signature buffer at runtime from
wc_LmsKey_GetSigLen / wc_XmssKey_GetSigLen, since LMS/XMSS signatures
are parameter-dependent and can exceed MAX_ENCODED_SIG_SZ.
- Forward-declare LmsKey/XmssKey in asn_public.h (guarded typedefs in
wc_lms.h/wc_xmss.h) so the shared signatures compile regardless of
feature macros, mirroring the Falcon/ML-DSA/SLH-DSA convention.
- Enable WC_ENABLE_ASYM_KEY_EXPORT/IMPORT for LMS/XMSS builds so the
asymmetric SPKI encoder is compiled.
- The original (non-template) asn_orig.c MakeAnyCert/MakeCertReq keep
signature parity but ignore the new keys; LMS/XMSS cert generation is
template-only, consistent with the verification support.
Like all stateful hash-based signatures, each generated certificate and
each CSR proof-of-possession consumes one one-time signature; callers
must persist key state through the read/write callbacks.
Tests:
- test_rfc9802_lms_x509_gen and test_rfc9802_xmss_x509_gen generate a
self-signed root CA and a PKCS#10 CSR for LMS and XMSS, then verify
the cert through wolfSSL_CertManagerVerifyBuffer and the CSR's
proof-of-possession through wc_ParseCert.
https://claude.ai/code/session_01RDkoNViK5aNkUAJqnuL8Y5
Addresses code review findings on the LMS/XMSS certificate/CSR generation change: - SignCert: in WOLFSSL_NO_MALLOC builds the CertSignCtx signature buffer is a fixed MAX_ENCODED_SIG_SZ array. The runtime LMS/XMSS sizing only grew the malloc'd buffer, so a signature larger than MAX_ENCODED_SIG_SZ would overflow the fixed array. Now hard-fail with BUFFER_E in that case instead of writing past the buffer. - settings.h: only pull LMS/XMSS into WC_ENABLE_ASYM_KEY_EXPORT/IMPORT when not built verify-only, so verify-only configs no longer compile the unused private-key DER export/import paths. - asn_public.h: document the stateful one-time-signature caveat on the new LMS_TYPE/XMSS_TYPE/XMSSMT_TYPE values where API users will see it. - Tests: refactor the cert+CSR round trip into a shared helper and extend coverage to multi-level HSS (L2) and XMSS^MT (XMSSMT_TYPE / XMSSMTk OID / CTC_XMSSMT), which were previously unexercised; drop the redundant XMEMSET before wc_InitCert. Verified with full, WOLFSSL_ASN_ORIGINAL (non-template), and verify-only LMS/XMSS builds; api suite passes with 0 failures. https://claude.ai/code/session_01RDkoNViK5aNkUAJqnuL8Y5
Addresses the second round of review feedback. - SignCert now rejects a signature type that does not match the key: an LMS key requires CTC_HSS_LMS, and an XMSS key requires CTC_XMSS or CTC_XMSSMT according to key->is_xmssmt. Since MakeAnyCert derives the SubjectPublicKeyInfo OID from is_xmssmt, this guarantees the emitted signatureAlgorithm always agrees with the public key, so a mismatched sigType can no longer silently produce a malformed certificate. The check runs before any signing, so no one-time signature is consumed. - The XMSS_TYPE/XMSSMT_TYPE selector passed to wc_MakeCert_ex, wc_MakeCertReq_ex and wc_SignCert_ex is now validated against the key's actual tree variant (BAD_FUNC_ARG on mismatch), so the two selectors are no longer silently interchangeable. - asn_orig.c (non-template build): MakeAnyCert/MakeCertReq now emit a WOLFSSL_MSG and return ALGO_ID_E when handed an LMS/XMSS key, instead of a bare BAD_FUNC_ARG, making the "requires WOLFSSL_ASN_TEMPLATE" limitation diagnosable. - Tests: add negative cases exercising the new validation (LMS key signed with CTC_XMSS -> ALGO_ID_E; XMSSMT_TYPE selector on a single-tree XMSS key -> BAD_FUNC_ARG; single-tree XMSS key signed with CTC_XMSSMT -> ALGO_ID_E). Documented the void* key parameter of the round-trip helper. No interop test added: OpenSSL still lacks LMS/XMSS X.509 certificate signing (openssl/openssl#21360) and Bouncy Castle's encoding is not yet aligned with the final RFC 9802, so there is no aligned third-party implementation to interoperate against. https://claude.ai/code/session_01RDkoNViK5aNkUAJqnuL8Y5
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.
Overview
Builds on the existing RFC 9802 LMS/XMSS X.509 verification support by wiring HSS/LMS and XMSS/XMSS^MT keys into the certificate and PKCS#10 certificate-request generation API. These stateful hash-based schemes follow the same "sign the message directly, no pre-hash" pattern already used for Falcon / ML-DSA / SLH-DSA.
CSR support is included (per design discussion): cert signing and CSR proof-of-possession share the same
MakeSignature()dispatch, and there's no reason to special-case CSRs out. The only caveat — each cert and each CSR consumes one of the key's finite one-time signatures — is inherent to the scheme and documented at the API surface.Public API
CertTypeselectorsLMS_TYPE,XMSS_TYPE,XMSSMT_TYPEaccepted bywc_MakeCert_ex,wc_SignCert_exandwc_MakeCertReq_ex.cert_enumsvaluesLMS_KEY,XMSS_KEY,XMSSMT_KEY.wc_LmsKey_PublicKeyToDer/wc_XmssKey_PublicKeyToDerencoders that emit the RFC 9802 SubjectPublicKeyInfo via the existingSetAsymKeyDerPublichelper and the already-registeredHSS_LMSk/XMSSk/XMSSMTkkey OIDs.cert->sigTypetoCTC_HSS_LMS/CTC_XMSS/CTC_XMSSMT.Implementation
LmsKey*/XmssKey*throughEncodePublicKey,MakeAnyCert,MakeCertReq,MakeSignatureandSignCert(ASN.1 template path), mirroring the existing PQ-key plumbing.SignCertsizes the signature buffer at runtime fromwc_LmsKey_GetSigLen/wc_XmssKey_GetSigLen, since LMS/XMSS signatures are parameter-dependent and can exceedMAX_ENCODED_SIG_SZ. InWOLFSSL_NO_MALLOCbuilds (fixed-size buffer) an oversized signature fails cleanly withBUFFER_Erather than overflowing.SignCertvalidates thatsigTypematches the key (LMS →CTC_HSS_LMS; XMSS →CTC_XMSS/CTC_XMSSMTperis_xmssmt), and theXMSS_TYPE/XMSSMT_TYPEselector is validated against the key's tree variant — so a mismatch returns an error instead of silently emitting a malformed certificate.LmsKey/XmssKeyinasn_public.h(guarded typedefs inwc_lms.h/wc_xmss.h) so the shared signatures compile regardless of feature macros.WC_ENABLE_ASYM_KEY_EXPORT/IMPORTfor non-verify-only LMS/XMSS builds so the SPKI encoder is compiled.MakeAnyCert/MakeCertReqemit a clear diagnostic andALGO_ID_Eif handed such a key.Tests
test_rfc9802_lms_x509_gen/test_rfc9802_xmss_x509_gengenerate a self-signed root CA and a PKCS#10 CSR, then verify the cert viawolfSSL_CertManagerVerifyBufferand the CSR proof-of-possession viawc_ParseCert. Coverage includes single-level LMS, multi-level HSS (L2), single-tree XMSS, and XMSS^MT, plus negative cases for sigType/keyType and selector mismatches.Notes / scope
WOLFSSL_ASN_ORIGINAL(non-template), and verify-only LMS/XMSS builds; the API test suite passes with 0 failures, andtestwolfcryptpasses.https://claude.ai/code/session_01RDkoNViK5aNkUAJqnuL8Y5
Generated by Claude Code