From eb9f72b9952b0e67f43ca11d1107ad37f67fccc9 Mon Sep 17 00:00:00 2001 From: Aidan Garske Date: Tue, 6 Oct 2026 15:46:41 -0700 Subject: [PATCH] Clean up the README and wiki documentation --- README.md | 86 ++++++++++++++++---------------- docs/API-Reference.md | 16 +++--- docs/Attestation-Notes.md | 19 ++++--- docs/Configuration-and-Macros.md | 15 +++--- docs/Home.md | 14 +++--- docs/Message-Chunking.md | 8 +-- docs/Post-Quantum-ML-DSA.md | 18 +++---- docs/Post-Quantum-ML-KEM.md | 18 +++---- docs/Project-Structure.md | 2 +- docs/Testing-and-CI.md | 4 +- 10 files changed, 100 insertions(+), 100 deletions(-) diff --git a/README.md b/README.md index 8f47177..fd20cb9 100644 --- a/README.md +++ b/README.md @@ -1,22 +1,44 @@ # wolfSPDM -wolfSPDM is a lightweight C library implementing [SPDM 1.2 / 1.3 / 1.4](https://www.dmtf.org/sites/default/files/standards/documents/DSP0274_1.4.0.pdf) and [Secured Messages over MCTP (DSP0277)](https://www.dmtf.org/sites/default/files/standards/documents/DSP0277_1.2.0.pdf) using [wolfSSL](https://www.wolfssl.com/) as the crypto backend. It is a standalone, requester-only stack designed for embedded use, tested end-to-end against the DMTF [spdm-emu](https://github.com/DMTF/spdm-emu) emulator. +wolfSPDM is a lightweight C library implementing [SPDM 1.2 / 1.3 / 1.4](https://www.dmtf.org/sites/default/files/standards/documents/DSP0274_1.4.0.pdf) and [Secured Messages over MCTP (DSP0277)](https://www.dmtf.org/sites/default/files/standards/documents/DSP0277_1.2.0.pdf), using [wolfSSL](https://www.wolfssl.com/) as the crypto backend. It provides both the **standard DMTF SPDM requester** for embedded use and the **TCG-spec TPM SPDM binding** that powers wolfTPM, tested end-to-end against the DMTF [spdm-emu](https://github.com/DMTF/spdm-emu) emulator. + +## Standard and TCG TPM SPDM + +wolfSPDM is one SPDM implementation with a shared core: version, capability, and algorithm negotiation, key exchange, secured sessions, transcript, and crypto. The standard DMTF requester and the TCG TPM binding are closely related modes on that core, selected by build switches: + +- **Standard DMTF SPDM** (default): the 1.2 / 1.3 / 1.4 certificate requester (DSP0274 and Secured Messages over MCTP DSP0277), post-quantum ready, for embedded use. +- **TCG TPM SPDM**: the TCG-spec SPDM binding (TPM transport, identity-key mutual auth, PSK, responder) that provides wolfTPM's SPDM support. + +**Standalone (DMTF requester):** + +```bash +./configure +make +``` + +**With wolfTPM (TCG TPM SPDM):** wolfTPM builds wolfSPDM automatically when its SPDM support is enabled (`WOLFTPM_SPDM`). To build the TPM side here, opt into the pieces you need on top of the default: + +```bash +./configure --enable-tcg --enable-psk --enable-responder +make +``` + +Add `--disable-mctp` for a TPM-only build that drops the standard DMTF requester entirely, and `--enable-nuvoton` / `--enable-nations` for vendor TPM commands. Each piece is independent, so you can compose exactly what you want: `--enable-tcg` alone gives just the TCG binding (PSK and the responder stay off until you enable them). ## Main Features - **Standard SPDM 1.2 / 1.3 / 1.4 requester** per DMTF DSP0274 and DSP0277 - **Algorithm Set B fixed:** ECDSA P-384, ECDHE P-384, SHA-384, AES-256-GCM, HKDF-SHA384 -- **Post-quantum signatures (SPDM 1.4):** optional ML-DSA-44 / 65 / 87 (FIPS 204), dual-stacked with ECDSA P-384 — see the [Post-Quantum ML-DSA](https://github.com/aidangarske/wolfSPDM/wiki/Post-Quantum-ML-DSA) wiki page -- **Post-quantum key exchange (SPDM 1.4):** optional ML-KEM-512 / 768 / 1024 (FIPS 203), advertised alongside ECDHE P-384 — see the [Post-Quantum ML-KEM](https://github.com/aidangarske/wolfSPDM/wiki/Post-Quantum-ML-KEM) wiki page +- **Post-quantum signatures (SPDM 1.4):** optional ML-DSA-44 / 65 / 87 (FIPS 204), dual-stacked with ECDSA P-384. See the [Post-Quantum ML-DSA](https://github.com/wolfSSL/wolfSPDM/wiki/Post-Quantum-ML-DSA) wiki page. +- **Post-quantum key exchange (SPDM 1.4):** optional ML-KEM-512 / 768 / 1024 (FIPS 203), advertised alongside ECDHE P-384. See the [Post-Quantum ML-KEM](https://github.com/wolfSSL/wolfSPDM/wiki/Post-Quantum-ML-KEM) wiki page. - **Fully post-quantum SPDM handshake:** ML-KEM key exchange + ML-DSA authentication (no classical asymmetric crypto), proven end-to-end against spdm-emu -- **Zero-malloc by default:** static memory, ~19 KB context (~59 KB with ML-DSA), ideal for constrained/embedded environments -- **Optional `--enable-dynamic-mem`** for heap-allocated contexts on small-stack platforms +- **Zero-malloc by default:** static context for constrained targets; optional `--enable-dynamic-mem` for heap-allocated contexts on small-stack platforms - **Full session lifecycle:** key exchange, finish, encrypted messaging, heartbeat keep-alive, key update - **Device attestation:** signed / unsigned `GET_MEASUREMENTS`, sessionless `CHALLENGE_AUTH`, certificate-chain validation against trusted root CAs - **Compatible with DMTF spdm-emu** for interoperability testing (21-test matrix across 1.2 / 1.3 / 1.4) - **Path to FIPS 140-3** via wolfCrypt FIPS Certificate #4718 (sole crypto dependency) -## Supported Operations (RFC / DSP0274) +## Supported Operations (DSP0274 / DSP0277) | Operation | DSP0274 | wolfSPDM API | |---|---|---| @@ -45,7 +67,7 @@ sudo ldconfig `--enable-sp` enables Single Precision math with optimized ECC P-384, required for SPDM Algorithm Set B on ARM64 and other constrained targets. `--enable-all` works as a superset. -For post-quantum cryptography, add `--enable-mldsa` (signatures, FIPS 204) and/or `--enable-mlkem` (key exchange, FIPS 203) to wolfSSL — use wolfSSL master (or a release that ships the `wc_MlDsaKey` context API and `wc_MlKemKey` API). wolfSPDM then auto-enables each when the linked wolfSSL provides it; `./configure --disable-mldsa` / `--disable-mlkem` force them off. Enabling both gives a fully post-quantum SPDM handshake (ML-KEM key exchange + ML-DSA authentication). +For post-quantum support, build wolfSSL with `--enable-mldsa` (FIPS 204) and/or `--enable-mlkem` (FIPS 203). Use wolfSSL master or a release carrying the `wc_MlDsaKey` and `wc_MlKemKey` APIs. wolfSPDM auto-enables each when the linked wolfSSL provides it (`--disable-mldsa` / `--disable-mlkem` force them off); enabling both gives a fully post-quantum handshake (ML-KEM key exchange + ML-DSA authentication). ## Build @@ -74,7 +96,7 @@ make check ### Memory Modes -**Static (default):** zero heap allocation. The caller provides a buffer (`WOLFSPDM_CTX_STATIC_SIZE` bytes: 32 KB, 40 KB with ML-KEM, 72 KB with ML-DSA) and wolfSPDM operates entirely within it. Ideal for embedded and constrained environments where malloc is unavailable or undesirable. +**Static (default):** zero heap allocation. The caller provides a buffer of `WOLFSPDM_CTX_STATIC_SIZE` bytes and wolfSPDM operates entirely within it. Ideal for embedded and constrained environments where malloc is unavailable or undesirable. ```c #include @@ -112,18 +134,7 @@ export SPDM_EMU_PATH=../spdm-emu/build/bin ./examples/spdm_test.sh ``` -The driver starts/stops `spdm_responder_emu` per test and runs seven scenarios — Session, Signed Measurements, Unsigned Measurements, Challenge, Heartbeat, Key Update, Application Data (PLDM GetTID) — across SPDM 1.2, 1.3, and 1.4 (21 tests total). - -## Relationship to wolfTPM's SPDM - -wolfSPDM is the SPDM stack wolfTPM builds on. Its core is the SPDM code that wolfTPM shipped in `src/spdm/` (TCG binding, Nuvoton NPCT75x and Nations NS350 vendor commands, PSK, the responder), with the standard DMTF requester layered on top. Build switches decide which side is compiled, so a standalone build carries none of the TPM code and a wolfTPM build carries none of the standard requester: - -| Build | Compiled in | `sizeof(WOLFSPDM_CTX)` (arm64) | -|---|---|---| -| Standalone (default) | Standard DSP0274 / DSP0277 requester: certificates, attestation, heartbeat, key update, chunking, application data; ML-DSA / ML-KEM when wolfSSL has them | ~19 KB classical, ~59 KB with ML-DSA | -| Standalone + TPM side | Adds `--enable-tcg` / `--enable-nuvoton` / `--enable-nations` / `--enable-psk` / `--enable-responder` | ~19 KB classical | -| Pure TCG (`--disable-mctp`) | TCG binding, vendors, PSK and responder only | ~9.6 KB | -| wolfTPM (`WOLFTPM_SPDM`, profile `WOLFSPDM_PROFILE_TPM`) | What wolfTPM needs: TCG binding, vendors, PSK, responder | ~9.5 KB | +The driver starts/stops `spdm_responder_emu` per test and runs seven scenarios across SPDM 1.2, 1.3, and 1.4 (21 tests total): Session, Signed Measurements, Unsigned Measurements, Challenge, Heartbeat, Key Update, and Application Data (PLDM GetTID). ## CI / Testing @@ -138,32 +149,25 @@ Runs on every push and PR: - **SPDM Emulator Integration**: 21-test matrix (7 scenarios x SPDM 1.2 / 1.3 / 1.4) across ubuntu-22.04 x64, ubuntu-24.04 x64, and ubuntu-24.04-arm aarch64, plus chunking against small-buffer responders - **SPDM Emulator PQC**: ML-DSA-44 / 65 / 87, ML-KEM-512 / 768 / 1024 and the fully post-quantum handshake against spdm-emu on OpenSSL - **wolfTPM downstream**: wolfTPM master built with this wolfSPDM in its 14 SPDM configurations, its unit tests, and the fwTPM TCG and PSK end-to-end runs; the standard requester must stay compiled out -- **Skoll review**: wolfSSL deep-review pipeline, pre-merge security and code review - - - - - - - - + + ## Documentation -Full documentation is available in the [GitHub Wiki](https://github.com/aidangarske/wolfSPDM/wiki): +Full documentation is available in the [GitHub Wiki](https://github.com/wolfSSL/wolfSPDM/wiki): -- [Getting Started](https://github.com/aidangarske/wolfSPDM/wiki/Getting-Started): Build instructions, prerequisites, memory modes, and first connection steps -- [Supported Operations](https://github.com/aidangarske/wolfSPDM/wiki/Supported-Operations): SPDM operation coverage and API mapping -- [API Reference](https://github.com/aidangarske/wolfSPDM/wiki/API-Reference): Public function groups and common error-code references -- [Configuration and Macros](https://github.com/aidangarske/wolfSPDM/wiki/Configuration-and-Macros): Configure flags and compile-time feature controls -- [Post-Quantum ML-DSA](https://github.com/aidangarske/wolfSPDM/wiki/Post-Quantum-ML-DSA): Post-quantum signatures (FIPS 204) -- [Post-Quantum ML-KEM](https://github.com/aidangarske/wolfSPDM/wiki/Post-Quantum-ML-KEM): Post-quantum key exchange (FIPS 203) and the fully post-quantum handshake -- [Message Chunking](https://github.com/aidangarske/wolfSPDM/wiki/Message-Chunking): SPDM 1.2 CHUNK_GET reassembly for large responses -- [Testing and CI](https://github.com/aidangarske/wolfSPDM/wiki/Testing-and-CI): Unit tests, emulator integration tests, and CI workflow coverage -- [Project Structure](https://github.com/aidangarske/wolfSPDM/wiki/Project-Structure): Source layout and module responsibilities -- [Attestation Notes](https://github.com/aidangarske/wolfSPDM/wiki/Attestation-Notes): Measurement and challenge attestation behavior +- [Getting Started](https://github.com/wolfSSL/wolfSPDM/wiki/Getting-Started): Build instructions, prerequisites, memory modes, and first connection steps +- [Supported Operations](https://github.com/wolfSSL/wolfSPDM/wiki/Supported-Operations): SPDM operation coverage and API mapping +- [API Reference](https://github.com/wolfSSL/wolfSPDM/wiki/API-Reference): Public function groups and common error-code references +- [Configuration and Macros](https://github.com/wolfSSL/wolfSPDM/wiki/Configuration-and-Macros): Configure flags and compile-time feature controls +- [Post-Quantum ML-DSA](https://github.com/wolfSSL/wolfSPDM/wiki/Post-Quantum-ML-DSA): Post-quantum signatures (FIPS 204) +- [Post-Quantum ML-KEM](https://github.com/wolfSSL/wolfSPDM/wiki/Post-Quantum-ML-KEM): Post-quantum key exchange (FIPS 203) and the fully post-quantum handshake +- [Message Chunking](https://github.com/wolfSSL/wolfSPDM/wiki/Message-Chunking): SPDM 1.2 CHUNK_GET reassembly for large responses +- [Testing and CI](https://github.com/wolfSSL/wolfSPDM/wiki/Testing-and-CI): Unit tests, emulator integration tests, and CI workflow coverage +- [Project Structure](https://github.com/wolfSSL/wolfSPDM/wiki/Project-Structure): Source layout and module responsibilities +- [Attestation Notes](https://github.com/wolfSSL/wolfSPDM/wiki/Attestation-Notes): Measurement and challenge attestation behavior ## License @@ -173,6 +177,4 @@ Copyright (C) 2006-2026 wolfSSL Inc. ## Support -> **Note:** wolfSPDM is currently maintained by wolfSSL developers but is not yet classified as an officially supported product. It was designed from the ground up to meet the same quality standards as the rest of the wolfSSL suite with future adoption in mind. We are eager to transition this to a fully supported product as demand grows; if your organization requires official support, has specific feature requirements, or just has general questions or guidance with the product, please reach out. - For commercial licensing, professional support contracts, or to discuss moving wolfSPDM into your production environment, contact [wolfSSL](https://www.wolfssl.com/contact/). diff --git a/docs/API-Reference.md b/docs/API-Reference.md index eee5d42..e72dfcb 100644 --- a/docs/API-Reference.md +++ b/docs/API-Reference.md @@ -19,13 +19,13 @@ otherwise; failures are negative error codes from `wolfspdm/spdm_error.h`. - `wolfSPDM_SetIO` - `wolfSPDM_SetMode` / `wolfSPDM_GetMode` *(`WOLFSPDM_MODE_AUTO` / `_NUVOTON` / `_NATIONS` / `_NATIONS_PSK`)* -- `wolfSPDM_SetResponderPubKey` — pin the responder key (96-byte P-384 X‖Y) for cert-less operation -- `wolfSPDM_SetRequesterKeyPair` *(`WOLFSPDM_MUTUAL_AUTH` builds — TCG or TPM profile)* -- `wolfSPDM_SetMaxVersion` — cap the negotiated version (0x12-0x14) -- `wolfSPDM_SetRequesterSessionId` — rejects `0x0000`, `0xFFFF`, and low bytes `0x10`-`0x1F` +- `wolfSPDM_SetResponderPubKey`: pin the responder key (96-byte P-384 X‖Y) for cert-less operation +- `wolfSPDM_SetRequesterKeyPair` *(`WOLFSPDM_MUTUAL_AUTH` builds, TCG or TPM profile)* +- `wolfSPDM_SetMaxVersion`: cap the negotiated version (0x12-0x14) +- `wolfSPDM_SetRequesterSessionId`: rejects `0x0000`, `0xFFFF`, and low bytes `0x10`-`0x1F` - `wolfSPDM_SetTrustedCAs` *(not with `WOLFSPDM_NO_CERT`)* - `wolfSPDM_AllowUntrustedCerts` *(not with `WOLFSPDM_NO_CERT`)* -- `wolfSPDM_SetKeyExchangePref` *(not with `WOLFSPDM_NO_CERT`)* — see [[Post-Quantum ML-KEM]] +- `wolfSPDM_SetKeyExchangePref` *(not with `WOLFSPDM_NO_CERT`)*; see [[Post-Quantum ML-KEM]] - `wolfSPDM_SetDebug` ## Session establishment and state @@ -36,7 +36,7 @@ otherwise; failures are negative error codes from `wolfspdm/spdm_error.h`. - `wolfSPDM_GetSessionId` - `wolfSPDM_GetNegotiatedVersion` - `wolfSPDM_GetVersion_Negotiated` *(older name for `wolfSPDM_GetNegotiatedVersion`)* -- `wolfSPDM_GetLastPeerError` — Param1 of the last SPDM ERROR, 0 if none +- `wolfSPDM_GetLastPeerError`: Param1 of the last SPDM ERROR, 0 if none - `wolfSPDM_GetConnectionHandle` / `wolfSPDM_GetFipsIndicator` *(`WOLFSPDM_TCG` only)* ## Fine-grained handshake (standard requester) @@ -101,7 +101,7 @@ otherwise; failures are negative error codes from `wolfspdm/spdm_error.h`. - `wolfSPDM_RespInit` / `wolfSPDM_RespFree` / `wolfSPDM_RespGetCtxSize` - `wolfSPDM_RespSetMode`, `wolfSPDM_RespSetPSK`, `wolfSPDM_RespSetIdentityKey` - `wolfSPDM_RespSetTpmCallback`, `wolfSPDM_RespSetDebug` -- `wolfSPDM_RespHandleMessage` — returns `WOLFSPDM_E_FRAMING` on a non-TCG +- `wolfSPDM_RespHandleMessage`: returns `WOLFSPDM_E_FRAMING` on a non-TCG inbound frame; callers must drop the connection rather than fall through to the TPM parser - `wolfSPDM_RespReset`, `wolfSPDM_RespIsLocked`, `wolfSPDM_RespIsSessionActive` @@ -121,6 +121,6 @@ Defined in `wolfspdm/spdm_error.h`: - `WOLFSPDM_E_IO_FAIL`, `WOLFSPDM_E_TIMEOUT`, `WOLFSPDM_E_PEER_ERROR`, `WOLFSPDM_E_SEQUENCE` - `WOLFSPDM_E_NOT_CONNECTED`, `WOLFSPDM_E_ALREADY_INIT`, `WOLFSPDM_E_NO_MEMORY` - `WOLFSPDM_E_SESSION_INVALID`, `WOLFSPDM_E_KEY_EXCHANGE`, `WOLFSPDM_E_NOT_AVAILABLE` -- `WOLFSPDM_E_FRAMING` — frame did not parse (e.g. plaintext TPM2 while SPDM mode is active) +- `WOLFSPDM_E_FRAMING`: frame did not parse (e.g. plaintext TPM2 while SPDM mode is active) - `WOLFSPDM_E_NOT_IMPL`, `WOLFSPDM_E_CERT_FAIL`, `WOLFSPDM_E_CERT_PARSE` - `WOLFSPDM_E_KEY_UPDATE`, `WOLFSPDM_E_MEASUREMENT`, `WOLFSPDM_E_CHALLENGE`, `WOLFSPDM_E_CHUNK` diff --git a/docs/Attestation-Notes.md b/docs/Attestation-Notes.md index b23b8a4..1745fc4 100644 --- a/docs/Attestation-Notes.md +++ b/docs/Attestation-Notes.md @@ -32,19 +32,19 @@ signature over it; an unsigned request adds itself to the hash and leaves the run open for the next call. Signature verification (measurements and `CHALLENGE_AUTH`) uses whichever -asymmetric algorithm was negotiated — ECDSA P-384 or, on SPDM 1.4 with ML-DSA +asymmetric algorithm was negotiated: ECDSA P-384 or, on SPDM 1.4 with ML-DSA built in, ML-DSA-44/65/87. See [[Post-Quantum ML-DSA]]. Result access: - `wolfSPDM_GetMeasurementCount` -- `wolfSPDM_GetMeasurementBlock` — `valueSz` is in/out; `measType` is the DMTF +- `wolfSPDM_GetMeasurementBlock`: `valueSz` is in/out; `measType` is the DMTF value type, 0 for raw (non-DMTF-spec) blocks Relevant return codes: - `WOLFSPDM_SUCCESS` -- `WOLFSPDM_E_CAPS_MISMATCH` — signed/unsigned measurement capability not negotiated -- `WOLFSPDM_E_MEASUREMENT` — malformed or inconsistent `MEASUREMENTS` response -- `WOLFSPDM_E_BAD_SIGNATURE` / `WOLFSPDM_E_CRYPTO_FAIL` — signature length mismatch or verification failure +- `WOLFSPDM_E_CAPS_MISMATCH`: signed/unsigned measurement capability not negotiated +- `WOLFSPDM_E_MEASUREMENT`: malformed or inconsistent `MEASUREMENTS` response +- `WOLFSPDM_E_BAD_SIGNATURE` / `WOLFSPDM_E_CRYPTO_FAIL`: signature length mismatch or verification failure ## Sessionless challenge attestation (`CHALLENGE_AUTH`) @@ -62,8 +62,7 @@ Prerequisite state (checked, returns `WOLFSPDM_E_BAD_STATE` otherwise): **M1 running hash.** M1 starts at the VCA transcript when the certificate chain is fetched and accumulates through `CHALLENGE`/`CHALLENGE_AUTH`. -`wolfSPDM_KeyExchange` restarts M1 at the VCA before building its request — -`KEY_EXCHANGE` drops `GET_DIGESTS`/`GET_CERTIFICATE` from its own M1 — and a +`wolfSPDM_KeyExchange` restarts M1 at the VCA before building its request (`KEY_EXCHANGE` drops `GET_DIGESTS`/`GET_CERTIFICATE` from its own M1) and a successful `CHALLENGE` restarts M1 again afterward, so the next M1 is the VCA plus only the messages that follow. @@ -72,9 +71,9 @@ plus only the messages that follow. Relevant return codes: - `WOLFSPDM_E_BAD_STATE`, `WOLFSPDM_E_CAPS_MISMATCH` -- `WOLFSPDM_E_CERT_FAIL` — chain validation failed -- `WOLFSPDM_E_CHALLENGE` — malformed or mismatched `CHALLENGE_AUTH` -- `WOLFSPDM_E_BAD_SIGNATURE` / `WOLFSPDM_E_CRYPTO_FAIL` — signature failure +- `WOLFSPDM_E_CERT_FAIL`: chain validation failed +- `WOLFSPDM_E_CHALLENGE`: malformed or mismatched `CHALLENGE_AUTH` +- `WOLFSPDM_E_BAD_SIGNATURE` / `WOLFSPDM_E_CRYPTO_FAIL`: signature failure ## Signature context strings diff --git a/docs/Configuration-and-Macros.md b/docs/Configuration-and-Macros.md index 6e94da5..adcaf16 100644 --- a/docs/Configuration-and-Macros.md +++ b/docs/Configuration-and-Macros.md @@ -6,7 +6,7 @@ From `configure.ac`: | Option | Default | Defines | Effect | |--------|---------|---------|--------| -| `--with-wolfssl=PATH` | system paths | — | Adds wolfSSL include/library search paths | +| `--with-wolfssl=PATH` | system paths | None | Adds wolfSSL include/library search paths | | `--enable-debug` | off | `WOLFSPDM_DEBUG` | Debug output, `-g -O0` | | `--enable-dynamic-mem` | off | `WOLFSPDM_DYNAMIC_MEMORY` | Heap-allocated context, enables `wolfSPDM_New` | | `--disable-cert` | enabled | `WOLFSPDM_NO_CERT` | Drops the standard certificate-based requester | @@ -17,8 +17,8 @@ From `configure.ac`: | `--disable-challenge` | enabled | `WOLFSPDM_NO_CHALLENGE` | Drops CHALLENGE | | `--disable-heartbeat` | enabled | `WOLFSPDM_NO_HEARTBEAT` | Drops HEARTBEAT | | `--disable-key-update` | enabled | `WOLFSPDM_NO_KEY_UPDATE` | Drops KEY_UPDATE | -| `--disable-mldsa` | auto | `WOLFSPDM_NO_MLDSA` | Force ML-DSA off (default follows wolfSSL — see [[Post-Quantum ML-DSA]]) | -| `--disable-mlkem` | auto | `WOLFSPDM_NO_MLKEM` | Force ML-KEM off (default follows wolfSSL — see [[Post-Quantum ML-KEM]]) | +| `--disable-mldsa` | auto | `WOLFSPDM_NO_MLDSA` | Force ML-DSA off (default follows wolfSSL; see [[Post-Quantum ML-DSA]]) | +| `--disable-mlkem` | auto | `WOLFSPDM_NO_MLKEM` | Force ML-KEM off (default follows wolfSSL; see [[Post-Quantum ML-KEM]]) | | `--enable-tcg` | off | `WOLFSPDM_TCG` | TCG SPDM binding (TPM transport) | | `--enable-nuvoton` | off | `WOLFSPDM_NUVOTON` | Nuvoton NPCT75x vendor commands (implies `--enable-tcg`) | | `--enable-nations` | off | `WOLFSPDM_NATIONS` | Nations NS350 vendor commands (implies `--enable-tcg` and `--enable-psk`) | @@ -68,10 +68,10 @@ Defined in `wolfspdm/spdm.h` depending on build flags: - `WOLFSPDM_HAS_HEARTBEAT` *(not defined if `WOLFSPDM_NO_HEARTBEAT`)* - `WOLFSPDM_HAS_KEY_UPDATE` *(not defined if `WOLFSPDM_NO_KEY_UPDATE`)* - `WOLFSPDM_HAVE_MLDSA` *(defined when ML-DSA is built in; follows wolfSSL's - `WOLFSSL_HAVE_MLDSA`, suppress with `WOLFSPDM_NO_MLDSA`)* — see + `WOLFSSL_HAVE_MLDSA`, suppress with `WOLFSPDM_NO_MLDSA`)*; see [[Post-Quantum ML-DSA]] - `WOLFSPDM_HAVE_MLKEM` *(defined when ML-KEM is built in; follows wolfSSL's - `WOLFSSL_HAVE_MLKEM`, suppress with `WOLFSPDM_NO_MLKEM`)* — see + `WOLFSSL_HAVE_MLKEM`, suppress with `WOLFSPDM_NO_MLKEM`)*; see [[Post-Quantum ML-KEM]]. The advertised key-exchange methods are chosen at runtime with `wolfSPDM_SetKeyExchangePref(ctx, advDhe, kemMask)` (default: ECDHE + every ML-KEM set built in). @@ -93,9 +93,8 @@ defaults grow when ML-DSA or ML-KEM is built in (all are overridable with | `WOLFSPDM_MAX_TRUSTED_CA` | `4096` | `4096` | `8192` | | `WOLFSPDM_MAX_TRANSCRIPT` | `4096` | `8192` | `16384` | -Measured `sizeof(WOLFSPDM_CTX)` on arm64: ~19 KB classical, ~24 KB ML-KEM -only, ~59 KB with ML-DSA, ~9.5 KB in the TPM profile (well under the -corresponding `WOLFSPDM_CTX_STATIC_SIZE`). +Each build's `sizeof(WOLFSPDM_CTX)` stays within the corresponding +`WOLFSPDM_CTX_STATIC_SIZE` shown above. Other overridable size macros (`wolfspdm/spdm_types.h`): `WOLFSPDM_DATA_TRANSFER_SIZE` (default `WOLFSPDM_MAX_MSG_SIZE`, floor 42), diff --git a/docs/Home.md b/docs/Home.md index d62459d..5ca0d03 100644 --- a/docs/Home.md +++ b/docs/Home.md @@ -1,10 +1,10 @@ # wolfSPDM Documentation -Welcome to the wolfSPDM wiki. wolfSPDM implements SPDM over two layers: a -**wolfTPM-derived TCG binding core** (Nuvoton / Nations Technology TPM -transport, PSK, identity-key mutual auth, and an SPDM responder) and, layered -on top of it behind compile-time switches, the **standard DMTF requester** -(certificates, measurements, challenge, chunking, PQC). +Welcome to the wolfSPDM wiki. wolfSPDM is a lightweight C SPDM library for +embedded use. It implements the **standard DMTF requester** (DSP0274 +certificates, measurements, challenge, chunking, post-quantum) and, behind +compile-time switches, a **wolfTPM-derived TCG binding** (Nuvoton / Nations TPM +transport, PSK, identity-key mutual auth, and an SPDM responder). ## What is wolfSPDM? @@ -77,8 +77,8 @@ After `FINISH`, secured messaging and maintenance operations are available. ## Quick Links -- [GitHub Repository](https://github.com/aidangarske/wolfSPDM) -- [README](https://github.com/aidangarske/wolfSPDM/blob/main/README.md) +- [GitHub Repository](https://github.com/wolfSSL/wolfSPDM) +- [README](https://github.com/wolfSSL/wolfSPDM/blob/main/README.md) - [DMTF DSP0274 (SPDM)](https://www.dmtf.org/sites/default/files/standards/documents/DSP0274_1.4.0.pdf) - [DMTF DSP0277 (Secured Messages)](https://www.dmtf.org/sites/default/files/standards/documents/DSP0277_1.2.0.pdf) - [wolfSSL Website](https://www.wolfssl.com/) diff --git a/docs/Message-Chunking.md b/docs/Message-Chunking.md index 07b367c..2129037 100644 --- a/docs/Message-Chunking.md +++ b/docs/Message-Chunking.md @@ -3,8 +3,8 @@ SPDM 1.2 added a *Large SPDM message transfer mechanism* (DSP0274 Sec. 10.27): when a message is larger than a peer's `DataTransferSize`, it is split into pieces and reassembled on the other end. wolfSPDM implements **both** -directions — `CHUNK_SEND` for large outbound requests and `CHUNK_GET` for -large inbound responses — in the clear and inside secured sessions, once both +directions: `CHUNK_SEND` for large outbound requests and `CHUNK_GET` for +large inbound responses, in the clear and inside secured sessions, once both sides negotiate `CHUNK_CAP`. This is what lets ML-DSA-87 and ML-KEM work over the wire: ML-DSA-87 signed @@ -44,7 +44,7 @@ carries a multi-hundred-byte encapsulation key. See against the responder's negotiated `DataTransferSize` even when `WOLFSPDM_NO_CHUNK` is defined or `CHUNK_CAP` was not negotiated: a clear request larger than that limit is refused locally with -`WOLFSPDM_E_BUFFER_SMALL` — wolfSPDM never emits an oversized, non-conformant +`WOLFSPDM_E_BUFFER_SMALL`; wolfSPDM never emits an oversized, non-conformant message. ## Compile-time configuration @@ -73,7 +73,7 @@ The configure summary prints `Chunking: yes|no`. ## References -- DMTF DSP0274 1.4.0 — Sec. 10.27 (Large SPDM message transfer) +- DMTF DSP0274 1.4.0: Sec. 10.27 (Large SPDM message transfer) - `ERROR(LargeResponse)` = error code `0x0F`; `CHUNK_SEND` = `0x85`, `CHUNK_GET` = `0x86`, `CHUNK_SEND_ACK` = `0x05`, `CHUNK_RESPONSE` = `0x06`; `CHUNK_CAP` = `0x00020000` diff --git a/docs/Post-Quantum-ML-DSA.md b/docs/Post-Quantum-ML-DSA.md index f0ef0bb..8f2aa81 100644 --- a/docs/Post-Quantum-ML-DSA.md +++ b/docs/Post-Quantum-ML-DSA.md @@ -37,7 +37,7 @@ chain link by link: - If a trusted root CA is configured (`wolfSPDM_SetTrustedCAs`), its SHA-384 hash must match the chain header's `RootHash`, and the root itself signs the next certificate in the chain. -- Each subsequent certificate must be signed by the one before it — either +- Each subsequent certificate must be signed by the one before it: either ECDSA-SHA384 (`ECDSAk`), or pure ML-DSA (`wc_MlDsaKey_VerifyCtx` with an empty context) when the issuer carries an ML-DSA key. - The leaf key must match the negotiated signature algorithm: for ML-DSA, its @@ -80,7 +80,7 @@ ML-DSA follows the linked wolfSSL automatically: it is enabled when wolfSSL reports `WOLFSSL_HAVE_MLDSA` and provides the `wc_MlDsaKey` context API (build wolfSSL with `--enable-mldsa`), the standard requester is built (not `WOLFSPDM_NO_CERT`), and `--disable-mldsa` was not passed. The -capability is detected at configure time — wolfSPDM does not gate on a +capability is detected at configure time; wolfSPDM does not gate on a wolfSSL version number. ```sh @@ -100,15 +100,15 @@ The configure summary prints `ML-DSA: yes|no`. PQC signatures, public keys, and certificate chains are multi-kilobyte, so `WOLFSPDM_CTX_STATIC_SIZE` grows to 73728 bytes when ML-DSA is built in (32768 -classical, 40960 ML-KEM only — see [[Configuration and Macros]]). Measured -`sizeof(WOLFSPDM_CTX)` on arm64 is roughly 59 KB with ML-DSA, well under that -cap. ML-DSA-44 and ML-DSA-65 responses fit a single SPDM message at common +classical, 40960 ML-KEM only; see [[Configuration and Macros]]). The measured +`sizeof(WOLFSPDM_CTX)` stays well under that cap. ML-DSA-44 and ML-DSA-65 +responses fit a single SPDM message at common `DataTransferSize` values; ML-DSA-87 responses (sig 4627 B) typically exceed it, so the responder chunks them and wolfSPDM reassembles via -`CHUNK_GET` — see [[Message Chunking]]. +`CHUNK_GET`. See [[Message Chunking]]. ## References -- DMTF DSP0274 1.4.0 — SPDM Specification (§15 SPDMsign, §15.5 ML-DSA, Tables 19/20) -- NIST FIPS 204 — ML-DSA; FIPS 203 — ML-KEM -- wolfSSL `wc_mldsa.h` — `wc_MlDsaKey_*` API +- DMTF DSP0274 1.4.0: SPDM Specification (§15 SPDMsign, §15.5 ML-DSA, Tables 19/20) +- NIST FIPS 204: ML-DSA; FIPS 203: ML-KEM +- wolfSSL `wc_mldsa.h`: `wc_MlDsaKey_*` API diff --git a/docs/Post-Quantum-ML-KEM.md b/docs/Post-Quantum-ML-KEM.md index 11133aa..b3e9bf2 100644 --- a/docs/Post-Quantum-ML-KEM.md +++ b/docs/Post-Quantum-ML-KEM.md @@ -6,7 +6,7 @@ alongside the classical ECDHE P-384 group so the responder selects one. ML-KEM rides the certificate flow, so it is only available when the standard requester is built (not `WOLFSPDM_NO_CERT`). -ML-KEM in SPDM 1.4 is **standalone, not hybrid** — DSP0274 §23.5 states "key +ML-KEM in SPDM 1.4 is **standalone, not hybrid**: DSP0274 §23.5 states "key encapsulation (ML-KEM) for session establishment. **No support for hybrid algorithms.**" When ML-KEM is negotiated it *replaces* the DHE group, and its decapsulated 32-byte shared secret feeds the existing key schedule in place of @@ -18,7 +18,7 @@ post-quantum SPDM handshake**. 1. The requester generates an ephemeral ML-KEM key pair and sends the **encapsulation key `ek`** as the `KEY_EXCHANGE` `ExchangeData` (replacing the 96-byte ECDHE X‖Y point). The ephemeral key lives in the context as a - union of `ecc_key` and `MlKemKey` (`ctx->ephemeral`) — only one is ever + union of `ecc_key` and `MlKemKey` (`ctx->ephemeral`); only one is ever live per session. 2. The responder encapsulates, returning the **ciphertext `c`** as the `KEY_EXCHANGE_RSP` `ExchangeData` (alongside its signature and HMAC). @@ -36,7 +36,7 @@ failure. In `NEGOTIATE_ALGORITHMS`, wolfSPDM advertises a `KEMAlg` `AlgStruct` (`AlgType = 0x07`, DSP0274 1.4 Table 24) with the ML-KEM sets the linked wolfSSL was built with, dual-stack alongside the DHE group. The responder -selects **exactly one** key-exchange method — a DHE group **or** a KEM, never +selects **exactly one** key-exchange method: a DHE group **or** a KEM, never both (no hybrid). wolfSPDM enforces that mutual exclusivity when parsing `ALGORITHMS`. @@ -95,25 +95,25 @@ unchanged. Two size effects: - **Larger KEY_EXCHANGE request.** The `ek` (up to 1568 B for ML-KEM-1024) makes the request larger than the ~158 B classical ECDHE request. If it exceeds the negotiated `DataTransferSize`, wolfSPDM sends it with - `CHUNK_SEND` when the responder has negotiated `CHUNK_CAP` — see + `CHUNK_SEND` when the responder has negotiated `CHUNK_CAP`; see [[Message Chunking]]. Without chunking support on either side, a request that exceeds `DataTransferSize` is refused locally with `WOLFSPDM_E_BUFFER_SMALL` rather than sent oversized. - **Static context.** The ephemeral ML-KEM key lives in the context (a union with the classical `ecc_key`; only one is ever live), so ML-KEM-only builds use a larger `WOLFSPDM_CTX_STATIC_SIZE` (40960) than the classical profile - (32768) — see [[Configuration and Macros]]. A fully post-quantum + (32768); see [[Configuration and Macros]]. A fully post-quantum (ML-KEM + ML-DSA) build uses the ML-DSA budget (73728), which already covers it. When ML-KEM and ML-DSA are combined, an ML-DSA-87 signed response plus the ML-KEM ciphertext can exceed the `DataTransferSize`, so the responder chunks -it and wolfSPDM reassembles via `CHUNK_GET` — the full-PQ path exercises +it and wolfSPDM reassembles via `CHUNK_GET`; the full-PQ path exercises ML-KEM, ML-DSA, and chunking together. ## References -- DMTF DSP0274 1.4.0 — §10.17.2 (ML-KEM scheme), §10.17.3 (message formats, +- DMTF DSP0274 1.4.0: §10.17.2 (ML-KEM scheme), §10.17.3 (message formats, Table 77), §12.2 (KEM K/K′ computation), Table 24 (KEMAlg), §23.5 (no hybrid) -- NIST FIPS 203 — ML-KEM -- wolfSSL `wc_mlkem.h` — `wc_MlKemKey_*` API +- NIST FIPS 203: ML-KEM +- wolfSSL `wc_mlkem.h`: `wc_MlKemKey_*` API diff --git a/docs/Project-Structure.md b/docs/Project-Structure.md index e958b69..893b5bf 100644 --- a/docs/Project-Structure.md +++ b/docs/Project-Structure.md @@ -25,7 +25,7 @@ | `src/spdm_session.c` | Handshake exchange helper, `KeyExchange`/`Finish`, `Heartbeat`, `KeyUpdate` | | `src/spdm_internal.h` | Internal types, constants, and internal APIs shared across `src/` | -## Standard (certificate) requester modules — built with `BUILD_CERT` +## Standard (certificate) requester modules: built with `BUILD_CERT` Compiled when the standard requester is enabled (`--disable-cert` removes these; requires `WOLFSPDM_NO_CERT` not set): diff --git a/docs/Testing-and-CI.md b/docs/Testing-and-CI.md index 19026ed..2101278 100644 --- a/docs/Testing-and-CI.md +++ b/docs/Testing-and-CI.md @@ -44,7 +44,7 @@ Documented workflows include: - wolfTPM downstream: wolfTPM master built with this wolfSPDM in its 14 SPDM configurations, its SPDM unit tests, and the fwTPM TCG and PSK end-to-end runs; the standard requester symbols must stay out of `libwolftpm` -- SPDM Emulator PQC Test — wolfSSL master + spdm-emu (OpenSSL backend) on the +- SPDM Emulator PQC Test: wolfSSL master + spdm-emu (OpenSSL backend) on the full x64 + aarch64 matrix. Builds wolfSPDM ML-KEM-only as well as the combined config, then runs over the wire: ML-DSA-44/65/87 (signatures), ML-KEM-512/768/1024 (key exchange), and a **fully post-quantum** leg (ML-KEM-768 + ML-DSA-65/87) for @@ -75,7 +75,7 @@ See `.github/workflows/README.md` for workflow inventory details. unchunked request above the responder's DataTransferSize. - **Over-the-wire (CI):** ML-KEM-512/768/1024 against spdm-emu (`--dhe NONE --kem ML_KEM_*`), and a **fully post-quantum** leg pairing ML-KEM-768 with - ML-DSA-65/87 — the ML-DSA-87 case also exercises chunking, so ML-KEM + ML-DSA + + ML-DSA-65/87; the ML-DSA-87 case also exercises chunking, so ML-KEM + ML-DSA + CHUNK_GET reassembly all run in a single handshake. - **Config coverage (CI):** an ML-KEM-only build (`--disable-mldsa --enable-mlkem`) exercises the ML-KEM-only `WOLFSPDM_CTX_STATIC_SIZE` budget.