Skip to content

Commit 3d02300

Browse files
committed
Support for setting custom auth on NV write. Added example for NVRAM operations with authentication.
1 parent 0a3b8de commit 3d02300

File tree

6 files changed

+465
-43
lines changed

6 files changed

+465
-43
lines changed

examples/nvram/include.am

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,12 @@ examples_nvram_extend_SOURCES = examples/nvram/extend.c \
3333
examples/tpm_test_keys.c
3434
examples_nvram_extend_LDADD = src/libwolftpm.la $(LIB_STATIC_ADD)
3535
examples_nvram_extend_DEPENDENCIES = src/libwolftpm.la
36+
37+
noinst_PROGRAMS += examples/nvram/nvauth
38+
examples_nvram_nvauth_SOURCES = examples/nvram/nvauth.c \
39+
examples/tpm_test_keys.c
40+
examples_nvram_nvauth_LDADD = src/libwolftpm.la $(LIB_STATIC_ADD)
41+
examples_nvram_nvauth_DEPENDENCIES = src/libwolftpm.la
3642
endif
3743

3844
example_nvramdir = $(exampledir)/nvram
@@ -41,10 +47,12 @@ dist_example_nvram_DATA = \
4147
examples/nvram/read.c \
4248
examples/nvram/counter.c \
4349
examples/nvram/policy_nv.c \
44-
examples/nvram/extend.c
50+
examples/nvram/extend.c \
51+
examples/nvram/nvauth.c
4552

4653
DISTCLEANFILES+= examples/nvram/.libs/store \
4754
examples/nvram/.libs/read \
4855
examples/nvram/.libs/counter \
4956
examples/nvram/.libs/policy_nv \
50-
examples/nvram/.libs/extend
57+
examples/nvram/.libs/extend \
58+
examples/nvram/.libs/nvauth

examples/nvram/nvauth.c

