Merge pull request #303 from jpbland1/preseal

add script for preseal a public key to tpm
pull/305/head
David Garske 2023-05-05 15:02:55 -07:00 committed by GitHub
commit 0b7603f7bf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 327 additions and 29 deletions

4
.gitignore vendored
View File

@ -70,6 +70,10 @@ tools/keytools/x64
tools/keytools/Debug
tools/keytools/Release
# preseal binary
tools/preseal/preseal
tools/preseal/preseal.exe
# delta binaries
tools/delta/bmdiff
tools/delta/bmpatch

View File

@ -166,6 +166,9 @@ keytools:
@$(MAKE) -C tools/keytools clean
@$(MAKE) -C tools/keytools
preseal:
@$(MAKE) -C tools/preseal
test-app/image_v1_signed.bin: $(BOOT_IMG)
@echo "\t[SIGN] $(BOOT_IMG)"
$(Q)(test $(SIGN) = NONE) || $(SIGN_TOOL) $(SIGN_OPTIONS) $(BOOT_IMG) $(PRIVATE_KEY) 1

View File

@ -8,24 +8,36 @@ 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
openssl dgst -sha256 -sign policy-key.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
#extract the raw policy-key public section
openssl ec -in policy-key.pem -text -noout
echo "925a8a35dbe4bd419a35fbf9bd30ce1440380f6d3bcd9bc5558c1fa8adb88d92c88b797dfca39af80ca9729c61508813df8254575cef48674071cf75c30e6aa8" | xxd -r -p - policy-public-key.raw
openssl ec -in private-key.pem -text -noout
echo "925a8a35dbe4bd419a35fbf9bd30ce1440380f6d3bcd9bc5558c1fa8adb88d92c88b797dfca39af80ca9729c61508813df8254575cef48674071cf75c30e6aa8" | xxd -r -p - public-key.raw
```
Next we need to manually make the image signature
Next we need to manually make the image signature, note that the header contains the policy pubkey instead of the real pubkey which will be sealed to the TPM:
```
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
tools/keytools/sign --ecc256 --sha256 --sha-only image.elf policy-public-key.raw 1
openssl pkeyutl -sign -inkey private-key.pem -in test-app/image_v1_digest.bin > imageSignature
openssl asn1parse -inform DER -in imageSignature
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 imageSignature.raw policySigned.raw
tools/keytools/sign --ecc256 --sha256 --manual-sign --policy-signed my_image policy-public-key.raw 1 imageSignature.raw policySigned.raw
```
Lastly, the pubkey needs to be sealed to the TPM. Note that the previous commands could be run from a seperate system, this one must be run on a system connected to the TPM:
```
tools/preseal/preseal public-key.raw policy-public-key.raw policySigned.raw test-app/image_v1_digest.bin 25166336 25166337 16
```
## 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

@ -567,8 +567,7 @@ uint16_t wolfBoot_find_header(uint8_t *haystack, uint16_t type, uint8_t **ptr);
#if defined(WOLFBOOT_TPM) && defined(WOLFTPM_KEYSTORE)
#if defined(WOLFTPM_ENCRYPT_KEYSTORE) && defined(EXT_ENCRYPTED)
int wolfBoot_unseal_encryptkey(struct wolfBoot_image *img, uint8_t* key,
uint32_t* keySz);
int wolfBoot_unseal_encryptkey(uint8_t* key, uint32_t* keySz);
#endif
int wolfBoot_reseal_keys(struct wolfBoot_image* newImg,

View File

@ -67,6 +67,7 @@ extern "C" {
#ifdef WOLFBOOT_TPM
int wolfBoot_tpm2_init(void);
void wolfBoot_tpm2_deinit(void);
#endif
void wolfBoot_start(void);

View File

@ -43,8 +43,7 @@ static WOLFTPM2_DEV wolftpm_dev;
static uint8_t wolftpmPcrArray[1] = {WOLFTPM_PCR_INDEX};
static int wolfBoot_unseal_pubkey(struct wolfBoot_image *img, uint8_t* pubkey,
WOLFTPM2_KEY* tpmKey);
static int wolfBoot_unseal_pubkey(uint8_t* pubkey, WOLFTPM2_KEY* tpmKey);
#endif
#endif /* WOLFBOOT_TPM */
@ -142,7 +141,7 @@ static void wolfBoot_verify_signature(uint8_t key_slot,
if (ret < 0)
return;
#ifdef WOLFTPM_KEYSTORE
ret = wolfBoot_unseal_pubkey(img, pubkey, &tpmKey);
ret = wolfBoot_unseal_pubkey(pubkey, &tpmKey);
if (ret < 0)
return;
#endif
@ -780,9 +779,6 @@ int wolfBoot_tpm2_init(void)
#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 */
@ -804,15 +800,20 @@ int wolfBoot_tpm2_init(void)
return 0;
}
void wolfBoot_tpm2_deinit(void)
{
wolfTPM2_Cleanup(&wolftpm_dev);
}
/* Currently only supports ecc256 */
#ifdef WOLFTPM_KEYSTORE
#if defined(WOLFTPM_ENCRYPT_KEYSTORE) && defined(EXT_ENCRYPTED)
int wolfBoot_unseal_encryptkey(struct wolfBoot_image *img, uint8_t* key,
uint32_t* keySz)
int wolfBoot_unseal_encryptkey(uint8_t* key, uint32_t* keySz)
{
WOLFTPM2_SESSION wolftpm_session;
WOLFTPM2_KEY tpmKey;
PCR_Reset_In pcrReset;
struct wolfBoot_image boot;
uint8_t* pubkey;
uint8_t* pubkeyHint;
uint8_t* policySignature;
@ -820,12 +821,23 @@ int wolfBoot_unseal_encryptkey(struct wolfBoot_image *img, uint8_t* key,
int ret;
uint16_t pubkeyHintSize;
uint16_t policySignatureSz;
uint8_t bootDigest[WOLFBOOT_SHA_DIGEST_SIZE];
XMEMSET(&wolftpm_session, 0, sizeof(WOLFTPM2_SESSION));
XMEMSET(&tpmKey, 0, sizeof(tpmKey));
XMEMSET(&pcrReset, 0, sizeof(PCR_Reset_In));
/* get the boot partition, PCR is always set to boot hash */
ret = wolfBoot_open_image(&boot, PART_BOOT);
if (ret != 0)
return ret;
/* get the boot digest */
if (image_hash(&boot, bootDigest) != 0)
return -1;
/* find the keyslot of the public key */
pubkeyHintSize = get_header(img, HDR_PUBKEY, &pubkeyHint);
pubkeyHintSize = get_header(&boot, HDR_PUBKEY, &pubkeyHint);
if (pubkeyHintSize != WOLFBOOT_SHA_DIGEST_SIZE)
return -1; /* Invalid hash size for public key hint */
@ -847,7 +859,7 @@ int wolfBoot_unseal_encryptkey(struct wolfBoot_image *img, uint8_t* key,
/* extend the PCRs with the image hash */
ret = wolfTPM2_ExtendPCR(&wolftpm_dev, wolftpmPcrArray[0], TPM_ALG_SHA256,
img->sha_hash, WOLFBOOT_SHA_DIGEST_SIZE);
bootDigest, WOLFBOOT_SHA_DIGEST_SIZE);
if (ret != TPM_RC_SUCCESS)
return -ret;
@ -876,7 +888,7 @@ int wolfBoot_unseal_encryptkey(struct wolfBoot_image *img, uint8_t* key,
return -ret;
/* get the PolicySigned signature tlv */
policySignatureSz = get_header(img, HDR_POLICY_SIGNATURE, &policySignature);
policySignatureSz = get_header(&boot, HDR_POLICY_SIGNATURE, &policySignature);
if (policySignatureSz != IMAGE_SIGNATURE_SIZE)
return -1;
@ -917,7 +929,9 @@ int wolfBoot_reseal_keys(struct wolfBoot_image* newImg,
uint16_t policySignatureSz;
uint16_t pubkeyHintSize;
uint8_t tpmPubkey[KEYSTORE_PUBKEY_SIZE_ECC256];
uint8_t workingDigest[WOLFBOOT_SHA_DIGEST_SIZE];
XMEMSET(&wolftpm_session, 0, sizeof(WOLFTPM2_SESSION));
XMEMSET(&tpmKey, 0, sizeof(tpmKey));
XMEMSET(&pcrReset, 0, sizeof(PCR_Reset_In));
@ -935,6 +949,10 @@ int wolfBoot_reseal_keys(struct wolfBoot_image* newImg,
if (pubkey == NULL)
return -1;
/* get the backupImg hash */
if (image_hash(backupImg, workingDigest) != 0)
return -1;
/* clear out the PCR digest */
pcrReset.pcrHandle = wolftpmPcrArray[0];
@ -944,7 +962,7 @@ int wolfBoot_reseal_keys(struct wolfBoot_image* newImg,
/* extend the PCRs with the backupImg hash */
ret = wolfTPM2_ExtendPCR(&wolftpm_dev, wolftpmPcrArray[0], TPM_ALG_SHA256,
backupImg->sha_hash, WOLFBOOT_SHA_DIGEST_SIZE);
workingDigest, WOLFBOOT_SHA_DIGEST_SIZE);
if (ret != TPM_RC_SUCCESS)
return -ret;
@ -1001,11 +1019,21 @@ int wolfBoot_reseal_keys(struct wolfBoot_image* newImg,
return -ret;
#endif
/* unload the session handle */
wolfTPM2_SetAuthSession(&wolftpm_dev, 0, NULL, 0);
/* unload the key and session handle */
wolfTPM2_UnloadHandle(&wolftpm_dev, &tpmKey.handle);
wolfTPM2_UnloadHandle(&wolftpm_dev, &wolftpm_session.handle);
wolfBoot_tpm2_deinit();
wolfBoot_tpm2_init();
XMEMSET(&wolftpm_session, 0, sizeof(WOLFTPM2_SESSION));
XMEMSET(&tpmKey, 0, sizeof(tpmKey));
XMEMSET(&pcrReset, 0, sizeof(PCR_Reset_In));
/* get the newImg hash */
if (image_hash(newImg, workingDigest) != 0)
return -1;
/* clear out the PCR digest */
pcrReset.pcrHandle = wolftpmPcrArray[0];
@ -1015,7 +1043,7 @@ int wolfBoot_reseal_keys(struct wolfBoot_image* newImg,
/* extend the PCRs with the newImg hash */
ret = wolfTPM2_ExtendPCR(&wolftpm_dev, wolftpmPcrArray[0], TPM_ALG_SHA256,
newImg->sha_hash, WOLFBOOT_SHA_DIGEST_SIZE);
workingDigest, WOLFBOOT_SHA_DIGEST_SIZE);
if (ret != TPM_RC_SUCCESS)
return -ret;
@ -1036,6 +1064,13 @@ int wolfBoot_reseal_keys(struct wolfBoot_image* newImg,
if (ret != TPM_RC_SUCCESS)
return -ret;
/* Load public key into TPM */
ret = wolfTPM2_LoadEccPublicKey(&wolftpm_dev, &tpmKey, TPM_ECC_NIST_P256,
pubkey, KEYSTORE_ECC_POINT_SIZE, pubkey + KEYSTORE_ECC_POINT_SIZE,
KEYSTORE_ECC_POINT_SIZE);
if (ret < 0)
return -ret;
/* seal the NV key with the new policyDigest*/
ret = wolfTPM2_SealWithAuthSigNV(&wolftpm_dev, &tpmKey, &wolftpm_session,
TPM_ALG_SHA256, TPM_ALG_SHA256, (word32*)wolftpmPcrArray,
@ -1066,25 +1101,39 @@ int wolfBoot_reseal_keys(struct wolfBoot_image* newImg,
wolfTPM2_UnloadHandle(&wolftpm_dev, &wolftpm_session.handle);
wolfBoot_tpm2_deinit();
wolfBoot_tpm2_init();
return 0;
}
static int wolfBoot_unseal_pubkey(struct wolfBoot_image *img, uint8_t* pubkey,
WOLFTPM2_KEY* tpmKey)
static int wolfBoot_unseal_pubkey(uint8_t* pubkey, WOLFTPM2_KEY* tpmKey)
{
WOLFTPM2_SESSION wolftpm_session;
PCR_Reset_In pcrReset;
PCR_SetAuthPolicy_In setAuthPolicy;
struct wolfBoot_image boot;
int ret;
uint8_t* policySignature;
uint32_t pubkeySz = KEYSTORE_PUBKEY_SIZE_ECC256;
uint32_t tpmPubkeySz = KEYSTORE_PUBKEY_SIZE_ECC256;
uint16_t policySignatureSz;
uint8_t tpmPubkey[KEYSTORE_PUBKEY_SIZE_ECC256];
uint8_t bootDigest[WOLFBOOT_SHA_DIGEST_SIZE];
XMEMSET(&wolftpm_session, 0, sizeof(WOLFTPM2_SESSION));
XMEMSET(&pcrReset, 0, sizeof(PCR_Reset_In));
XMEMSET(&setAuthPolicy, 0, sizeof(PCR_Reset_In));
/* get the boot partition, PCR is always set to boot hash */
ret = wolfBoot_open_image(&boot, PART_BOOT);
if (ret != 0)
return ret;
/* get the boot digest */
if (image_hash(&boot, bootDigest) != 0)
return -1;
/* clear out the PCR digest */
pcrReset.pcrHandle = wolftpmPcrArray[0];
@ -1094,7 +1143,7 @@ static int wolfBoot_unseal_pubkey(struct wolfBoot_image *img, uint8_t* pubkey,
/* extend the PCRs with the image hash */
ret = wolfTPM2_ExtendPCR(&wolftpm_dev, wolftpmPcrArray[0], TPM_ALG_SHA256,
img->sha_hash, WOLFBOOT_SHA_DIGEST_SIZE);
bootDigest, WOLFBOOT_SHA_DIGEST_SIZE);
if (ret != TPM_RC_SUCCESS)
return -ret;
@ -1116,7 +1165,7 @@ static int wolfBoot_unseal_pubkey(struct wolfBoot_image *img, uint8_t* pubkey,
return -ret;
/* get the PolicySigned signature tlv */
policySignatureSz = get_header(img, HDR_POLICY_SIGNATURE, &policySignature);
policySignatureSz = get_header(&boot, HDR_POLICY_SIGNATURE, &policySignature);
if (policySignatureSz != IMAGE_SIGNATURE_SIZE)
return -1;

View File

@ -1040,7 +1040,7 @@ int RAMFUNCTION chacha_init(void)
#ifdef WOLFTPM_ENCRYPT_KEYSTORE
wolfBoot_open_image(&boot, PART_BOOT);
if (wolfBoot_unseal_encryptkey(&boot, key, &keySz) != 0)
if (wolfBoot_unseal_encryptkey(key, &keySz) != 0)
return -1;
#endif
@ -1086,7 +1086,7 @@ int aes_init(void)
#ifdef WOLFTPM_ENCRYPT_KEYSTORE
wolfBoot_open_image(&boot, PART_BOOT);
if (wolfBoot_unseal_encryptkey(&boot, key, &keySz) != 0)
if (wolfBoot_unseal_encryptkey(key, &keySz) != 0)
return -1;
#endif

View File

@ -579,6 +579,9 @@ void RAMFUNCTION wolfBoot_start(void)
}
}
PART_SANITY_CHECK(&boot);
#ifdef WOLFBOOT_TPM
wolfBoot_tpm2_deinit();
#endif
hal_prepare_boot();
do_boot((void *)boot.fw_base);
}

View File

@ -0,0 +1,12 @@
CC = gcc
all: preseal
preseal:
$(Q)$(CC) -o $@ $@.c -lwolftpm
debug:
$(Q)$(CC) -o preseal preseal.c -g -lwolftpm -lwolfssl
clean:
rm -f preseal

View File

@ -0,0 +1,215 @@
/* preseal.c
*
* Copyright (C) 2023 wolfSSL Inc.
*
* This file is part of wolfBoot.
*
* wolfBoot is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* wolfBoot is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
#include <wolfssl/options.h>
#include <wolfssl/wolfcrypt/settings.h>
#include <wolfssl/wolfcrypt/ecc.h>
#include <wolfssl/wolfcrypt/hash.h>
#include <wolftpm/tpm2_wrap.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#define DEFAULT_PCR_INDEX 16
static int readFile(char* name, uint8_t* buf, uint32_t* bufSz)
{
int ret;
int fd;
struct stat st;
/* check size */
ret = stat(name, &st);
if (ret == 0) {
if (st.st_size > *bufSz)
return INPUT_SIZE_E;
fd = open(name, O_RDONLY);
if (fd < 0)
ret = fd;
}
/* read the contents */
if (ret == 0) {
ret = read(fd, buf, st.st_size);
if (ret >= 0) {
*bufSz = ret;
ret = 0;
}
close(fd);
}
return ret;
}
static void usage()
{
printf("preseal pubkey policypubkey policysignature imagedigest sealNVindex digestNVindex [pcrindex]\n");
printf("pubkey: the verification key to seal into the tpm\n");
printf("policypubkey: the pubkey used sign the policy expiration date\n");
printf("policysignature: the signature of the policy expiration date\n");
printf("imagedigest: the digest of the image that this pubkey verifies\n");
printf("sealNVindex: the NV index to seal the pubkey to\n");
printf("digestNVindex: the NV index to seal the policyDigest to\n");
printf("pcrindex: the pcrindex to extend with the imagedigest, defaults to 16\n");
}
int main(int argc, char** argv)
{
int rc = -1;
WOLFTPM2_DEV dev;
WOLFTPM2_SESSION tpmSession;
WOLFTPM2_KEY authKey;
PCR_Reset_In pcrReset;
/* default to aes since parm encryption is required */
TPM_ALG_ID paramEncAlg = TPM_ALG_CFB;
uint8_t pcrArray[48];
uint32_t pcrArraySz = 1;
uint8_t pubkey[ECC_MAXSIZE];
uint32_t pubkeySz = ECC_MAXSIZE;
uint8_t policyPubkey[ECC_MAXSIZE];
uint32_t policyPubkeySz = ECC_MAXSIZE;
uint8_t policySigned[ECC_MAXSIZE];
uint32_t policySignedSz = ECC_MAXSIZE;
uint8_t imageDigest[WC_MAX_DIGEST_SIZE];
uint32_t imageDigestSz = WC_MAX_DIGEST_SIZE;
uint32_t sealNvIndex;
uint32_t policyDigestNvIndex;
#ifdef DEBUG_SIGNTOOL
wolfSSL_Debugging_ON();
#endif
if (argc < 7) {
usage();
return 0;
}
XMEMSET(&dev, 0, sizeof(WOLFTPM2_DEV));
XMEMSET(&tpmSession, 0, sizeof(WOLFTPM2_SESSION));
XMEMSET(&authKey, 0, sizeof(WOLFTPM2_KEY));
XMEMSET(&pcrReset, 0, sizeof(PCR_Reset_In));
rc = readFile(argv[1], pubkey, &pubkeySz);
if (rc != 0) {
printf("Failed to read pubkey\n");
return 1;
}
rc = readFile(argv[2], policyPubkey, &policyPubkeySz);
if (rc != 0) {
printf("Failed to read policypubkey\n");
return 1;
}
rc = readFile(argv[3], policySigned, &policySignedSz);
if (rc != 0) {
printf("Failed to read policysignature\n");
return 1;
}
rc = readFile(argv[4], imageDigest, &imageDigestSz);
if (rc != 0) {
printf("Failed to read imagedigest\n");
return 1;
}
sealNvIndex = atoi(argv[5]);
policyDigestNvIndex = atoi(argv[6]);
/* TODO change this to a loop when multiple pcr's are supported */
if (argc > 7 )
pcrArray[0] = atoi(argv[7]);
else
pcrArray[0] = DEFAULT_PCR_INDEX;
rc = wolfTPM2_Init(&dev, NULL, NULL);
if (rc != TPM_RC_SUCCESS) {
printf("wolfTPM2_Init failed 0x%x: %s\n", rc, TPM2_GetRCString(rc));
goto exit;
}
pcrReset.pcrHandle = pcrArray[0];
rc = TPM2_PCR_Reset(&pcrReset);
if (rc != TPM_RC_SUCCESS) {
printf("TPM2_PCR_Reset failed 0x%x: %s\n", rc, TPM2_GetRCString(rc));
goto exit;
}
rc = wolfTPM2_ExtendPCR(&dev, pcrArray[0], TPM_ALG_SHA256,
imageDigest, imageDigestSz);
if (rc != TPM_RC_SUCCESS) {
printf("wolfTPM2_ExtendPCR failed 0x%x: %s\n", rc, TPM2_GetRCString(rc));
goto exit;
}
rc = wolfTPM2_StartSession(&dev, &tpmSession, NULL, NULL,
TPM_SE_POLICY, paramEncAlg);
if (rc != TPM_RC_SUCCESS) {
printf("wolfTPM2_StartSession failed 0x%x: %s\n", rc,
TPM2_GetRCString(rc));
goto exit;
}
rc = wolfTPM2_SetAuthSession(&dev, 0, &tpmSession,
(TPMA_SESSION_decrypt | TPMA_SESSION_encrypt |
TPMA_SESSION_continueSession));
if (rc != TPM_RC_SUCCESS) {
printf("wolfTPM2_SetAuthSession failed 0x%x: %s\n", rc,
TPM2_GetRCString(rc));
goto exit;
}
rc = wolfTPM2_LoadEccPublicKey(&dev, (WOLFTPM2_KEY*)&authKey,
TPM_ECC_NIST_P256, policyPubkey, 32, policyPubkey + 32, 32);
if (rc != TPM_RC_SUCCESS) {
printf("wolfTPM2_LoadEccPublicKey failed\n");
goto exit;
}
rc = wolfTPM2_SealWithAuthSigNV(&dev, &authKey, &tpmSession, TPM_ALG_SHA256,
TPM_ALG_SHA256, (word32*)pcrArray, pcrArraySz, pubkey, pubkeySz, NULL,
0, policySigned, policySignedSz, sealNvIndex, policyDigestNvIndex);
if (rc != TPM_RC_SUCCESS) {
printf("wolfTPM2_SealWithAuthPolicyNV failed 0x%x: %s\n", rc,
TPM2_GetRCString(rc));
goto exit;
}
exit:
if (rc != 0) {
printf("Failure 0x%x: %s\n", rc, wolfTPM2_GetRCString(rc));
}
wolfTPM2_UnloadHandle(&dev, &authKey.handle);
wolfTPM2_UnloadHandle(&dev, &tpmSession.handle);
wolfTPM2_Cleanup(&dev);
return rc;
}