Skip to content

Commit 708703f

Browse files
committed
More sealing/unsealing examples (work from @jpbland1)
1 parent acdbc44 commit 708703f

10 files changed

Lines changed: 2370 additions & 10 deletions

File tree

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,12 +65,15 @@ examples/keygen/external_import
6565
examples/nvram/store
6666
examples/nvram/read
6767
examples/nvram/counter
68+
examples/nvram/seal_policy_auth_nv
69+
examples/nvram/seal_policy_auth_nv_external
6870
examples/gpio/gpio_config
6971
examples/gpio/gpio_set
7072
examples/gpio/gpio_read
7173
examples/gpio/gpio_nuvoton
7274
examples/seal/seal
7375
examples/seal/unseal
76+
examples/seal/seal_policy_auth
7477
examples/attestation/make_credential
7578
examples/attestation/activate_credential
7679
examples/boot/secure_rot

examples/README.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,47 @@ After a successful unsealing, the data is stored into a new file. If no filename
453453
See [examples/boot/README.md](/examples/boot/README.md)
454454

455455

456+
### Sealing data to the TPM with policy authorization
457+
458+
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
459+
460+
```
461+
$ ./examples/seal/seal_policy_auth -ecc -aes 16
462+
Example for sealing data to the TPM with policy authorization
463+
PCR Indicies:16
464+
Use Parameter Encryption: CFB
465+
wolfTPM2_Init: success
466+
TPM2_StartAuthSession: sessionHandle 0x3000000
467+
Loading SRK: Storage 0x81000200 (282 bytes)
468+
ECC template
469+
Loaded sealBlob to 0x80000002
470+
TPM2_StartAuthSession: sessionHandle 0x3000000
471+
Unsealed secret matches!
472+
473+
$ ./examples/nvram/seal_policy_auth_nv -ecc -aes 16
474+
Example for sealing data to NV memory with policy authorization
475+
PCR Indicies:16
476+
Use Parameter Encryption: CFB
477+
wolfTPM2_Init: success
478+
TPM2_StartAuthSession: sessionHandle 0x3000000
479+
Loading SRK: Storage 0x81000200 (282 bytes)
480+
ECC template
481+
TPM2_StartAuthSession: sessionHandle 0x3000000
482+
Unsealed secret matches!
483+
484+
$ ./examples/nvram/seal_policy_auth_nv_external -ecc -aes 16
485+
Warning: Unrecognized option: -ecc
486+
Example for sealing data to NV memory with policy authorization
487+
PCR Indicies:16
488+
Use Parameter Encryption: CFB
489+
wolfTPM2_Init: success
490+
Loading SRK: Storage 0x81000200 (282 bytes)
491+
TPM2_StartAuthSession: sessionHandle 0x3000000
492+
TPM2_StartAuthSession: sessionHandle 0x3000000
493+
Unsealed secret matches!
494+
```
495+
496+
456497
## Secure Boot
457498

458499
### TPM based root of trust

examples/nvram/include.am

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,28 @@ examples_nvram_counter_SOURCES = examples/nvram/counter.c \
2121
examples/tpm_test_keys.c
2222
examples_nvram_counter_LDADD = src/libwolftpm.la $(LIB_STATIC_ADD)
2323
examples_nvram_counter_DEPENDENCIES = src/libwolftpm.la
24+
25+
noinst_PROGRAMS += examples/nvram/seal_policy_auth_nv
26+
examples_nvram_seal_policy_auth_nv_SOURCES = examples/nvram/seal_policy_auth_nv.c \
27+
examples/tpm_test_keys.c
28+
examples_nvram_seal_policy_auth_nv_LDADD = src/libwolftpm.la $(LIB_STATIC_ADD)
29+
examples_nvram_seal_policy_auth_nv_DEPENDENCIES = src/libwolftpm.la
30+
31+
noinst_PROGRAMS += examples/nvram/seal_policy_auth_nv_external
32+
examples_nvram_seal_policy_auth_nv_external_SOURCES = examples/nvram/seal_policy_auth_nv_external.c \
33+
examples/tpm_test_keys.c
34+
examples_nvram_seal_policy_auth_nv_external_LDADD = src/libwolftpm.la $(LIB_STATIC_ADD)
35+
examples_nvram_seal_policy_auth_nv_external_DEPENDENCIES = src/libwolftpm.la
36+
2437
endif
2538

2639
example_nvramdir = $(exampledir)/nvram
2740
dist_example_nvram_DATA = \
2841
examples/nvram/store.c \
2942
examples/nvram/read.c \
30-
examples/nvram/counter.c
43+
examples/nvram/counter.c \
44+
examples/nvram/seal_policy_auth_nv.c \
45+
examples/nvram/seal_policy_auth_nv_external.c
3146

