get wolfboot simulator working with the tpm simulator

move pcr reset and extend outside of session

the tpm uses policy checking for modifying PCR's so we need to reset and extend the PCR's with the image hash before the session begins, currently tested unseal, having trouble getting the simulator to run update in order to test reseal
pull/296/head
John Bland 2023-05-03 11:39:25 -04:00
parent eb30566bba
commit fe2b797b01
5 changed files with 135 additions and 73 deletions

View File

@ -443,6 +443,7 @@ ifeq ($(TARGET),sim)
LD_START_GROUP=
LD_END_GROUP=
BOOT_IMG=test-app/image.elf
CFLAGS+=-DARCH_SIM
endif
BOOT_IMG?=test-app/image.bin

View File

@ -9,12 +9,23 @@ Next you need to use external signing to sign the image you want to include and
```
echo -n -e '\x00\x00\x00\x00' > zeroExpiry
openssl dgst -sha256 -sign policy_signed_ecc.pem -out policySigned zeroExpiry
#extract the raw key signature, should be 64 bytes
openssl asn1parse -inform DER -in policySigned
echo "4BDAC51C517C0F3D8EDBB632B514262C256E289565A2F1CD8605A4F775302C0CD7BBFE0242CAA536A30C87A37756C390DB9A2B06037B15476A509CA06B857B6D" | xxd -r -p - policySigned.raw
```
Next we need to manually make the image signature
```
tools/keytools/sign --ecc256 --sha256 --sha-only test-app/image.elf policy-public-key.raw 1
openssl pkeyutl -sign -inkey private-key.pem -in test-app/image_v1_digest.bin > test-app/image_v1.sig
echo "6C7B61198E1575F21FB6FFE3D65AE267BF72CC7A660105F61D9130CE1351320685A41D401F3B453951C06A3150DBC51F9B7CFA39748079B489E6C1CFAECF2EBF" | xxd -r -p - imageSignature.raw
```
Next you need to create the image using the sign keytool with the --manual-sign option and the --policy-sign option:
```
tools/keytools/sign --ecc256 --sha256 --manual-sign --policy-signed my_image.bin policy_signed_ecc.raw 1 my_image_sig policySigned
tools/keytools/sign --ecc256 --sha256 --manual-sign --policy-signed my_image.bin policy_signed_ecc.raw 1 imageSignature.raw policySigned.raw
```
## NOTE: the PolicySigned key is used in place of the real signing key and acts as an intermediate key to unseal the actual signing key form the TPM

View File

@ -10,7 +10,7 @@ ifeq ($(WOLFBOOT_TPM_KEYSTORE),1)
ifneq ($(WOLFBOOT_TPM_KEYSTORE_NV_INDEX),)
ifneq ($(WOLFBOOT_TPM_POLICY_NV_INDEX),)
WOLFTPM:=1
CFLAGS+=-DWOLFTPM_KEYSTORE -DWOLFTPM_KEYSTORE_INDEX=$(WOLFBOOT_TPM_KEYSTORE_NV_INDEX) -DWOLFTPM_POLICY_DIGEST_INDEX=$(WOLFBOOT_TPM_POLICY_NV_INDEX)
CFLAGS+=-DWOLFTPM_KEYSTORE -DWOLFTPM_KEYSTORE_INDEX=$(WOLFBOOT_TPM_KEYSTORE_NV_INDEX) -DWOLFTPM_POLICY_DIGEST_INDEX=$(WOLFBOOT_TPM_POLICY_NV_INDEX) -DWOLFSSL_AES_CFB
ifeq ($(WOLFBOOT_TPM_ENCRYPT_KEYSTORE),1)
ifneq ($(WOLFBOOT_TPM_ENCRYPT_KEYSTORE_NV_INDEX),)
@ -448,15 +448,21 @@ ifeq ($(WOLFTPM),1)
lib/wolfTPM/src/tpm2_param_enc.o
CFLAGS+=-D"WOLFBOOT_TPM" -D"SIZEOF_LONG=4" -Ilib/wolfTPM \
-D"MAX_COMMAND_SIZE=1024" -D"MAX_RESPONSE_SIZE=1024" -D"WOLFTPM2_MAX_BUFFER=1500" \
-D"MAX_SESSION_NUM=1" -D"MAX_DIGEST_BUFFER=973" \
-D"MAX_SESSION_NUM=2" -D"MAX_DIGEST_BUFFER=973" \
-D"WOLFTPM_SMALL_STACK"
# Chip Type: WOLFTPM_SLB9670, WOLFTPM_ST33, WOLFTPM_MCHP
CFLAGS+=-D"WOLFTPM_SLB9670"
# Use TPM for hashing (slow)
#CFLAGS+=-D"WOLFBOOT_HASH_TPM"
ifneq ($(SPI_FLASH),1)
# don't use spi if we're using simulator
ifeq ($(SIM_TPM),1)
CFLAGS+=-DWOLFTPM_SWTPM -DTPM_TIMEOUT_TRIES=0
OBJS+=./lib/wolfTPM/src/tpm2_swtpm.o
else
WOLFCRYPT_OBJS+=hal/spi/spi_drv_$(SPI_TARGET).o
endif
endif
WOLFCRYPT_OBJS+=./lib/wolfssl/wolfcrypt/src/aes.o
WOLFCRYPT_OBJS+=./lib/wolfssl/wolfcrypt/src/hmac.o
ifeq ($(DEBUG),1)

