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 #define LOGMODULE test
17 #include "util/log.h"
18 #include "util/aux_util.h"
19
20 /** This test is intended to test context save and load.
21 *
22 * We start by creating a primary key (Esys_CreatePrimary).
23 * Based in the primary a second key with an password define in the sensitive
24 * area will be created.
25 * This key will be loaded and saved with the ContextSave command.
26 * After the key is flushed the key will be loaded again with ContextLoad
27 * and will be used to create a third key
28 *
29 * Tested ESAPI commands:
30 * - Esys_ContextLoad() (M)
31 * - Esys_ContextSave() (M)
32 * - Esys_Create() (M)
33 * - Esys_CreatePrimary() (M)
34 * - Esys_FlushContext() (M)
35 * - Esys_Load() (M)
36 *
37 * Used compiler defines: TEST_ECC
38 *
39 * @param[in,out] esys_context The ESYS_CONTEXT.
40 * @retval EXIT_FAILURE
41 * @retval EXIT_SUCCESS
42 */
43
44 int
test_esys_save_and_load_context(ESYS_CONTEXT * esys_context)45 test_esys_save_and_load_context(ESYS_CONTEXT * esys_context)
46 {
47 TSS2_RC r;
48 ESYS_TR primaryHandle = ESYS_TR_NONE;
49 ESYS_TR loadedKeyHandle1 = ESYS_TR_NONE;
50 ESYS_TR loadedKeyHandle2 = ESYS_TR_NONE;
51
52 TPM2B_PUBLIC *outPublic = NULL;
53 TPM2B_CREATION_DATA *creationData = NULL;
54 TPM2B_DIGEST *creationHash = NULL;
55 TPMT_TK_CREATION *creationTicket = NULL;
56
57 TPM2B_PUBLIC *outPublic2 = NULL;
58 TPM2B_PRIVATE *outPrivate2 = NULL;
59 TPM2B_CREATION_DATA *creationData2 = NULL;
60 TPM2B_DIGEST *creationHash2 = NULL;
61 TPMT_TK_CREATION *creationTicket2 = NULL;
62
63 TPMS_CONTEXT *context = NULL;
64
65 TPM2B_AUTH authValuePrimary = {
66 .size = 5,
67 .buffer = {1, 2, 3, 4, 5}
68 };
69
70 TPM2B_SENSITIVE_CREATE inSensitivePrimary = {
71 .size = 0,
72 .sensitive = {
73 .userAuth = {
74 .size = 0,
75 .buffer = {0 },
76 },
77 .data = {
78 .size = 0,
79 .buffer = {0},
80 },
81 },
82 };
83
84 inSensitivePrimary.sensitive.userAuth = authValuePrimary;
85
86 #ifdef TEST_ECC
87 TPM2B_PUBLIC inPublic = {
88 .size = 0,
89 .publicArea = {
90 .type = TPM2_ALG_ECC,
91 .nameAlg = TPM2_ALG_SHA256,
92 .objectAttributes = (TPMA_OBJECT_USERWITHAUTH |
93 TPMA_OBJECT_RESTRICTED |
94 TPMA_OBJECT_SIGN_ENCRYPT |
95 TPMA_OBJECT_FIXEDTPM |
96 TPMA_OBJECT_FIXEDPARENT |
97 TPMA_OBJECT_SENSITIVEDATAORIGIN),
98 .authPolicy = {
99 .size = 0,
100 },
101 .parameters.eccDetail = {
102 .symmetric = {
103 .algorithm = TPM2_ALG_NULL,
104 .keyBits.aes = 128,
105 .mode.aes = TPM2_ALG_CFB,
106 },
107 .scheme = {
108 .scheme = TPM2_ALG_ECDSA,
109 .details = {
110 .ecdsa = {.hashAlg = TPM2_ALG_SHA256}},
111 },
112 .curveID = TPM2_ECC_NIST_P256,
113 .kdf = {
114 .scheme = TPM2_ALG_NULL,
115 .details = {}}
116 },
117 .unique.ecc = {
118 .x = {.size = 0,.buffer = {}},
119 .y = {.size = 0,.buffer = {}},
120 },
121 },
122 };
123 LOG_INFO("\nECC key will be created.");
124 #else
125 TPM2B_PUBLIC inPublic = {
126 .size = 0,
127 .publicArea = {
128 .type = TPM2_ALG_RSA,
129 .nameAlg = TPM2_ALG_SHA256,
130 .objectAttributes = (TPMA_OBJECT_USERWITHAUTH |
131 TPMA_OBJECT_RESTRICTED |
132 TPMA_OBJECT_DECRYPT |
133 TPMA_OBJECT_FIXEDTPM |
134 TPMA_OBJECT_FIXEDPARENT |
135 TPMA_OBJECT_SENSITIVEDATAORIGIN),
136 .authPolicy = {
137 .size = 0,
138 },
139 .parameters.rsaDetail = {
140 .symmetric = {
141 .algorithm = TPM2_ALG_AES,
142 .keyBits.aes = 128,
143 .mode.aes = TPM2_ALG_CFB},
144 .scheme = {
145 .scheme = TPM2_ALG_NULL
146 },
147 .keyBits = 2048,
148 .exponent = 0,
149 },
150 .unique.rsa = {
151 .size = 0,
152 .buffer = {},
153 },
154 },
155 };
156 LOG_INFO("\nRSA key will be created.");
157 #endif /* TEST_ECC */
158
159 TPM2B_DATA outsideInfo = {
160 .size = 0,
161 .buffer = {},
162 };
163
164 TPML_PCR_SELECTION creationPCR = {
165 .count = 0,
166 };
167
168 TPM2B_AUTH authValue = {
169 .size = 0,
170 .buffer = {}
171 };
172
173 r = Esys_TR_SetAuth(esys_context, ESYS_TR_RH_OWNER, &authValue);
174 goto_if_error(r, "Error: TR_SetAuth", error);
175
176 RSRC_NODE_T *primaryHandle_node;
177
178 r = Esys_CreatePrimary(esys_context, ESYS_TR_RH_OWNER, ESYS_TR_PASSWORD,
179 ESYS_TR_NONE, ESYS_TR_NONE, &inSensitivePrimary, &inPublic,
180 &outsideInfo, &creationPCR, &primaryHandle,
181 &outPublic, &creationData, &creationHash,
182 &creationTicket);
183 goto_if_error(r, "Error esys create primary", error);
184
185 r = esys_GetResourceObject(esys_context, primaryHandle,
186 &primaryHandle_node);
187 goto_if_error(r, "Error Esys GetResourceObject", error);
188
189 LOG_INFO("Created Primary with handle 0x%08x...",
190 primaryHandle_node->rsrc.handle);
191
192 r = Esys_TR_SetAuth(esys_context, primaryHandle, &authValuePrimary);
193 goto_if_error(r, "Error: TR_SetAuth", error);
194
195 TPM2B_AUTH authKey2 = {
196 .size = 6,
197 .buffer = {6, 7, 8, 9, 10, 11}
198 };
199
200 TPM2B_SENSITIVE_CREATE inSensitive2 = {
201 .size = 0,
202 .sensitive = {
203 .userAuth = {
204 .size = 0,
205 .buffer = {0}
206 },
207 .data = {
208 .size = 0,
209 .buffer = {}
210 }
211 }
212 };
213
214 inSensitive2.sensitive.userAuth = authKey2;
215
216 TPM2B_SENSITIVE_CREATE inSensitive3 = {
217 .size = 0,
218 .sensitive = {
219 .userAuth = {
220 .size = 0,
221 .buffer = {}
222 },
223 .data = {
224 .size = 0,
225 .buffer = {}
226 }
227 }
228 };
229
230 TPM2B_PUBLIC inPublic2 = {
231 .size = 0,
232 .publicArea = {
233 .type = TPM2_ALG_RSA,
234 .nameAlg = TPM2_ALG_SHA256,
235 .objectAttributes = (TPMA_OBJECT_USERWITHAUTH |
236 TPMA_OBJECT_RESTRICTED |
237 TPMA_OBJECT_DECRYPT |
238 TPMA_OBJECT_FIXEDTPM |
239 TPMA_OBJECT_FIXEDPARENT |
240 TPMA_OBJECT_SENSITIVEDATAORIGIN),
241
242 .authPolicy = {
243 .size = 0,
244 },
245 .parameters.rsaDetail = {
246 .symmetric = {
247 .algorithm = TPM2_ALG_AES,
248 .keyBits.aes = 128,
249 .mode.aes = TPM2_ALG_CFB
250 },
251 .scheme = {
252 .scheme =
253 TPM2_ALG_NULL,
254 },
255 .keyBits = 2048,
256 .exponent = 0
257 },
258 .unique.rsa = {
259 .size = 0,
260 .buffer = {}
261 ,
262 }
263 }
264 };
265
266 TPM2B_DATA outsideInfo2 = {
267 .size = 0,
268 .buffer = {}
269 ,
270 };
271
272 TPML_PCR_SELECTION creationPCR2 = {
273 .count = 0,
274 };
275
276 r = Esys_Create(esys_context,
277 primaryHandle,
278 ESYS_TR_PASSWORD, ESYS_TR_NONE, ESYS_TR_NONE,
279 &inSensitive2,
280 &inPublic2,
281 &outsideInfo2,
282 &creationPCR2,
283 &outPrivate2,
284 &outPublic2,
285 &creationData2, &creationHash2, &creationTicket2);
286 goto_if_error(r, "Error esys create ", error);
287
288 LOG_INFO("\nSecond key created.");
289
290 r = Esys_Load(esys_context,
291 primaryHandle,
292 ESYS_TR_PASSWORD,
293 ESYS_TR_NONE,
294 ESYS_TR_NONE, outPrivate2, outPublic2, &loadedKeyHandle1);
295 goto_if_error(r, "Error esys load ", error);
296
297 Esys_Free(outPublic2);
298 Esys_Free(outPrivate2);
299 Esys_Free(creationData2);
300 Esys_Free(creationHash2);
301 Esys_Free(creationTicket2);
302
303 LOG_INFO("\nSecond Key loaded.");
304
305 r = Esys_ContextSave(esys_context, loadedKeyHandle1, &context);
306 goto_if_error(r, "Error esys context save", error);
307
308 r = Esys_FlushContext(esys_context, loadedKeyHandle1);
309 goto_if_error(r, "Error esys flush context", error);
310
311 loadedKeyHandle1 = ESYS_TR_NONE;
312
313 r = Esys_ContextLoad(esys_context, context, &loadedKeyHandle2);
314 goto_if_error(r, "Error esys context load", error);
315
316 r = Esys_TR_SetAuth(esys_context, loadedKeyHandle2, &authKey2);
317 goto_if_error(r, "Error esys TR_SetAuth ", error);
318
319 r = Esys_Create(esys_context,
320 loadedKeyHandle2,
321 ESYS_TR_PASSWORD, ESYS_TR_NONE, ESYS_TR_NONE,
322 &inSensitive3,
323 &inPublic2,
324 &outsideInfo2,
325 &creationPCR2,
326 &outPrivate2,
327 &outPublic2,
328 &creationData2, &creationHash2, &creationTicket2);
329 goto_if_error(r, "Error esys second create ", error);
330
331 r = Esys_FlushContext(esys_context, primaryHandle);
332 goto_if_error(r, "Error: FlushContext", error);
333
334 primaryHandle = ESYS_TR_NONE;
335
336 r = Esys_FlushContext(esys_context, loadedKeyHandle2);
337 goto_if_error(r, "Error: FlushContext", error);
338
339 Esys_Free(outPublic);
340 Esys_Free(creationData);
341 Esys_Free(creationHash);
342 Esys_Free(creationTicket);
343
344 Esys_Free(outPublic2);
345 Esys_Free(outPrivate2);
346 Esys_Free(creationData2);
347 Esys_Free(creationHash2);
348 Esys_Free(creationTicket2);
349
350 Esys_Free(context);
351 return EXIT_SUCCESS;
352
353 error:
354
355 if (loadedKeyHandle1 != ESYS_TR_NONE) {
356 if (Esys_FlushContext(esys_context, loadedKeyHandle1) != TSS2_RC_SUCCESS) {
357 LOG_ERROR("Cleanup loadedKeyHandle1 failed.");
358 }
359 }
360
361 if (loadedKeyHandle2 != ESYS_TR_NONE) {
362 if (Esys_FlushContext(esys_context, loadedKeyHandle2) != TSS2_RC_SUCCESS) {
363 LOG_ERROR("Cleanup loadedKeyHandle2 failed.");
364 }
365 }
366
367 if (primaryHandle != ESYS_TR_NONE) {
368 if (Esys_FlushContext(esys_context, primaryHandle) != TSS2_RC_SUCCESS) {
369 LOG_ERROR("Cleanup primaryHandle failed.");
370 }
371 }
372
373 Esys_Free(outPublic);
374 Esys_Free(creationData);
375 Esys_Free(creationHash);
376 Esys_Free(creationTicket);
377
378 Esys_Free(outPublic2);
379 Esys_Free(outPrivate2);
380 Esys_Free(creationData2);
381 Esys_Free(creationHash2);
382 Esys_Free(creationTicket2);
383
384 Esys_Free(context);
385 return EXIT_FAILURE;
386 }
387
388 int
test_invoke_esapi(ESYS_CONTEXT * esys_context)389 test_invoke_esapi(ESYS_CONTEXT * esys_context) {
390 return test_esys_save_and_load_context(esys_context);
391 }
392