3247
DISTCLEANFILES+= examples/nvram/.libs/store
3348
DISTCLEANFILES+= examples/nvram/.libs/read
Lines changed: 296 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,296 @@
1+
/* seal_policy_auth_nv.c
2+
*
3+
* Copyright (C) 2006-2023 wolfSSL Inc.
4+
*
5+
* This file is part of wolfTPM.
6+
*
7+
* wolfTPM is free software; you can redistribute it and/or modify
8+
* it under the terms of the GNU General Public License as published by
9+
* the Free Software Foundation; either version 2 of the License, or
10+
* (at your option) any later version.
11+
*
12+
* wolfTPM is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU General Public License
18+
* along with this program; if not, write to the Free Software
19+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
20+
*/
21+
22+
/* This is a helper tool for setting policies on a TPM 2.0 PCR */
23+
24+
#include <wolftpm/tpm2_wrap.h>
25+
26+
#ifndef WOLFTPM2_NO_WRAPPER
27+
28+
#ifndef WOLFTPM2_NO_WOLFCRYPT
29+
#include <wolfssl/wolfcrypt/hash.h>
30+
#endif
31+
32+
#include <examples/nvram/nvram.h>
33+
#include <hal/tpm_io.h>
34+
#include <examples/tpm_test.h>
35+
#include <examples/tpm_test_keys.h>
36+
37+
#include <stdio.h>
38+
39+
/******************************************************************************/
40+
/* --- BEGIN TPM2.0 PCR Policy example tool -- */
41+
/******************************************************************************/
42+
43+
static void usage(void)
44+
{
45+
printf("Expected usage:\n");
46+
printf("./examples/nvram/seal_policy_auth_nv [-aes/xor] [-rsa/ecc] [pcr]\n");
47+
printf("* -aes/xor: Use Parameter Encryption\n");
48+
printf("* -rsa/ecc: Pick sealing key type, (default rsa)\n");
49+
printf("* pcr: PCR index between 0-23 (default %d)\n", TPM2_DEMO_PCR_INDEX);
50+
}
51+
52+
static const word32 sealNvIndex = TPM2_DEMO_NV_TEST_INDEX;
53+
static const word32 policyDigestNvIndex = TPM2_DEMO_NV_TEST_INDEX + 1;
54+
55+
int TPM2_PCR_Seal_With_Policy_Auth_NV_Test(void* userCtx, int argc, char *argv[])
56+
{
57+
int i;
58+
int rc = -1;
59+
WOLFTPM2_NV nv;
60+
WOLFTPM2_DEV dev;
61+
WOLFTPM2_KEY storage;
62+
WOLFTPM2_SESSION tpmSession;
63+
WOLFTPM2_KEYBLOB authKey;
64+
TPMT_PUBLIC authTemplate;
65+
/* default to aes since parm encryption is required */
66+
TPM_ALG_ID paramEncAlg = TPM_ALG_CFB;
67+
word32 pcrIndex = TPM2_DEMO_PCR_INDEX;
68+
byte pcrArray[PCR_SELECT_MAX*2];
69+
word32 pcrArraySz = 0;
70+
byte secret[16];
71+
byte secretOut[16];
72+
word32 secretOutSz = (word32)sizeof(secretOut);
73+
byte policySignedSig[MAX_RSA_KEY_BYTES];
74+
word32 policySignedSigSz = MAX_RSA_KEY_BYTES;
75+
TPM_ALG_ID alg = TPM_ALG_RSA;
76+
77+
XMEMSET(&dev, 0, sizeof(WOLFTPM2_DEV));
78+
XMEMSET(&storage, 0, sizeof(WOLFTPM2_KEY));
79+
XMEMSET(&tpmSession, 0, sizeof(WOLFTPM2_SESSION));
80+
XMEMSET(&nv, 0, sizeof(nv));
81+
XMEMSET(&authTemplate, 0, sizeof(TPMT_PUBLIC));
82+
83+
/* set the secret */
84+
for (i = 0; i < (int)sizeof(secret); i++) {
85+
secret[i] = i;
86+
}
87+
88+
if (argc >= 2) {
89+
if (XSTRCMP(argv[1], "-?") == 0 ||
90+
XSTRCMP(argv[1], "-h") == 0 ||
91+
XSTRCMP(argv[1], "--help") == 0) {
92+
usage();
93+
return 0;
94+
}
95+
}
96+
while (argc > 1) {
97+
if (XSTRCMP(argv[argc-1], "-aes") == 0) {
98+
paramEncAlg = TPM_ALG_CFB;
99+
}
100+
else if (XSTRCMP(argv[argc-1], "-xor") == 0) {
101+
paramEncAlg = TPM_ALG_XOR;
102+
}
103+
else if (XSTRCMP(argv[argc-1], "-rsa") == 0) {
104+
alg = TPM_ALG_RSA;
105+
}
106+
else if (XSTRCMP(argv[argc-1], "-ecc") == 0) {
107+
alg = TPM_ALG_ECC;
108+
}
109+
else if (argv[argc-1][0] != '-') {
110+
/* TODO: Allow selection of multiple PCR's SHA-1 or SHA2-256 */
111+
pcrIndex = XATOI(argv[argc-1]);
112+
if (pcrIndex > PCR_LAST) {
113+
printf("PCR index is out of range (0-23)\n");
114+
usage();
115+
return 0;
116+
}
117+
pcrArray[pcrArraySz] = pcrIndex;
118+
pcrArraySz++;
119+
}
120+
else {
121+
printf("Warning: Unrecognized option: %s\n", argv[argc-1]);
122+
}
123+
argc--;
124+
}
125+
126+
if (pcrArraySz == 0) {
127+
pcrArray[pcrArraySz] = pcrIndex;
128+
pcrArraySz++;
129+
}
130+
131+
printf("Example for sealing data to NV memory with policy authorization\n");
132+
printf("\tPCR Indicies:");
133+
134+
for (i = 0; i < (int)pcrArraySz; i++) {
135+
printf("%d ", pcrArray[i]);
136+
}
137+
138+
printf("\n");
139+
140+
printf("\tUse Parameter Encryption: %s\n", TPM2_GetAlgName(paramEncAlg));
141+
142+
rc = wolfTPM2_Init(&dev, TPM2_IoCb, userCtx);
143+
if (rc != TPM_RC_SUCCESS) {
144+
printf("wolfTPM2_Init failed 0x%x: %s\n", rc, TPM2_GetRCString(rc));
145+
goto exit;
146+
}
147+
printf("wolfTPM2_Init: success\n");
148+
149+
/* session is required for pcr authorization */
150+
/* Start an authenticated policy session (salted / unbound) */
151+
rc = wolfTPM2_StartSession(&dev, &tpmSession, NULL, NULL,
152+
TPM_SE_POLICY, paramEncAlg);
153+
if (rc != 0) goto exit;
154+
printf("TPM2_StartAuthSession: sessionHandle 0x%x\n",
155+
(word32)tpmSession.handle.hndl);
156+
157+
/* set session for authorization of the storage key */
158+
rc = wolfTPM2_SetAuthSession(&dev, 0, &tpmSession,
159+
(TPMA_SESSION_decrypt | TPMA_SESSION_encrypt |
160+
TPMA_SESSION_continueSession));
161+
if (rc != 0) goto exit;
162+
163+
/* get SRK */
164+
rc = getPrimaryStoragekey(&dev, &storage, TPM_ALG_RSA);
165+
if (rc != 0) goto exit;
166+
167+
/* create the auth key template */
168+
if (alg == TPM_ALG_RSA) {
169+
printf("RSA template\n");
170+
rc = wolfTPM2_GetKeyTemplate_RSA(&authTemplate,
171+
TPMA_OBJECT_sensitiveDataOrigin | TPMA_OBJECT_userWithAuth |
172+
TPMA_OBJECT_decrypt | TPMA_OBJECT_sign | TPMA_OBJECT_noDA);
173+
}
174+
else if (alg == TPM_ALG_ECC) {
175+
printf("ECC template\n");
176+
rc = wolfTPM2_GetKeyTemplate_ECC(&authTemplate,
177+
TPMA_OBJECT_sensitiveDataOrigin | TPMA_OBJECT_userWithAuth |
178+
TPMA_OBJECT_sign | TPMA_OBJECT_noDA,
179+
TPM_ECC_NIST_P256, TPM_ALG_ECDSA);
180+
}
181+
if (rc != TPM_RC_SUCCESS) {
182+
printf("create template failed failed\n");
183+
goto exit;
184+
}
185+
186+
/* generate the authorized key, this auth key can also generated and */
187+
/* loaded externally */
188+
rc = wolfTPM2_CreateKey(&dev, &authKey, &storage.handle,
189+
&authTemplate, NULL, 0);
190+
if (rc != TPM_RC_SUCCESS) {
191+
printf("wolfTPM2_CreateKey failed\n");
192+
goto exit;
193+
}
194+
195+
rc = wolfTPM2_LoadKey(&dev, &authKey, &storage.handle);
196+
if (rc != TPM_RC_SUCCESS) {
197+
printf("wolfTPM2_LoadKey failed\n");
198+
goto exit;
199+
}
200+
201+
/* seal the secret */
202+
rc = wolfTPM2_SealWithAuthKeyNV(&dev, (WOLFTPM2_KEY*)&authKey,
203+
&tpmSession, TPM_ALG_SHA256, TPM_ALG_SHA256, pcrArray,
204+
pcrArraySz, secret, sizeof(secret),
205+
NULL, 0, sealNvIndex, policyDigestNvIndex, policySignedSig,
206+
&policySignedSigSz);
207+
if (rc != TPM_RC_SUCCESS) {
208+
printf("wolfTPM2_SealWithAuthPolicyNV failed 0x%x: %s\n", rc,
209+
TPM2_GetRCString(rc));
210+
goto exit;
211+
}
212+
213+
/* reset our session */
214+
wolfTPM2_UnloadHandle(&dev, &tpmSession.handle);
215+
XMEMSET(&tpmSession, 0, sizeof(WOLFTPM2_SESSION));
216+
217+
rc = wolfTPM2_StartSession(&dev, &tpmSession, NULL, NULL,
218+
TPM_SE_POLICY, paramEncAlg);
219+
if (rc != 0) goto exit;
220+
printf("TPM2_StartAuthSession: sessionHandle 0x%x\n",
221+
(word32)tpmSession.handle.hndl);
222+
223+
/* set session for authorization of the storage key */
224+
rc = wolfTPM2_SetAuthSession(&dev, 0, &tpmSession,
225+
(TPMA_SESSION_decrypt | TPMA_SESSION_encrypt |
226+
TPMA_SESSION_continueSession));
227+
if (rc != 0) goto exit;
228+
229+
nv.handle.hndl = sealNvIndex;
230+
231+
/* try to unseal with the regular command, should fail */
232+
rc = wolfTPM2_NVReadAuth(&dev, &nv, sealNvIndex,
233+
secretOut, &secretOutSz, 0);
234+
if (rc == TPM_RC_SUCCESS) {
235+
printf("wolfTPM2_NVReadAuth failed, it should not have allowed a read"
236+
" without PolicyAuthorizeNV 0x%x: %s\n", rc, TPM2_GetRCString(rc));
237+
goto exit;
238+
}
239+
240+
/* unseal the secret */
241+
rc = wolfTPM2_UnsealWithAuthSigNV(&dev, (WOLFTPM2_KEY*)&authKey,
242+
&tpmSession, TPM_ALG_SHA256, pcrArray,
243+
pcrArraySz, NULL, 0, policySignedSig, policySignedSigSz, sealNvIndex,
244+
policyDigestNvIndex, secretOut, &secretOutSz);
245+
if (rc != TPM_RC_SUCCESS) {
246+
printf("wolfTPM2_UnsealWithAuthSigNV failed 0x%x: %s\n", rc,
247+
TPM2_GetRCString(rc));
248+
goto exit;
249+
}
250+
251+
if (XMEMCMP(secret, secretOut, sizeof(secret)) != 0) {
252+
printf("Unsealed secret does not match\n");
253+
goto exit;
254+
}
255+
else {
256+
printf("Unsealed secret matches!\n");
257+
}
258+
259+
exit:
260+
if (rc != 0) {
261+
printf("Failure 0x%x: %s\n", rc, wolfTPM2_GetRCString(rc));
262+
}
263+
264+
wolfTPM2_SetAuthPassword(&dev, 0, NULL);
265+
266+
wolfTPM2_UnloadHandle(&dev, &authKey.handle);
267+
wolfTPM2_UnloadHandle(&dev, &storage.handle);
268+
wolfTPM2_UnloadHandle(&dev, &tpmSession.handle);
269+
270+
wolfTPM2_Cleanup(&dev);
271+
272+
return rc;
273+
}
274+
275+
/******************************************************************************/
276+
/* --- END TPM2.0 PCR Policy example tool -- */
277+
/******************************************************************************/
278+
279+
#endif /* !WOLFTPM2_NO_WRAPPER */
280+
281+
#ifndef NO_MAIN_DRIVER
282+
int main(int argc, char *argv[])
283+
{
284+
int rc = -1;
285+
286+
#ifndef WOLFTPM2_NO_WRAPPER
287+
rc = TPM2_PCR_Seal_With_Policy_Auth_NV_Test(NULL, argc, argv);
288+
#else
289+
printf("Wrapper code not compiled in\n");
290+
(void)argc;
291+
(void)argv;
292+
#endif /* !WOLFTPM2_NO_WRAPPER */
293+
294+
return rc;
295+
}
296+
#endif

0 commit comments

Comments
 (0)