From fe2b797b01be64491b2a55d5836056a992e7711d Mon Sep 17 00:00:00 2001 From: John Bland Date: Wed, 3 May 2023 11:39:25 -0400 Subject: [PATCH] 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 --- arch.mk | 1 + docs/PubkeySealing.md | 13 ++- options.mk | 12 ++- src/image.c | 180 ++++++++++++++++++++++++++---------------- test-app/app_sim.c | 2 +- 5 files changed, 135 insertions(+), 73 deletions(-) diff --git a/arch.mk b/arch.mk index 4f231bab..6ff37b3d 100644 --- a/arch.mk +++ b/arch.mk @@ -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 diff --git a/docs/PubkeySealing.md b/docs/PubkeySealing.md index 77d2f127..d4fc20d6 100644 --- a/docs/PubkeySealing.md +++ b/docs/PubkeySealing.md @@ -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 diff --git a/options.mk b/options.mk index ae74f94b..b465fd87 100644 --- a/options.mk +++ b/options.mk @@ -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,14 +448,20 @@ 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) - WOLFCRYPT_OBJS+=hal/spi/spi_drv_$(SPI_TARGET).o + # 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 diff --git a/src/image.c b/src/image.c index 57c24c1c..35b79f39 100644 --- a/src/image.c +++ b/src/image.c @@ -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 */ diff --git a/test-app/app_sim.c b/test-app/app_sim.c index a7de122a..36486312 100644 --- a/test-app/app_sim.c +++ b/test-app/app_sim.c @@ -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; }