Skip to content

Commit

Permalink
Improvements to the secure_rot example. Add support for manually plac…
Browse files Browse the repository at this point in the history
…ing hash.
  • Loading branch information
dgarske committed Aug 15, 2023
1 parent b159d70 commit b7c374d
Show file tree
Hide file tree
Showing 9 changed files with 169 additions and 184 deletions.
3 changes: 2 additions & 1 deletion examples/boot/include.am
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
if BUILD_EXAMPLES
noinst_PROGRAMS += examples/boot/secure_rot
noinst_HEADERS += examples/boot/boot.h
examples_boot_secure_rot_SOURCES = examples/boot/secure_rot.c
examples_boot_secure_rot_SOURCES = examples/boot/secure_rot.c \
examples/tpm_test_keys.c
examples_boot_secure_rot_LDADD = src/libwolftpm.la $(LIB_STATIC_ADD)
examples_boot_secure_rot_DEPENDENCIES = src/libwolftpm.la
endif
Expand Down
228 changes: 106 additions & 122 deletions examples/boot/secure_rot.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,58 +32,61 @@

#include <hal/tpm_io.h>
#include <examples/tpm_test.h>
#include <examples/tpm_test_keys.h>
#include <examples/boot/boot.h>

#include <wolfssl/wolfcrypt/hash.h>

/* WC_HASH_TYPE_SHA256 or WC_HASH_TYPE_SHA384 */
#define TPM2_SECURE_ROT_HASH_ALGO WC_HASH_TYPE_SHA256

#define TPM2_SECURE_ROT_EXAMPLE_PUB_KEY "certs/example-rsa-key-pub.der"

/******************************************************************************/
/* --- BEGIN TPM NVRAM Secure Boot Root of Trust Example -- */
/******************************************************************************/
static void usage(void)
{
printf("Expected usage:\n");
printf("./examples/boot/secure_rot [-nvindex] [-write] [-lock]\n");
printf("./examples/boot/secure_rot [-nvindex] [-write=/-hash=] [-auth] [-sha384] [-lock]\n");
printf("* -nvindex=[handle] (default 0x%x)\n",
TPM2_DEMO_NV_SECURE_ROT_INDEX);
printf("* -hash=hash: Hex string digest to write\n");
printf("* -write=filename: DER formatted public key to write\n");
printf("\tDefault public key: " TPM2_SECURE_ROT_EXAMPLE_PUB_KEY "\n");
printf("* -auth=password: Optional password for NV\n");
printf("* -sha384: Use SHA2-384 (default is SHA2-256)\n");
printf("* -lock: Lock the write\n");
printf("\nExamples:\n");
printf("\t./examples/boot/secure_rot -write=./certs/example-ecc256-key-pub.der\n");
printf("\t./examples/boot/secure_rot -sha384 -hash="
"e77dd3112a27948a3f2d87f32dc69ebe"
"ed0b3344c5d7726f5742f4f0c0f451aa"
"be4213f8b3b986639e69ed0ea8b49d94\n"
);
}

/* forward declaration */
static int load_file(const char* fname, byte** buf, size_t* bufLen);

