mirror of https://github.com/wolfSSL/wolfTPM.git
Add PQC parameter encryption and ML-DSA support to examples
parent
74f428bdfb
commit
0f51da58d0
|
|
@ -215,7 +215,7 @@ exit:
|
|||
return rc;
|
||||
}
|
||||
|
||||
#ifdef WOLFTPM_PQC
|
||||
#ifdef WOLFTPM_MLDSA
|
||||
/* Benchmark Pure ML-DSA: key gen, sign and verify (sign/verify sequence). */
|
||||
static int bench_pqc_mldsa(WOLFTPM2_DEV* dev, double maxDuration,
|
||||
double maxKeyGenDurSec)
|
||||
|
|
@ -291,7 +291,9 @@ exit:
|
|||
wolfTPM2_UnloadHandle(dev, &mldsaKey.handle);
|
||||
return rc;
|
||||
}
|
||||
#endif /* WOLFTPM_MLDSA */
|
||||
|
||||
#ifdef WOLFTPM_MLKEM
|
||||
/* Benchmark ML-KEM: key gen, encapsulate and decapsulate. */
|
||||
static int bench_pqc_mlkem(WOLFTPM2_DEV* dev, double maxDuration,
|
||||
double maxKeyGenDurSec)
|
||||
|
|
@ -353,7 +355,7 @@ exit:
|
|||
wolfTPM2_UnloadHandle(dev, &mlkemKey.handle);
|
||||
return rc;
|
||||
}
|
||||
#endif /* WOLFTPM_PQC */
|
||||
#endif /* WOLFTPM_MLKEM */
|
||||
|
||||
static void usage(void)
|
||||
{
|
||||
|
|
@ -677,17 +679,21 @@ int TPM2_Wrapper_BenchArgs(void* userCtx, int argc, char *argv[])
|
|||
rc = wolfTPM2_UnloadHandle(&dev, &eccKey.handle);
|
||||
if (rc != 0) goto exit;
|
||||
|
||||
#ifdef WOLFTPM_PQC
|
||||
#if defined(WOLFTPM_MLDSA) || defined(WOLFTPM_MLKEM)
|
||||
/* Post-quantum (TPM 2.0 v1.85). Skipped under parameter encryption: the
|
||||
* large PQC public-key responses exceed the parameter-decryption buffer
|
||||
* (TPM_RC_... BUFFER_E). Free the storage key first so the larger PQC keys
|
||||
* fit within the TPM's transient object slots. */
|
||||
if (paramEncAlg == TPM_ALG_NULL) {
|
||||
wolfTPM2_UnloadHandle(&dev, &storageKey.handle);
|
||||
#ifdef WOLFTPM_MLDSA
|
||||
rc = bench_pqc_mldsa(&dev, maxDuration, maxKeyGenDurSec);
|
||||
if (rc != 0) goto exit;
|
||||
#endif
|
||||
#ifdef WOLFTPM_MLKEM
|
||||
rc = bench_pqc_mlkem(&dev, maxDuration, maxKeyGenDurSec);
|
||||
if (rc != 0) goto exit;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -47,6 +47,10 @@ static void usage(void)
|
|||
printf("Primary Key Type:\n");
|
||||
printf("\t-rsa: Use RSA for asymmetric key generation (DEFAULT)\n");
|
||||
printf("\t-ecc: Use ECC for asymmetric key generation \n");
|
||||
#ifdef WOLFTPM_MLDSA
|
||||
printf("\t-mldsa[=44|65|87]: Use ML-DSA for primary key generation "
|
||||
"(v1.85, default 65)\n");
|
||||
#endif
|
||||
printf("Hierarchy:\n");
|
||||
printf("\t-oh: Create keys under the Owner Hierarchy (DEFAULT)\n");
|
||||
printf("\t-eh: Create keys under the Endorsement Hierarchy\n");
|
||||
|
|
@ -77,8 +81,26 @@ static void usage(void)
|
|||
printf("\t* Create SRK used by wolfTPM:\n");
|
||||
printf("\t\tcreate_primary -rsa -oh -auth=ThisIsMyStorageKeyAuth "
|
||||
"-store=0x81000200\n");
|
||||
#ifdef WOLFTPM_MLDSA
|
||||
printf("\t* Create an ML-DSA-65 primary key:\n");
|
||||
printf("\t\tcreate_primary -mldsa -oh\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef WOLFTPM_MLDSA
|
||||
static int mldsaParamSet(const char* optVal, TPMI_MLDSA_PARAMETER_SET* ps)
|
||||
{
|
||||
int n = XATOI(optVal);
|
||||
switch (n) {
|
||||
case 0: /* missing or empty suffix, use default */
|
||||
case 65: *ps = TPM_MLDSA_65; return TPM_RC_SUCCESS;
|
||||
case 44: *ps = TPM_MLDSA_44; return TPM_RC_SUCCESS;
|
||||
case 87: *ps = TPM_MLDSA_87; return TPM_RC_SUCCESS;
|
||||
default: return TPM_RC_FAILURE;
|
||||
}
|
||||
}
|
||||
#endif /* WOLFTPM_MLDSA */
|
||||
|
||||
int TPM2_CreatePrimaryKey_Example(void* userCtx, int argc, char *argv[])
|
||||
{
|
||||
int rc;
|
||||
|
|
@ -98,6 +120,9 @@ int TPM2_CreatePrimaryKey_Example(void* userCtx, int argc, char *argv[])
|
|||
#ifdef WOLFTPM_PROVISIONING
|
||||
int useIAKTemplate = 0, useIDevIDTemplate = 0;
|
||||
#endif
|
||||
#ifdef WOLFTPM_MLDSA
|
||||
TPMI_MLDSA_PARAMETER_SET mldsaPs = TPM_MLDSA_65; /* default param set */
|
||||
#endif
|
||||
|
||||
if (argc >= 2) {
|
||||
if (XSTRCMP(argv[1], "-?") == 0 ||
|
||||
|
|
@ -114,6 +139,19 @@ int TPM2_CreatePrimaryKey_Example(void* userCtx, int argc, char *argv[])
|
|||
else if (XSTRCMP(argv[argc-1], "-ecc") == 0) {
|
||||
alg = TPM_ALG_ECC;
|
||||
}
|
||||
#ifdef WOLFTPM_MLDSA
|
||||
else if (XSTRCMP(argv[argc-1], "-mldsa") == 0 ||
|
||||
XSTRNCMP(argv[argc-1], "-mldsa=",
|
||||
XSTRLEN("-mldsa=")) == 0) {
|
||||
const char* optVal = (argv[argc-1][6] == '=') ?
|
||||
argv[argc-1] + 7 : "";
|
||||
if (mldsaParamSet(optVal, &mldsaPs) != TPM_RC_SUCCESS) {
|
||||
usage();
|
||||
return 0;
|
||||
}
|
||||
alg = TPM_ALG_MLDSA;
|
||||
}
|
||||
#endif
|
||||
else if (XSTRCMP(argv[argc-1], "-aes") == 0) {
|
||||
paramEncAlg = TPM_ALG_CFB;
|
||||
}
|
||||
|
|
@ -221,6 +259,17 @@ int TPM2_CreatePrimaryKey_Example(void* userCtx, int argc, char *argv[])
|
|||
else
|
||||
rc = wolfTPM2_GetKeyTemplate_ECC_SRK(&publicTemplate);
|
||||
}
|
||||
#ifdef WOLFTPM_MLDSA
|
||||
else if (alg == TPM_ALG_MLDSA) {
|
||||
/* ML-DSA is sign-only and has no AIK/IAK/IDevID variant; the
|
||||
* wrapper enforces TPMA_OBJECT_sign and clears decrypt. */
|
||||
rc = wolfTPM2_GetKeyTemplate_MLDSA(&publicTemplate,
|
||||
TPMA_OBJECT_sign | TPMA_OBJECT_fixedTPM |
|
||||
TPMA_OBJECT_fixedParent | TPMA_OBJECT_sensitiveDataOrigin |
|
||||
TPMA_OBJECT_userWithAuth | TPMA_OBJECT_noDA,
|
||||
mldsaPs, 0 /* allowExternalMu: 0 avoids TPM_RC_EXT_MU */);
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
rc = BAD_FUNC_ARG;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -75,15 +75,27 @@ static void usage(void)
|
|||
printf("* -sym: Use Symmetric Cipher for key generation\n");
|
||||
printf("\tDefault Symmetric Cipher is AES CTR with 256 bits\n");
|
||||
printf("* -keyedhash: Use Keyed Hash for key generation\n");
|
||||
#ifdef WOLFTPM_PQC
|
||||
#ifdef WOLFTPM_MLDSA
|
||||
printf("* -mldsa[=44|65|87]: Use ML-DSA for signing (v1.85, default 65)\n");
|
||||
#endif
|
||||
#ifdef WOLFTPM_HASH_MLDSA
|
||||
printf("* -hash_mldsa[=44|65|87]: Use Hash-ML-DSA for signing "
|
||||
"(v1.85, default 65 with SHA-256 pre-hash)\n");
|
||||
#endif
|
||||
#ifdef WOLFTPM_MLKEM
|
||||
printf("* -mlkem[=512|768|1024]: Use ML-KEM for key encapsulation "
|
||||
"(v1.85, default 768)\n");
|
||||
#endif
|
||||
printf("* -t: Use default template (otherwise AIK)\n");
|
||||
printf("* -aes/xor: Use Parameter Encryption\n");
|
||||
#ifdef WOLFTPM_MLKEM
|
||||
printf("* -paramkey=mlkem[=512|768|1024]: Use an ML-KEM key as the "
|
||||
"param-enc session salt (v1.85, default 768)\n");
|
||||
#endif
|
||||
#ifdef WOLFTPM_MLDSA
|
||||
printf("* -paramkey=mldsa[=44|65|87]: Use an ML-DSA key as the "
|
||||
"param-enc session bind (v1.85, default 65)\n");
|
||||
#endif
|
||||
printf("* -unique=[value]\n");
|
||||
printf("\t* Used for the KDF of the create\n");
|
||||
printf("* -auth=pass: Use custom password for key authentication\n");
|
||||
|
|
@ -102,17 +114,21 @@ static void usage(void)
|
|||
printf("\t* Symmetric key, AES, CBC mode, 128 bits, "\
|
||||
"with XOR parameter encryption\n");
|
||||
printf("\t\t keygen -sym=aescbc256 -xor\n");
|
||||
#ifdef WOLFTPM_PQC
|
||||
#ifdef WOLFTPM_MLDSA
|
||||
printf("\t* ML-DSA-65 signing key\n");
|
||||
printf("\t\t keygen -mldsa\n");
|
||||
#endif
|
||||
#ifdef WOLFTPM_HASH_MLDSA
|
||||
printf("\t* Hash-ML-DSA-87 with SHA-256 pre-hash\n");
|
||||
printf("\t\t keygen -hash_mldsa=87\n");
|
||||
#endif
|
||||
#ifdef WOLFTPM_MLKEM
|
||||
printf("\t* ML-KEM-1024 key encapsulation key\n");
|
||||
printf("\t\t keygen -mlkem=1024\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef WOLFTPM_PQC
|
||||
#ifdef WOLFTPM_MLDSA
|
||||
static int mldsaParamSet(const char* optVal, TPMI_MLDSA_PARAMETER_SET* ps)
|
||||
{
|
||||
int n = XATOI(optVal);
|
||||
|
|
@ -124,7 +140,9 @@ static int mldsaParamSet(const char* optVal, TPMI_MLDSA_PARAMETER_SET* ps)
|
|||
default: return TPM_RC_FAILURE;
|
||||
}
|
||||
}
|
||||
#endif /* WOLFTPM_MLDSA */
|
||||
|
||||
#ifdef WOLFTPM_MLKEM
|
||||
static int mlkemParamSet(const char* optVal, TPMI_MLKEM_PARAMETER_SET* ps)
|
||||
{
|
||||
int n = XATOI(optVal);
|
||||
|
|
@ -136,7 +154,7 @@ static int mlkemParamSet(const char* optVal, TPMI_MLKEM_PARAMETER_SET* ps)
|
|||
default: return TPM_RC_FAILURE;
|
||||
}
|
||||
}
|
||||
#endif /* WOLFTPM_PQC */
|
||||
#endif /* WOLFTPM_MLKEM */
|
||||
|
||||
static int symChoice(const char* symMode, TPM_ALG_ID* algSym, int* keyBits)
|
||||
{
|
||||
|
|
@ -176,8 +194,15 @@ int TPM2_Keygen_Example(void* userCtx, int argc, char *argv[])
|
|||
TPMI_ALG_PUBLIC srkAlg = TPM_ALG_RSA; /* default matches seal.c / keyload.c */
|
||||
TPM_ALG_ID algSym = TPM_ALG_CTR; /* default Symmetric Cipher, see usage */
|
||||
TPM_ALG_ID paramEncAlg = TPM_ALG_NULL;
|
||||
#ifdef WOLFTPM_PQC
|
||||
#if defined(WOLFTPM_MLKEM) || defined(WOLFTPM_MLDSA)
|
||||
TPM_ALG_ID pqcParamEncAlg = TPM_ALG_NULL;
|
||||
int pqcParamSet = 0;
|
||||
WOLFTPM2_KEY pqcKey;
|
||||
#endif
|
||||
#ifdef WOLFTPM_MLDSA
|
||||
TPMI_MLDSA_PARAMETER_SET mldsaPs = TPM_MLDSA_65; /* default */
|
||||
#endif
|
||||
#ifdef WOLFTPM_MLKEM
|
||||
TPMI_MLKEM_PARAMETER_SET mlkemPs = TPM_MLKEM_768; /* default */
|
||||
#endif
|
||||
WOLFTPM2_SESSION tpmSession;
|
||||
|
|
@ -228,7 +253,7 @@ int TPM2_Keygen_Example(void* userCtx, int argc, char *argv[])
|
|||
alg = TPM_ALG_KEYEDHASH;
|
||||
bAIK = 0;
|
||||
}
|
||||
#ifdef WOLFTPM_PQC
|
||||
#ifdef WOLFTPM_MLDSA
|
||||
else if (XSTRCMP(argv[argc-1], "-mldsa") == 0 ||
|
||||
XSTRNCMP(argv[argc-1], "-mldsa=",
|
||||
XSTRLEN("-mldsa=")) == 0) {
|
||||
|
|
@ -241,6 +266,8 @@ int TPM2_Keygen_Example(void* userCtx, int argc, char *argv[])
|
|||
alg = TPM_ALG_MLDSA;
|
||||
bAIK = 0;
|
||||
}
|
||||
#endif /* WOLFTPM_MLDSA */
|
||||
#ifdef WOLFTPM_HASH_MLDSA
|
||||
else if (XSTRCMP(argv[argc-1], "-hash_mldsa") == 0 ||
|
||||
XSTRNCMP(argv[argc-1], "-hash_mldsa=",
|
||||
XSTRLEN("-hash_mldsa=")) == 0) {
|
||||
|
|
@ -253,6 +280,8 @@ int TPM2_Keygen_Example(void* userCtx, int argc, char *argv[])
|
|||
alg = TPM_ALG_HASH_MLDSA;
|
||||
bAIK = 0;
|
||||
}
|
||||
#endif /* WOLFTPM_HASH_MLDSA */
|
||||
#ifdef WOLFTPM_MLKEM
|
||||
else if (XSTRCMP(argv[argc-1], "-mlkem") == 0 ||
|
||||
XSTRNCMP(argv[argc-1], "-mlkem=",
|
||||
XSTRLEN("-mlkem=")) == 0) {
|
||||
|
|
@ -265,7 +294,7 @@ int TPM2_Keygen_Example(void* userCtx, int argc, char *argv[])
|
|||
alg = TPM_ALG_MLKEM;
|
||||
bAIK = 0;
|
||||
}
|
||||
#endif /* WOLFTPM_PQC */
|
||||
#endif /* WOLFTPM_MLKEM */
|
||||
else if (XSTRCMP(argv[argc-1], "-t") == 0) {
|
||||
bAIK = 0;
|
||||
}
|
||||
|
|
@ -281,6 +310,18 @@ int TPM2_Keygen_Example(void* userCtx, int argc, char *argv[])
|
|||
else if (XSTRCMP(argv[argc-1], "-xor") == 0) {
|
||||
paramEncAlg = TPM_ALG_XOR;
|
||||
}
|
||||
#if defined(WOLFTPM_MLKEM) || defined(WOLFTPM_MLDSA)
|
||||
else if (XSTRNCMP(argv[argc-1], "-paramkey=",
|
||||
XSTRLEN("-paramkey=")) == 0) {
|
||||
/* PQC key for the param-enc session, e.g. "mlkem=768"/"mldsa=65" */
|
||||
const char* pkVal = argv[argc-1] + XSTRLEN("-paramkey=");
|
||||
if (parsePqcParamSet(pkVal, &pqcParamEncAlg, &pqcParamSet) != 1) {
|
||||
printf("Invalid -paramkey value: %s\n", pkVal);
|
||||
usage();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
else if (XSTRNCMP(argv[argc-1], "-unique=", XSTRLEN("-unique=")) == 0) {
|
||||
uniqueStr = argv[argc-1] + XSTRLEN("-unique=");
|
||||
}
|
||||
|
|
@ -310,6 +351,9 @@ int TPM2_Keygen_Example(void* userCtx, int argc, char *argv[])
|
|||
XMEMSET(&primaryBlob, 0, sizeof(primaryBlob));
|
||||
XMEMSET(&tpmSession, 0, sizeof(tpmSession));
|
||||
XMEMSET(&auth, 0, sizeof(auth));
|
||||
#if defined(WOLFTPM_MLKEM) || defined(WOLFTPM_MLDSA)
|
||||
XMEMSET(&pqcKey, 0, sizeof(pqcKey));
|
||||
#endif
|
||||
|
||||
/* Only use the ECC SRK for ECC child keys; RSA, SYMCIPHER, KEYEDHASH
|
||||
* all stay on the RSA SRK so that keyload/seal can round-trip them. */
|
||||
|
|
@ -323,6 +367,16 @@ int TPM2_Keygen_Example(void* userCtx, int argc, char *argv[])
|
|||
}
|
||||
}
|
||||
|
||||
#if defined(WOLFTPM_MLKEM) || defined(WOLFTPM_MLDSA)
|
||||
/* A PQC param-enc key only supplies the salt/bind material; a symmetric
|
||||
* session cipher is still required. Default to AES-CFB if none given. */
|
||||
if (pqcParamEncAlg != TPM_ALG_NULL && paramEncAlg == TPM_ALG_NULL) {
|
||||
paramEncAlg = TPM_ALG_CFB;
|
||||
printf("PQC param-enc key selected; defaulting session cipher to "
|
||||
"AES-CFB.\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
printf("TPM2.0 Key generation example\n");
|
||||
printf("\tKey Blob: %s\n", outputFile);
|
||||
printf("\tAlgorithm: %s\n", TPM2_GetAlgName(alg));
|
||||
|
|
@ -364,9 +418,20 @@ int TPM2_Keygen_Example(void* userCtx, int argc, char *argv[])
|
|||
if (srkAlg == TPM_ALG_RSA)
|
||||
bindKey = NULL; /* cannot bind to key without RSA enabled */
|
||||
#endif
|
||||
/* Start an authenticated session (salted / unbound) with parameter encryption */
|
||||
rc = wolfTPM2_StartSession(&dev, &tpmSession, bindKey, NULL,
|
||||
TPM_SE_HMAC, paramEncAlg);
|
||||
#if defined(WOLFTPM_MLKEM) || defined(WOLFTPM_MLDSA)
|
||||
if (pqcParamEncAlg != TPM_ALG_NULL) {
|
||||
/* Use a PQC primary as the param-enc session key: ML-KEM salt
|
||||
* or ML-DSA bind. This replaces the salted-to-SRK session. */
|
||||
rc = getPrimaryParamEncKey(&dev, &tpmSession, &pqcKey,
|
||||
pqcParamEncAlg, pqcParamSet, paramEncAlg);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
/* Start an authenticated session (salted / unbound) with parameter encryption */
|
||||
rc = wolfTPM2_StartSession(&dev, &tpmSession, bindKey, NULL,
|
||||
TPM_SE_HMAC, paramEncAlg);
|
||||
}
|
||||
if (rc != 0) goto exit;
|
||||
printf("HMAC Session: Handle 0x%x\n",
|
||||
(word32)tpmSession.handle.hndl);
|
||||
|
|
@ -405,7 +470,7 @@ int TPM2_Keygen_Example(void* userCtx, int argc, char *argv[])
|
|||
"not symmetric or keyedhash keys.\n");
|
||||
rc = BAD_FUNC_ARG;
|
||||
}
|
||||
#ifdef WOLFTPM_PQC
|
||||
#if defined(WOLFTPM_MLDSA) || defined(WOLFTPM_MLKEM)
|
||||
else if (alg == TPM_ALG_MLDSA || alg == TPM_ALG_HASH_MLDSA ||
|
||||
alg == TPM_ALG_MLKEM) {
|
||||
printf("AIK template is RSA or ECC only; PQC keys use their "
|
||||
|
|
@ -454,7 +519,7 @@ int TPM2_Keygen_Example(void* userCtx, int argc, char *argv[])
|
|||
TPM_ALG_SHA256, YES, NO);
|
||||
publicTemplate.objectAttributes |= TPMA_OBJECT_sensitiveDataOrigin;
|
||||
}
|
||||
#ifdef WOLFTPM_PQC
|
||||
#ifdef WOLFTPM_MLDSA
|
||||
else if (alg == TPM_ALG_MLDSA) {
|
||||
printf("ML-DSA template (parameter set %u)\n",
|
||||
(unsigned)mldsaPs);
|
||||
|
|
@ -462,10 +527,12 @@ int TPM2_Keygen_Example(void* userCtx, int argc, char *argv[])
|
|||
TPMA_OBJECT_sign | TPMA_OBJECT_fixedTPM |
|
||||
TPMA_OBJECT_fixedParent | TPMA_OBJECT_sensitiveDataOrigin |
|
||||
TPMA_OBJECT_userWithAuth | TPMA_OBJECT_noDA,
|
||||
mldsaPs, 0 /* allowExternalMu — TPM_RC_EXT_MU at create
|
||||
mldsaPs, 0 /* allowExternalMu - TPM_RC_EXT_MU at create
|
||||
* per Part 2 Sec.12.2.3.6 when SET on a TPM
|
||||
* without μ-direct sign support */);
|
||||
* without mu-direct sign support */);
|
||||
}
|
||||
#endif /* WOLFTPM_MLDSA */
|
||||
#ifdef WOLFTPM_HASH_MLDSA
|
||||
else if (alg == TPM_ALG_HASH_MLDSA) {
|
||||
printf("Hash-ML-DSA template (parameter set %u, pre-hash %s)\n",
|
||||
(unsigned)mldsaPs, TPM2_GetAlgName(TPM_ALG_SHA256));
|
||||
|
|
@ -475,6 +542,8 @@ int TPM2_Keygen_Example(void* userCtx, int argc, char *argv[])
|
|||
TPMA_OBJECT_userWithAuth | TPMA_OBJECT_noDA,
|
||||
mldsaPs, TPM_ALG_SHA256);
|
||||
}
|
||||
#endif /* WOLFTPM_HASH_MLDSA */
|
||||
#ifdef WOLFTPM_MLKEM
|
||||
else if (alg == TPM_ALG_MLKEM) {
|
||||
printf("ML-KEM template (parameter set %u)\n",
|
||||
(unsigned)mlkemPs);
|
||||
|
|
@ -484,7 +553,7 @@ int TPM2_Keygen_Example(void* userCtx, int argc, char *argv[])
|
|||
TPMA_OBJECT_userWithAuth | TPMA_OBJECT_noDA,
|
||||
mlkemPs);
|
||||
}
|
||||
#endif /* WOLFTPM_PQC */
|
||||
#endif /* WOLFTPM_MLKEM */
|
||||
else {
|
||||
rc = BAD_FUNC_ARG;
|
||||
}
|
||||
|
|
@ -613,6 +682,9 @@ exit:
|
|||
wolfTPM2_UnloadHandle(&dev, &primary->handle);
|
||||
wolfTPM2_UnloadHandle(&dev, &newKeyBlob.handle);
|
||||
wolfTPM2_UnloadHandle(&dev, &tpmSession.handle);
|
||||
#if defined(WOLFTPM_MLKEM) || defined(WOLFTPM_MLDSA)
|
||||
wolfTPM2_UnloadHandle(&dev, &pqcKey.handle);
|
||||
#endif
|
||||
|
||||
wolfTPM2_Cleanup(&dev);
|
||||
return rc;
|
||||
|
|
|
|||
|
|
@ -50,6 +50,14 @@ static void usage(void)
|
|||
printf("./examples/nvram/counter [-nvindex=] [-aes/-xor]\n");
|
||||
printf("* -nvindex=[handle] (default 0x%x)\n", TPM2_DEMO_NV_COUNTER_INDEX);
|
||||
printf("* -aes/xor: Use Parameter Encryption\n");
|
||||
#ifdef WOLFTPM_MLKEM
|
||||
printf("* -mlkem[=512|768|1024]: Use an ML-KEM key as the param-enc "
|
||||
"session salt (v1.85, default 768)\n");
|
||||
#endif
|
||||
#ifdef WOLFTPM_MLDSA
|
||||
printf("* -mldsa[=44|65|87]: Use an ML-DSA key as the param-enc "
|
||||
"session bind (v1.85, default 65)\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
int TPM2_NVRAM_Counter_Example(void* userCtx, int argc, char *argv[])
|
||||
|
|
@ -63,12 +71,20 @@ int TPM2_NVRAM_Counter_Example(void* userCtx, int argc, char *argv[])
|
|||
TPMS_NV_PUBLIC nvPublic;
|
||||
TPMI_RH_NV_AUTH authHandle = TPM_RH_OWNER; /* or TPM_RH_PLATFORM */
|
||||
int paramEncAlg = TPM_ALG_NULL;
|
||||
#if defined(WOLFTPM_MLKEM) || defined(WOLFTPM_MLDSA)
|
||||
TPM_ALG_ID pqcParamEncAlg = TPM_ALG_NULL;
|
||||
int pqcParamSet = 0;
|
||||
WOLFTPM2_KEY pqcKey;
|
||||
#endif
|
||||
word32 nvIndex = TPM2_DEMO_NV_COUNTER_INDEX;
|
||||
|
||||
XMEMSET(&tpmSession, 0, sizeof(tpmSession));
|
||||
XMEMSET(&parent, 0, sizeof(parent));
|
||||
XMEMSET(&nv, 0, sizeof(nv));
|
||||
XMEMSET(&storage, 0, sizeof(storage));
|
||||
#if defined(WOLFTPM_MLKEM) || defined(WOLFTPM_MLDSA)
|
||||
XMEMSET(&pqcKey, 0, sizeof(pqcKey));
|
||||
#endif
|
||||
|
||||
if (argc >= 2) {
|
||||
if (XSTRCMP(argv[1], "-?") == 0 ||
|
||||
|
|
@ -104,6 +120,17 @@ int TPM2_NVRAM_Counter_Example(void* userCtx, int argc, char *argv[])
|
|||
else if (XSTRCMP(argv[argc-1], "-xor") == 0) {
|
||||
paramEncAlg = TPM_ALG_XOR;
|
||||
}
|
||||
#if defined(WOLFTPM_MLKEM) || defined(WOLFTPM_MLDSA)
|
||||
else if (parsePqcParamEncArg(argv[argc-1], &pqcParamEncAlg,
|
||||
&pqcParamSet) != 0) {
|
||||
/* PQC option; an unsupported parameter set (alg left NULL) is a
|
||||
* fatal typo, not a silent drop of parameter encryption. */
|
||||
if (pqcParamEncAlg == TPM_ALG_NULL) {
|
||||
usage();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
printf("Warning: Unrecognized option: %s\n", argv[argc-1]);
|
||||
}
|
||||
|
|
@ -111,6 +138,16 @@ int TPM2_NVRAM_Counter_Example(void* userCtx, int argc, char *argv[])
|
|||
argc--;
|
||||
}
|
||||
|
||||
#if defined(WOLFTPM_MLKEM) || defined(WOLFTPM_MLDSA)
|
||||
/* A PQC param-enc key only supplies the salt/bind material; a symmetric
|
||||
* session cipher is still required. Default to AES-CFB if none given. */
|
||||
if (pqcParamEncAlg != TPM_ALG_NULL && paramEncAlg == TPM_ALG_NULL) {
|
||||
paramEncAlg = TPM_ALG_CFB;
|
||||
printf("PQC param-enc key selected; defaulting session cipher to "
|
||||
"AES-CFB.\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
printf("NV Counter: NV Index 0x%x\n", nvIndex);
|
||||
if (paramEncAlg == TPM_ALG_CFB) {
|
||||
printf("Parameter Encryption: Enabled. (AES CFB)\n\n");
|
||||
|
|
@ -130,9 +167,20 @@ int TPM2_NVRAM_Counter_Example(void* userCtx, int argc, char *argv[])
|
|||
}
|
||||
|
||||
if (paramEncAlg != TPM_ALG_NULL) {
|
||||
/* Start TPM session for parameter encryption */
|
||||
rc = wolfTPM2_StartSession(&dev, &tpmSession, NULL, NULL,
|
||||
TPM_SE_HMAC, paramEncAlg);
|
||||
#if defined(WOLFTPM_MLKEM) || defined(WOLFTPM_MLDSA)
|
||||
if (pqcParamEncAlg != TPM_ALG_NULL) {
|
||||
/* Use a PQC primary as the param-enc session key: ML-KEM salt
|
||||
* or ML-DSA bind. */
|
||||
rc = getPrimaryParamEncKey(&dev, &tpmSession, &pqcKey,
|
||||
pqcParamEncAlg, pqcParamSet, paramEncAlg);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
/* Start TPM session for parameter encryption */
|
||||
rc = wolfTPM2_StartSession(&dev, &tpmSession, NULL, NULL,
|
||||
TPM_SE_HMAC, paramEncAlg);
|
||||
}
|
||||
if (rc != 0) goto exit;
|
||||
printf("TPM2_StartAuthSession: sessionHandle 0x%x\n",
|
||||
(word32)tpmSession.handle.hndl);
|
||||
|
|
@ -160,8 +208,6 @@ int TPM2_NVRAM_Counter_Example(void* userCtx, int argc, char *argv[])
|
|||
nvAttributes, 8, (byte*)gNvAuth, sizeof(gNvAuth)-1);
|
||||
if (rc != 0) goto exit;
|
||||
|
||||
wolfTPM2_SetAuthHandle(&dev, 0, &nv.handle);
|
||||
|
||||
rc = wolfTPM2_NVReadPublic(&dev, nvIndex, &nvPublic);
|
||||
}
|
||||
if (rc != TPM_RC_SUCCESS) {
|
||||
|
|
@ -178,6 +224,11 @@ int TPM2_NVRAM_Counter_Example(void* userCtx, int argc, char *argv[])
|
|||
goto exit;
|
||||
}
|
||||
|
||||
/* Set the NV index auth in slot 0 (slot 1 holds the param-enc session). A
|
||||
* salted/PQC param-enc session leaves slot 0 pointing at the salt key, so
|
||||
* reset it here for both the create and existing-index paths. */
|
||||
wolfTPM2_SetAuthHandle(&dev, 0, &nv.handle);
|
||||
|
||||
rc = wolfTPM2_NVIncrement(&dev, &nv);
|
||||
if (rc != TPM_RC_SUCCESS) {
|
||||
printf("NV Increment failed\n");
|
||||
|
|
@ -191,6 +242,9 @@ exit:
|
|||
}
|
||||
|
||||
wolfTPM2_UnloadHandle(&dev, &tpmSession.handle);
|
||||
#if defined(WOLFTPM_MLKEM) || defined(WOLFTPM_MLDSA)
|
||||
wolfTPM2_UnloadHandle(&dev, &pqcKey.handle);
|
||||
#endif
|
||||
wolfTPM2_Cleanup(&dev);
|
||||
|
||||
return rc;
|
||||
|
|
|
|||
|
|
@ -57,6 +57,14 @@ static void usage(void)
|
|||
printf("* -priv: Store only the private part of the key\n");
|
||||
printf("* -pub: Store only the public part of the key\n");
|
||||
printf("* -aes/xor: Use Parameter Encryption\n");
|
||||
#ifdef WOLFTPM_MLKEM
|
||||
printf("* -mlkem[=512|768|1024]: Use an ML-KEM key as the param-enc "
|
||||
"session salt (v1.85, default 768)\n");
|
||||
#endif
|
||||
#ifdef WOLFTPM_MLDSA
|
||||
printf("* -mldsa[=44|65|87]: Use an ML-DSA key as the param-enc "
|
||||
"session bind (v1.85, default 65)\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
int TPM2_NVRAM_Store_Example(void* userCtx, int argc, char *argv[])
|
||||
|
|
@ -71,6 +79,11 @@ int TPM2_NVRAM_Store_Example(void* userCtx, int argc, char *argv[])
|
|||
TPMI_RH_NV_AUTH authHandle = TPM_RH_OWNER; /* or TPM_RH_PLATFORM */
|
||||
const char* filename = "keyblob.bin";
|
||||
int paramEncAlg = TPM_ALG_NULL;
|
||||
#if defined(WOLFTPM_MLKEM) || defined(WOLFTPM_MLDSA)
|
||||
TPM_ALG_ID pqcParamEncAlg = TPM_ALG_NULL;
|
||||
int pqcParamSet = 0;
|
||||
WOLFTPM2_KEY pqcKey;
|
||||
#endif
|
||||
int partialStore = 0;
|
||||
int offset = 0;
|
||||
/* Needed for TPM2_AppendPublic */
|
||||
|
|
@ -121,6 +134,17 @@ int TPM2_NVRAM_Store_Example(void* userCtx, int argc, char *argv[])
|
|||
else if (XSTRCMP(argv[argc-1], "-pub") == 0) {
|
||||
partialStore = PUBLIC_PART_ONLY;
|
||||
}
|
||||
#if defined(WOLFTPM_MLKEM) || defined(WOLFTPM_MLDSA)
|
||||
else if (parsePqcParamEncArg(argv[argc-1], &pqcParamEncAlg,
|
||||
&pqcParamSet) != 0) {
|
||||
/* PQC option; an unsupported parameter set (alg left NULL) is a
|
||||
* fatal typo, not a silent drop of parameter encryption. */
|
||||
if (pqcParamEncAlg == TPM_ALG_NULL) {
|
||||
usage();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
else if (argv[argc-1][0] != '-') {
|
||||
filename = argv[argc-1];
|
||||
}
|
||||
|
|
@ -130,6 +154,16 @@ int TPM2_NVRAM_Store_Example(void* userCtx, int argc, char *argv[])
|
|||
argc--;
|
||||
};
|
||||
|
||||
#if defined(WOLFTPM_MLKEM) || defined(WOLFTPM_MLDSA)
|
||||
/* A PQC param-enc key only supplies the salt/bind material; a symmetric
|
||||
* session cipher is still required. Default to AES-CFB if none given. */
|
||||
if (pqcParamEncAlg != TPM_ALG_NULL && paramEncAlg == TPM_ALG_NULL) {
|
||||
paramEncAlg = TPM_ALG_CFB;
|
||||
printf("PQC param-enc key selected; defaulting session cipher to "
|
||||
"AES-CFB.\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
if (paramEncAlg == TPM_ALG_CFB) {
|
||||
printf("Parameter Encryption: Enabled. (AES CFB)\n\n");
|
||||
}
|
||||
|
|
@ -144,6 +178,9 @@ int TPM2_NVRAM_Store_Example(void* userCtx, int argc, char *argv[])
|
|||
XMEMSET(&keyBlob, 0, sizeof(keyBlob));
|
||||
XMEMSET(&tpmSession, 0, sizeof(tpmSession));
|
||||
XMEMSET(&parent, 0, sizeof(parent));
|
||||
#if defined(WOLFTPM_MLKEM) || defined(WOLFTPM_MLDSA)
|
||||
XMEMSET(&pqcKey, 0, sizeof(pqcKey));
|
||||
#endif
|
||||
|
||||
rc = wolfTPM2_Init(&dev, TPM2_IoCb, userCtx);
|
||||
if (rc != TPM_RC_SUCCESS) {
|
||||
|
|
@ -152,9 +189,20 @@ int TPM2_NVRAM_Store_Example(void* userCtx, int argc, char *argv[])
|
|||
}
|
||||
|
||||
if (paramEncAlg != TPM_ALG_NULL) {
|
||||
/* Start TPM session for parameter encryption */
|
||||
rc = wolfTPM2_StartSession(&dev, &tpmSession, NULL, NULL,
|
||||
TPM_SE_HMAC, paramEncAlg);
|
||||
#if defined(WOLFTPM_MLKEM) || defined(WOLFTPM_MLDSA)
|
||||
if (pqcParamEncAlg != TPM_ALG_NULL) {
|
||||
/* Use a PQC primary as the param-enc session key: ML-KEM salt
|
||||
* or ML-DSA bind. */
|
||||
rc = getPrimaryParamEncKey(&dev, &tpmSession, &pqcKey,
|
||||
pqcParamEncAlg, pqcParamSet, paramEncAlg);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
/* Start TPM session for parameter encryption */
|
||||
rc = wolfTPM2_StartSession(&dev, &tpmSession, NULL, NULL,
|
||||
TPM_SE_HMAC, paramEncAlg);
|
||||
}
|
||||
if (rc != 0) goto exit;
|
||||
printf("TPM2_StartAuthSession: sessionHandle 0x%x\n",
|
||||
(word32)tpmSession.handle.hndl);
|
||||
|
|
@ -246,6 +294,9 @@ exit:
|
|||
}
|
||||
|
||||
wolfTPM2_UnloadHandle(&dev, &tpmSession.handle);
|
||||
#if defined(WOLFTPM_MLKEM) || defined(WOLFTPM_MLDSA)
|
||||
wolfTPM2_UnloadHandle(&dev, &pqcKey.handle);
|
||||
#endif
|
||||
wolfTPM2_Cleanup(&dev);
|
||||
|
||||
return rc;
|
||||
|
|
|
|||
|
|
@ -49,6 +49,14 @@ static void usage(void)
|
|||
printf("* filename: for saving the TPMS_ATTEST structure to a file\n");
|
||||
printf("* -ecc: Use RSA or ECC for SRK/AIK\n");
|
||||
printf("* -aes/xor: Use Parameter Encryption\n");
|
||||
#ifdef WOLFTPM_MLKEM
|
||||
printf("* -mlkem[=512|768|1024]: Use an ML-KEM key as the param-enc "
|
||||
"session salt (v1.85, default 768)\n");
|
||||
#endif
|
||||
#ifdef WOLFTPM_MLDSA
|
||||
printf("* -mldsa[=44|65|87]: Use an ML-DSA key as the param-enc "
|
||||
"session bind (v1.85, default 65)\n");
|
||||
#endif
|
||||
printf("Demo usage without parameters, generates quote over PCR%d and\n"
|
||||
"saves the output TPMS_ATTEST structure to \"quote.blob\" file.\n",
|
||||
TPM2_TEST_PCR);
|
||||
|
|
@ -80,6 +88,11 @@ int TPM2_PCR_Quote_Test(void* userCtx, int argc, char *argv[])
|
|||
} cmdOut;
|
||||
TPM_ALG_ID paramEncAlg = TPM_ALG_NULL;
|
||||
WOLFTPM2_SESSION tpmSession;
|
||||
#if defined(WOLFTPM_MLKEM) || defined(WOLFTPM_MLDSA)
|
||||
TPM_ALG_ID pqcParamEncAlg = TPM_ALG_NULL;
|
||||
int pqcParamSet = 0;
|
||||
WOLFTPM2_KEY pqcKey;
|
||||
#endif
|
||||
#if !defined(NO_FILESYSTEM) && !defined(NO_WRITE_TEMP_FILES)
|
||||
XFILE f;
|
||||
#endif
|
||||
|
|
@ -87,6 +100,9 @@ int TPM2_PCR_Quote_Test(void* userCtx, int argc, char *argv[])
|
|||
XMEMSET(&storage, 0, sizeof(storage));
|
||||
XMEMSET(&aik, 0, sizeof(aik));
|
||||
XMEMSET(&tpmSession, 0, sizeof(tpmSession));
|
||||
#if defined(WOLFTPM_MLKEM) || defined(WOLFTPM_MLDSA)
|
||||
XMEMSET(&pqcKey, 0, sizeof(pqcKey));
|
||||
#endif
|
||||
|
||||
if (argc >= 2) {
|
||||
if (XSTRCMP(argv[1], "-?") == 0 ||
|
||||
|
|
@ -123,9 +139,30 @@ int TPM2_PCR_Quote_Test(void* userCtx, int argc, char *argv[])
|
|||
else if (XSTRCMP(argv[argc-1], "-xor") == 0) {
|
||||
paramEncAlg = TPM_ALG_XOR;
|
||||
}
|
||||
#if defined(WOLFTPM_MLKEM) || defined(WOLFTPM_MLDSA)
|
||||
else if (parsePqcParamEncArg(argv[argc-1], &pqcParamEncAlg,
|
||||
&pqcParamSet) != 0) {
|
||||
/* PQC option; an unsupported parameter set (alg left NULL) is a
|
||||
* fatal typo, not a silent drop of parameter encryption. */
|
||||
if (pqcParamEncAlg == TPM_ALG_NULL) {
|
||||
usage();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
argc--;
|
||||
}
|
||||
|
||||
#if defined(WOLFTPM_MLKEM) || defined(WOLFTPM_MLDSA)
|
||||
/* A PQC param-enc key only supplies the salt/bind material; a symmetric
|
||||
* session cipher is still required. Default to AES-CFB if none given. */
|
||||
if (pqcParamEncAlg != TPM_ALG_NULL && paramEncAlg == TPM_ALG_NULL) {
|
||||
paramEncAlg = TPM_ALG_CFB;
|
||||
printf("PQC param-enc key selected; defaulting session cipher to "
|
||||
"AES-CFB.\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
printf("PCR Quote example - Demo of signed PCR measurement\n");
|
||||
printf("\tOutput file: %s\n", outputFile);
|
||||
printf("\tPCR Index: %d\n", pcrIndex);
|
||||
|
|
@ -198,9 +235,20 @@ int TPM2_PCR_Quote_Test(void* userCtx, int argc, char *argv[])
|
|||
if (alg == TPM_ALG_RSA)
|
||||
bindKey = NULL; /* cannot bind to key without RSA enabled */
|
||||
#endif
|
||||
/* Start an authenticated session (salted / unbound) with parameter encryption */
|
||||
rc = wolfTPM2_StartSession(&dev, &tpmSession, bindKey, NULL,
|
||||
TPM_SE_HMAC, paramEncAlg);
|
||||
#if defined(WOLFTPM_MLKEM) || defined(WOLFTPM_MLDSA)
|
||||
if (pqcParamEncAlg != TPM_ALG_NULL) {
|
||||
/* Use a PQC primary as the param-enc session key: ML-KEM salt
|
||||
* or ML-DSA bind. The RSA/ECC SRK stays the AIK parent. */
|
||||
rc = getPrimaryParamEncKey(&dev, &tpmSession, &pqcKey,
|
||||
pqcParamEncAlg, pqcParamSet, paramEncAlg);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
/* Start an authenticated session (salted / unbound) with parameter encryption */
|
||||
rc = wolfTPM2_StartSession(&dev, &tpmSession, bindKey, NULL,
|
||||
TPM_SE_HMAC, paramEncAlg);
|
||||
}
|
||||
if (rc != 0) goto exit;
|
||||
printf("TPM2_StartAuthSession: sessionHandle 0x%x\n",
|
||||
(word32)tpmSession.handle.hndl);
|
||||
|
|
@ -334,6 +382,9 @@ exit:
|
|||
wolfTPM2_UnloadHandle(&dev, &aik.handle);
|
||||
wolfTPM2_UnloadHandle(&dev, &storage.handle);
|
||||
wolfTPM2_UnloadHandle(&dev, &tpmSession.handle);
|
||||
#if defined(WOLFTPM_MLKEM) || defined(WOLFTPM_MLDSA)
|
||||
wolfTPM2_UnloadHandle(&dev, &pqcKey.handle);
|
||||
#endif
|
||||
|
||||
wolfTPM2_Cleanup(&dev);
|
||||
|
||||
|
|
|
|||
|
|
@ -430,6 +430,168 @@ int getPrimaryStoragekey(WOLFTPM2_DEV* pDev, WOLFTPM2_KEY* pStorageKey,
|
|||
return rc;
|
||||
}
|
||||
|
||||
#if defined(WOLFTPM_MLDSA) || defined(WOLFTPM_MLKEM)
|
||||
int getPrimaryParamEncKey(WOLFTPM2_DEV* pDev, WOLFTPM2_SESSION* session,
|
||||
WOLFTPM2_KEY* pqcKey, TPM_ALG_ID pqcAlg, int paramSet, int paramEncAlg)
|
||||
{
|
||||
int rc;
|
||||
TPMT_PUBLIC publicTemplate;
|
||||
#ifdef WOLFTPM_MLDSA
|
||||
WOLFTPM2_KEY saltKey; /* transient SRK salt for the ML-DSA bound session */
|
||||
#if !defined(NO_RSA)
|
||||
TPM_ALG_ID saltAlg = TPM_ALG_RSA;
|
||||
#else
|
||||
TPM_ALG_ID saltAlg = TPM_ALG_ECC;
|
||||
#endif
|
||||
#endif
|
||||
const char* pqcAuth = "pqcParamEnc"; /* primary userAuth; the bind auth for
|
||||
* ML-DSA, immaterial for the ML-KEM
|
||||
* salt key */
|
||||
|
||||
if (pDev == NULL || session == NULL || pqcKey == NULL)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
XMEMSET(pqcKey, 0, sizeof(*pqcKey));
|
||||
XMEMSET(&publicTemplate, 0, sizeof(publicTemplate));
|
||||
#ifdef WOLFTPM_MLDSA
|
||||
XMEMSET(&saltKey, 0, sizeof(saltKey));
|
||||
#endif
|
||||
|
||||
if (pqcAlg == TPM_ALG_MLKEM) {
|
||||
#ifdef WOLFTPM_MLKEM
|
||||
/* ML-KEM salt key: restricted decryption, which requires a symmetric
|
||||
* definition (a TPM rejects a restricted key without one). */
|
||||
rc = wolfTPM2_GetKeyTemplate_MLKEM(&publicTemplate,
|
||||
TPMA_OBJECT_decrypt | TPMA_OBJECT_restricted |
|
||||
TPMA_OBJECT_fixedTPM | TPMA_OBJECT_fixedParent |
|
||||
TPMA_OBJECT_sensitiveDataOrigin | TPMA_OBJECT_userWithAuth |
|
||||
TPMA_OBJECT_noDA, (TPMI_MLKEM_PARAMETER_SET)paramSet);
|
||||
if (rc == TPM_RC_SUCCESS) {
|
||||
publicTemplate.parameters.mlkemDetail.symmetric.algorithm =
|
||||
TPM_ALG_AES;
|
||||
publicTemplate.parameters.mlkemDetail.symmetric.keyBits.aes = 128;
|
||||
publicTemplate.parameters.mlkemDetail.symmetric.mode.aes =
|
||||
TPM_ALG_CFB;
|
||||
}
|
||||
#else
|
||||
(void)paramSet;
|
||||
return NOT_COMPILED_IN;
|
||||
#endif
|
||||
}
|
||||
else if (pqcAlg == TPM_ALG_MLDSA) {
|
||||
#ifdef WOLFTPM_MLDSA
|
||||
/* ML-DSA is sign-only; it can only be a session bind entity. */
|
||||
rc = wolfTPM2_GetKeyTemplate_MLDSA(&publicTemplate,
|
||||
TPMA_OBJECT_sign | TPMA_OBJECT_fixedTPM |
|
||||
TPMA_OBJECT_fixedParent | TPMA_OBJECT_sensitiveDataOrigin |
|
||||
TPMA_OBJECT_userWithAuth | TPMA_OBJECT_noDA,
|
||||
(TPMI_MLDSA_PARAMETER_SET)paramSet, 0);
|
||||
#else
|
||||
(void)paramSet;
|
||||
return NOT_COMPILED_IN;
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
if (rc != TPM_RC_SUCCESS)
|
||||
return rc;
|
||||
|
||||
rc = wolfTPM2_CreatePrimaryKey(pDev, pqcKey, TPM_RH_OWNER, &publicTemplate,
|
||||
(const byte*)pqcAuth, (int)XSTRLEN(pqcAuth));
|
||||
if (rc != TPM_RC_SUCCESS)
|
||||
return rc;
|
||||
printf("PQC param-enc key: %s primary 0x%x\n", TPM2_GetAlgName(pqcAlg),
|
||||
(word32)pqcKey->handle.hndl);
|
||||
|
||||
/* ML-KEM keys the session salt (tpmKey). ML-DSA is sign-only so it can
|
||||
* only bind; a transient SRK provides the salt (confidentiality) while the
|
||||
* ML-DSA key supplies the binding. */
|
||||
if (pqcAlg == TPM_ALG_MLKEM) {
|
||||
rc = wolfTPM2_StartSession(pDev, session, pqcKey, NULL,
|
||||
TPM_SE_HMAC, paramEncAlg);
|
||||
}
|
||||
else {
|
||||
#ifdef WOLFTPM_MLDSA
|
||||
rc = wolfTPM2_CreateSRK(pDev, &saltKey, saltAlg, NULL, 0);
|
||||
if (rc == TPM_RC_SUCCESS) {
|
||||
rc = wolfTPM2_StartSession(pDev, session, &saltKey,
|
||||
&pqcKey->handle, TPM_SE_HMAC, paramEncAlg);
|
||||
/* salt is baked into the session key; drop the salt key handle */
|
||||
wolfTPM2_UnloadHandle(pDev, &saltKey.handle);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if (rc != TPM_RC_SUCCESS) {
|
||||
printf("PQC param-enc StartSession failed 0x%x: %s\n", rc,
|
||||
TPM2_GetRCString(rc));
|
||||
wolfTPM2_UnloadHandle(pDev, &pqcKey->handle);
|
||||
XMEMSET(pqcKey, 0, sizeof(*pqcKey));
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Returns 1 and sets the alg and paramSet outputs for a valid PQC value, -1 if
|
||||
* the value names a PQC algorithm but with an unsupported parameter set
|
||||
* (message printed), or 0 if it is not a PQC option. Outputs are committed
|
||||
* only on success. An empty suffix ("mlkem=") uses the default like "mlkem". */
|
||||
int parsePqcParamSet(const char* val, TPM_ALG_ID* alg, int* paramSet)
|
||||
{
|
||||
int n;
|
||||
int localSet;
|
||||
|
||||
if (val == NULL || alg == NULL || paramSet == NULL)
|
||||
return 0;
|
||||
#ifdef WOLFTPM_MLKEM
|
||||
if (XSTRCMP(val, "mlkem") == 0 ||
|
||||
XSTRNCMP(val, "mlkem=", 6) == 0) {
|
||||
n = (val[5] == '=' && val[6] != '\0') ? XATOI(&val[6]) : 768;
|
||||
if (n == 512)
|
||||
localSet = TPM_MLKEM_512;
|
||||
else if (n == 768)
|
||||
localSet = TPM_MLKEM_768;
|
||||
else if (n == 1024)
|
||||
localSet = TPM_MLKEM_1024;
|
||||
else {
|
||||
printf("Invalid ML-KEM parameter set: %d (use 512, 768, or 1024)\n",
|
||||
n);
|
||||
return -1;
|
||||
}
|
||||
*alg = TPM_ALG_MLKEM;
|
||||
*paramSet = localSet;
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
#ifdef WOLFTPM_MLDSA
|
||||
if (XSTRCMP(val, "mldsa") == 0 ||
|
||||
XSTRNCMP(val, "mldsa=", 6) == 0) {
|
||||
n = (val[5] == '=' && val[6] != '\0') ? XATOI(&val[6]) : 65;
|
||||
if (n == 44)
|
||||
localSet = TPM_MLDSA_44;
|
||||
else if (n == 65)
|
||||
localSet = TPM_MLDSA_65;
|
||||
else if (n == 87)
|
||||
localSet = TPM_MLDSA_87;
|
||||
else {
|
||||
printf("Invalid ML-DSA parameter set: %d (use 44, 65, or 87)\n", n);
|
||||
return -1;
|
||||
}
|
||||
*alg = TPM_ALG_MLDSA;
|
||||
*paramSet = localSet;
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int parsePqcParamEncArg(const char* arg, TPM_ALG_ID* alg, int* paramSet)
|
||||
{
|
||||
if (arg == NULL || arg[0] != '-')
|
||||
return 0;
|
||||
return parsePqcParamSet(arg + 1, alg, paramSet);
|
||||
}
|
||||
#endif /* WOLFTPM_MLDSA || WOLFTPM_MLKEM */
|
||||
|
||||
int getRSAkey(WOLFTPM2_DEV* pDev, WOLFTPM2_KEY* pStorageKey, WOLFTPM2_KEY* key,
|
||||
void* pWolfRsaKey, int tpmDevId, const byte* auth, int authSz,
|
||||
TPMT_PUBLIC* publicTemplate)
|
||||
|
|
|
|||
|
|
@ -52,6 +52,29 @@ WOLFTPM_LOCAL int getPrimaryStoragekey(WOLFTPM2_DEV* pDev,
|
|||
WOLFTPM2_KEY* pStorageKey,
|
||||
TPM_ALG_ID alg);
|
||||
|
||||
#if defined(WOLFTPM_MLDSA) || defined(WOLFTPM_MLKEM)
|
||||
/* Create a transient PQC primary and start an HMAC param-enc session using it:
|
||||
* ML-KEM as the session salt key, ML-DSA as the bind key (with a transient SRK
|
||||
* salt, since sign-only ML-DSA cannot supply one). The session is started but
|
||||
* not assigned a slot; the caller calls wolfTPM2_SetAuthSession() and later
|
||||
* unloads pqcKey->handle and session->handle. */
|
||||
WOLFTPM_LOCAL int getPrimaryParamEncKey(WOLFTPM2_DEV* pDev,
|
||||
WOLFTPM2_SESSION* session,
|
||||
WOLFTPM2_KEY* pqcKey,
|
||||
TPM_ALG_ID pqcAlg,
|
||||
int paramSet,
|
||||
int paramEncAlg);
|
||||
|
||||
/* Parse a PQC parameter-set value ("mlkem[=512|768|1024]" /
|
||||
* "mldsa[=44|65|87]"). Returns 1 on a valid value (sets the alg and paramSet
|
||||
* outputs), -1 if a PQC algorithm is named with an unsupported set (printed),
|
||||
* or 0 if not a PQC value. parsePqcParamEncArg() takes the "-" option form. */
|
||||
WOLFTPM_LOCAL int parsePqcParamSet(const char* val, TPM_ALG_ID* alg,
|
||||
int* paramSet);
|
||||
WOLFTPM_LOCAL int parsePqcParamEncArg(const char* arg, TPM_ALG_ID* alg,
|
||||
int* paramSet);
|
||||
#endif
|
||||
|
||||
WOLFTPM_LOCAL int getRSAkey(WOLFTPM2_DEV* pDev,
|
||||
WOLFTPM2_KEY* pStorageKey,
|
||||
WOLFTPM2_KEY* key,
|
||||
|
|
|
|||
|
|
@ -10,7 +10,8 @@ noinst_PROGRAMS += examples/wrap/wrap_test \
|
|||
examples/wrap/encrypt_decrypt
|
||||
noinst_HEADERS += examples/wrap/wrap_test.h
|
||||
|
||||
examples_wrap_wrap_test_SOURCES = examples/wrap/wrap_test.c
|
||||
examples_wrap_wrap_test_SOURCES = examples/wrap/wrap_test.c \
|
||||
examples/tpm_test_keys.c
|
||||
examples_wrap_wrap_test_LDADD = src/libwolftpm.la $(LIB_STATIC_ADD)
|
||||
examples_wrap_wrap_test_DEPENDENCIES = src/libwolftpm.la
|
||||
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@
|
|||
|
||||
#include <hal/tpm_io.h>
|
||||
#include <examples/tpm_test.h>
|
||||
#include <examples/tpm_test_keys.h>
|
||||
#include <examples/wrap/wrap_test.h>
|
||||
|
||||
/* Configuration */
|
||||
|
|
@ -50,9 +51,16 @@
|
|||
static void usage(void)
|
||||
{
|
||||
printf("Expected Usage:\n");
|
||||
printf("./examples/wrap/wrap_test [-aes/xor]\n");
|
||||
printf("./examples/wrap/wrap_test [-aes/xor] [-mlkem/-mldsa]\n");
|
||||
printf("* -aes/xor: Use Parameter Encryption\n");
|
||||
|
||||
#ifdef WOLFTPM_MLKEM
|
||||
printf("* -mlkem[=512|768|1024]: Use an ML-KEM key as the param-enc "
|
||||
"session salt (v1.85, default 768)\n");
|
||||
#endif
|
||||
#ifdef WOLFTPM_MLDSA
|
||||
printf("* -mldsa[=44|65|87]: Use an ML-DSA key as the param-enc "
|
||||
"session bind (v1.85, default 65)\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
int TPM2_Wrapper_Test(void* userCtx)
|
||||
|
|
@ -125,11 +133,21 @@ int TPM2_Wrapper_TestArgs(void* userCtx, int argc, char *argv[])
|
|||
#endif /* !WOLFTPM2_NO_WOLFCRYPT */
|
||||
TPM_ALG_ID paramEncAlg = TPM_ALG_NULL;
|
||||
WOLFTPM2_SESSION tpmSession;
|
||||
#if defined(WOLFTPM_MLKEM) || defined(WOLFTPM_MLDSA)
|
||||
/* Optional PQC key used as the parameter-encryption session salt
|
||||
* (ML-KEM) or bind (ML-DSA) key. */
|
||||
TPM_ALG_ID pqcParamEncAlg = TPM_ALG_NULL;
|
||||
int pqcParamSet = 0;
|
||||
WOLFTPM2_KEY pqcKey;
|
||||
#endif
|
||||
|
||||
XMEMSET(&rsaKey, 0, sizeof(rsaKey));
|
||||
XMEMSET(&eccKey, 0, sizeof(eccKey));
|
||||
XMEMSET(&aesKey, 0, sizeof(aesKey));
|
||||
XMEMSET(&publicKey, 0, sizeof(publicKey));
|
||||
#if defined(WOLFTPM_MLKEM) || defined(WOLFTPM_MLDSA)
|
||||
XMEMSET(&pqcKey, 0, sizeof(pqcKey));
|
||||
#endif
|
||||
#ifndef WOLFTPM2_NO_WOLFCRYPT
|
||||
#ifndef NO_RSA
|
||||
XMEMSET(&wolfRsaPubKey, 0, sizeof(wolfRsaPubKey));
|
||||
|
|
@ -159,12 +177,33 @@ int TPM2_Wrapper_TestArgs(void* userCtx, int argc, char *argv[])
|
|||
else if (XSTRCMP(argv[argc-1], "-xor") == 0) {
|
||||
paramEncAlg = TPM_ALG_XOR;
|
||||
}
|
||||
#if defined(WOLFTPM_MLKEM) || defined(WOLFTPM_MLDSA)
|
||||
else if (parsePqcParamEncArg(argv[argc-1], &pqcParamEncAlg,
|
||||
&pqcParamSet) != 0) {
|
||||
/* PQC option; an unsupported parameter set (alg left NULL) is a
|
||||
* fatal typo, not a silent drop of parameter encryption. */
|
||||
if (pqcParamEncAlg == TPM_ALG_NULL) {
|
||||
usage();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
printf("Warning: Unrecognized option: %s\n", argv[argc-1]);
|
||||
}
|
||||
argc--;
|
||||
}
|
||||
|
||||
#if defined(WOLFTPM_MLKEM) || defined(WOLFTPM_MLDSA)
|
||||
/* A PQC param-enc key only supplies the salt/bind material; a symmetric
|
||||
* session cipher is still required. Default to AES-CFB if none given. */
|
||||
if (pqcParamEncAlg != TPM_ALG_NULL && paramEncAlg == TPM_ALG_NULL) {
|
||||
paramEncAlg = TPM_ALG_CFB;
|
||||
printf("PQC param-enc key selected; defaulting session cipher to "
|
||||
"AES-CFB.\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
printf("TPM2 Demo for Wrapper API's\n");
|
||||
|
||||
|
||||
|
|
@ -265,8 +304,19 @@ int TPM2_Wrapper_TestArgs(void* userCtx, int argc, char *argv[])
|
|||
#ifdef NO_RSA
|
||||
bindKey = NULL; /* cannot bind to key without RSA enabled */
|
||||
#endif
|
||||
rc = wolfTPM2_StartSession(&dev, &tpmSession, bindKey, NULL,
|
||||
TPM_SE_HMAC, paramEncAlg);
|
||||
#if defined(WOLFTPM_MLKEM) || defined(WOLFTPM_MLDSA)
|
||||
if (pqcParamEncAlg != TPM_ALG_NULL) {
|
||||
/* Use a PQC primary as the param-enc session key: ML-KEM salt
|
||||
* or ML-DSA bind. The RSA storageKey stays the child parent. */
|
||||
rc = getPrimaryParamEncKey(&dev, &tpmSession, &pqcKey,
|
||||
pqcParamEncAlg, pqcParamSet, paramEncAlg);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
rc = wolfTPM2_StartSession(&dev, &tpmSession, bindKey, NULL,
|
||||
TPM_SE_HMAC, paramEncAlg);
|
||||
}
|
||||
if (rc != 0) goto exit;
|
||||
printf("TPM2_StartAuthSession: sessionHandle 0x%x\n",
|
||||
(word32)tpmSession.handle.hndl);
|
||||
|
|
@ -1036,6 +1086,9 @@ exit:
|
|||
wolfTPM2_UnloadHandle(&dev, &eccKey.handle);
|
||||
wolfTPM2_UnloadHandle(&dev, &ekKey.handle);
|
||||
wolfTPM2_UnloadHandle(&dev, &tpmSession.handle);
|
||||
#if defined(WOLFTPM_MLKEM) || defined(WOLFTPM_MLDSA)
|
||||
wolfTPM2_UnloadHandle(&dev, &pqcKey.handle);
|
||||
#endif
|
||||
|
||||
/* Only doShutdown=1: Just shutdown the TPM */
|
||||
wolfTPM2_Reset(&dev, 1, 0);
|
||||
|
|
|
|||
Loading…
Reference in New Issue