Skip to content

Commit

Permalink
More sealing/unsealing examples (work from @jpbland1)
Browse files Browse the repository at this point in the history
  • Loading branch information
dgarske committed Sep 11, 2023
1 parent acdbc44 commit 48027b7
Show file tree
Hide file tree
Showing 10 changed files with 2,366 additions and 10 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,15 @@ examples/keygen/external_import
examples/nvram/store
examples/nvram/read
examples/nvram/counter
examples/nvram/seal_policy_auth_nv
examples/nvram/seal_policy_auth_nv_external
examples/gpio/gpio_config
examples/gpio/gpio_set
examples/gpio/gpio_read
examples/gpio/gpio_nuvoton
examples/seal/seal
examples/seal/unseal
examples/seal/seal_policy_auth
examples/attestation/make_credential
examples/attestation/activate_credential
examples/boot/secure_rot
Expand Down
41 changes: 41 additions & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,47 @@ After a successful unsealing, the data is stored into a new file. If no filename
See [examples/boot/README.md](/examples/boot/README.md)


### Sealing data to the TPM with policy authorization

Data can also be sealed to the TPM, either to NVM or regular, with policy authorization. ./examples/seal/seal\_policy\_auth.c shows an example of how to seal data to the TPM using the wolfTPM2\_SealWithAuthKey function and unseal with wolfTPM2\_UnsealWithAuthSig. These functions call wolfTPM2\_PolicyPCR to add the PCR values to the policyDigest and TPM2\_PolicyAuthorize to sign the digest with either an ecc or rsa key. ./examples/nvram/seal\_policy\_auth\_nv.c is similar but seals to the data to NVM and uses TPM2\_PolicyAuthorizeNV to keep the policyDigest in NVM so it persists in between boots. ./examples/nvram/seal\_policy\_auth\_nv\_external.c works the same way but it shows how to use a key generated from outside wolfTPM, currently only supports ecc256 keys

```
$ ./examples/seal/seal_policy_auth -ecc -aes 16
Example for sealing data to the TPM with policy authorization
PCR Indicies:16
Use Parameter Encryption: CFB
wolfTPM2_Init: success
TPM2_StartAuthSession: sessionHandle 0x3000000
Loading SRK: Storage 0x81000200 (282 bytes)
ECC template
Loaded sealBlob to 0x80000002
TPM2_StartAuthSession: sessionHandle 0x3000000
Unsealed secret matches!
$ ./examples/nvram/seal_policy_auth_nv -ecc -aes 16
Example for sealing data to NV memory with policy authorization
PCR Indicies:16
Use Parameter Encryption: CFB
wolfTPM2_Init: success
TPM2_StartAuthSession: sessionHandle 0x3000000
Loading SRK: Storage 0x81000200 (282 bytes)
ECC template
TPM2_StartAuthSession: sessionHandle 0x3000000
Unsealed secret matches!
$ ./examples/nvram/seal_policy_auth_nv_external -ecc -aes 16
Warning: Unrecognized option: -ecc
Example for sealing data to NV memory with policy authorization
PCR Indicies:16
Use Parameter Encryption: CFB
wolfTPM2_Init: success
Loading SRK: Storage 0x81000200 (282 bytes)
TPM2_StartAuthSession: sessionHandle 0x3000000
TPM2_StartAuthSession: sessionHandle 0x3000000
Unsealed secret matches!
```


## Secure Boot

### TPM based root of trust
Expand Down
17 changes: 16 additions & 1 deletion examples/nvram/include.am
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,28 @@ examples_nvram_counter_SOURCES = examples/nvram/counter.c \
examples/tpm_test_keys.c
examples_nvram_counter_LDADD = src/libwolftpm.la $(LIB_STATIC_ADD)
examples_nvram_counter_DEPENDENCIES = src/libwolftpm.la

noinst_PROGRAMS += examples/nvram/seal_policy_auth_nv
examples_nvram_seal_policy_auth_nv_SOURCES = examples/nvram/seal_policy_auth_nv.c \
examples/tpm_test_keys.c
examples_nvram_seal_policy_auth_nv_LDADD = src/libwolftpm.la $(LIB_STATIC_ADD)
examples_nvram_seal_policy_auth_nv_DEPENDENCIES = src/libwolftpm.la

