Skip to content

[skus,fake_keygen] Migrate from SPHINCS+ to SLH-DSA signing - #26

Open
AlexJones0 wants to merge 8 commits into
lowRISC:mainfrom
AlexJones0:slh_dsa_migration
Open

AlexJones0 wants to merge 8 commits into
lowRISC:mainfrom
AlexJones0:slh_dsa_migration

Conversation

@AlexJones0

@AlexJones0 AlexJones0 commented Sep 29, 2026 •

Copy link
Copy Markdown
Contributor

NOTE: This PR depends on #24, and should not be merged until that PR is merged. As such, the first 2 commits of this PR are taken from #24. Only the last 6 commits of this PR are relevant to review here. This also depends on the implementation of a variety of PRs to OpenTitan (lowRISC/opentitan#31551 and lowRISC/opentitan#31553 collectively contain most of the required changes).

This PR migrates the fake SPHINCS+ keys in the SoftHSM2 test instance to standardized SLH-DSA keys. It defines the fake keygen flow to support these keys and makes improvements to the documentation and supporting scripts to make it more clear how to use these flows to run keygen (aside: some improvements still need to be made to general documentation about the changes that are needed outside of SoftHSM2). To completely remove the SPHINCS+ keys from the SoftHSM2 token and insert new SLH-DSA keys, the fake keygen instance is recreated from scratch -- as a result, all existing keys (including ECDSA keys) are effectively rotated by this change. Relevant key material is then propagated to the OTP configuration.

Targets are created for the SLH-DSA signatures, and the open SKU signing flows are updated to use SLH-DSA signing. Note that, although I've run a test signing/release flow from my fork, this will still need to be run for the changes in this PR so that the release archives are updated appropriately. The handling of this should be clarified before this is merged.

One additional note: the downstream perso signing flows rely on the signature directory having an spx_keyset, which this PR retains. It might be worth thinking about how we handle this case, as for example maybe we might want to support different keysets / keyset names?

See the commit messages for more information.

Upstream OpenTitan `earlgrey_1.0.0` has moved to adding a default
keytype to identify keys, where keys can override the keytype. This is
currently being used just to disambiguate SPHINCS+ (`spx`) and SLH-DSA
(`slh-dsa`) keys, but may be extended in the future to refactor the
current signing rule interface, which is a bit crowded.

To ensure SPHINCS+ signing still works with downstream changes, and in
preparation for any future changes, identify the correct default keytype
on every keyset defined in this repository.

Signed-off-by: Alex Jones <alex.jones@lowrisc.org>
Upstream OpenTitan earlgrey_1.0.0 has split the personalization binary
into two parts: flash scrambling and personalization. Update the SKU
configurations to match these changes, so that we can continue building
valid releases.

Signed-off-by: Alex Jones <alex.jones@lowrisc.org>
Small clarifications just to make the documentation a little bit clearer
about the manual steps that must be performed to use SoftHSM.

Signed-off-by: Alex Jones <alex.jones@lowrisc.org>
Comment on lines +138 to +140
// The keys may be exported in plaintext so that they can be
// imported into another HSM.
CKA_SENSITIVE: false,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some background on this choice:

We'd normally want this to be true: the private keys should always live inside the HSM security boundary. However:

  • We are skeptical of HSM backup/restore solutions.
  • We don't want HSM vendor lock-in.
  • We don't want to have a dependency on the long-term stability/existence of a particular vendor (Google's first-generation RoT chip already has a longer-than-expected lifetime).

# If we want to use any SPHINCS+ keys (distinct from SLH-DSA keys), we must set the
# SPX_MODULE to be used. Note that for any SPHINCS+ keys that are stored in the token,
# PKCS#11 elementary files (CKO_DATA objects) are used to store the key material.
export HSMTOOL_SPX_MODULE=pkcs11-ef

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We'll want to get to a world where we don't need this.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree, I think I made the decision to keep this for the migration, but in reality none of the SLH-DSA commands use it so we should just be able to drop it completely if you'd prefer.

