xref: /aosp_15_r20/external/tpm2-tss/test/integration/esys-duplicate.int.c (revision 758e9fba6fc9adbf15340f70c73baee7b168b1c9)
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