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; }