noinst_PROGRAMS += examples/nvram/seal_policy_auth_nv_external
examples_nvram_seal_policy_auth_nv_external_SOURCES = examples/nvram/seal_policy_auth_nv_external.c \
examples/tpm_test_keys.c
examples_nvram_seal_policy_auth_nv_external_LDADD = src/libwolftpm.la $(LIB_STATIC_ADD)
examples_nvram_seal_policy_auth_nv_external_DEPENDENCIES = src/libwolftpm.la

endif

example_nvramdir = $(exampledir)/nvram
dist_example_nvram_DATA = \
examples/nvram/store.c \
examples/nvram/read.c \
examples/nvram/counter.c
examples/nvram/counter.c \
examples/nvram/seal_policy_auth_nv.c \
examples/nvram/seal_policy_auth_nv_external.c

DISTCLEANFILES+= examples/nvram/.libs/store
DISTCLEANFILES+= examples/nvram/.libs/read
Expand Down
294 changes: 294 additions & 0 deletions examples/nvram/seal_policy_auth_nv.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,294 @@
/* seal_policy_auth_nv.c
*
* Copyright (C) 2006-2023 wolfSSL Inc.
*
* This file is part of wolfTPM.
*
* wolfTPM 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.
*
* wolfTPM 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-1301, USA
*/

/* This is a helper tool for setting policies on a TPM 2.0 PCR */

#include <wolftpm/tpm2_wrap.h>

#include <stdio.h>

#if !defined(WOLFTPM2_NO_WRAPPER) && !defined(WOLFTPM2_NO_WOLFCRYPT)

#include <examples/nvram/nvram.h>
#include <hal/tpm_io.h>
#include <examples/tpm_test.h>
#include <examples/tpm_test_keys.h>
#include <wolfssl/wolfcrypt/hash.h>

/******************************************************************************/
/* --- BEGIN TPM2.0 PCR Policy example tool -- */
/******************************************************************************/

static void usage(void)
{
printf("Expected usage:\n");
printf("./examples/nvram/seal_policy_auth_nv [-aes/xor] [-rsa/ecc] [pcr]\n");
printf("* -aes/xor: Use Parameter Encryption\n");
printf("* -rsa/ecc: Pick sealing key type, (default rsa)\n");
printf("* pcr: PCR index between 0-23 (default %d)\n", TPM2_DEMO_PCR_INDEX);
}

static const word32 sealNvIndex = TPM2_DEMO_NV_TEST_INDEX;
static const word32 policyDigestNvIndex = TPM2_DEMO_NV_TEST_INDEX + 1;

