1 /* SPDX-License-Identifier: BSD-2-Clause */
2 /*******************************************************************************
3 * Copyright 2017-2018, Fraunhofer SIT sponsored by Infineon Technologies AG
4 * All rights reserved.
5 *******************************************************************************/
6
7 #ifdef HAVE_CONFIG_H
8 #include <config.h>
9 #endif
10
11 #include <stdlib.h>
12
13 #include "tss2_esys.h"
14
15 #include "esys_iutil.h"
16 #include "test-esapi.h"
17 #define LOGMODULE test
18 #include "util/log.h"
19 #include "util/aux_util.h"
20
21 /** This test is intended to test the command Esys_NV_Certify.
22 *
23 * We create a RSA primary signing key which will be used as signing key
24 * for the NV data.
25 *
26 * Tested ESAPI commands:
27 * - Esys_CreatePrimary() (M)
28 * - Esys_FlushContext() (M)
29 * - Esys_NV_Certify() (O)
30 * - Esys_NV_DefineSpace() (M)
31 * - Esys_NV_UndefineSpace() (M)
32 * - Esys_NV_Write() (M)
33 *
34 * @param[in,out] esys_context The ESYS_CONTEXT.
35 * @retval EXIT_FAILURE
36 * @retval EXIT_SKIP
37 * @retval EXIT_SUCCESS
38 */
39
40 int
test_esys_nv_certify(ESYS_CONTEXT * esys_context)41 test_esys_nv_certify(ESYS_CONTEXT * esys_context)
42 {
43 TSS2_RC r;
44 ESYS_TR signHandle = ESYS_TR_NONE;
45 ESYS_TR nvHandle = ESYS_TR_NONE;
46 int failure_return = EXIT_FAILURE;
47
48 TPM2B_PUBLIC *outPublic = NULL;
49 TPM2B_CREATION_DATA *creationData = NULL;
50 TPM2B_DIGEST *creationHash = NULL;
51 TPMT_TK_CREATION *creationTicket = NULL;
52 TPM2B_ATTEST *certifyInfo = NULL;
53 TPMT_SIGNATURE *signature = NULL;
54
55 TPM2B_AUTH authValuePrimary = {
56 .size = 5,
57 .buffer = {1, 2, 3, 4, 5}
58 };
59
60 TPM2B_SENSITIVE_CREATE inSensitivePrimary = {
61 .size = 0,
62 .sensitive = {
63 .userAuth = {
64 .size = 0,
65 .buffer = {0},
66 },
67 .data = {
68 .size = 0,
69 .buffer = {0},
70 },
71 },
72 };
73
74 inSensitivePrimary.sensitive.userAuth = authValuePrimary;
75
76 TPM2B_PUBLIC inPublic = {
77 .size = 0,
78 .publicArea = {
79 .type = TPM2_ALG_RSA,
80 .nameAlg = TPM2_ALG_SHA1,
81 .objectAttributes = (
82 TPMA_OBJECT_USERWITHAUTH |
83 TPMA_OBJECT_RESTRICTED |
84 TPMA_OBJECT_SIGN_ENCRYPT |
85 TPMA_OBJECT_FIXEDTPM |
86 TPMA_OBJECT_FIXEDPARENT |
87 TPMA_OBJECT_SENSITIVEDATAORIGIN
88 ),
89 .authPolicy = {
90 .size = 0,
91 },
92 .parameters.rsaDetail = {
93 .symmetric = {
94 .algorithm = TPM2_ALG_NULL,
95 .keyBits.aes = 128,
96 .mode.aes = TPM2_ALG_CFB,
97 },
98 .scheme = {
99 .scheme = TPM2_ALG_RSASSA,
100 .details = { .rsassa = { .hashAlg = TPM2_ALG_SHA1 }},
101
102 },
103 .keyBits = 2048,
104 .exponent = 0,
105 },
106 .unique.rsa = {
107 .size = 0,
108 .buffer = {},
109 },
110 },
111 };
112
113 TPM2B_AUTH authValue = {
114 .size = 0,
115 .buffer = {}
116 };
117
118
119 TPM2B_DATA outsideInfo = {
120 .size = 0,
121 .buffer = {},
122 };
123
124
125 TPML_PCR_SELECTION creationPCR = {
126 .count = 0,
127 };
128
129 LOG_INFO("\nRSA key will be created.");
130
131 r = Esys_TR_SetAuth(esys_context, ESYS_TR_RH_OWNER, &authValue);
132 goto_if_error(r, "Error: TR_SetAuth", error);
133
134 r = Esys_CreatePrimary(esys_context, ESYS_TR_RH_OWNER, ESYS_TR_PASSWORD,
135 ESYS_TR_NONE, ESYS_TR_NONE, &inSensitivePrimary,
136 &inPublic, &outsideInfo, &creationPCR,
137 &signHandle, &outPublic, &creationData,
138 &creationHash, &creationTicket);
139 goto_if_error(r, "Error esys create primary", error);
140
141 TPM2B_AUTH auth = {.size = 20,
142 .buffer={10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
143 20, 21, 22, 23, 24, 25, 26, 27, 28, 29}};
144
145 TPM2B_NV_PUBLIC publicInfo = {
146 .size = 0,
147 .nvPublic = {
148 .nvIndex =TPM2_NV_INDEX_FIRST,
149 .nameAlg = TPM2_ALG_SHA1,
150 .attributes = (
151 TPMA_NV_OWNERWRITE |
152 TPMA_NV_AUTHWRITE |
153 TPMA_NV_WRITE_STCLEAR |
154 TPMA_NV_READ_STCLEAR |
155 TPMA_NV_AUTHREAD |
156 TPMA_NV_OWNERREAD
157 ),
158 .authPolicy = {
159 .size = 0,
160 .buffer = {},
161 },
162 .dataSize = 32,
163 }
164 };
165
166 r = Esys_NV_DefineSpace(esys_context,
167 ESYS_TR_RH_OWNER,
168 ESYS_TR_PASSWORD,
169 ESYS_TR_NONE,
170 ESYS_TR_NONE,
171 &auth,
172 &publicInfo,
173 &nvHandle);
174 goto_if_error(r, "Error esys define nv space", error);
175
176 UINT16 offset = 0;
177 TPM2B_MAX_NV_BUFFER nv_test_data = { .size = 20,
178 .buffer={0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
179 1, 2, 3, 4, 5, 6, 7, 8, 9}};
180
181 r = Esys_NV_Write(esys_context,
182 nvHandle,
183 nvHandle,
184 ESYS_TR_PASSWORD,
185 ESYS_TR_NONE,
186 ESYS_TR_NONE,
187 &nv_test_data,
188 offset);
189 goto_if_error(r, "Error esys nv write", error);
190
191 TPM2B_DATA qualifyingData = {0};
192 TPMT_SIG_SCHEME inScheme = { .scheme = TPM2_ALG_NULL };
193
194 r = Esys_NV_Certify(
195 esys_context,
196 signHandle,
197 ESYS_TR_RH_OWNER,
198 nvHandle,
199 ESYS_TR_PASSWORD,
200 ESYS_TR_PASSWORD,
201 ESYS_TR_NONE,
202 &qualifyingData,
203 &inScheme,
204 20,
205 0,
206 &certifyInfo,
207 &signature);
208
209 if ((r == TPM2_RC_COMMAND_CODE) ||
210 (r == (TPM2_RC_COMMAND_CODE | TSS2_RESMGR_RC_LAYER)) ||
211 (r == (TPM2_RC_COMMAND_CODE | TSS2_RESMGR_TPM_RC_LAYER))) {
212 LOG_WARNING("Command TPM2_NV_Certify not supported by TPM.");
213 failure_return = EXIT_SKIP;
214 goto error;
215 }
216
217 goto_if_error(r, "Error: NV_Certify", error);
218
219 r = Esys_NV_UndefineSpace(esys_context,
220 ESYS_TR_RH_OWNER,
221 nvHandle,
222 ESYS_TR_PASSWORD,
223 ESYS_TR_NONE,
224 ESYS_TR_NONE
225 );
226 goto_if_error(r, "Error: NV_UndefineSpace", error);
227
228 r = Esys_FlushContext(esys_context,signHandle);
229 goto_if_error(r, "Error: FlushContext", error);
230
231 Esys_Free(outPublic);
232 Esys_Free(creationData);
233 Esys_Free(creationHash);
234 Esys_Free(creationTicket);
235 Esys_Free(certifyInfo);
236 Esys_Free(signature);
237 return EXIT_SUCCESS;
238
239 error:
240
241 if (signHandle != ESYS_TR_NONE) {
242 if (Esys_FlushContext(esys_context, signHandle) != TSS2_RC_SUCCESS) {
243 LOG_ERROR("Cleanup signHandle failed.");
244 }
245 }
246
247 if (nvHandle != ESYS_TR_NONE) {
248 if (Esys_NV_UndefineSpace(esys_context,
249 ESYS_TR_RH_OWNER,
250 nvHandle,
251 ESYS_TR_PASSWORD,
252 ESYS_TR_NONE,
253 ESYS_TR_NONE) != TSS2_RC_SUCCESS) {
254 LOG_ERROR("Cleanup nvHandle failed.");
255 }
256 }
257
258 Esys_Free(outPublic);
259 Esys_Free(creationData);
260 Esys_Free(creationHash);
261 Esys_Free(creationTicket);
262 Esys_Free(certifyInfo);
263 Esys_Free(signature);
264 return failure_return;
265 }
266
267 int
test_invoke_esapi(ESYS_CONTEXT * esys_context)268 test_invoke_esapi(ESYS_CONTEXT * esys_context) {
269 return test_esys_nv_certify(esys_context);
270 }
271