ML-DSA renaming

pull/509/head
Tobias Frauenschläger 2026-05-20 13:09:26 -07:00
parent 5673e7dec5
commit 77e31c0ebb
9 changed files with 97 additions and 87 deletions

View File

@ -38,7 +38,7 @@ Portable TPM 2.0 project designed for embedded use.
* Support for HMAC Sessions.
* Support for reading Endorsement certificates (EK Credential Profile).
* Includes a portable firmware TPM 2.0 implementation (fwTPM, also known as fTPM / swtpm) for embedded platforms without a discrete TPM chip. See [Firmware TPM (fwTPM / fTPM / swtpm)](#firmware-tpm-fwtpm--ftpm--swtpm) below.
* **Post-quantum cryptography support** via TPM 2.0 Library Specification v1.85: ML-DSA (FIPS 204) signing and ML-KEM (FIPS 203) key encapsulation, enabled with `--enable-pqc` (alias for `--enable-v185`). Auto-detected when `--enable-fwtpm` is built against a wolfCrypt that has Dilithium + ML-KEM. Both the client library and the fwTPM server implement the eight new v1.85 PQC commands. See [Post-Quantum Cryptography (v1.85)](#post-quantum-cryptography-v185) below.
* **Post-quantum cryptography support** via TPM 2.0 Library Specification v1.85: ML-DSA (FIPS 204) signing and ML-KEM (FIPS 203) key encapsulation, enabled with `--enable-pqc` (alias for `--enable-v185`). Auto-detected when `--enable-fwtpm` is built against a wolfCrypt that has ML-DSA + ML-KEM. Both the client library and the fwTPM server implement the eight new v1.85 PQC commands. See [Post-Quantum Cryptography (v1.85)](#post-quantum-cryptography-v185) below.
Note: See [examples/README.md](examples/README.md) for details on using the examples.
@ -87,7 +87,7 @@ are forward-compatible — the same wrapper API targets both.
```
./configure --enable-wolftpm --enable-pkcallbacks --enable-keygen \
--enable-dilithium --enable-mlkem --enable-experimental \
--enable-mldsa --enable-mlkem \
--enable-harden CFLAGS="-DWC_RSA_NO_PADDING"
make
sudo make install

View File

@ -714,22 +714,27 @@ else
test "x$ENABLED_WOLFCRYPT" = "xyes"
then
# Probe the actual symbols, not just the headers. wolfSSL ships
# dilithium.h and wc_mlkem.h even without the implementation
# compiled (function decls are gated behind HAVE_DILITHIUM /
# wc_mldsa.h and wc_mlkem.h even without the implementation
# compiled (function decls are gated behind WOLFSSL_HAVE_MLDSA /
# HAVE_MLKEM which only get defined via wolfssl/options.h after
# the right --enable-* flags). Include options.h first so the
# gate is set before the header decls are parsed.
AC_CHECK_DECL([wc_dilithium_init],
[WOLFTPM_HAVE_DILITHIUM_FN=yes],
[WOLFTPM_HAVE_DILITHIUM_FN=no],
# Probing the canonical wc_MlDsaKey_Init also doubles as a
# wolfSSL-version probe: older wolfSSL that predates PR #10436
# ships only <wolfssl/wolfcrypt/dilithium.h>, fails the probe,
# and auto-detect quietly stays off (explicit opt-in below emits
# an actionable error).
AC_CHECK_DECL([wc_MlDsaKey_Init],
[WOLFTPM_HAVE_MLDSA_FN=yes],
[WOLFTPM_HAVE_MLDSA_FN=no],
[[#include <wolfssl/options.h>
#include <wolfssl/wolfcrypt/dilithium.h>]])
#include <wolfssl/wolfcrypt/wc_mldsa.h>]])
AC_CHECK_DECL([wc_MlKemKey_Init],
[WOLFTPM_HAVE_MLKEM_FN=yes],
[WOLFTPM_HAVE_MLKEM_FN=no],
[[#include <wolfssl/options.h>
#include <wolfssl/wolfcrypt/wc_mlkem.h>]])
if test "x$WOLFTPM_HAVE_DILITHIUM_FN" = "xyes" && \
if test "x$WOLFTPM_HAVE_MLDSA_FN" = "xyes" && \
test "x$WOLFTPM_HAVE_MLKEM_FN" = "xyes"
then
AC_MSG_NOTICE([wolfCrypt ML-DSA + ML-KEM detected; auto-enabling --enable-v185 (use --disable-v185 or --disable-pqc to opt out)])
@ -747,12 +752,16 @@ then
# Explicit opt-in: re-probe so we fail at configure time (with a
# clear hint about wolfSSL flags) rather than deep inside the compile
# with a cryptic error. Header existence alone is not enough -- the
# actual functions must be declared (gated by HAVE_DILITHIUM /
# HAVE_MLKEM in wolfssl/options.h).
AC_CHECK_DECL([wc_dilithium_init], [],
[AC_MSG_ERROR([--enable-v185/--enable-pqc requires wolfSSL built with --enable-dilithium --enable-experimental])],
# actual functions must be declared (gated by WOLFSSL_HAVE_MLDSA /
# HAVE_MLKEM in wolfssl/options.h). The probed symbol
# `wc_MlDsaKey_Init` is the canonical FIPS 204 entry point introduced
# by wolfSSL PR #10436 (post-v5.9.1-stable): wolfTPM consumes
# <wolfssl/wolfcrypt/wc_mldsa.h> directly, so older wolfSSL that
# only ships <wolfssl/wolfcrypt/dilithium.h> is not supported here.
AC_CHECK_DECL([wc_MlDsaKey_Init], [],
[AC_MSG_ERROR([--enable-v185/--enable-pqc requires wolfSSL built with --enable-mldsa (or alias --enable-dilithium) and --enable-experimental, ships post-v5.9.1-stable])],
[[#include <wolfssl/options.h>
#include <wolfssl/wolfcrypt/dilithium.h>]])
#include <wolfssl/wolfcrypt/wc_mldsa.h>]])
AC_CHECK_DECL([wc_MlKemKey_Init], [],
[AC_MSG_ERROR([--enable-v185/--enable-pqc requires wolfSSL >= v5.8.0-stable built with --enable-mlkem --enable-experimental])],
[[#include <wolfssl/options.h>

View File

@ -504,7 +504,7 @@ Sizing logic lives in `wolftpm/fwtpm/fwtpm.h` (constants
`FWTPM_MAX_MLDSA_SIG_SIZE`, `FWTPM_MAX_MLDSA_PUB_SIZE`,
`FWTPM_MAX_MLKEM_CT_SIZE`, `FWTPM_MAX_MLKEM_PUB_SIZE`) and
`wolftpm/fwtpm/fwtpm_tis.h` (FIFO size). The MLDSA constants come from
wolfCrypt's `DILITHIUM_LEVEL{2,3,5}_*_SIZE` macros; the MLKEM constants
wolfCrypt's `WC_MLDSA_{44,65,87}_*_SIZE` macros; the MLKEM constants
are FIPS 203 spec values (wolfCrypt's `WC_ML_KEM_*_SIZE` macros aren't
preprocessor-evaluable).
@ -741,7 +741,7 @@ every `Startup(CLEAR)`.
Enabled with `--enable-pqc` (alias `--enable-v185`) at configure time, or
auto-detected when `--enable-fwtpm` is built against a wolfCrypt that has
both Dilithium and ML-KEM available. Both flags set the internal
both ML-DSA and ML-KEM available. Both flags set the internal
`WOLFTPM_V185` macro that gates the implementation. Pass `--disable-pqc`
to opt out when auto-detect would otherwise enable it. Implements the
post-quantum additions from TCG TPM 2.0 Library Specification v1.85 using
@ -776,7 +776,7 @@ PQC primary keys follow the same deterministic derivation model as RSA/ECC:
hierarchy seed + template → KDFa-derived seed → FIPS 203/204 key expansion.
- **ML-DSA**: `KDFa(nameAlg, seed, "MLDSA", hashUnique) → 32-byte Xi`
`wc_dilithium_make_key_from_seed` → (pub, expanded-priv). The wire format stores
`wc_MlDsaKey_MakeKeyFromSeed` → (pub, expanded-priv). The wire format stores
only the 32-byte Xi per TCG Part 2 Table 210.
- **Hash-ML-DSA**: label is `"HASH_MLDSA"`; same seed size and expansion.
- **ML-KEM**: `KDFa(nameAlg, seed, "MLKEM", hashUnique) → 64-byte (d‖z)`
@ -797,7 +797,7 @@ buffer parameter.
Hash-ML-DSA sequences (both sign and verify) use wolfCrypt's `wc_HashAlg` context
to stream the message into the key's hash algorithm; `TPM2_SignSequenceComplete`
finalizes the hash and calls `wc_dilithium_sign_ctx_hash`.
finalizes the hash and calls `wc_MlDsaKey_SignCtxHash`.
Signature wire formats differ per spec Part 2 Table 217:

View File

@ -47,7 +47,7 @@ wolfTPM implements the post-quantum additions from **TCG TPM 2.0 Library Specifi
Eight new TPM 2.0 commands are supported: `TPM2_Encapsulate`, `TPM2_Decapsulate`, `TPM2_SignDigest`, `TPM2_VerifyDigestSignature`, `TPM2_SignSequenceStart`, `TPM2_SignSequenceComplete`, `TPM2_VerifySequenceStart`, `TPM2_VerifySequenceComplete`.
Algorithm behavior matches FIPS 203 / FIPS 204 via wolfCrypt's ML-KEM and ML-DSA (Dilithium) modules, validated against NIST ACVP test vectors.
Algorithm behavior matches FIPS 203 / FIPS 204 via wolfCrypt's ML-KEM and ML-DSA modules, validated against NIST ACVP test vectors.
The firmware TPM (fwTPM) server also implements v1.85 PQC — see [FWTPM.md](FWTPM.md#tpm-20-v185-post-quantum-support) for algorithm, command, primary-key derivation, and sequence-handler details.

View File

@ -13,8 +13,8 @@ the full fwTPM PQC reference.
**wolfSSL** (ML-DSA and ML-KEM in wolfCrypt):
```
./configure --enable-wolftpm --enable-dilithium --enable-mlkem \
--enable-experimental --enable-harden --enable-keygen
./configure --enable-wolftpm --enable-mldsa --enable-mlkem \
--enable-harden --enable-keygen
make
sudo make install
```

BIN
fwtpm_test_nv.bin 100644

Binary file not shown.

View File

@ -1151,16 +1151,13 @@ static TPM_RC FwCmd_GetCapability(FWTPM_CTX* ctx, TPM2_Packet* cmd,
!defined(WOLFSSL_NO_KYBER1024)
TPMA_ML_PARAMETER_SET_mlKem_1024 |
#endif
#if (defined(WOLFSSL_WC_DILITHIUM) || defined(HAVE_DILITHIUM)) && \
!defined(WOLFSSL_NO_ML_DSA_44)
#if defined(WOLFSSL_HAVE_MLDSA) && !defined(WOLFSSL_NO_ML_DSA_44)
TPMA_ML_PARAMETER_SET_mlDsa_44 |
#endif
#if (defined(WOLFSSL_WC_DILITHIUM) || defined(HAVE_DILITHIUM)) && \
!defined(WOLFSSL_NO_ML_DSA_65)
#if defined(WOLFSSL_HAVE_MLDSA) && !defined(WOLFSSL_NO_ML_DSA_65)
TPMA_ML_PARAMETER_SET_mlDsa_65 |
#endif
#if (defined(WOLFSSL_WC_DILITHIUM) || defined(HAVE_DILITHIUM)) && \
!defined(WOLFSSL_NO_ML_DSA_87)
#if defined(WOLFSSL_HAVE_MLDSA) && !defined(WOLFSSL_NO_ML_DSA_87)
TPMA_ML_PARAMETER_SET_mlDsa_87 |
#endif
0 },

View File

@ -61,7 +61,7 @@
#include <wolfssl/wolfcrypt/hmac.h>
#ifdef WOLFTPM_V185
#include <wolfssl/version.h>
#include <wolfssl/wolfcrypt/dilithium.h>
#include <wolfssl/wolfcrypt/wc_mldsa.h>
#include <wolfssl/wolfcrypt/wc_mlkem.h>
#endif
@ -692,7 +692,7 @@ TPM_RC FwDeriveEccPrimaryKey(TPMI_ALG_HASH nameAlg,
* primary key derived against this build will require migration.
* See docs/FWTPM.md and FwDeriveMldsaPrimaryKeySeed for details. */
/* Map TPM v1.85 ML-DSA parameter set to wolfCrypt dilithium level. */
/* Map TPM v1.85 ML-DSA parameter set to wolfCrypt ML-DSA level. */
static int FwGetWcMldsaLevel(TPMI_MLDSA_PARAMETER_SET ps)
{
switch (ps) {
@ -761,13 +761,13 @@ TPM_RC FwGenerateMldsaKey(TPMI_MLDSA_PARAMETER_SET parameterSet,
TPM2B_PUBLIC_KEY_MLDSA* pubOut)
{
TPM_RC rc = TPM_RC_SUCCESS;
FWTPM_DECLARE_VAR(dilithiumKey, dilithium_key);
FWTPM_DECLARE_VAR(keyVar, wc_MlDsaKey);
int level;
word32 outSz;
int wcRet;
int keyInit = 0;
FWTPM_ALLOC_VAR(dilithiumKey, dilithium_key);
FWTPM_ALLOC_VAR(keyVar, wc_MlDsaKey);
level = FwGetWcMldsaLevel(parameterSet);
if (level < 0) {
@ -775,27 +775,27 @@ TPM_RC FwGenerateMldsaKey(TPMI_MLDSA_PARAMETER_SET parameterSet,
}
if (rc == 0) {
wcRet = wc_dilithium_init(dilithiumKey);
wcRet = wc_MlDsaKey_Init(keyVar, NULL, INVALID_DEVID);
if (wcRet != 0) {
rc = TPM_RC_FAILURE;
}
}
if (rc == 0) {
keyInit = 1;
wcRet = wc_dilithium_set_level(dilithiumKey, (byte)level);
wcRet = wc_MlDsaKey_SetParams(keyVar, level);
if (wcRet != 0) {
rc = TPM_RC_FAILURE;
}
}
if (rc == 0) {
wcRet = wc_dilithium_make_key_from_seed(dilithiumKey, seedXi);
wcRet = wc_MlDsaKey_MakeKeyFromSeed(keyVar, seedXi);
if (wcRet != 0) {
rc = TPM_RC_FAILURE;
}
}
if (rc == 0) {
outSz = (word32)sizeof(pubOut->buffer);
wcRet = wc_dilithium_export_public(dilithiumKey, pubOut->buffer, &outSz);
wcRet = wc_MlDsaKey_ExportPubRaw(keyVar, pubOut->buffer, &outSz);
if (wcRet != 0) {
rc = TPM_RC_FAILURE;
}
@ -805,9 +805,9 @@ TPM_RC FwGenerateMldsaKey(TPMI_MLDSA_PARAMETER_SET parameterSet,
}
if (keyInit) {
wc_dilithium_free(dilithiumKey);
wc_MlDsaKey_Free(keyVar);
}
FWTPM_FREE_VAR(dilithiumKey);
FWTPM_FREE_VAR(keyVar);
return rc;
}
@ -1369,9 +1369,9 @@ TPM_RC FwDecapsulateEcdhDhkem(WC_RNG* rng, const FWTPM_Object* recipObj,
#endif /* HAVE_ECC */
/* Internal helper: rebuild a deterministic ML-DSA keypair from its stored
* 32-byte xi seed and return a ready-to-use dilithium_key plus wcLevel. */
* 32-byte xi seed and return a ready-to-use wc_MlDsaKey plus wcLevel. */
static TPM_RC FwLoadMldsaFromSeed(TPMI_MLDSA_PARAMETER_SET parameterSet,
const byte* seedXi, dilithium_key* keyOut, int* keyInitOut)
const byte* seedXi, wc_MlDsaKey* keyOut, int* keyInitOut)
{
TPM_RC rc = TPM_RC_SUCCESS;
int level;
@ -1384,18 +1384,18 @@ static TPM_RC FwLoadMldsaFromSeed(TPMI_MLDSA_PARAMETER_SET parameterSet,
return TPM_RC_PARMS;
}
wcRet = wc_dilithium_init(keyOut);
wcRet = wc_MlDsaKey_Init(keyOut, NULL, INVALID_DEVID);
if (wcRet != 0) {
return TPM_RC_FAILURE;
}
*keyInitOut = 1;
wcRet = wc_dilithium_set_level(keyOut, (byte)level);
wcRet = wc_MlDsaKey_SetParams(keyOut, (byte)level);
if (wcRet != 0) {
rc = TPM_RC_FAILURE;
}
if (rc == 0) {
wcRet = wc_dilithium_make_key_from_seed(keyOut, seedXi);
wcRet = wc_MlDsaKey_MakeKeyFromSeed(keyOut, seedXi);
if (wcRet != 0) {
rc = TPM_RC_FAILURE;
}
@ -1414,17 +1414,17 @@ TPM_RC FwSignMldsaMessage(WC_RNG* rng,
TPM2B_MLDSA_SIGNATURE* sigOut)
{
TPM_RC rc;
FWTPM_DECLARE_VAR(keyVar, dilithium_key);
FWTPM_DECLARE_VAR(keyVar, wc_MlDsaKey);
int keyInit = 0;
word32 sigSz;
int wcRet;
/* wc_dilithium_*_ctx_* take contextSz as a byte; guard the cast. */
/* wc_MlDsaKey_SignCtx / _SignCtxHash take ctxLen as a byte; guard the cast. */
if (contextSz < 0 || contextSz > 255) {
return TPM_RC_VALUE;
}
FWTPM_ALLOC_VAR(keyVar, dilithium_key);
FWTPM_ALLOC_VAR(keyVar, wc_MlDsaKey);
rc = FwLoadMldsaFromSeed(parameterSet, seedXi, keyVar, &keyInit);
@ -1433,11 +1433,12 @@ TPM_RC FwSignMldsaMessage(WC_RNG* rng,
/* FIPS 204 Algorithm 2 hedged sign: wolfCrypt requires a non-NULL
* RNG to source the 32-byte `rnd` value. Passing the TPM's internal
* RNG matches normal TPM signing practice (side-channel hedging). */
wcRet = wc_dilithium_sign_ctx_msg(
wcRet = wc_MlDsaKey_SignCtx(
keyVar,
context, (byte)contextSz,
msg, (word32)msgSz,
sigOut->buffer, &sigSz,
keyVar, rng);
msg, (word32)msgSz,
rng);
if (wcRet != 0) {
rc = TPM_RC_FAILURE;
}
@ -1447,7 +1448,7 @@ TPM_RC FwSignMldsaMessage(WC_RNG* rng,
}
if (keyInit) {
wc_dilithium_free(keyVar);
wc_MlDsaKey_Free(keyVar);
}
FWTPM_FREE_VAR(keyVar);
return rc;
@ -1461,7 +1462,7 @@ TPM_RC FwVerifyMldsaMessage(TPMI_MLDSA_PARAMETER_SET parameterSet,
const byte* sig, int sigSz)
{
TPM_RC rc = TPM_RC_SUCCESS;
FWTPM_DECLARE_VAR(keyVar, dilithium_key);
FWTPM_DECLARE_VAR(keyVar, wc_MlDsaKey);
int level;
int keyInit = 0;
int verifyRes = 0;
@ -1471,44 +1472,45 @@ TPM_RC FwVerifyMldsaMessage(TPMI_MLDSA_PARAMETER_SET parameterSet,
return TPM_RC_VALUE;
}
FWTPM_ALLOC_VAR(keyVar, dilithium_key);
FWTPM_ALLOC_VAR(keyVar, wc_MlDsaKey);
level = FwGetWcMldsaLevel(parameterSet);
if (level < 0) {
rc = TPM_RC_PARMS;
}
if (rc == 0) {
wcRet = wc_dilithium_init(keyVar);
wcRet = wc_MlDsaKey_Init(keyVar, NULL, INVALID_DEVID);
if (wcRet != 0) {
rc = TPM_RC_FAILURE;
}
}
if (rc == 0) {
keyInit = 1;
wcRet = wc_dilithium_set_level(keyVar, (byte)level);
wcRet = wc_MlDsaKey_SetParams(keyVar, (byte)level);
if (wcRet != 0) {
rc = TPM_RC_FAILURE;
}
}
if (rc == 0) {
wcRet = wc_dilithium_import_public(pubIn->buffer, pubIn->size, keyVar);
wcRet = wc_MlDsaKey_ImportPubRaw(keyVar, pubIn->buffer, pubIn->size);
if (wcRet != 0) {
rc = TPM_RC_KEY;
}
}
if (rc == 0) {
wcRet = wc_dilithium_verify_ctx_msg(
wcRet = wc_MlDsaKey_VerifyCtx(
keyVar,
sig, (word32)sigSz,
context, (byte)contextSz,
msg, (word32)msgSz,
&verifyRes, keyVar);
&verifyRes);
if (wcRet != 0 || verifyRes != 1) {
rc = TPM_RC_SIGNATURE;
}
}
if (keyInit) {
wc_dilithium_free(keyVar);
wc_MlDsaKey_Free(keyVar);
}
FWTPM_FREE_VAR(keyVar);
return rc;
@ -1524,7 +1526,7 @@ TPM_RC FwSignMldsaHash(WC_RNG* rng,
TPM2B_MLDSA_SIGNATURE* sigOut)
{
TPM_RC rc;
FWTPM_DECLARE_VAR(keyVar, dilithium_key);
FWTPM_DECLARE_VAR(keyVar, wc_MlDsaKey);
int keyInit = 0;
word32 sigSz;
int wcHash;
@ -1534,7 +1536,7 @@ TPM_RC FwSignMldsaHash(WC_RNG* rng,
return TPM_RC_VALUE;
}
FWTPM_ALLOC_VAR(keyVar, dilithium_key);
FWTPM_ALLOC_VAR(keyVar, wc_MlDsaKey);
wcHash = FwGetWcHashType(hashAlg);
if (wcHash == WC_HASH_TYPE_NONE) {
@ -1547,11 +1549,12 @@ TPM_RC FwSignMldsaHash(WC_RNG* rng,
if (rc == 0) {
sigSz = (word32)sizeof(sigOut->buffer);
/* Hedged sign (FIPS 204 Alg 2 step 7) — wolfCrypt requires RNG. */
wcRet = wc_dilithium_sign_ctx_hash(
wcRet = wc_MlDsaKey_SignCtxHash(
keyVar,
context, (byte)contextSz,
wcHash, digest, (word32)digestSz,
sigOut->buffer, &sigSz,
keyVar, rng);
digest, (word32)digestSz,
wcHash, rng);
if (wcRet != 0) {
rc = TPM_RC_FAILURE;
}
@ -1561,7 +1564,7 @@ TPM_RC FwSignMldsaHash(WC_RNG* rng,
}
if (keyInit) {
wc_dilithium_free(keyVar);
wc_MlDsaKey_Free(keyVar);
}
FWTPM_FREE_VAR(keyVar);
return rc;
@ -1576,7 +1579,7 @@ TPM_RC FwVerifyMldsaHash(TPMI_MLDSA_PARAMETER_SET parameterSet,
const byte* sig, int sigSz)
{
TPM_RC rc = TPM_RC_SUCCESS;
FWTPM_DECLARE_VAR(keyVar, dilithium_key);
FWTPM_DECLARE_VAR(keyVar, wc_MlDsaKey);
int level;
int keyInit = 0;
int verifyRes = 0;
@ -1587,7 +1590,7 @@ TPM_RC FwVerifyMldsaHash(TPMI_MLDSA_PARAMETER_SET parameterSet,
return TPM_RC_VALUE;
}
FWTPM_ALLOC_VAR(keyVar, dilithium_key);
FWTPM_ALLOC_VAR(keyVar, wc_MlDsaKey);
wcHash = FwGetWcHashType(hashAlg);
if (wcHash == WC_HASH_TYPE_NONE) {
@ -1600,37 +1603,38 @@ TPM_RC FwVerifyMldsaHash(TPMI_MLDSA_PARAMETER_SET parameterSet,
}
if (rc == 0) {
wcRet = wc_dilithium_init(keyVar);
wcRet = wc_MlDsaKey_Init(keyVar, NULL, INVALID_DEVID);
if (wcRet != 0) {
rc = TPM_RC_FAILURE;
}
}
if (rc == 0) {
keyInit = 1;
wcRet = wc_dilithium_set_level(keyVar, (byte)level);
wcRet = wc_MlDsaKey_SetParams(keyVar, (byte)level);
if (wcRet != 0) {
rc = TPM_RC_FAILURE;
}
}
if (rc == 0) {
wcRet = wc_dilithium_import_public(pubIn->buffer, pubIn->size, keyVar);
wcRet = wc_MlDsaKey_ImportPubRaw(keyVar, pubIn->buffer, pubIn->size);
if (wcRet != 0) {
rc = TPM_RC_KEY;
}
}
if (rc == 0) {
wcRet = wc_dilithium_verify_ctx_hash(
wcRet = wc_MlDsaKey_VerifyCtxHash(
keyVar,
sig, (word32)sigSz,
context, (byte)contextSz,
wcHash, digest, (word32)digestSz,
&verifyRes, keyVar);
digest, (word32)digestSz,
wcHash, &verifyRes);
if (wcRet != 0 || verifyRes != 1) {
rc = TPM_RC_SIGNATURE;
}
}
if (keyInit) {
wc_dilithium_free(keyVar);
wc_MlDsaKey_Free(keyVar);
}
FWTPM_FREE_VAR(keyVar);
return rc;

View File

@ -2919,53 +2919,53 @@ static void test_fwtpm_mldsa_sequence_roundtrip(void)
/* ------------------------------------------------------------------ */
#include "pqc_kat_vectors.h"
#include <wolfssl/wolfcrypt/dilithium.h>
#include <wolfssl/wolfcrypt/wc_mldsa.h>
#include <wolfssl/wolfcrypt/wc_mlkem.h>
/* Layer A: wolfCrypt-only verify against NIST ACVP MLDSA-44 pinned vector. */
static void test_fwtpm_mldsa_nist_kat_verify(void)
{
dilithium_key key;
wc_MlDsaKey key;
int res = 0;
int rc;
rc = wc_dilithium_init_ex(&key, NULL, INVALID_DEVID);
rc = wc_MlDsaKey_Init(&key, NULL, INVALID_DEVID);
AssertIntEQ(rc, 0);
rc = wc_dilithium_set_level(&key, WC_ML_DSA_44);
rc = wc_MlDsaKey_SetParams(&key, WC_ML_DSA_44);
AssertIntEQ(rc, 0);
rc = wc_dilithium_import_public(gNistMldsa44Pk, sizeof(gNistMldsa44Pk),
&key);
rc = wc_MlDsaKey_ImportPubRaw(&key, gNistMldsa44Pk,
sizeof(gNistMldsa44Pk));
AssertIntEQ(rc, 0);
rc = wc_dilithium_verify_ctx_msg(
rc = wc_MlDsaKey_VerifyCtx(&key,
gNistMldsa44Sig, (word32)sizeof(gNistMldsa44Sig),
gNistMldsa44Ctx, (byte)sizeof(gNistMldsa44Ctx),
gNistMldsa44Msg, (word32)sizeof(gNistMldsa44Msg),
&res, &key);
&res);
AssertIntEQ(rc, 0);
AssertIntEQ(res, 1);
wc_dilithium_free(&key);
wc_MlDsaKey_Free(&key);
fwtpm_pass("MLDSA NIST KAT Verify (wolfCrypt):", 1);
}
/* Layer A: wolfCrypt-only keygen determinism against wolfSSL MLDSA-44 vector. */
static void test_fwtpm_mldsa_wolfssl_keygen_kat(void)
{
dilithium_key key;
wc_MlDsaKey key;
byte pub[sizeof(gWolfSslMldsa44Pk)];
word32 pubSz = (word32)sizeof(pub);
int rc;
rc = wc_dilithium_init_ex(&key, NULL, INVALID_DEVID);
rc = wc_MlDsaKey_Init(&key, NULL, INVALID_DEVID);
AssertIntEQ(rc, 0);
rc = wc_dilithium_set_level(&key, WC_ML_DSA_44);
rc = wc_MlDsaKey_SetParams(&key, WC_ML_DSA_44);
AssertIntEQ(rc, 0);
rc = wc_dilithium_make_key_from_seed(&key, gWolfSslMldsa44Seed);
rc = wc_MlDsaKey_MakeKeyFromSeed(&key, gWolfSslMldsa44Seed);
AssertIntEQ(rc, 0);
rc = wc_dilithium_export_public(&key, pub, &pubSz);
rc = wc_MlDsaKey_ExportPubRaw(&key, pub, &pubSz);
AssertIntEQ(rc, 0);
AssertIntEQ(pubSz, sizeof(gWolfSslMldsa44Pk));
AssertIntEQ(XMEMCMP(pub, gWolfSslMldsa44Pk, pubSz), 0);
wc_dilithium_free(&key);
wc_MlDsaKey_Free(&key);
fwtpm_pass("MLDSA wolfSSL keygen KAT:", 1);
}