@cfrantz

cfrantz commented Oct 9, 2026

Copy link
Copy Markdown
Collaborator

Overall, this LGTM.

@AlexJones0

Copy link
Copy Markdown
Contributor Author

The last force push replaces the checked-in owner/app keys to match, and updates the X.509 DICE CA cert as well. It standardizes to use the spx_keyset name (in relation to the open question in the PR), since this is probably going to be the easiest solution for now.

Now that upstream hsmtool supports SLH-DSA, we can update the fake
keygen templates (root, owner, application) to use SLH-DSA keys instead
of SPHINCS+ keys. This requires tweaking some of the parameters, and
moving the export to happen via the `export` command, rather than at
generation time, as before (with `hsmtool spx`).

Also update the status of two TODOs related to this in the docs.

Signed-off-by: Alex Jones <alex.jones@lowrisc.org>
- Change the bash shebang used for increased compatibility with
  different systems/environments.
- Add some basic status prints to the keygen and export which describe
  which subdir we are generating keys for - this helps a bit with
  debugging misconfigured keygen & export templates.
- Since the CA subdir currently doesn't export any keys in PEM format,
  the shell expansion of the `*.pem` globs will fail in the final tar.
  Since this is expected, set the shell option to not error on null
  globs whilst executing these tars to silence some noise.
- The last time this script was run, only the CA key was generated - and
  the commenting out of other subdirs was kept in. Restore this to its
  original state.

Signed-off-by: Alex Jones <alex.jones@lowrisc.org>
Most of the subdirs (root, owner, application, but not ca) have changed
from using SPHINCS+ keys to SLH-DSA keys. Completely re-generate the
SoftHSM2 token from scratch using the full keygen & exporting flow.

For posterity, this was generated by following the commands documented
in `skus/open/fake_keygen/README.md`.

Signed-off-by: Alex Jones <alex.jones@lowrisc.org>
The documentation refers to using `HSMTOOL_SPX_MODULE` for SLH-DSA keys,
but these are actually for "SPHINCS+" keys as we would call them, as
they are used with hsmtool's legacy `spx` hierarchy, and not the newer
`slh-dsa` hierarchy.

I considered removing this completely, but it could cause problems if
someone wants to add some SPHINCS+ keys in the future. Instead, for now,
clarify the documentation a bit and leave it as is.

Signed-off-by: Alex Jones <alex.jones@lowrisc.org>
Replace the root, owner and CA keys with the fake keys that were
generated by the latest round of keygen. The owner and application keys
are documented as TBD, but they match the previous fake keygen round, so
these are updated to match.

Changes to use SLH-DSA keys instead of SPHINCS+ keys mean that the
SoftHSM2 token containing the fake keys has been regenerated. As such,
all fake keys (including existing ECDSA keys) have been rotated.

Rotating the root keys also involves updating the OTP configuration,
which is included here. The SPHINCS+ keysets now identify the keys as
SLH-DSA keys for the downstream OpenTitan signing rules. Some outdated
documentation is also replaced - removed a couple of stale TODOs, and
changed some extensions from `.pem` to `.der` where required for ECDSA
keys.

Since the ECDSA CA key has been rotated, the X.509 DICE CA cert is
also correspondingly updated. This was done via OpenSSL:
```
openssl req -new -x509 \
  -config skus/open/keys/ca/dice_ca.conf \
  -engine pkcs11 -keyform engine \
  -key "pkcs11:token=temp;object=nuvoton-ot00-ca-ecdsa-0;type=private?pin-value=123456" \
  -sha256 -days 99999 \
  -out skus/open/keys/ca/dice_ca.pem
```
And self-verified with `openssl verify -CAfile ...`

Signed-off-by: Alex Jones <alex.jones@lowrisc.org>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants