lowRISC / lowRISC/opentitan

[RFC] CNSA 2.0 Compliance Rooted in the ROM

Open
#30,765 4 comments 0 reactions 2 assignees Claimed by @vogelpi View on GitHub
CNSA2.0 RFC:Proposal SW:ROM SW:ROM_EXT Triage Priority
Dominant language
SystemVerilog
Stars
3.6k
Forks
1.1k
Avg merge
2d 22h
Merged PRs (30d)
141

Description

### Description

This RFC proposes a path to [CNSA 2.0](https://media.defense.gov/2025/May/30/2003728741/-1/-1/0/CSA_CNSA_2.0_ALGORITHMS.PDF) (NSA Commercial National Security Algorithm Suite 2.0) compliance for the OpenTitan secure boot chain, anchored in the EarlGrey ROM. It is based on an analysis of the current ROM, ROM\_EXT, ownership, and attestation implementations.

## CNSA 2.0 requirements relevant to OpenTitan

CNSA 2.0 ([September 2022](https://media.defense.gov/2025/May/30/2003728741/-1/-1/0/CSA_CNSA_2.0_ALGORITHMS.PDF), with [subsequent FAQ updates](https://media.defense.gov/2022/Sep/07/2003071836/-1/-1/0/CSI_CNSA_2.0_FAQ_.PDF)) replaces the quantum-vulnerable public-key algorithms of CNSA 1.0 (ECDSA P-384, ECDH P-384, RSA-3072) with quantum-resistant algorithms:

| Function | CNSA 2.0 algorithm | Standard | Notes |
| :---- | :---- | :---- | :---- |
| **Software / firmware signing** | LMS or XMSS (excluded from this proposal see scope note below), or ML-DSA-87 | NIST SP 800-208 / FIPS 204 | ML-DSA-87 is permitted for signing per NSA guidance. |
| General digital signatures | ML-DSA-87 | FIPS 204 | Security category 5\. |
| Key establishment | ML-KEM-1024 | FIPS 203 | Security category 5\. |
| Symmetric encryption | AES-256 | FIPS 197 | |
| Hashing | SHA-384 or SHA-512 | FIPS 180-4 | SHAKE remains acceptable *inside* ML-DSA (it is intrinsic to FIPS 204). |

OpenTitan does not support the use of stateful signatures due to operational concerns. This RFC excludes the stateful hash-based schemes (LMS and XMSS) for this purpose.

**ML-DSA-87 is the sole quantum-resistant signature algorithm used** in this proposal, and the design consequences of its larger keys, signatures, and verifier footprint are discussed at a high level.

## Current cryptographic composition of the boot-chain

Summary of the current boot-chain implementation.

| Boot step | Mechanism | Algorithms | Where |
| :---- | :---- | :---- | :---- |
| ROM integrity | Hardware check at power-up: `rom_ctrl` streams ROM to KMAC, compares cSHAKE-256 digest against expected value in top 8 ROM words; digest also folded into `CreatorRootKey` via keymgr | cSHAKE-256 (SHA-3 family) | `hw/ip/rom_ctrl/` |
| ROM verifies ROM\_EXT | Mandatory ECDSA \+ optional (OTP-gated, `CREATOR_SW_CFG_SIGVERIFY_SPX_EN`) SPHINCS+ hybrid, AND-composed via the XOR-share `flash_exec` unlock word (`kSigverifyFlashExec = kSigverifyEcdsaSuccess ^ kSigverifySpxSuccess`) | ECDSA P-256 (OTBN) \+ SPHINCS+-SHA2-128s (HMAC HW); image digest SHA-256 | `sw/device/silicon_creator/rom/rom.c`, `lib/sigverify/` |
| Creator root keys | 4 ECDSA \+ 4 SPX slots in OTP `ROT_CREATOR_AUTH_CODESIGN` (locked, SHA-256 integrity hash), one-way per-slot revocation in `ROT_CREATOR_AUTH_STATE` (BLANK → PROVISIONED → REVOKED) | ECDSA P-256 (68 B/slot), SPX (40 B/slot) | `rom/sigverify_otp_keys.{c,h}` |
| Anti-rollback | `security_version` vs `boot_data.min_security_version_rom_ext`; digest poisoning \+ boot-policy rejection | SHA-256 boot\_data digest | `lib/boot_data.h`, `rom/boot_policy.c` |
| ROM\_EXT verifies BL0 | Owner application key: ECDSA P-256, or hybrid ECDSA \+ SPHINCS+ (pure SPX not allowed for app keys); SPX key/signature carried as manifest extensions | ECDSA P-256, SPHINCS+-SHA2-128s | `rom_ext/rom_ext_verify.c`, `lib/ownership/owner_verify.c` |
| Ownership transfer | Owner block (2048 B, three 96-B `owner_keydata_t` slots: owner/activate/unlock); inline signatures ECDSA-only, SPX/hybrid require an 8 KiB detached-signature page | ECDSA P-256, SPHINCS+ | `lib/ownership/` |
| Attestation (DICE) | UDS → CDI\_0 → CDI\_1 certificate chain, keymgr-derived keys, OTBN sign/endorse | ECDSA P-256 only | `lib/cert/dice*.c` |
| Sealing / measurement | KMAC-256 owner-page seal (keymgr sideload); SHA-256 measurements | KMAC-256, SHA-256 | `lib/ownership/ownership_key.c` |

## Gap analysis

| \# | Gap | CNSA 2.0 requirement | Severity |
| :---- | :---- | :---- | :---- |
| G1 | ROM signature verification is ECDSA P-256 \+ optional SPHINCS+-128s | Firmware signatures must be ML-DSA-87 exclusively by 2030 | **Blocking**: ECDSA P-256 and SPHINCS+ are not CNSA 2.0 approved |
| G2 | Image digest, boot\_data digest, OTP key-partition integrity hash are SHA-256 | SHA-384 or SHA-512 for general hashing | High (SHAKE acceptable only inside FIPS 204 constructions) |
| G3 | ML-DSA-87 exists only as an OTBN/cryptolib app; it is not integrated into any boot stage, and the current 32 KiB metal ROM cannot host the OTBN verify app alongside the existing boot code (resolved by the 196 KiB ROM in EarlGrey v2) | ML-DSA-87 verification must be rooted in the first immutable stage | **Blocking**: Existing silicon cannot meet this requirement. |
| G4 | ML-DSA-87 public keys (2592B) and signatures (4627B) do not fit any existing key/signature container: OTP slots, inline manifest fields, `owner_keydata_t` | Root keys must be anchored in OTP; signatures must be carried with the image | High |
| G5 | Owner/ownership structures cap keys at 96 B (`owner_keydata_t`) and inline signatures are ECDSA-only | Owner-stage verification must also migrate | High |
| G6 | DICE attestation chain is ECDSA P-256 only | Attestation signatures should move to CNSA algorithms (P-384 interim, ML-DSA-87 target) | Medium |
| G7 | OTP `ROT_CREATOR_AUTH_CODESIGN` layout hard-codes ECDSA-P256 / ML-DSA slots | Root-key anchors for ML-DSA-87 and ECDSA P-384 need a new layout | **Blocking**: Existing silicon cannot meet this requirement. |
| G8 | No ML-KEM-1024 (affects encrypted firmware-update / rescue channels, not signature-based boot) | Key establishment | Low: ML-KEM is part of the OpenTitan roadmap. |
| G9 | Deployed EarlGrey silicon has an immutable ROM that can never verify CNSA 2.0 signatures | — | Structural: full "rooted in ROM" compliance requires a ROM spin; deployed parts need an interim root at ROM\_EXT |

## Proposed architecture

### Algorithm selection

**ROM verifies ROM\_EXT: ML-DSA-87, hybrid with ECDSA P-384 during the transition**. Integration analysis for ML-DSA-87 at ROM stage:

| Dimension | Consequence for the ROM design |
| :---- | :---- |
| Verifier implementation | Use a hardened, ACVP-tested **OTBN `mldsa87_verify` app**. The OTBN app binary must be stored in ROM and loaded into OTBN IMEM/DMEM by the ROM (the same model as today's `kOtbnAppBoot` ECDSA app) |
| Trusted Computing Base (TCB) | OTBN **and** KMAC (SHAKE, driven via OTBN's KMAC CSR interface) are part of the TCB. Both blocks are already exercised pre-kernel today (OTBN for ECDSA, KMAC by `rom_ctrl` hardware), but their drivers/apps now need ROM-grade fault-injection review. |
| Public key | Cannot live in OTP. Anchor a **SHA-384 digest** of the key in the OTP slot; the full key travels in a signed manifest extension and is digest-checked in SRAM before use. Same trust math, constant OTP cost. |
| Signature | Carried as a manifest extension; the current SPHINCS+ extension is \~7.9 KiB, so memory-side capacity is a non-issue. |
| Verify performance | Fast on OTBN (NTT-based); well within the boot-time budget (top-level specific). |
| ROM size | The current 32 KiB ROM could not absorb the OTBN verify app plus driver, hash-anchored key handling, and SHA-384 plumbing even after deleting the SPHINCS+ verifier. The **next EarlGrey generation grows the ROM to 196 KiB**, which comfortably hosts the ML-DSA-87 verify app (multi-KiB IMEM image) alongside the existing boot code. All other top-levels are recommended to increase ROM sizes accordingly. |
| Signer | **Stateless**: no signing-state management, standard HSM key handling, backups permitted. This is what the stateful-scheme exclusion buys. |

**Owner stages (ROM\_EXT verifies BL0; ownership transfer): ML-DSA-87, hybrid with ECDSA P-384 during the transition**. Owner keys move to a key-by-digest scheme to fit existing structures.

**Attestation (DICE): ECDSA P-384 interim hybrid, ML-DSA-87 target**, both already implemented on OTBN.

**Hashing: SHA-384** (HMAC hardware) for the image digest, usage-constraint binding, boot\_data digest, OTP key-partition integrity hash, and ML-DSA public-key anchoring in the new ROM generation.

**Key establishment: ML-KEM-1024** added to cryptolib (OTBN \+ KMAC interface) for encrypted update/rescue payloads (not part of this RFC, but referenced for completeness).

Update by @vogelpi: correct links, added link to relevant FAQ.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.