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 #include "tss2_mu.h"
15
16 #include "esys_iutil.h"
17 #include "test-esapi.h"
18 #define LOGMODULE test
19 #include "util/log.h"
20 #include "util/aux_util.h"
21
22 /** This test is intended to test the ESAPI commands Duplicate and Rewrap.
23 *
24 * We start by creating a primary key (Esys_CreatePrimary).
25 * This primary key will be used as parent key for the Duplicate
26 * command. A second primary key will be the parent key of the
27 * duplicated key. In the last step the key is rewrapped with the
28 * first primary key as parent key.
29 *
30 * Tested ESAPI commands:
31 * - Esys_Create() (M)
32 * - Esys_CreatePrimary() (M)
33 * - Esys_Duplicate() (M)
34 * - Esys_FlushContext() (M)
35 * - Esys_Load() (M)
36 * - Esys_PolicyAuthValue() (M)
37 * - Esys_PolicyCommandCode() (M)
38 * - Esys_PolicyGetDigest() (M)
39 * - Esys_ReadPublic() (M)
40 * - Esys_Rewrap() (O)
41 * - Esys_StartAuthSession() (M)
42 *
43 * @param[in,out] esys_context The ESYS_CONTEXT.
44 * @retval EXIT_FAILURE
45 * @retval EXIT_SKIP
46 * @retval EXIT_SUCCESS
47 */
48
49 int
test_esys_duplicate(ESYS_CONTEXT * esys_context)50 test_esys_duplicate(ESYS_CONTEXT * esys_context)
51 {
52 TSS2_RC r;
53 ESYS_TR primaryHandle = ESYS_TR_NONE;
54 ESYS_TR primaryHandle2 = ESYS_TR_NONE;
55 ESYS_TR loadedKeyHandle = ESYS_TR_NONE;
56 ESYS_TR policySession = ESYS_TR_NONE;
57 int failure_return = EXIT_FAILURE;
58
59 TPM2B_DIGEST *policyDigestTrial = NULL;
60 TPM2B_PUBLIC *outPublic = NULL;
61 TPM2B_CREATION_DATA *creationData = NULL;
62 TPM2B_DIGEST *creationHash = NULL;
63 TPMT_TK_CREATION *creationTicket = NULL;
64
65 TPM2B_PUBLIC *outPublic2 = NULL;
66 TPM2B_PRIVATE *outPrivate2 = NULL;
67 TPM2B_CREATION_DATA *creationData2 = NULL;
68 TPM2B_DIGEST *creationHash2 = NULL;
69 TPMT_TK_CREATION *creationTicket2 = NULL;
70
71 TPM2B_PUBLIC *keyPublic = NULL;
72 TPM2B_NAME *keyName = NULL;
73 TPM2B_NAME *keyQualifiedName = NULL;
74
75 TPM2B_DATA *encryptionKeyOut = NULL;
76 TPM2B_PRIVATE *duplicate = NULL;
77 TPM2B_ENCRYPTED_SECRET *outSymSeed = NULL;
78
79 TPM2B_PRIVATE *outDuplicate = NULL;
80 TPM2B_ENCRYPTED_SECRET *outSymSeed2 = NULL;
81
82 /*
83 * First the policy value to be able to use Esys_Duplicate for an object has to be
84 * determined with a policy trial session.
85 */
86 ESYS_TR sessionTrial = ESYS_TR_NONE;
87 TPMT_SYM_DEF symmetricTrial = {.algorithm = TPM2_ALG_AES,
88 .keyBits = {.aes = 128},
89 .mode = {.aes = TPM2_ALG_CFB}
90 };
91 TPM2B_NONCE nonceCallerTrial = {
92 .size = 20,
93 .buffer = {11, 12, 13, 14, 15, 16, 17, 18, 19, 11,
94 21, 22, 23, 24, 25, 26, 27, 28, 29, 30}
95 };
96
97 r = Esys_StartAuthSession(esys_context, ESYS_TR_NONE, ESYS_TR_NONE,
98 ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
99 &nonceCallerTrial,
100 TPM2_SE_TRIAL, &symmetricTrial, TPM2_ALG_SHA1,
101 &sessionTrial);
102 goto_if_error(r, "Error: During initialization of policy trial session", error);
103
104 r = Esys_PolicyAuthValue(esys_context,
105 sessionTrial,
106 ESYS_TR_NONE,
107 ESYS_TR_NONE,
108 ESYS_TR_NONE
109 );
110 goto_if_error(r, "Error: PolicyAuthValue", error);
111
112 r = Esys_PolicyCommandCode(esys_context,
113 sessionTrial,
114 ESYS_TR_NONE,
115 ESYS_TR_NONE,
116 ESYS_TR_NONE,
117 TPM2_CC_Duplicate
118 );
119 goto_if_error(r, "Error: PolicyCommandCode", error);
120
121 r = Esys_PolicyGetDigest(esys_context,
122 sessionTrial,
123 ESYS_TR_NONE,
124 ESYS_TR_NONE,
125 ESYS_TR_NONE,
126 &policyDigestTrial
127 );
128 goto_if_error(r, "Error: PolicyGetDigest", error);
129
130 TPM2B_AUTH authValuePrimary = {
131 .size = 5,
132 .buffer = {1, 2, 3, 4, 5}
133 };
134
135 TPM2B_SENSITIVE_CREATE inSensitivePrimary = {
136 .size = 0,
137 .sensitive = {
138 .userAuth = {
139 .size = 0,
140 .buffer = {0 },
141 },
142 .data = {
143 .size = 0,
144 .buffer = {0},
145 },
146 },
147 };
148
149 inSensitivePrimary.sensitive.userAuth = authValuePrimary;
150
151 TPM2B_PUBLIC inPublic = {
152 .size = 0,
153 .publicArea = {
154 .type = TPM2_ALG_RSA,
155 .nameAlg = TPM2_ALG_SHA1,
156 .objectAttributes = (TPMA_OBJECT_USERWITHAUTH |
157 TPMA_OBJECT_RESTRICTED |
158 TPMA_OBJECT_DECRYPT |
159 TPMA_OBJECT_FIXEDTPM |
160 TPMA_OBJECT_FIXEDPARENT |
161 TPMA_OBJECT_SENSITIVEDATAORIGIN),
162 .authPolicy = {
163 .size = 0,
164 },
165 .parameters.rsaDetail = {
166 .symmetric = {
167 .algorithm = TPM2_ALG_AES,
168 .keyBits.aes = 128,
169 .mode.aes = TPM2_ALG_CFB},
170 .scheme = {
171 .scheme = TPM2_ALG_NULL
172 },
173 .keyBits = 2048,
174 .exponent = 0,
175 },
176 .unique.rsa = {
177 .size = 0,
178 .buffer = {},
179 },
180 },
181 };
182 LOG_INFO("\nRSA key will be created.");
183 TPM2B_DATA outsideInfo = {
184 .size = 0,
185 .buffer = {},
186 };
187
188 TPML_PCR_SELECTION creationPCR = {
189 .count = 0,
190 };
191
192 TPM2B_AUTH authValue = {
193 .size = 0,
194 .buffer = {}
195 };
196
197 r = Esys_TR_SetAuth(esys_context, ESYS_TR_RH_OWNER, &authValue);
198 goto_if_error(r, "Error: TR_SetAuth", error);
199
200 RSRC_NODE_T *primaryHandle_node;
201
202 r = Esys_CreatePrimary(esys_context, ESYS_TR_RH_OWNER, ESYS_TR_PASSWORD,
203 ESYS_TR_NONE, ESYS_TR_NONE,
204 &inSensitivePrimary, &inPublic,
205 &outsideInfo, &creationPCR, &primaryHandle,
206 &outPublic, &creationData, &creationHash,
207 &creationTicket);
208 goto_if_error(r, "Error esys create primary", error);
209
210 Esys_Free(outPublic);
211 Esys_Free(creationData);
212 Esys_Free(creationHash);
213 Esys_Free(creationTicket);
214
215 r = Esys_CreatePrimary(esys_context, ESYS_TR_RH_OWNER, ESYS_TR_PASSWORD,
216 ESYS_TR_NONE, ESYS_TR_NONE,
217 &inSensitivePrimary, &inPublic,
218 &outsideInfo, &creationPCR, &primaryHandle2,
219 &outPublic, &creationData, &creationHash,
220 &creationTicket);
221 goto_if_error(r, "Error esys create primary", error);
222
223 r = esys_GetResourceObject(esys_context, primaryHandle,
224 &primaryHandle_node);
225 goto_if_error(r, "Error Esys GetResourceObject", error);
226
227 LOG_INFO("Created Primary with handle 0x%08x...",
228 primaryHandle_node->rsrc.handle);
229
230 r = Esys_TR_SetAuth(esys_context, primaryHandle, &authValuePrimary);
231 goto_if_error(r, "Error: TR_SetAuth", error);
232
233 TPM2B_AUTH authKey2 = {
234 .size = 6,
235 .buffer = {6, 7, 8, 9, 10, 11}
236 };
237
238 TPM2B_SENSITIVE_CREATE inSensitive2 = {
239 .size = 0,
240 .sensitive = {
241 .userAuth = {
242 .size = 0,
243 .buffer = {0}
244 },
245 .data = {
246 .size = 0,
247 .buffer = {}
248 }
249 }
250 };
251
252 inSensitive2.sensitive.userAuth = authKey2;
253
254 TPM2B_PUBLIC inPublic2 = {
255 .size = 0,
256 .publicArea = {
257 .type = TPM2_ALG_RSA,
258 .nameAlg = TPM2_ALG_SHA1,
259 .objectAttributes = (TPMA_OBJECT_USERWITHAUTH |
260 TPMA_OBJECT_RESTRICTED |
261 TPMA_OBJECT_DECRYPT |
262 TPMA_OBJECT_SENSITIVEDATAORIGIN),
263
264 .authPolicy = {
265 .size = 0,
266 },
267 .parameters.rsaDetail = {
268 .symmetric = {
269 .algorithm = TPM2_ALG_AES,
270 .keyBits.aes = 128,
271 .mode.aes = TPM2_ALG_CFB
272 },
273 .scheme = {
274 .scheme =
275 TPM2_ALG_NULL,
276 },
277 .keyBits = 2048,
278 .exponent = 0
279 },
280 .unique.rsa = {
281 .size = 0,
282 .buffer = {}
283 ,
284 }
285 }
286 };
287
288 TPM2B_DATA outsideInfo2 = {
289 .size = 0,
290 .buffer = {}
291 ,
292 };
293
294 TPML_PCR_SELECTION creationPCR2 = {
295 .count = 0,
296 };
297
298 inPublic2.publicArea.authPolicy = *policyDigestTrial;
299
300 r = Esys_Create(esys_context,
301 primaryHandle,
302 ESYS_TR_PASSWORD, ESYS_TR_NONE, ESYS_TR_NONE,
303 &inSensitive2,
304 &inPublic2,
305 &outsideInfo2,
306 &creationPCR2,
307 &outPrivate2,
308 &outPublic2,
309 &creationData2, &creationHash2, &creationTicket2);
310 goto_if_error(r, "Error esys create ", error);
311
312 LOG_INFO("\nSecond key created.");
313
314 r = Esys_Load(esys_context,
315 primaryHandle,
316 ESYS_TR_PASSWORD,
317 ESYS_TR_NONE,
318 ESYS_TR_NONE, outPrivate2, outPublic2, &loadedKeyHandle);
319 goto_if_error(r, "Error esys load ", error);
320
321 LOG_INFO("\nSecond Key loaded.");
322
323 r = Esys_TR_SetAuth(esys_context, loadedKeyHandle, &authKey2);
324 goto_if_error(r, "Error esys TR_SetAuth ", error);
325
326 r = Esys_ReadPublic(esys_context,
327 loadedKeyHandle,
328 ESYS_TR_NONE,
329 ESYS_TR_NONE,
330 ESYS_TR_NONE,
331 &keyPublic,
332 &keyName,
333 &keyQualifiedName);
334
335 goto_if_error(r, "Error esys ReadPublic", error);
336
337 TPMT_SYM_DEF policySymmetric = {.algorithm = TPM2_ALG_AES,
338 .keyBits = {.aes = 128},
339 .mode = {.aes = TPM2_ALG_CFB}
340 };
341 TPM2B_NONCE policyNonceCaller = {
342 .size = 20,
343 .buffer = {11, 12, 13, 14, 15, 16, 17, 18, 19, 11,
344 21, 22, 23, 24, 25, 26, 27, 28, 29, 30}
345 };
346
347 r = Esys_StartAuthSession(esys_context, ESYS_TR_NONE, ESYS_TR_NONE,
348 ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
349 &policyNonceCaller,
350 TPM2_SE_POLICY, &policySymmetric, TPM2_ALG_SHA1,
351 &policySession);
352 goto_if_error(r, "Error: During initialization of policy trial session", error);
353
354
355 r = Esys_PolicyAuthValue(esys_context,
356 policySession,
357 ESYS_TR_NONE,
358 ESYS_TR_NONE,
359 ESYS_TR_NONE
360 );
361 goto_if_error(r, "Error: PolicyAuthValue", error);
362
363 r = Esys_PolicyCommandCode(esys_context,
364 policySession,
365 ESYS_TR_NONE,
366 ESYS_TR_NONE,
367 ESYS_TR_NONE,
368 TPM2_CC_Duplicate
369 );
370 goto_if_error(r, "Error: PolicyCommandCode", error);
371
372 TPM2B_DATA encryptionKey = {
373 .size = 16,
374 .buffer = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
375 11, 12, 13, 14, 15, 16 }
376 };
377
378 TPMT_SYM_DEF_OBJECT symmetric = {.algorithm = TPM2_ALG_AES,
379 .keyBits = {.aes = 128},
380 .mode = {.aes = TPM2_ALG_CFB}};
381
382 r = Esys_Duplicate(
383 esys_context,
384 loadedKeyHandle,
385 primaryHandle2,
386 policySession,
387 ESYS_TR_NONE,
388 ESYS_TR_NONE,
389 &encryptionKey,
390 &symmetric,
391 &encryptionKeyOut,
392 &duplicate,
393 &outSymSeed);
394
395 goto_if_error(r, "Error: Duplicate", error);
396
397 r = Esys_Rewrap(esys_context,
398 primaryHandle2,
399 primaryHandle,
400 ESYS_TR_PASSWORD, ESYS_TR_NONE, ESYS_TR_NONE,
401 duplicate,
402 keyName,
403 outSymSeed,
404 &outDuplicate,
405 &outSymSeed2);
406
407 if ((r == TPM2_RC_COMMAND_CODE) ||
408 (r == (TPM2_RC_COMMAND_CODE | TSS2_RESMGR_RC_LAYER)) ||
409 (r == (TPM2_RC_COMMAND_CODE | TSS2_RESMGR_TPM_RC_LAYER))) {
410 LOG_WARNING("Command TPM2_Rewrap not supported by TPM.");
411 failure_return = EXIT_SKIP;
412 goto error;
413 }
414
415 goto_if_error(r, "Error: Rewrap", error);
416
417 r = Esys_FlushContext(esys_context, primaryHandle);
418 goto_if_error(r, "Flushing context", error);
419
420 primaryHandle = ESYS_TR_NONE;
421
422 r = Esys_FlushContext(esys_context, primaryHandle2);
423 goto_if_error(r, "Flushing context", error);
424
425 primaryHandle2 = ESYS_TR_NONE;
426
427 r = Esys_FlushContext(esys_context, loadedKeyHandle);
428 goto_if_error(r, "Flushing context", error);
429
430 loadedKeyHandle = ESYS_TR_NONE;
431
432 r = Esys_FlushContext(esys_context, sessionTrial);
433 goto_if_error(r, "Flushing context", error);
434
435 r = Esys_FlushContext(esys_context, policySession);
436 goto_if_error(r, "Flushing context", error);
437
438 Esys_Free(policyDigestTrial);
439 Esys_Free(outPublic);
440 Esys_Free(creationData);
441 Esys_Free(creationHash);
442 Esys_Free(creationTicket);
443 Esys_Free(outPublic2);
444 Esys_Free(outPrivate2);
445 Esys_Free(creationData2);
446 Esys_Free(creationHash2);
447 Esys_Free(creationTicket2);
448 Esys_Free(keyPublic);
449 Esys_Free(keyName);
450 Esys_Free(keyQualifiedName);
451 Esys_Free(encryptionKeyOut);
452 Esys_Free(duplicate);
453 Esys_Free(outSymSeed);
454 Esys_Free(outDuplicate);
455 Esys_Free(outSymSeed2);
456 return EXIT_SUCCESS;
457
458 error:
459
460 if (policySession != ESYS_TR_NONE) {
461 if (Esys_FlushContext(esys_context, policySession) != TSS2_RC_SUCCESS) {
462 LOG_ERROR("Cleanup policySession failed.");
463 }
464 }
465
466 if (sessionTrial != ESYS_TR_NONE) {
467 if (Esys_FlushContext(esys_context, sessionTrial) != TSS2_RC_SUCCESS) {
468 LOG_ERROR("Cleanup sessionTrial failed.");
469 }
470 }
471
472 if (loadedKeyHandle != ESYS_TR_NONE) {
473 if (Esys_FlushContext(esys_context, loadedKeyHandle) != TSS2_RC_SUCCESS) {
474 LOG_ERROR("Cleanup loadedKeyHandle failed.");
475 }
476 }
477
478 if (primaryHandle != ESYS_TR_NONE) {
479 if (Esys_FlushContext(esys_context, primaryHandle) != TSS2_RC_SUCCESS) {
480 LOG_ERROR("Cleanup primaryHandle failed.");
481 }
482 }
483
484 if (primaryHandle2 != ESYS_TR_NONE) {
485 if (Esys_FlushContext(esys_context, primaryHandle2) != TSS2_RC_SUCCESS) {
486 LOG_ERROR("Cleanup primaryHandle2 failed.");
487 }
488 }
489
490 Esys_Free(policyDigestTrial);
491 Esys_Free(outPublic);
492 Esys_Free(creationData);
493 Esys_Free(creationHash);
494 Esys_Free(creationTicket);
495 Esys_Free(outPublic2);
496 Esys_Free(outPrivate2);
497 Esys_Free(creationData2);
498 Esys_Free(creationHash2);
499 Esys_Free(creationTicket2);
500 Esys_Free(keyPublic);
501 Esys_Free(keyName);
502 Esys_Free(keyQualifiedName);
503 Esys_Free(encryptionKeyOut);
504 Esys_Free(duplicate);
505 Esys_Free(outSymSeed);
506 Esys_Free(outDuplicate);
507 Esys_Free(outSymSeed2);
508 return failure_return;
509 }
510
511 int
test_invoke_esapi(ESYS_CONTEXT * esys_context)512 test_invoke_esapi(ESYS_CONTEXT * esys_context) {
513 return test_esys_duplicate(esys_context);
514 }
515