Repository navigation
Fix hybrid LMS/XMSS keystore import and PQ secondary builds - #963
Merged
Merged
Conversation
danielinux
approved these changes
Oct 29, 2026
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.
Description
Hybrid signing has never worked with LMS or XMSS as one of the two algorithms. On current master:
wolfBoot_verify_signature_lms()and..._xmss()imported the public key atKEYSTORE_PUBKEY_SIZE, the keystore slot width. WithWOLFBOOT_UNIVERSAL_KEYSTORE=1that macro falls through to the RSA-4096 value, so the key arrives padded and the import rejects it. In a single-algorithm build the macro is the LMS or XMSS size, which is whysim-lmsandsim-xmsspass and this went unseen. The key tools always store exactlyKEYSTORE_PUBKEY_SIZE_LMSor_XMSSbytes in the slot, so the verify side now imports that length. ML-DSA was unaffected, as it already asked the key for its own length.The same assumption - that the primary algorithm describes the whole keystore - caused three more. The
SIGN_SECONDARYbranches defined the primary macros to get the verify bodies compiled, so a classic primary with a post-quantum secondary definedwolfBoot_verify_signature_primarytwice and did not build; the slot width and the-Wstack-usageceiling followed the primary alone; andkeygen -imistook slot padding for a DER header when reading the first public key back out of the keystore.Separately, the LMS callback setters and
wc_LmsKey_Reload()reject a key already inWC_LMS_STATE_OK, which is what a successful signature leaves behind, so a delta image - which signs its own header - failed. The key is now loaded once. Andheader_required_size()now sizes the manifest for every image rather than only when a certificate chain, custom TLV or DTS is present, with the delta path resolving the same growth before it computes the inverse-patch offset.Testing
Adds simulator jobs pairing LMS and XMSS with ECDSA P-256 under a universal keystore, in both orderings, which is the combination that had no coverage. Reverting only the changed source files makes all three new jobs fail, so they are regression tests rather than decoration.
sim-lms,sim-xmss,sim-ml-dsa-ecc-hybridandsim.configare unchanged, the unit tests pass, and the LMS and XMSS footprint limits are untouched because the verify paths come out byte-identical in size.