Lines changed: 351 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,351 @@
1+
/* nvauth.c
2+
*
3+
* Copyright (C) 2006-2025 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 3 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-1335, USA
20+
*/
21+
22+
/* Tool and example for NVRAM operations with authentication
23+
*
24+
* This example demonstrates creating, writing, reading, and deleting
25+
* NV indices with owner authentication. It shows how to use
26+
* owner authentication for write/delete operations while allowing
27+
* unauthenticated reads.
28+
*
29+
*/
30+
31+
#ifdef HAVE_CONFIG_H
32+
#include <config.h>
33+
#endif
34+
35+
#include <wolftpm/tpm2_wrap.h>
36+
37+
#include <stdio.h>
38+
#include <stdlib.h>
39+
#include <string.h>
40+
41+
#ifndef WOLFTPM2_NO_WRAPPER
42+
43+
#include <examples/nvram/nvram.h>
44+
#include <hal/tpm_io.h>
45+
#include <examples/tpm_test.h>
46+
#include <examples/tpm_test_keys.h>
47+
48+
/******************************************************************************/
49+
/* --- BEGIN TPM NVRAM Auth Example -- */
50+
/******************************************************************************/
51+
static void usage(void)
52+
{
53+
printf("Expected usage:\n");
54+
printf("./examples/nvram/nvauth\n");
55+
printf("* -all Run all operations in order (create, write, read, delete)\n");
56+
printf("* -ownerauth[=<auth>] Auth for owner (optional)\n");
57+
printf("* -setownerauth Set owner auth\n");
58+
printf("* -create[=auth] Create NV index (optional: set nvIndex auth)\n");
59+
printf("* -write[=<val>] Write value to NV index (optional: specify value, default: test)\n");
60+
printf("* -delete Delete NV index\n");
61+
printf("* -aes/xor: Enable Parameter Encryption\n");
62+
}
63+
64+
int TPM2_NVRAM_Auth_Example(void* userCtx, int argc, char *argv[])
65+
{
66+
int rc = 0;
67+
int i;
68+
WOLFTPM2_DEV dev;
69+
WOLFTPM2_SESSION session;
70+
WOLFTPM2_NV nv;
71+
word32 nvIndex = TPM2_DEMO_NVRAM_OWNER_INDEX;
72+
byte buf[64];
73+
word32 bufLen = sizeof(buf);
74+
int paramEncAlg = TPM_ALG_NULL;
75+
const char* ownerAuthStr = NULL;
76+
const char* nvIndexAuthStr = NULL;
77+
WOLFTPM2_HANDLE owner;
78+
WOLFTPM2_HANDLE nvIndexAuth;
79+
80+
/* Command line flags */
81+
int do_create = 0;
82+
int do_write = 0;
83+
int do_read = 0;
84+
int do_delete = 0;
85+
const char* write_value = "test";
86+
int set_owner_auth = 0;
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+
97+
/* Parse command line arguments */
98+
for (i = 1; i < argc; i++) {
99+
/* Handle -ownerauth[=<auth>] */
100+
if (XSTRNCMP(argv[i], "-ownerauth=", XSTRLEN("-ownerauth=")) == 0) {
101+
ownerAuthStr = argv[i] + XSTRLEN("-ownerauth=");
102+
}
103+
else if (XSTRCMP(argv[i], "-setownerauth") == 0) {
104+
set_owner_auth = 1;
105+
}
106+
/* Handle -create[=auth] */
107+
else if (XSTRNCMP(argv[i], "-create=", XSTRLEN("-create=")) == 0) {
108+
do_create = 1;
109+
nvIndexAuthStr = argv[i] + XSTRLEN("-create=");
110+
}
111+
else if (XSTRCMP(argv[i], "-create") == 0) {
112+
do_create = 1;
113+
}
114+
/* Handle -write[=<val>] */
115+
else if (XSTRNCMP(argv[i], "-write=", XSTRLEN("-write=")) == 0) {
116+
do_write = 1;
117+
write_value = argv[i] + XSTRLEN("-write=");
118+
}
119+
else if (XSTRCMP(argv[i], "-write") == 0) {
120+
do_write = 1;
121+
}
122+
else if (XSTRCMP(argv[i], "-read") == 0) {
123+
do_read = 1;
124+
}
125+
else if (XSTRCMP(argv[i], "-delete") == 0) {
126+
do_delete = 1;
127+
}
128+
else if (XSTRCMP(argv[i], "-all") == 0) {
129+
do_create = 1;
130+
do_write = 1;
131+
do_read = 1;
132+
do_delete = 1;
133+
}
134+
else if (XSTRCMP(argv[i], "-aes") == 0) {
135+
paramEncAlg = TPM_ALG_CFB;
136+
}
137+
else if (XSTRCMP(argv[i], "-xor") == 0) {
138+
paramEncAlg = TPM_ALG_XOR;
139+
}
140+
else {
141+
printf("Warning: Unrecognized option: %s\n", argv[i]);
142+
}
143+
}
144+
145+
printf("Example for NVRAM operations with authentication\n");
146+
printf("NV Index: 0x%x\n", nvIndex);
147+
if (paramEncAlg == TPM_ALG_CFB) {
148+
printf("Parameter Encryption: Enabled. (AES CFB)\n\n");
149+
}
150+
else if (paramEncAlg == TPM_ALG_XOR) {
151+
printf("Parameter Encryption: Enabled. (XOR)\n\n");
152+
}
153+
154+
/* setup the owner authentication for NV write/delete */
155+
XMEMSET(&owner, 0, sizeof(owner));
156+
owner.hndl = TPM_RH_OWNER;
157+
if (ownerAuthStr != NULL) {
158+
owner.auth.size = (word16)XSTRLEN(ownerAuthStr);
159+
XMEMCPY(owner.auth.buffer, ownerAuthStr, owner.auth.size);
160+
}
161+
162+
/* setup the nvIndex authentication */
163+
XMEMSET(&nvIndexAuth, 0, sizeof(nvIndexAuth));
164+
nvIndexAuth.hndl = nvIndex;
165+
if (nvIndexAuthStr != NULL) {
166+
nvIndexAuth.auth.size = (word16)XSTRLEN(nvIndexAuthStr);
167+
XMEMCPY(nvIndexAuth.auth.buffer, nvIndexAuthStr, nvIndexAuth.auth.size);
168+
}
169+
170+
rc = wolfTPM2_Init(&dev, TPM2_IoCb, userCtx);
171+
if (rc != TPM_RC_SUCCESS) {
172+
printf("Failed to initialize TPM: 0x%x\n", rc);
173+
goto cleanup;
174+
}
175+
176+
if (paramEncAlg != TPM_ALG_NULL) {
177+
rc = wolfTPM2_StartSession(&dev, &session, NULL, NULL, TPM_SE_HMAC,
178+
paramEncAlg);
179+
if (rc != TPM_RC_SUCCESS) {
180+
printf("Failed to start session: 0x%x\n", rc);
181+
goto cleanup;
182+
}
183+
184+
rc = wolfTPM2_SetAuthSession(&dev, 1, &session,
185+
(TPMA_SESSION_decrypt | TPMA_SESSION_encrypt |
186+
TPMA_SESSION_continueSession));
187+
if (rc != TPM_RC_SUCCESS) {
188+
printf("Failed to set auth session: 0x%x\n", rc);
189+
goto cleanup;
190+
}
191+
}
192+
193+
if (set_owner_auth) {
194+
/* Example for setting the owner authentication */
195+
HierarchyChangeAuth_In in;
196+
XMEMSET(&in, 0, sizeof(in));
197+
in.authHandle = owner.hndl;
198+
in.newAuth.size = owner.auth.size;
199+
XMEMCPY(in.newAuth.buffer, owner.auth.buffer, in.newAuth.size);
200+
rc = TPM2_HierarchyChangeAuth(&in);
201+
if (rc != TPM_RC_SUCCESS) {
202+
printf("Failed to set owner auth: 0x%x (%s), allowing error and "
203+
"continuing as it might already be set\n",
204+
rc, wolfTPM2_GetRCString(rc));
205+
rc = TPM_RC_SUCCESS;
206+
}
207+
printf("Owner hierarchy auth set\n");
208+
}
209+
210+
if (do_create) {
211+
/* Try to open an existing */
212+
rc = wolfTPM2_NVOpen(&dev, &nv, nvIndex,
213+
nvIndexAuth.auth.buffer, nvIndexAuth.auth.size);
214+
if (rc != TPM_RC_SUCCESS) {
215+
/* Require owner password to write/delete and no password to read */
216+
word32 nvAttributes =
217+
(TPMA_NV_AUTHREAD | TPMA_NV_OWNERWRITE | TPM_NT_ORDINARY);
218+
/* Can also switch to using AUTHWRITE or OWNERREAD to flip permissions */
219+
220+
/* By default the nv auth handle is the nvIndex handle,
221+
* but it can also be a hierarchy handle */
222+
nv.handle.hndl = owner.hndl;
223+
/* Set auth for the owner hierarchy */
224+
wolfTPM2_SetAuthHandle(&dev, 0, &owner);
225+
226+
/* if the NV is not found then create it */
227+
rc = wolfTPM2_NVCreateAuth(&dev, &owner, &nv, nvIndex,
228+
nvAttributes, sizeof(buf),
229+
nvIndexAuth.auth.buffer, nvIndexAuth.auth.size);
230+
if (rc != TPM_RC_SUCCESS) {
231+
printf("Failed to create NV index: 0x%x\n", rc);
232+
goto cleanup;
233+
}
234+
printf("Created NV index 0x%x\n", nvIndex);
235+
}
236+
else {
237+
printf("NV index 0x%x already exists\n", nvIndex);
238+
}
239+
}
240+
241+
if (do_write) {
242+
rc = wolfTPM2_NVOpen(&dev, &nv, nvIndex,
243+
nvIndexAuth.auth.buffer, nvIndexAuth.auth.size);
244+
if (rc != TPM_RC_SUCCESS) {
245+
printf("Failed to open NV index for write: 0x%x\n", rc);
246+
goto cleanup;
247+
}
248+
249+
/* By default the nv auth handle is the nvIndex handle,
250+
* but it can also be a hierarchy handle */
251+
nv.handle.hndl = owner.hndl;
252+
wolfTPM2_SetAuthHandle(&dev, 0, &owner);
253+
wolfTPM2_SetAuthHandle(&dev, 1, &nvIndexAuth);
254+
255+
bufLen = (word32)XSTRLEN(write_value)+1;
256+
rc = wolfTPM2_NVWriteData(&dev,
257+
(paramEncAlg != TPM_ALG_NULL) ? &session : NULL,
258+
TPM_ALG_NULL, NULL, 0, &nv, nvIndex, (byte*)write_value,
259+
bufLen, 0, NW_WRITE_FLAG_AUTH_CUSTOM);
260+
if (rc != TPM_RC_SUCCESS) {
261+
printf("Failed to write to NV index: 0x%x\n", rc);
262+
goto cleanup;
263+
}
264+
printf("Wrote %u bytes to NV index 0x%x\n", bufLen, nvIndex);
265+
}
266+
267+
if (do_read) {
268+
TPMS_NV_PUBLIC nvPublic;
269+
270+
/* Prepare auth for NV Index */
271+
XMEMSET(&nv, 0, sizeof(nv));
272+
273+
/* Clear all auth. Not required here, since wolfTPM2_NVReadAuth does it,
274+
* but demonstrating that the auth is not required for a read because
275+
* AUTHREAD is not set */
276+
wolfTPM2_SetAuthPassword(&dev, 0, NULL);
277+
wolfTPM2_SetAuthPassword(&dev, 1, NULL);
278+
279+
rc = wolfTPM2_NVOpen(&dev, &nv, nvIndex,
280+
nvIndexAuth.auth.buffer, nvIndexAuth.auth.size);
281+
if (rc != TPM_RC_SUCCESS) {
282+
printf("Failed to open NV index for read: 0x%x\n", rc);
283+
goto cleanup;
284+
}
285+
286+
rc = wolfTPM2_NVReadPublic(&dev, nvIndex, &nvPublic);
287+
if (rc != TPM_RC_SUCCESS) {
288+
printf("Failed to read public from NV index: 0x%x\n", rc);
289+
goto cleanup;
290+
}
291+
bufLen = nvPublic.dataSize;
292+
293+
rc = wolfTPM2_NVReadAuth(&dev, &nv, nvIndex, buf, &bufLen, 0);
294+
if (rc != TPM_RC_SUCCESS) {
295+
printf("Failed to read from NV index: 0x%x\n", rc);
296+
goto cleanup;
297+
}
298+
299+
printf("Read %u bytes from NV index:\n", bufLen);
300+
printf("Data: %s\n", buf);
301+
}
302+
303+
if (do_delete) {
304+
wolfTPM2_SetAuthHandle(&dev, 0, &owner);
305+
wolfTPM2_SetAuthHandle(&dev, 1, &nvIndexAuth);
306+
307+
rc = wolfTPM2_NVDeleteAuth(&dev, &owner, nvIndex);
308+
if (rc != TPM_RC_SUCCESS) {
309+
printf("Failed to delete NV index: 0x%x\n", rc);
310+
goto cleanup;
311+
}
312+
printf("Deleted NV index 0x%x\n", nvIndex);
313+
}
314+
315+
cleanup:
316+
317+
if (rc != 0) {
318+
printf("\nFailure 0x%x: %s\n\n", rc, wolfTPM2_GetRCString(rc));
319+
}
320+
321+
wolfTPM2_UnsetAuth(&dev, 0);
322+
if (paramEncAlg != TPM_ALG_NULL) {
323+
wolfTPM2_UnloadHandle(&dev, &session.handle);
324+
}
325+
wolfTPM2_Cleanup(&dev);
326+
327+
return rc;
328+
}
329+
330+
/******************************************************************************/
331+
/* --- END TPM NVRAM Auth Example -- */
332+
/******************************************************************************/
333+
#endif /* !WOLFTPM2_NO_WRAPPER */
334+
335+
#ifndef NO_MAIN_DRIVER
336+
int main(int argc, char *argv[])
337+
{
338+
int rc = NOT_COMPILED_IN;
339+
340+
#ifndef WOLFTPM2_NO_WRAPPER
341+
rc = TPM2_NVRAM_Auth_Example(NULL, argc, argv);
342+
#else
343+
printf("NVRAM code not compiled in\n");
344+
(void)argc;
345+
(void)argv;
346+
#endif
347+
348+
return rc;
349+
}
350+
#endif
351+

examples/nvram/nvram.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ int TPM2_PCR_Seal_With_Policy_Auth_NV_Test(void* userCtx, int argc, char *argv[]
3333
int TPM2_PCR_Seal_With_Policy_Auth_NV_External_Test(void* userCtx, int argc, char *argv[]);
3434
int TPM2_NVRAM_PolicyNV_Example(void* userCtx, int argc, char *argv[]);
3535
int TPM2_NVRAM_Extend_Example(void* userCtx, int argc, char *argv[]);
36+
int TPM2_NVRAM_Auth_Example(void* userCtx, int argc, char *argv[]);
3637

3738
#ifdef __cplusplus
3839
} /* extern "C" */

0 commit comments

Comments
 (0)