/* Example for reading unique system registers for derived authentication
* used to access TPM NV */
static int GetSystemUniqueAuth(enum wc_HashType hashType, byte* authBuf)
static signed char HexCharToByte(signed char ch)
{
int rc;
wc_HashAlg hash;
uint32_t reg1 = 0x01234567;
uint32_t reg2 = 0x89ABCDEF;
uint32_t reg3 = 0x01234567;
uint32_t reg4 = 0x89ABCDEF;

rc = wc_HashInit(&hash, hashType);
if (rc == 0) {
rc = wc_HashUpdate(&hash, hashType, (byte*)&reg1, sizeof(reg1));
if (rc == 0)
rc = wc_HashUpdate(&hash, hashType, (byte*)&reg2, sizeof(reg2));
if (rc == 0)
rc = wc_HashUpdate(&hash, hashType, (byte*)&reg3, sizeof(reg3));
if (rc == 0)
rc = wc_HashUpdate(&hash, hashType, (byte*)&reg4, sizeof(reg4));
if (rc == 0) {
rc = wc_HashFinal(&hash, hashType, authBuf);
signed char ret = (signed char)ch;
if (ret >= '0' && ret <= '9')
ret -= '0';
else if (ret >= 'A' && ret <= 'F')
ret -= 'A' - 10;
else if (ret >= 'a' && ret <= 'f')
ret -= 'a' - 10;
else
ret = -1; /* error case - return code must be signed */
return ret;
}
static int HexToByte(const char *hex, unsigned char *output, unsigned long sz)
{
int outSz = 0;
word32 i;
for (i = 0; i < sz; i+=2) {
signed char ch1, ch2;
ch1 = HexCharToByte(hex[i]);
ch2 = HexCharToByte(hex[i+1]);
if ((ch1 < 0) || (ch2 < 0)) {
return -1;
}
wc_HashFree(&hash, hashType);
output[outSz++] = (unsigned char)((ch1 << 4) + ch2);
}
return rc;
return outSz;
}

int TPM2_Boot_SecureROT_Example(void* userCtx, int argc, char *argv[])
Expand All @@ -93,26 +96,27 @@ int TPM2_Boot_SecureROT_Example(void* userCtx, int argc, char *argv[])
WOLFTPM2_SESSION tpmSession;
WOLFTPM2_HANDLE parent;
WOLFTPM2_NV nv;
TPMS_NV_PUBLIC nvPublic;
word32 nvAttributes;
/* always use AES CFB parameter encryption */
int paramEncAlg = TPM_ALG_CFB;
/* use platform handle to prevent TPM2_Clear from removing */
TPMI_RH_NV_AUTH authHandle = TPM_RH_PLATFORM;
const char* filename = TPM2_SECURE_ROT_EXAMPLE_PUB_KEY;
const char* filename = NULL;
word32 nvIndex = TPM2_DEMO_NV_SECURE_ROT_INDEX;
int doWrite = 0, doLock = 0;
byte* buf = NULL;
size_t bufSz = 0;
enum wc_HashType hashType = TPM2_SECURE_ROT_HASH_ALGO;
enum wc_HashType hashType = WC_HASH_TYPE_SHA256;
byte digest[WC_MAX_DIGEST_SIZE];
word32 digestSz = wc_HashGetDigestSize(hashType);
word32 digestSz = 0;
byte authBuf[WC_SHA256_DIGEST_SIZE];
word32 authBufSz = 0;

if (digestSz <= 0) {
printf("Unsupported hash type %d!\n", hashType);
usage();
return -1;
}
XMEMSET(&tpmSession, 0, sizeof(tpmSession));
XMEMSET(&parent, 0, sizeof(parent));
XMEMSET(authBuf, 0, sizeof(authBuf));
XMEMSET(digest, 0, sizeof(digest));

if (argc >= 2) {
if (XSTRCMP(argv[1], "-?") == 0 ||
Expand All @@ -124,26 +128,54 @@ int TPM2_Boot_SecureROT_Example(void* userCtx, int argc, char *argv[])
}
while (argc > 1) {
if (XSTRNCMP(argv[argc-1], "-nvindex=", XSTRLEN("-nvindex=")) == 0) {
nvIndex = (word32)XSTRTOL(argv[argc-1] +
XSTRLEN("-nvindex="), NULL, 0);
const char* nvIndexStr = argv[argc-1] + XSTRLEN("-nvindex=");
nvIndex = (word32)XSTRTOL(nvIndexStr, NULL, 0);
if ((authHandle == TPM_RH_PLATFORM && (
nvIndex > TPM_20_PLATFORM_MFG_NV_SPACE &&
nvIndex < TPM_20_OWNER_NV_SPACE)) ||
(authHandle == TPM_RH_OWNER && (
nvIndex > TPM_20_OWNER_NV_SPACE &&
nvIndex < TPM_20_TCG_NV_SPACE)))
{
printf("Invalid NV Index %s\n", argv[argc-1] + 8);
nvIndex = 0;
fprintf(stderr, "Invalid NV Index %s\n", nvIndexStr);
usage();
return -1;
}
}
else if (XSTRNCMP(argv[argc-1], "-write=", XSTRLEN("-write=")) == 0) {
doWrite = 1;
filename = argv[argc-1] + XSTRLEN("-write=");
}
else if (XSTRCMP(argv[argc-1], "-write") == 0) {
else if (XSTRNCMP(argv[argc-1], "-hash=", XSTRLEN("-hash=")) == 0) {
const char* hashHexStr = argv[argc-1] + XSTRLEN("-hash=");
int hashHexStrLen = (int)XSTRLEN(hashHexStr);
if (hashHexStrLen > (int)sizeof(digest)*2+1)
hashHexStrLen = -1;
else
digestSz = HexToByte(hashHexStr, digest, hashHexStrLen);
if (digestSz < 0) {
fprintf(stderr, "Invalid hash length\n");
usage();
return -1;
}
doWrite = 1;
}
else if (XSTRNCMP(argv[argc-1], "-auth=", XSTRLEN("-auth=")) == 0) {
const char* authHexStr = argv[argc-1] + XSTRLEN("-auth=");
int authHexStrLen = (int)XSTRLEN(authHexStr);
if (authHexStrLen > (int)sizeof(authBuf)*2+1)
authBufSz = -1;
else
authBufSz = HexToByte(authHexStr, authBuf, authHexStrLen);
if (authBufSz < 0) {
fprintf(stderr, "Invalid auth length\n");
usage();
return -1;
}
}
else if (XSTRCMP(argv[argc-1], "-sha384") == 0) {
hashType = WC_HASH_TYPE_SHA384;
}
else if (XSTRCMP(argv[argc-1], "-lock") == 0) {
doLock = 1;
}
Expand All @@ -153,25 +185,15 @@ int TPM2_Boot_SecureROT_Example(void* userCtx, int argc, char *argv[])
argc--;
};

XMEMSET(&tpmSession, 0, sizeof(tpmSession));
XMEMSET(&parent, 0, sizeof(parent));
XMEMSET(digest, 0, sizeof(digest));
/* setup the parent handle OWNER/PLATFORM */
parent.hndl = authHandle;

rc = wolfTPM2_Init(&dev, TPM2_IoCb, userCtx);
if (rc != TPM_RC_SUCCESS) {
printf("\nwolfTPM2_Init failed\n");
goto exit;
}

/* Derive a unique value from hardware to authenticate the NV */
rc = GetSystemUniqueAuth(hashType, authBuf);
if (rc != 0) {
printf("Error getting system unique NV auth! %d\n", rc);
goto exit;
}
printf("NV Auth (%d)\n", (int)sizeof(authBuf));
TPM2_PrintBin(authBuf, sizeof(authBuf));

/* Start TPM session for parameter encryption */
printf("Parameter Encryption: Enabled %s and HMAC\n\n",
TPM2_GetAlgName(paramEncAlg));
Expand All @@ -186,23 +208,32 @@ int TPM2_Boot_SecureROT_Example(void* userCtx, int argc, char *argv[])
TPMA_SESSION_continueSession));
if (rc != 0) goto exit;

printf("NV Auth (%d)\n", authBufSz);
TPM2_PrintBin(authBuf, authBufSz);

/* Open file */
if (doWrite) {
printf("Storing hash of public key file %s to "
"NV index 0x%x with password protection\n\n",
filename, nvIndex);
if (filename == NULL) {
printf("Storing hash to NV index 0x%x\n\n", nvIndex);
}
else {
printf("Storing hash of public key file %s to NV index 0x%x\n\n",
filename, nvIndex);

rc = loadFile(filename, &buf, &bufSz);
if (rc == 0) {
/* hash public key */
digestSz = wc_HashGetDigestSize(hashType);
rc = wc_Hash(hashType, buf, (word32)bufSz, digest, digestSz);
}
}

rc = load_file(filename, &buf, &bufSz);
if (rc == 0) {
/* hash public key */
rc = wc_Hash(hashType, buf, (word32)bufSz, digest, digestSz);

printf("Public Key Hash (%d)\n", digestSz);
TPM2_PrintBin(digest, digestSz);
}
if (rc == 0) {
/* Get NV attributes */
parent.hndl = authHandle;
rc = wolfTPM2_GetNvAttributesTemplate(parent.hndl, &nvAttributes);
}
if (rc == 0) {
Expand All @@ -211,7 +242,7 @@ int TPM2_Boot_SecureROT_Example(void* userCtx, int argc, char *argv[])

/* Create NV */
rc = wolfTPM2_NVCreateAuth(&dev, &parent, &nv, nvIndex,
nvAttributes, digestSz, authBuf, sizeof(authBuf));
nvAttributes, digestSz, authBuf, authBufSz);
if (rc == TPM_RC_NV_DEFINED) {
printf("Warning: NV Index 0x%x already exists!\n", nvIndex);
rc = 0;
Expand All @@ -228,8 +259,14 @@ int TPM2_Boot_SecureROT_Example(void* userCtx, int argc, char *argv[])
/* Setup the NV access */
XMEMSET(&nv, 0, sizeof(nv));
nv.handle.hndl = nvIndex;
nv.handle.auth.size = sizeof(authBuf);
XMEMCPY(nv.handle.auth.buffer, authBuf, sizeof(authBuf));
nv.handle.auth.size = authBufSz;
XMEMCPY(nv.handle.auth.buffer, authBuf, nv.handle.auth.size);

/* Read the NV Index publicArea to have up to date NV Index Name */
rc = wolfTPM2_NVReadPublic(&dev, nvIndex, &nvPublic);
if (rc == 0) {
digestSz = nvPublic.dataSize;
}

/* Read access */
printf("Reading NV 0x%x public key hash\n", nvIndex);
Expand Down Expand Up @@ -263,59 +300,6 @@ int TPM2_Boot_SecureROT_Example(void* userCtx, int argc, char *argv[])
return rc;
}

static int load_file(const char* fname, byte** buf, size_t* bufLen)
{
int ret;
#if !defined(NO_FILESYSTEM)
long int fileSz;
XFILE lFile;

if (fname == NULL || buf == NULL || bufLen == NULL)
return BAD_FUNC_ARG;

/* set defaults */
*buf = NULL;
*bufLen = 0;

/* open file (read-only binary) */
lFile = XFOPEN(fname, "rb");
if (!lFile) {
fprintf(stderr, "Error loading %s\n", fname);
return BUFFER_E;
}

XFSEEK(lFile, 0, XSEEK_END);
fileSz = (int)ftell(lFile);
XFSEEK(lFile, 0, XSEEK_SET);
if (fileSz > 0) {
*bufLen = (size_t)fileSz;
*buf = (byte*)XMALLOC(*bufLen, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (*buf == NULL) {
ret = MEMORY_E;
fprintf(stderr,
"Error allocating %lu bytes\n", (unsigned long)*bufLen);
}
else {
size_t readLen = fread(*buf, *bufLen, 1, lFile);

/* check response code */
ret = (readLen > 0) ? 0 : -1;
}
}
else {
ret = BUFFER_E;
}
fclose(lFile);
#else
(void)fname;
(void)buf;
(void)bufLen;
ret = NOT_COMPILED_IN;
#endif
return ret;
}
/* !NO_FILESYSTEM */

/******************************************************************************/
/* --- END TPM NVRAM Secure Boot Root of Trust Example -- */
/******************************************************************************/
Expand Down
8 changes: 4 additions & 4 deletions examples/csr/csr.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,10 @@ static int TPM2_CSR_Generate(WOLFTPM2_DEV* dev, int keyType, WOLFTPM2_KEY* key,
output.size = rc;
printf("Generated/Signed Cert (PEM %d)\n", output.size);
#if !defined(NO_FILESYSTEM) && !defined(NO_WRITE_TEMP_FILES)
FILE* pemFile = fopen(outputPemFile, "wb");
if (pemFile) {
rc = (int)fwrite(output.buffer, 1, output.size, pemFile);
fclose(pemFile);
XFILE pemFile = XFOPEN(outputPemFile, "wb");
if (pemFile != XBADFILE) {
rc = (int)XFWRITE(output.buffer, 1, output.size, pemFile);
XFCLOSE(pemFile);
rc = (rc == output.size) ? 0 : -1;
if (rc == 0) {
printf("Saved to %s\n", outputPemFile);
Expand Down
2 changes: 1 addition & 1 deletion examples/pcr/extend.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ int TPM2_PCR_Extend_Test(void* userCtx, int argc, char *argv[])
if (filename) {
fp = XFOPEN(filename, "rb");
}
if (filename && fp) {
if (filename && fp != XBADFILE) {
#if !defined(NO_SHA256)
wc_InitSha256(&sha256);
while (!XFEOF(fp)) {
Expand Down
Loading

0 comments on commit b7c374d

Please sign in to comment.