View File

@ -41,7 +41,6 @@ static WOLFTPM2_DEV wolftpm_dev;
#include "wolfboot/wolfboot.h"
#endif
static WOLFTPM2_SESSION wolftpm_session;
static uint8_t wolftpmPcrArray[1] = {WOLFTPM_PCR_INDEX};
static int wolfBoot_unseal_pubkey(struct wolfBoot_image *img, uint8_t* pubkey,
@ -714,7 +713,7 @@ static void key_sha3_384(uint8_t key_slot, uint8_t *hash)
#endif /* SHA3-384 */
#ifdef WOLFBOOT_TPM
#ifndef ARCH_SIM
static int TPM2_IoCb(TPM2_CTX* ctx, const byte* txBuf, byte* rxBuf,
word16 xferSz, void* userCtx)
{
@ -738,6 +737,7 @@ static int TPM2_IoCb(TPM2_CTX* ctx, const byte* txBuf, byte* rxBuf,
*/
return 0;
}
#endif /* !ARCH_SIM */
#if defined(WOLFBOOT_TPM) && defined(WOLFBOOT_MEASURED_BOOT)
static int measure_boot(struct wolfBoot_image *img)
@ -777,10 +777,20 @@ int wolfBoot_tpm2_init(void)
int rc;
word32 idx;
WOLFTPM2_CAPS caps;
#ifndef ARCH_SIM
spi_init(0,0);
#endif
#ifdef WOLFTPM_KEYSTORE
PCR_Reset_In pcrReset;
#endif
/* Init the TPM2 device */
/* simulator should use the network connection, not spi */
#ifdef ARCH_SIM
rc = wolfTPM2_Init(&wolftpm_dev, NULL, NULL);
#else
rc = wolfTPM2_Init(&wolftpm_dev, TPM2_IoCb, NULL);
#endif
if (rc != 0) {
return rc;
}
@ -791,19 +801,6 @@ int wolfBoot_tpm2_init(void)
return rc;
}
#ifdef WOLFTPM_KEYSTORE
/* start a policy session with parameter encryption */
rc = wolfTPM2_StartSession(&wolftpm_dev, &wolftpm_session, NULL, NULL,
TPM_SE_POLICY, TPM_ALG_CFB);
if (rc != TPM_RC_SUCCESS)
return rc;
/* set the auth session for the device */
rc = wolfTPM2_SetAuthSession(&wolftpm_dev, 0, &wolftpm_session,
(TPMA_SESSION_decrypt | TPMA_SESSION_encrypt | TPMA_SESSION_continueSession));
if (rc != TPM_RC_SUCCESS)
return rc;
#endif
return 0;
}
@ -813,16 +810,15 @@ int wolfBoot_tpm2_init(void)
int wolfBoot_unseal_encryptkey(struct wolfBoot_image *img, uint8_t* key,
uint32_t* keySz)
{
WOLFTPM2_SESSION wolftpm_session;
WOLFTPM2_KEY tpmKey;
PCR_Reset_In pcrReset;
uint8_t* pubkey;
uint8_t* pubkeyHint;
uint8_t* imageSignature;
uint8_t* policySignature;
int keySlot;
int ret;
uint16_t pubkeyHintSize;
uint16_t imageSignatureSz;
uint16_t policySignatureSz;
XMEMSET(&tpmKey, 0, sizeof(tpmKey));
@ -842,16 +838,6 @@ int wolfBoot_unseal_encryptkey(struct wolfBoot_image *img, uint8_t* key,
if (pubkey == NULL)
return -1;
/* get the img signature */
imageSignatureSz = get_header(img, HDR_SIGNATURE, &imageSignature);
if (imageSignatureSz != IMAGE_SIGNATURE_SIZE)
return -1;
/* clear out the policy digest */
ret = wolfTPM2_PolicyRestart(wolftpm_session.handle.hndl);
if (ret != TPM_RC_SUCCESS)
return -ret;
/* clear out the PCR digest */
pcrReset.pcrHandle = wolftpmPcrArray[0];
@ -859,9 +845,26 @@ int wolfBoot_unseal_encryptkey(struct wolfBoot_image *img, uint8_t* key,
if (ret != TPM_RC_SUCCESS)
return -ret;
/* extend the PCRs with the image signature */
/* extend the PCRs with the image hash */
ret = wolfTPM2_ExtendPCR(&wolftpm_dev, wolftpmPcrArray[0], TPM_ALG_SHA256,
imageSignature, imageSignatureSz);
img->sha_hash, WOLFBOOT_SHA_DIGEST_SIZE);
if (ret != TPM_RC_SUCCESS)
return -ret;
/* start a policy session with parameter encryption */
ret = wolfTPM2_StartSession(&wolftpm_dev, &wolftpm_session, NULL, NULL,
TPM_SE_POLICY, TPM_ALG_CFB);
if (ret != TPM_RC_SUCCESS)
return -ret;
/* set the auth session for the device */
ret = wolfTPM2_SetAuthSession(&wolftpm_dev, 0, &wolftpm_session,
(TPMA_SESSION_decrypt | TPMA_SESSION_encrypt | TPMA_SESSION_continueSession));
if (ret != TPM_RC_SUCCESS)
return -ret;
/* clear out the policy digest */
ret = wolfTPM2_PolicyRestart(wolftpm_session.handle.hndl);
if (ret != TPM_RC_SUCCESS)
return -ret;
@ -877,7 +880,7 @@ int wolfBoot_unseal_encryptkey(struct wolfBoot_image *img, uint8_t* key,
if (policySignatureSz != IMAGE_SIGNATURE_SIZE)
return -1;
/* unseal the NV pubkey */
/* unseal the NV encrypt */
ret = wolfTPM2_UnsealWithAuthSigNV(&wolftpm_dev, &tpmKey, &wolftpm_session,
TPM_ALG_SHA256, (word32*)wolftpmPcrArray, sizeof(wolftpmPcrArray), NULL,
0, policySignature, policySignatureSz, WOLFTPM_ENCRYPT_KEYSTORE_INDEX,
@ -885,6 +888,11 @@ int wolfBoot_unseal_encryptkey(struct wolfBoot_image *img, uint8_t* key,
if (ret != TPM_RC_SUCCESS)
return -ret;
/* unload the session handle */
wolfTPM2_SetAuthSession(&wolftpm_dev, 0, NULL, 0);
wolfTPM2_UnloadHandle(&wolftpm_dev, &wolftpm_session.handle);
return 0;
}
#endif /* WOLFTPM_ENCRYPT_KEYSTORE && EXT_ENCRYPTED */
@ -893,9 +901,9 @@ int wolfBoot_unseal_encryptkey(struct wolfBoot_image *img, uint8_t* key,
int wolfBoot_reseal_keys(struct wolfBoot_image* newImg,
struct wolfBoot_image* backupImg)
{
WOLFTPM2_SESSION wolftpm_session;
WOLFTPM2_KEY tpmKey;
PCR_Reset_In pcrReset;
uint8_t* imageSignature;
uint8_t* pubkeyHint;
uint8_t* pubkey;
uint8_t* policySignature;
@ -907,7 +915,6 @@ int wolfBoot_reseal_keys(struct wolfBoot_image* newImg,
int keySlot;
int ret;
uint16_t policySignatureSz;
uint16_t imageSignatureSz;
uint16_t pubkeyHintSize;
uint8_t tpmPubkey[KEYSTORE_PUBKEY_SIZE_ECC256];
@ -928,16 +935,6 @@ int wolfBoot_reseal_keys(struct wolfBoot_image* newImg,
if (pubkey == NULL)
return -1;
/* get the backupImg signature */
imageSignatureSz = get_header(backupImg, HDR_SIGNATURE, &imageSignature);
if (imageSignatureSz != IMAGE_SIGNATURE_SIZE)
return -1;
/* clear out the policy digest */
ret = wolfTPM2_PolicyRestart(wolftpm_session.handle.hndl);
if (ret != TPM_RC_SUCCESS)
return -ret;
/* clear out the PCR digest */
pcrReset.pcrHandle = wolftpmPcrArray[0];
@ -945,9 +942,26 @@ int wolfBoot_reseal_keys(struct wolfBoot_image* newImg,
if (ret != TPM_RC_SUCCESS)
return -ret;
/* extend the PCRs with the old image signature */
/* extend the PCRs with the backupImg hash */
ret = wolfTPM2_ExtendPCR(&wolftpm_dev, wolftpmPcrArray[0], TPM_ALG_SHA256,
imageSignature, imageSignatureSz);
backupImg->sha_hash, WOLFBOOT_SHA_DIGEST_SIZE);
if (ret != TPM_RC_SUCCESS)
return -ret;
/* start a policy session with parameter encryption */
ret = wolfTPM2_StartSession(&wolftpm_dev, &wolftpm_session, NULL, NULL,
TPM_SE_POLICY, TPM_ALG_CFB);
if (ret != TPM_RC_SUCCESS)
return -ret;
/* set the auth session for the device */
ret = wolfTPM2_SetAuthSession(&wolftpm_dev, 0, &wolftpm_session,
(TPMA_SESSION_decrypt | TPMA_SESSION_encrypt | TPMA_SESSION_continueSession));
if (ret != TPM_RC_SUCCESS)
return -ret;
/* clear out the policy digest */
ret = wolfTPM2_PolicyRestart(wolftpm_session.handle.hndl);
if (ret != TPM_RC_SUCCESS)
return -ret;
@ -987,15 +1001,10 @@ int wolfBoot_reseal_keys(struct wolfBoot_image* newImg,
return -ret;
#endif
/* get the newImg signature */
imageSignatureSz = get_header(newImg, HDR_SIGNATURE, &imageSignature);
if (imageSignatureSz != IMAGE_SIGNATURE_SIZE)
return -1;
/* unload the session handle */
wolfTPM2_SetAuthSession(&wolftpm_dev, 0, NULL, 0);
/* clear out the policy digest */
ret = wolfTPM2_PolicyRestart(wolftpm_session.handle.hndl);
if (ret != TPM_RC_SUCCESS)
return -ret;
wolfTPM2_UnloadHandle(&wolftpm_dev, &wolftpm_session.handle);
/* clear out the PCR digest */
pcrReset.pcrHandle = wolftpmPcrArray[0];
@ -1004,9 +1013,26 @@ int wolfBoot_reseal_keys(struct wolfBoot_image* newImg,
if (ret != TPM_RC_SUCCESS)
return -ret;
/* extend the PCRs with the new image signature */
/* extend the PCRs with the newImg hash */
ret = wolfTPM2_ExtendPCR(&wolftpm_dev, wolftpmPcrArray[0], TPM_ALG_SHA256,
imageSignature, imageSignatureSz);
newImg->sha_hash, WOLFBOOT_SHA_DIGEST_SIZE);
if (ret != TPM_RC_SUCCESS)
return -ret;
/* start a policy session with parameter encryption */
ret = wolfTPM2_StartSession(&wolftpm_dev, &wolftpm_session, NULL, NULL,
TPM_SE_POLICY, TPM_ALG_CFB);
if (ret != TPM_RC_SUCCESS)
return -ret;
/* set the auth session for the device */
ret = wolfTPM2_SetAuthSession(&wolftpm_dev, 0, &wolftpm_session,
(TPMA_SESSION_decrypt | TPMA_SESSION_encrypt | TPMA_SESSION_continueSession));
if (ret != TPM_RC_SUCCESS)
return -ret;
/* clear out the policy digest */
ret = wolfTPM2_PolicyRestart(wolftpm_session.handle.hndl);
if (ret != TPM_RC_SUCCESS)
return -ret;
@ -1035,33 +1061,29 @@ int wolfBoot_reseal_keys(struct wolfBoot_image* newImg,
return -ret;
#endif
/* unload the session handle */
wolfTPM2_SetAuthSession(&wolftpm_dev, 0, NULL, 0);
wolfTPM2_UnloadHandle(&wolftpm_dev, &wolftpm_session.handle);
return 0;
}
static int wolfBoot_unseal_pubkey(struct wolfBoot_image *img, uint8_t* pubkey,
WOLFTPM2_KEY* tpmKey)
{
WOLFTPM2_SESSION wolftpm_session;
PCR_Reset_In pcrReset;
PCR_SetAuthPolicy_In setAuthPolicy;
int ret;
uint8_t* policySignature;
uint8_t* imageSignature;
uint32_t pubkeySz = KEYSTORE_PUBKEY_SIZE_ECC256;
uint32_t tpmPubkeySz = KEYSTORE_PUBKEY_SIZE_ECC256;
uint16_t policySignatureSz;
uint16_t imageSignatureSz;
uint8_t tpmPubkey[KEYSTORE_PUBKEY_SIZE_ECC256];
XMEMSET(&pcrReset, 0, sizeof(PCR_Reset_In));
/* get the backupImg signature */
imageSignatureSz = get_header(img, HDR_SIGNATURE, &imageSignature);
if (imageSignatureSz != IMAGE_SIGNATURE_SIZE)
return -1;
/* clear out the policy digest */
ret = wolfTPM2_PolicyRestart(wolftpm_session.handle.hndl);
if (ret != TPM_RC_SUCCESS)
return -ret;
XMEMSET(&setAuthPolicy, 0, sizeof(PCR_Reset_In));
/* clear out the PCR digest */
pcrReset.pcrHandle = wolftpmPcrArray[0];
@ -1070,9 +1092,26 @@ static int wolfBoot_unseal_pubkey(struct wolfBoot_image *img, uint8_t* pubkey,
if (ret != TPM_RC_SUCCESS)
return -ret;
/* extend the PCRs with the old image signature */
/* extend the PCRs with the image hash */
ret = wolfTPM2_ExtendPCR(&wolftpm_dev, wolftpmPcrArray[0], TPM_ALG_SHA256,
imageSignature, imageSignatureSz);
img->sha_hash, WOLFBOOT_SHA_DIGEST_SIZE);
if (ret != TPM_RC_SUCCESS)
return -ret;
/* start a policy session with parameter encryption */
ret = wolfTPM2_StartSession(&wolftpm_dev, &wolftpm_session, NULL, NULL,
TPM_SE_POLICY, TPM_ALG_CFB);
if (ret != TPM_RC_SUCCESS)
return -ret;
/* set the auth session for the device */
ret = wolfTPM2_SetAuthSession(&wolftpm_dev, 0, &wolftpm_session,
(TPMA_SESSION_decrypt | TPMA_SESSION_encrypt | TPMA_SESSION_continueSession));
if (ret != TPM_RC_SUCCESS)
return -ret;
/* clear out the policy digest */
ret = wolfTPM2_PolicyRestart(wolftpm_session.handle.hndl);
if (ret != TPM_RC_SUCCESS)
return -ret;
@ -1099,6 +1138,11 @@ static int wolfBoot_unseal_pubkey(struct wolfBoot_image *img, uint8_t* pubkey,
if (ret != TPM_RC_SUCCESS)
return -ret;
/* unload the session handle */
wolfTPM2_SetAuthSession(&wolftpm_dev, 0, NULL, 0);
wolfTPM2_UnloadHandle(&wolftpm_dev, &wolftpm_session.handle);
return 0;
}
#endif /* WOLFTPM_KEYSTORE */

View File

@ -38,7 +38,7 @@ int do_cmd(const char *cmd)
if (strcmp(cmd, "powerfail") == 0)
return 1;
if (strcmp(cmd, "get_version") == 0) {
printf("%d", wolfBoot_current_firmware_version());
printf("%d\n", wolfBoot_current_firmware_version());
return 0;
}