wolfBoot-examples/sim-OTA/app/tpm_handler.c

181 lines
5.0 KiB
C

/* tpm_handler.c
*
* Copyright (C) 2006-2025 wolfSSL Inc.
*
* This file is part of wolfBoot-Examples.
*/
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include "wolftpm/tpm2.h"
#include "wolftpm/tpm2_wrap.h"
#include "tpm_handler.h"
#define TPM2_DEMO_STORAGE_KEY_HANDLE 0x81000200
static const char gStorageKeyAuth[] = "ThisIsMyStorageKeyAuth";
static const char gAiKeyAuth[] = "ThisIsMyAiKeyAuth";
int getPrimaryStorageKey(WOLFTPM2_DEV *pDev, WOLFTPM2_KEY *pStorageKey)
{
int rc;
TPM_HANDLE handle = TPM2_DEMO_STORAGE_KEY_HANDLE;
rc = wolfTPM2_ReadPublicKey(pDev, pStorageKey, handle);
if (rc != 0)
{
/* Create primary storage key */
rc = wolfTPM2_CreateSRK(pDev, pStorageKey, TPM_ALG_RSA,
(byte *)gStorageKeyAuth, sizeof(gStorageKeyAuth) - 1);
}
else
{
/* specify auth password for storage key */
pStorageKey->handle.auth.size = sizeof(gStorageKeyAuth) - 1;
XMEMCPY(pStorageKey->handle.auth.buffer, gStorageKeyAuth,
pStorageKey->handle.auth.size);
}
if (rc != 0)
{
printf("Loading SRK: Storage failed\n");
}
else
{
printf("Loading SRK: Storage 0x%x (%d bytes)\n",
(word32)pStorageKey->handle.hndl, pStorageKey->pub.size);
}
return rc;
}
int tpm_handler(void)
{
WOLFTPM2_DEV dev;
TPMS_ATTEST attestedData;
WOLFTPM2_CAPS caps;
WOLFTPM2_SESSION tpmSession;
TPMT_PUBLIC publicTemplate;
WOLFTPM2_KEY aikKey;
WOLFTPM2_KEY storage; /* SRK */
union
{
Quote_In quoteAsk;
byte maxInput[MAX_COMMAND_SIZE];
} cmdIn;
union
{
Quote_Out quoteResult;
byte maxOutput[MAX_RESPONSE_SIZE];
} cmdOut;
int rc;
printf("=== Attestation Test ===\n");
XMEMSET(&tpmSession, 0, sizeof(tpmSession));
XMEMSET(&storage, 0, sizeof(storage));
XMEMSET(&aikKey, 0, sizeof(aikKey));
rc = wolfTPM2_Init(&dev, NULL, NULL);
if (rc == 0)
{
/* Get device capabilities + options */
rc = wolfTPM2_GetCapabilities(&dev, &caps);
}
if (rc == 0)
{
printf("Mfg %s (%d), Vendor %s, Fw %u.%u (0x%x), "
"FIPS 140-2 %d, CC-EAL4 %d\n",
caps.mfgStr, caps.mfg, caps.vendorStr, caps.fwVerMajor,
caps.fwVerMinor, caps.fwVerVendor, caps.fips140_2, caps.cc_eal4);
}
else
{
printf("GetCapabilities failed\n");
return -1;
}
/* Generate or Read Storage Root Key */
rc = getPrimaryStorageKey(&dev, &storage);
if (rc == 0)
{
/* Generate AIK */
printf("Creating new key...\n");
rc = wolfTPM2_CreateAndLoadAIK(&dev, &aikKey, TPM_ALG_RSA,
&storage, (byte *)gAiKeyAuth, sizeof(gAiKeyAuth) - 1);
}
if (rc != TPM_RC_SUCCESS)
{
printf("wolfTPM2_CreateAndLoadAIK failed\n");
return -1;
}
else
{
printf("New key created and loaded (pub %d bytes)\n",
aikKey.pub.size);
}
/* Set the handle of AIK */
wolfTPM2_SetAuthHandle(&dev, 0, &aikKey.handle);
/* Prepare Quote request */
XMEMSET(&cmdIn.quoteAsk, 0, sizeof(cmdIn.quoteAsk));
XMEMSET(&cmdOut.quoteResult, 0, sizeof(cmdOut.quoteResult));
cmdIn.quoteAsk.signHandle = aikKey.handle.hndl;
cmdIn.quoteAsk.inScheme.scheme = TPM_ALG_RSASSA;
cmdIn.quoteAsk.inScheme.details.any.hashAlg = TPM_ALG_SHA256;
cmdIn.quoteAsk.qualifyingData.size = 0; /* optional */
/* Choose PCR for signing */
TPM2_SetupPCRSel(&cmdIn.quoteAsk.PCRselect, TPM_ALG_SHA256, 16);
rc = TPM2_Quote(&cmdIn.quoteAsk, &cmdOut.quoteResult);
if (rc != TPM_RC_SUCCESS)
{
printf("TPM2_Quote failed 0x%x: %s\n", rc, TPM2_GetRCString(rc));
return -1;
}
printf("Quote success\n");
rc = TPM2_ParseAttest(&cmdOut.quoteResult.quoted, &attestedData);
if (rc != TPM_RC_SUCCESS)
{
printf("TPM2_Packet_ParseAttest failed 0x%x: %s\n", rc,
TPM2_GetRCString(rc));
return -1;
}
if (attestedData.magic != TPM_GENERATED_VALUE)
{
printf("\tError, attested data not generated by the TPM = 0x%X\n",
attestedData.magic);
return -1;
}
else
{
printf("TPM with signature attests (type 0x%x):\n", attestedData.type);
printf("\tTPM signed %lu count of PCRs\n",
(unsigned long)attestedData.attested.quote.pcrSelect.count);
#ifdef DEBUG_WOLFTPM
printf("\tPCR digest:\n");
TPM2_PrintBin(attestedData.attested.quote.pcrDigest.buffer,
attestedData.attested.quote.pcrDigest.size);
printf("\tTPM generated signature:\n");
TPM2_PrintBin(cmdOut.quoteResult.signature.signature.rsassa.sig.buffer,
cmdOut.quoteResult.signature.signature.rsassa.sig.size);
#endif
}
rc = wolfTPM2_Cleanup(&dev);
if (rc != TPM_RC_SUCCESS)
{
printf("Failed to clean up\n");
return -1;
}
return 0;
}