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 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9 
10 #include <stdlib.h>
11 
12 #include "tss2_esys.h"
13 
14 #include "esys_iutil.h"
15 #define LOGMODULE test
16 #include "util/log.h"
17 #include "util/aux_util.h"
18 
19 /** This tests the Esys_TR_FromTPMPublic and Esys_TR_GetName functions by
20  *  creating an NV Index and then attempting to retrieve an ESYS_TR object for
21  *  it.
22  *  Then we call Esys_TR_GetName to see if the correct public name has been
23  * retrieved.
24  *
25  * Tested ESAPI commands:
26  *  - Esys_CreatePrimary() (M)
27  *  - Esys_EvictControl() (M)
28  *  - Esys_FlushContext() (M)
29  *  - Esys_ReadPublic() (M)
30  *
31  * @param[in,out] ectx The ESYS_CONTEXT.
32  * @retval EXIT_FAILURE
33  * @retval EXIT_SUCCESS
34  */
35 
36 int
test_esys_tr_fromTpmPublic_key(ESYS_CONTEXT * ectx)37 test_esys_tr_fromTpmPublic_key(ESYS_CONTEXT * ectx)
38 {
39     TSS2_RC r;
40     ESYS_TR primaryHandle = ESYS_TR_NONE;
41     ESYS_TR keyHandle = ESYS_TR_NONE;
42 
43     TPM2B_NAME *name1, *name2;
44 
45     TPM2B_AUTH authValuePrimary = {
46         .size = 5,
47         .buffer = {1, 2, 3, 4, 5}
48     };
49 
50     TPM2B_SENSITIVE_CREATE inSensitivePrimary = {
51         .size = 0,
52         .sensitive = {
53             .userAuth = {
54                  .size = 0,
55                  .buffer = {0 },
56              },
57             .data = {
58                  .size = 0,
59                  .buffer = {0},
60              },
61         },
62     };
63 
64     inSensitivePrimary.sensitive.userAuth = authValuePrimary;
65 
66     TPM2B_PUBLIC inPublic = {
67         .size = 0,
68         .publicArea = {
69             .type = TPM2_ALG_RSA,
70             .nameAlg = TPM2_ALG_SHA256,
71             .objectAttributes = (TPMA_OBJECT_USERWITHAUTH |
72                                  TPMA_OBJECT_RESTRICTED |
73                                  TPMA_OBJECT_DECRYPT |
74                                  TPMA_OBJECT_FIXEDTPM |
75                                  TPMA_OBJECT_FIXEDPARENT |
76                                  TPMA_OBJECT_SENSITIVEDATAORIGIN),
77             .authPolicy = {
78                  .size = 0,
79              },
80             .parameters.rsaDetail = {
81                  .symmetric = {
82                      .algorithm = TPM2_ALG_AES,
83                      .keyBits.aes = 128,
84                      .mode.aes = TPM2_ALG_CFB},
85                  .scheme = {
86                       .scheme = TPM2_ALG_NULL
87                   },
88                  .keyBits = 2048,
89                  .exponent = 0,
90              },
91             .unique.rsa = {
92                  .size = 0,
93                  .buffer = {},
94              },
95         },
96     };
97     LOG_INFO("\nRSA key will be created.");
98 
99     TPM2B_DATA outsideInfo = {
100         .size = 0,
101         .buffer = {},
102     };
103 
104     TPML_PCR_SELECTION creationPCR = {
105         .count = 0,
106     };
107 
108     r = Esys_CreatePrimary(ectx, ESYS_TR_RH_OWNER,
109                            ESYS_TR_PASSWORD, ESYS_TR_NONE, ESYS_TR_NONE,
110                            &inSensitivePrimary, &inPublic, &outsideInfo,
111                            &creationPCR,
112                            &primaryHandle, NULL, NULL, NULL, NULL);
113     goto_if_error(r, "Create primary", error);
114 
115     r = Esys_ReadPublic(ectx, primaryHandle,
116                         ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
117                         NULL, &name1, NULL);
118     goto_if_error(r, "Read Public", error);
119 
120     r = Esys_EvictControl(ectx, ESYS_TR_RH_OWNER, primaryHandle,
121                           ESYS_TR_PASSWORD, ESYS_TR_NONE, ESYS_TR_NONE,
122                           TPM2_PERSISTENT_FIRST, &keyHandle);
123     goto_if_error(r, "EvictControl make persistent", error_name1);
124 
125     r = Esys_FlushContext(ectx, primaryHandle);
126     goto_if_error(r, "Flushing primary", error_name1);
127 
128     r = Esys_TR_Close(ectx, &keyHandle);
129     goto_if_error(r, "TR close on nv object", error_name1);
130 
131     r = Esys_TR_FromTPMPublic(ectx, TPM2_PERSISTENT_FIRST,
132                               ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
133                               &keyHandle);
134     goto_if_error(r, "TR from TPM public", error_name1);
135 
136     r = Esys_TR_GetName(ectx, keyHandle, &name2);
137     goto_if_error(r, "TR get name", error_name1);
138 
139     r = Esys_EvictControl(ectx, ESYS_TR_RH_OWNER, keyHandle,
140                           ESYS_TR_PASSWORD, ESYS_TR_NONE, ESYS_TR_NONE,
141                           TPM2_PERSISTENT_FIRST, &keyHandle);
142     goto_if_error(r, "EvictControl delete", error_name2);
143 
144     if (name1->size != name2->size ||
145         memcmp(&name1->name[0], &name2->name[0], name1->size) != 0)
146     {
147         LOG_ERROR("Names mismatch between NV_GetPublic and TR_GetName");
148         goto error_name2;
149     }
150 
151     free(name1);
152     free(name2);
153 
154     return EXIT_SUCCESS;
155 
156 error_name2:
157     free(name2);
158 error_name1:
159     free(name1);
160 error:
161 
162     if (keyHandle != ESYS_TR_NONE) {
163         if (Esys_EvictControl(ectx, ESYS_TR_RH_OWNER, keyHandle,
164                               ESYS_TR_PASSWORD, ESYS_TR_NONE, ESYS_TR_NONE,
165                               TPM2_PERSISTENT_FIRST, &keyHandle) != TSS2_RC_SUCCESS) {
166             LOG_ERROR("Cleanup: EvictControl delete");
167         }
168     }
169 
170     if (primaryHandle != ESYS_TR_NONE) {
171         if (Esys_FlushContext(ectx, primaryHandle) != TSS2_RC_SUCCESS) {
172             LOG_ERROR("Cleanup primaryHandle failed.");
173         }
174     }
175 
176     return EXIT_FAILURE;
177 }
178 
179 int
test_invoke_esapi(ESYS_CONTEXT * esys_context)180 test_invoke_esapi(ESYS_CONTEXT * esys_context) {
181     return test_esys_tr_fromTpmPublic_key(esys_context);
182 }
183