Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 48 additions & 22 deletions examples/native/native_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,7 @@ int TPM2_Native_Test(void* userCtx)
int TPM2_Native_TestArgs(void* userCtx, int argc, char *argv[])
{
int rc;
int isAllocated = 0;
TPM2_CTX tpm2Ctx;

union {
Expand Down Expand Up @@ -863,22 +864,34 @@ int TPM2_Native_TestArgs(void* userCtx, int argc, char *argv[])
TPM2_PrintBin(cmdOut.policyGetDigest.policyDigest.buffer,
cmdOut.policyGetDigest.policyDigest.size);

/* Read PCR[0] SHA1 */
/* Many current TPMs allocate no SHA-1 bank; ask before selecting it. A
* query failure is reported, not silently treated as "no bank". */
pcrIndex = 0;
XMEMSET(&cmdIn.pcrRead, 0, sizeof(cmdIn.pcrRead));
TPM2_SetupPCRSel(&cmdIn.pcrRead.pcrSelectionIn, TPM_ALG_SHA1, pcrIndex);
rc = TPM2_PCR_Read(&cmdIn.pcrRead, &cmdOut.pcrRead);
rc = TPM2_IsPcrBankAllocated(TPM_ALG_SHA1, pcrIndex, &isAllocated);
if (rc != TPM_RC_SUCCESS) {
printf("TPM2_PCR_Read failed 0x%x: %s\n", rc,
printf("TPM2_IsPcrBankAllocated failed 0x%x: %s\n", rc,
TPM2_GetRCString(rc));
goto exit;
}
printf("TPM2_PCR_Read: Index %d, Digest Sz %d, Update Counter %d\n",
pcrIndex,
(int)cmdOut.pcrRead.pcrValues.digests[0].size,
(int)cmdOut.pcrRead.pcrUpdateCounter);
TPM2_PrintBin(cmdOut.pcrRead.pcrValues.digests[0].buffer,
cmdOut.pcrRead.pcrValues.digests[0].size);
if (!isAllocated) {
printf("TPM2_PCR_Read: SHA-1 skipped (no SHA-1 PCR bank allocated)\n");
}
else {
XMEMSET(&cmdIn.pcrRead, 0, sizeof(cmdIn.pcrRead));
TPM2_SetupPCRSel(&cmdIn.pcrRead.pcrSelectionIn, TPM_ALG_SHA1, pcrIndex);
rc = TPM2_PCR_Read(&cmdIn.pcrRead, &cmdOut.pcrRead);
if (rc != TPM_RC_SUCCESS) {
printf("TPM2_PCR_Read failed 0x%x: %s\n", rc,
TPM2_GetRCString(rc));
goto exit;
}
printf("TPM2_PCR_Read: Index %d, Digest Sz %d, Update Counter %d\n",
pcrIndex,
(int)cmdOut.pcrRead.pcrValues.digests[0].size,
(int)cmdOut.pcrRead.pcrUpdateCounter);
TPM2_PrintBin(cmdOut.pcrRead.pcrValues.digests[0].buffer,
cmdOut.pcrRead.pcrValues.digests[0].size);
}

#ifndef WOLFTPM2_NO_WOLFCRYPT
/* Set Auth Session index 0 */
Expand All @@ -892,20 +905,31 @@ int TPM2_Native_TestArgs(void* userCtx, int argc, char *argv[])
session[0].nonceCaller.size = TPM2_GetHashDigestSize(WOLFTPM2_WRAP_DIGEST);
session[0].auth = sessionAuth;

/* Policy PCR (Get) */
/* Policy PCR (Get). Selects the SHA-1 bank, so skip when unallocated. */
pcrIndex = 0;
XMEMSET(&cmdIn.policyPCR, 0, sizeof(cmdIn.policyPCR));
cmdIn.policyPCR.policySession = sessionHandle;
cmdIn.policyPCR.pcrDigest.size = 0;
TPM2_SetupPCRSel(&cmdIn.policyPCR.pcrs, TPM_ALG_SHA1, pcrIndex);
rc = TPM2_PolicyPCR(&cmdIn.policyPCR);
rc = TPM2_IsPcrBankAllocated(TPM_ALG_SHA1, pcrIndex, &isAllocated);
if (rc != TPM_RC_SUCCESS) {
printf("TPM2_PolicyPCR failed 0x%x: %s\n", rc,
printf("TPM2_IsPcrBankAllocated failed 0x%x: %s\n", rc,
TPM2_GetRCString(rc));
goto exit;
}
if (!isAllocated) {
printf("TPM2_PolicyPCR: SHA-1 skipped (no SHA-1 PCR bank allocated)\n");
}
else {
printf("TPM2_PolicyPCR: Updated\n");
XMEMSET(&cmdIn.policyPCR, 0, sizeof(cmdIn.policyPCR));
cmdIn.policyPCR.policySession = sessionHandle;
cmdIn.policyPCR.pcrDigest.size = 0;
TPM2_SetupPCRSel(&cmdIn.policyPCR.pcrs, TPM_ALG_SHA1, pcrIndex);
rc = TPM2_PolicyPCR(&cmdIn.policyPCR);
if (rc != TPM_RC_SUCCESS) {
printf("TPM2_PolicyPCR failed 0x%x: %s\n", rc,
TPM2_GetRCString(rc));
goto exit;
}
else {
printf("TPM2_PolicyPCR: Updated\n");
}
}
XMEMSET(&session[0], 0, sizeof(TPM2_AUTH_SESSION));
session[0].sessionHandle = TPM_RS_PW;
Expand Down Expand Up @@ -1635,7 +1659,7 @@ int TPM2_Native_TestArgs(void* userCtx, int argc, char *argv[])
cmdIn.encDec.decrypt = NO;
cmdIn.encDec.mode = TEST_AES_MODE;
rc = TPM2_EncryptDecrypt2(&cmdIn.encDec, &cmdOut.encDec);
if (WOLFTPM_IS_COMMAND_UNAVAILABLE(rc)) { /* some TPM's may not support command */
if (WOLFTPM_IS_COMMAND_UNAVAILABLE_OR_DISABLED(rc)) {
printf("TPM2_EncryptDecrypt2: Is not a supported feature without enabling due to export controls\n");
perform_EncryptDecrypt2 = 0;
rc = 0;
Expand All @@ -1657,7 +1681,9 @@ int TPM2_Native_TestArgs(void* userCtx, int argc, char *argv[])
cmdIn.encDec.decrypt = YES;
cmdIn.encDec.mode = TEST_AES_MODE;
rc = TPM2_EncryptDecrypt2(&cmdIn.encDec, &cmdOut.encDec);
if (rc == TPM_RC_COMMAND_CODE) { /* some TPM's may not support command */
if (WOLFTPM_IS_COMMAND_UNAVAILABLE_OR_DISABLED(rc)) {
/* Leave rc set: the check below inspects it to tell a real
* result from a skip, and cmdOut holds stale output. */
printf("TPM2_EncryptDecrypt2: Is not a supported feature without enabling due to export controls\n");
}
else if (rc != TPM_RC_SUCCESS) {
Expand All @@ -1673,7 +1699,7 @@ int TPM2_Native_TestArgs(void* userCtx, int argc, char *argv[])
cmdOut.encDec.outData.size) == 0) {
printf("Encrypt/Decrypt test success\n");
}
else if (WOLFTPM_IS_COMMAND_UNAVAILABLE(rc)) {
else if (WOLFTPM_IS_COMMAND_UNAVAILABLE_OR_DISABLED(rc)) {
printf("Encrypt/Decrypt test result allowed as pass since hardware doesn't support.\n");
rc = TPM_RC_SUCCESS;
}
Expand Down
11 changes: 11 additions & 0 deletions examples/pqc/pqc_ctrl.c
Original file line number Diff line number Diff line change
Expand Up @@ -493,6 +493,16 @@ static int do_hash_mldsa(WOLFTPM2_DEV* dev, TPMI_MLDSA_PARAMETER_SET ps)

rc = wolfTPM2_VerifyDigestSignature(dev, &key, digest, (int)sizeof(digest),
sig, sigSz, NULL, 0, &validation);
if (rc == BUFFER_E) {
/* Too large for this TPM to accept back for on-TPM verification.
* Signing worked but nothing checked it, so skip, not pass. Only
* BUFFER_E means oversize; a query error still reports FAIL. */
printf("SKIP HashML-DSA-%-3s signed %d bytes, not verified: "
"signature exceeds this TPM's input buffer\n",
mldsaName(ps), sigSz);
rc = TPM_RC_SUCCESS;
goto exit_quiet;
}
if (rc != TPM_RC_SUCCESS) goto exit;

if (validation.tag != TPM_ST_DIGEST_VERIFIED) {
Expand All @@ -510,6 +520,7 @@ static int do_hash_mldsa(WOLFTPM2_DEV* dev, TPMI_MLDSA_PARAMETER_SET ps)
printf("FAIL HashML-DSA-%-3s 0x%x: %s\n",
mldsaName(ps), rc, wolfTPM2_GetRCString(rc));
}
exit_quiet:
wolfTPM2_UnloadHandle(dev, &key.handle);
XFREE(sig, NULL, DYNAMIC_TYPE_TMP_BUFFER);
return rc;
Expand Down
37 changes: 23 additions & 14 deletions examples/wrap/wrap_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ int TPM2_Wrapper_Test(void* userCtx)
int TPM2_Wrapper_TestArgs(void* userCtx, int argc, char *argv[])
{
int rc, i;
int isSupported = 0;
WOLFTPM2_DEV dev;
WOLFTPM2_CAPS caps;
WOLFTPM2_KEY ekKey;
Expand Down Expand Up @@ -683,19 +684,27 @@ int TPM2_Wrapper_TestArgs(void* userCtx, int argc, char *argv[])
printf("ECC DH Test %s\n", rc == 0 ? "Passed" : "Failed");

/* ECC Public Key Signature Verify Test/Example */
rc = wolfTPM2_LoadEccPublicKey(&dev, &publicKey, TPM_ECC_NIST_P256,
kEccTestPubQX, sizeof(kEccTestPubQX),
kEccTestPubQY, sizeof(kEccTestPubQY));
/* Vector below uses a SHA-1 digest, which many current TPMs lack. */
rc = wolfTPM2_IsAlgSupported(&dev, TPM_ALG_SHA1, &isSupported);
if (rc != 0) goto exit;
if (!isSupported) {
printf("ECC Verify Test Skipped (TPM does not implement SHA-1)\n");
}
else {
rc = wolfTPM2_LoadEccPublicKey(&dev, &publicKey, TPM_ECC_NIST_P256,
kEccTestPubQX, sizeof(kEccTestPubQX),
kEccTestPubQY, sizeof(kEccTestPubQY));
if (rc != 0) goto exit;

rc = wolfTPM2_VerifyHashScheme(&dev, &publicKey,
kEccTestSigRS, sizeof(kEccTestSigRS),
kEccTestMsg, sizeof(kEccTestMsg), TPM_ALG_ECDSA, TPM_ALG_SHA1);
if (rc != 0) goto exit;
rc = wolfTPM2_VerifyHashScheme(&dev, &publicKey,
kEccTestSigRS, sizeof(kEccTestSigRS),
kEccTestMsg, sizeof(kEccTestMsg), TPM_ALG_ECDSA, TPM_ALG_SHA1);
if (rc != 0) goto exit;

rc = wolfTPM2_UnloadHandle(&dev, &publicKey.handle);
if (rc != 0) goto exit;
printf("ECC Verify Test Passed\n");
rc = wolfTPM2_UnloadHandle(&dev, &publicKey.handle);
if (rc != 0) goto exit;
printf("ECC Verify Test Passed\n");
}

/*------------------------------------------------------------------------*/
/* ECC KEY LOADING TESTS */
Expand Down Expand Up @@ -973,7 +982,7 @@ int TPM2_Wrapper_TestArgs(void* userCtx, int argc, char *argv[])
XMEMCPY(aesIv, TEST_AES_IV, (word32)sizeof(TEST_AES_IV));
rc = wolfTPM2_EncryptDecrypt(&dev, &aesKey, message.buffer, cipher.buffer,
message.size, aesIv, (word32)sizeof(aesIv), WOLFTPM2_ENCRYPT);
if (rc != 0 && !WOLFTPM_IS_COMMAND_UNAVAILABLE(rc)) goto exit;
if (rc != 0 && !WOLFTPM_IS_COMMAND_UNAVAILABLE_OR_DISABLED(rc)) goto exit;

XMEMSET(plain.buffer, 0, sizeof(plain.buffer));
plain.size = message.size;
Expand All @@ -990,7 +999,7 @@ int TPM2_Wrapper_TestArgs(void* userCtx, int argc, char *argv[])
XMEMCMP(cipher.buffer, TEST_AES_VERIFY, cipher.size) == 0) {
printf("Encrypt/Decrypt (known key) test success\n");
}
else if (WOLFTPM_IS_COMMAND_UNAVAILABLE(rc)) {
else if (WOLFTPM_IS_COMMAND_UNAVAILABLE_OR_DISABLED(rc)) {
printf("Encrypt/Decrypt: Is not a supported feature due to export controls\n");
}
else {
Expand Down Expand Up @@ -1020,7 +1029,7 @@ int TPM2_Wrapper_TestArgs(void* userCtx, int argc, char *argv[])
XMEMSET(aesIv, 0, sizeof(aesIv));
rc = wolfTPM2_EncryptDecrypt(&dev, &aesKey, message.buffer, cipher.buffer,
message.size, aesIv, (word32)sizeof(aesIv), WOLFTPM2_ENCRYPT);
if (rc != 0 && !WOLFTPM_IS_COMMAND_UNAVAILABLE(rc)) goto exit;
if (rc != 0 && !WOLFTPM_IS_COMMAND_UNAVAILABLE_OR_DISABLED(rc)) goto exit;

XMEMSET(plain.buffer, 0, sizeof(plain.buffer));
plain.size = message.size;
Expand All @@ -1035,7 +1044,7 @@ int TPM2_Wrapper_TestArgs(void* userCtx, int argc, char *argv[])
XMEMCMP(message.buffer, plain.buffer, message.size) == 0) {
printf("Encrypt/Decrypt test success\n");
}
else if (WOLFTPM_IS_COMMAND_UNAVAILABLE(rc)) {
else if (WOLFTPM_IS_COMMAND_UNAVAILABLE_OR_DISABLED(rc)) {
printf("Encrypt/Decrypt: Is not a supported feature due to export controls\n");
}
else {
Expand Down
82 changes: 82 additions & 0 deletions src/tpm2.c
Original file line number Diff line number Diff line change
Expand Up @@ -7816,6 +7816,88 @@ void TPM2_PrintPublicArea(const TPM2B_PUBLIC* pub)
}
#endif /* DEBUG_WOLFTPM */

/* TPM_CAP_ALGS returns algorithms with ID >= property, so a match at index 0
* means implemented. Fails closed: *isSupported is 0 on any error. */
int TPM2_IsAlgSupported(TPM_ALG_ID alg, int* isSupported)
{
int rc;
GetCapability_In in;
GetCapability_Out out;
TPML_ALG_PROPERTY* algs;

if (isSupported == NULL) {
return BAD_FUNC_ARG;
}
*isSupported = 0;

XMEMSET(&in, 0, sizeof(in));
XMEMSET(&out, 0, sizeof(out));
in.capability = TPM_CAP_ALGS;
in.property = alg;
in.propertyCount = 1;
rc = TPM2_GetCapability(&in, &out);
if (rc != TPM_RC_SUCCESS) {
return rc; /* query failure, distinct from "not supported" */
}
/* union - confirm the capability asked for */
if (out.capabilityData.capability != TPM_CAP_ALGS) {
return TPM_RC_VALUE;
}

algs = &out.capabilityData.data.algorithms;
if (algs->count >= 1 && algs->algProperties[0].alg == alg) {
*isSupported = 1;
}
return TPM_RC_SUCCESS;
}

/* Implementing a hash and allocating a bank for it are separate: a TPM may
* offer SHA-1 while allocating no SHA-1 bank, and a selection naming an
* unallocated bank is rejected. Ask before TPM2_SetupPCRSel(). Fails closed. */
int TPM2_IsPcrBankAllocated(TPM_ALG_ID hashAlg, int pcrIndex, int* isAllocated)
{
int rc;
word32 i;
GetCapability_In in;
GetCapability_Out out;
TPML_PCR_SELECTION* banks;

if (isAllocated == NULL) {
return BAD_FUNC_ARG;
}
*isAllocated = 0;
if (pcrIndex < 0) {
return BAD_FUNC_ARG;
}

XMEMSET(&in, 0, sizeof(in));
XMEMSET(&out, 0, sizeof(out));
in.capability = TPM_CAP_PCRS;
in.property = 0;
in.propertyCount = HASH_COUNT; /* all assigned banks */
rc = TPM2_GetCapability(&in, &out);
if (rc != TPM_RC_SUCCESS) {
return rc;
}
if (out.capabilityData.capability != TPM_CAP_PCRS) {
return TPM_RC_VALUE;
}

banks = &out.capabilityData.data.assignedPCR;
for (i = 0; i < banks->count; i++) {
if (banks->pcrSelections[i].hash != hashAlg) {
continue;
}
if ((pcrIndex / 8) < (int)banks->pcrSelections[i].sizeofSelect &&
(banks->pcrSelections[i].pcrSelect[pcrIndex / 8] &
(1 << (pcrIndex % 8))) != 0) {
*isAllocated = 1;
break;
}
}
return TPM_RC_SUCCESS;
}

/******************************************************************************/
/* --- END Helpful API's -- */
/******************************************************************************/
Loading
Loading