int TPM2_PCR_Seal_With_Policy_Auth_NV_Test(void* userCtx, int argc, char *argv[])
{
int i;
int rc = -1;
WOLFTPM2_NV nv;
WOLFTPM2_DEV dev;
WOLFTPM2_KEY storage;
WOLFTPM2_SESSION tpmSession;
WOLFTPM2_KEYBLOB authKey;
TPMT_PUBLIC authTemplate;
/* default to aes since parm encryption is required */
TPM_ALG_ID paramEncAlg = TPM_ALG_CFB;
word32 pcrIndex = TPM2_DEMO_PCR_INDEX;
byte pcrArray[PCR_SELECT_MAX*2];
word32 pcrArraySz = 0;
byte secret[16];
byte secretOut[16];
word32 secretOutSz = (word32)sizeof(secretOut);
byte policySignedSig[MAX_RSA_KEY_BYTES];
word32 policySignedSigSz = MAX_RSA_KEY_BYTES;
TPM_ALG_ID alg = TPM_ALG_RSA;

XMEMSET(&dev, 0, sizeof(WOLFTPM2_DEV));
XMEMSET(&storage, 0, sizeof(WOLFTPM2_KEY));
XMEMSET(&tpmSession, 0, sizeof(WOLFTPM2_SESSION));
XMEMSET(&nv, 0, sizeof(nv));
XMEMSET(&authTemplate, 0, sizeof(TPMT_PUBLIC));

/* set the secret */
for (i = 0; i < (int)sizeof(secret); i++) {
secret[i] = i;
}

if (argc >= 2) {
if (XSTRCMP(argv[1], "-?") == 0 ||
XSTRCMP(argv[1], "-h") == 0 ||
XSTRCMP(argv[1], "--help") == 0) {
usage();
return 0;
}
}
while (argc > 1) {
if (XSTRCMP(argv[argc-1], "-aes") == 0) {
paramEncAlg = TPM_ALG_CFB;
}
else if (XSTRCMP(argv[argc-1], "-xor") == 0) {
paramEncAlg = TPM_ALG_XOR;
}
else if (XSTRCMP(argv[argc-1], "-rsa") == 0) {
alg = TPM_ALG_RSA;
}
else if (XSTRCMP(argv[argc-1], "-ecc") == 0) {
alg = TPM_ALG_ECC;
}
else if (argv[argc-1][0] != '-') {
/* TODO: Allow selection of multiple PCR's SHA-1 or SHA2-256 */
pcrIndex = XATOI(argv[argc-1]);
if (pcrIndex > PCR_LAST) {
printf("PCR index is out of range (0-23)\n");
usage();
return 0;
}
pcrArray[pcrArraySz] = pcrIndex;
pcrArraySz++;
}
else {
printf("Warning: Unrecognized option: %s\n", argv[argc-1]);
}
argc--;
}

if (pcrArraySz == 0) {
pcrArray[pcrArraySz] = pcrIndex;
pcrArraySz++;
}

printf("Example for sealing data to NV memory with policy authorization\n");
printf("\tPCR Indicies:");

for (i = 0; i < (int)pcrArraySz; i++) {
printf("%d ", pcrArray[i]);
}

printf("\n");

printf("\tUse Parameter Encryption: %s\n", TPM2_GetAlgName(paramEncAlg));

rc = wolfTPM2_Init(&dev, TPM2_IoCb, userCtx);
if (rc != TPM_RC_SUCCESS) {
printf("wolfTPM2_Init failed 0x%x: %s\n", rc, TPM2_GetRCString(rc));
goto exit;
}
printf("wolfTPM2_Init: success\n");

/* session is required for pcr authorization */
/* Start an authenticated policy session (salted / unbound) */
rc = wolfTPM2_StartSession(&dev, &tpmSession, NULL, NULL,
TPM_SE_POLICY, paramEncAlg);
if (rc != 0) goto exit;
printf("TPM2_StartAuthSession: sessionHandle 0x%x\n",
(word32)tpmSession.handle.hndl);

/* set session for authorization of the storage key */
rc = wolfTPM2_SetAuthSession(&dev, 0, &tpmSession,
(TPMA_SESSION_decrypt | TPMA_SESSION_encrypt |
TPMA_SESSION_continueSession));
if (rc != 0) goto exit;

/* get SRK */
rc = getPrimaryStoragekey(&dev, &storage, TPM_ALG_RSA);
if (rc != 0) goto exit;

/* create the auth key template */
if (alg == TPM_ALG_RSA) {
printf("RSA template\n");
rc = wolfTPM2_GetKeyTemplate_RSA(&authTemplate,
TPMA_OBJECT_sensitiveDataOrigin | TPMA_OBJECT_userWithAuth |
TPMA_OBJECT_decrypt | TPMA_OBJECT_sign | TPMA_OBJECT_noDA);
}
else if (alg == TPM_ALG_ECC) {
printf("ECC template\n");
rc = wolfTPM2_GetKeyTemplate_ECC(&authTemplate,
TPMA_OBJECT_sensitiveDataOrigin | TPMA_OBJECT_userWithAuth |
TPMA_OBJECT_sign | TPMA_OBJECT_noDA,
TPM_ECC_NIST_P256, TPM_ALG_ECDSA);
}
if (rc != TPM_RC_SUCCESS) {
printf("create template failed failed\n");
goto exit;
}

/* generate the authorized key, this auth key can also generated and */
/* loaded externally */
rc = wolfTPM2_CreateKey(&dev, &authKey, &storage.handle,
&authTemplate, NULL, 0);
if (rc != TPM_RC_SUCCESS) {
printf("wolfTPM2_CreateKey failed\n");
goto exit;
}

rc = wolfTPM2_LoadKey(&dev, &authKey, &storage.handle);
if (rc != TPM_RC_SUCCESS) {
printf("wolfTPM2_LoadKey failed\n");
goto exit;
}

/* seal the secret */
rc = wolfTPM2_SealWithAuthKeyNV(&dev, (WOLFTPM2_KEY*)&authKey,
&tpmSession, TPM_ALG_SHA256, TPM_ALG_SHA256, pcrArray,
pcrArraySz, secret, sizeof(secret),
NULL, 0, sealNvIndex, policyDigestNvIndex, policySignedSig,
&policySignedSigSz);
if (rc != TPM_RC_SUCCESS) {
printf("wolfTPM2_SealWithAuthPolicyNV failed 0x%x: %s\n", rc,
TPM2_GetRCString(rc));
goto exit;
}

/* reset our session */
wolfTPM2_UnloadHandle(&dev, &tpmSession.handle);
XMEMSET(&tpmSession, 0, sizeof(WOLFTPM2_SESSION));

rc = wolfTPM2_StartSession(&dev, &tpmSession, NULL, NULL,
TPM_SE_POLICY, paramEncAlg);
if (rc != 0) goto exit;
printf("TPM2_StartAuthSession: sessionHandle 0x%x\n",
(word32)tpmSession.handle.hndl);

/* set session for authorization of the storage key */
rc = wolfTPM2_SetAuthSession(&dev, 0, &tpmSession,
(TPMA_SESSION_decrypt | TPMA_SESSION_encrypt |
TPMA_SESSION_continueSession));
if (rc != 0) goto exit;

nv.handle.hndl = sealNvIndex;

/* try to unseal with the regular command, should fail */
rc = wolfTPM2_NVReadAuth(&dev, &nv, sealNvIndex,
secretOut, &secretOutSz, 0);
if (rc == TPM_RC_SUCCESS) {
printf("wolfTPM2_NVReadAuth failed, it should not have allowed a read"
" without PolicyAuthorizeNV 0x%x: %s\n", rc, TPM2_GetRCString(rc));
goto exit;
}

/* unseal the secret */
rc = wolfTPM2_UnsealWithAuthSigNV(&dev, (WOLFTPM2_KEY*)&authKey,
&tpmSession, TPM_ALG_SHA256, pcrArray,
pcrArraySz, NULL, 0, policySignedSig, policySignedSigSz, sealNvIndex,
policyDigestNvIndex, secretOut, &secretOutSz);
if (rc != TPM_RC_SUCCESS) {
printf("wolfTPM2_UnsealWithAuthSigNV failed 0x%x: %s\n", rc,
TPM2_GetRCString(rc));
goto exit;
}

if (XMEMCMP(secret, secretOut, sizeof(secret)) != 0) {
printf("Unsealed secret does not match\n");
goto exit;
}
else {
printf("Unsealed secret matches!\n");
}

exit:
if (rc != 0) {
printf("Failure 0x%x: %s\n", rc, wolfTPM2_GetRCString(rc));
}

wolfTPM2_SetAuthPassword(&dev, 0, NULL);

wolfTPM2_UnloadHandle(&dev, &authKey.handle);
wolfTPM2_UnloadHandle(&dev, &storage.handle);
wolfTPM2_UnloadHandle(&dev, &tpmSession.handle);

wolfTPM2_Cleanup(&dev);

return rc;
}

/******************************************************************************/
/* --- END TPM2.0 PCR Policy example tool -- */
/******************************************************************************/

#endif /* !WOLFTPM2_NO_WRAPPER && !WOLFTPM2_NO_WOLFCRYPT */


#ifndef NO_MAIN_DRIVER
int main(int argc, char *argv[])
{
int rc = -1;

#if !defined(WOLFTPM2_NO_WRAPPER) && !defined(WOLFTPM2_NO_WOLFCRYPT)
rc = TPM2_PCR_Seal_With_Policy_Auth_NV_Test(NULL, argc, argv);
#else
printf("Wrapper code not compiled in\n");
(void)argc;
(void)argv;
#endif /* !WOLFTPM2_NO_WRAPPER && !WOLFTPM2_NO_WOLFCRYPT */

return rc;
}
#endif
Loading

0 comments on commit 48027b7

Please sign in to comment.