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 <stdbool.h>
12 #include <stdlib.h>
13
14 #include "tss2_esys.h"
15 #include "tss2_mu.h"
16
17 #include "esys_iutil.h"
18 #include "test-esapi.h"
19 #define LOGMODULE test
20 #include "util/log.h"
21 #include "util/aux_util.h"
22
check_name(ESYS_CONTEXT * esys_context,ESYS_TR object_handle)23 static bool check_name(ESYS_CONTEXT * esys_context, ESYS_TR object_handle)
24 {
25 bool result = false;
26
27 TPM2B_NAME *read_name = NULL;
28 TPM2B_NAME *get_name = NULL;
29
30 TSS2_RC r = Esys_ReadPublic(esys_context, object_handle,
31 ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
32 NULL, &read_name, NULL);
33 goto_if_error(r, "Error esys readpublic", out);
34
35 r = Esys_TR_GetName(esys_context, object_handle, &get_name);
36 goto_if_error(r, "Error esys getname", out);
37
38 if (read_name->size != get_name->size) {
39 LOG_ERROR("name size mismatch %u != %u",
40 read_name->size, get_name->size);
41 goto out;
42 }
43
44 result = memcmp(read_name->name, get_name->name, get_name->size) == 0;
45
46 out:
47 Esys_Free(read_name);
48 Esys_Free(get_name);
49
50 return result;
51 }
52 /** This test is intended to test the ESAPI command CreateLoaded.
53 *
54 * We start by creating a primary key (Esys_CreatePrimary).
55 * This primary key will be used as parent key for CreateLoaded.
56 *
57 * Tested ESAPI commands:
58 * - Esys_CreateLoaded() (F)
59 * - Esys_CreatePrimary() (M)
60 * - Esys_FlushContext() (M)
61 * - Esys_StartAuthSession() (M)
62 * - Esys_TR_GetName() (M)
63 * - Esys_TR_ReadPublic() (M)
64 *
65 * Used compiler defines: TEST_SESSION
66 *
67 * @param[in,out] esys_context The ESYS_CONTEXT.
68 * @retval EXIT_FAILURE
69 * @retval EXIT_SKIP
70 * @retval EXIT_SUCCESS
71 */
72
73 int
test_esys_createloaded(ESYS_CONTEXT * esys_context)74 test_esys_createloaded(ESYS_CONTEXT * esys_context)
75 {
76
77 TSS2_RC r;
78 ESYS_TR primaryHandle = ESYS_TR_NONE;
79 ESYS_TR objectHandle = ESYS_TR_NONE;
80 int failure_return = EXIT_FAILURE;
81
82 TPM2B_PUBLIC *outPublic = NULL;
83 TPM2B_CREATION_DATA *creationData = NULL;
84 TPM2B_DIGEST *creationHash = NULL;
85 TPMT_TK_CREATION *creationTicket = NULL;
86 TPM2B_PRIVATE *outPrivate2 = NULL;
87 TPM2B_PUBLIC *outPublic2 = NULL;
88
89 #ifdef TEST_SESSION
90 ESYS_TR session = ESYS_TR_NONE;
91 TPMT_SYM_DEF symmetric = {.algorithm = TPM2_ALG_AES,
92 .keyBits = {.aes = 128},
93 .mode = {.aes = TPM2_ALG_CFB}
94 };
95 TPMA_SESSION sessionAttributes;
96 TPM2B_NONCE nonceCaller = {
97 .size = 20,
98 .buffer = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
99 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}
100 };
101
102 memset(&sessionAttributes, 0, sizeof sessionAttributes);
103
104 r = Esys_StartAuthSession(esys_context, ESYS_TR_NONE, ESYS_TR_NONE,
105 ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
106 &nonceCaller,
107 TPM2_SE_HMAC, &symmetric, TPM2_ALG_SHA1,
108 &session);
109
110 goto_if_error(r, "Error: During initialization of session", error);
111 #endif /* TEST_SESSION */
112
113 TPM2B_PUBLIC inPublic = {
114 .size = 0,
115 .publicArea = {
116 .type = TPM2_ALG_RSA,
117 .nameAlg = TPM2_ALG_SHA256,
118 .objectAttributes = (TPMA_OBJECT_USERWITHAUTH |
119 TPMA_OBJECT_RESTRICTED |
120 TPMA_OBJECT_DECRYPT |
121 TPMA_OBJECT_FIXEDTPM |
122 TPMA_OBJECT_FIXEDPARENT |
123 TPMA_OBJECT_SENSITIVEDATAORIGIN),
124 .authPolicy = {
125 .size = 0,
126 },
127 .parameters.rsaDetail = {
128 .symmetric = {
129 .algorithm = TPM2_ALG_AES,
130 .keyBits.aes = 128,
131 .mode.aes = TPM2_ALG_CFB},
132 .scheme = {
133 .scheme = TPM2_ALG_NULL
134 },
135 .keyBits = 2048,
136 .exponent = 0,
137 },
138 .unique.rsa = {
139 .size = 0,
140 .buffer = {},
141 },
142 },
143 };
144
145 TPM2B_AUTH authValuePrimary = {
146 .size = 5,
147 .buffer = {1, 2, 3, 4, 5}
148 };
149
150 TPM2B_SENSITIVE_CREATE inSensitivePrimary = {
151 .size = 0,
152 .sensitive = {
153 .userAuth = authValuePrimary,
154 .data = {
155 .size = 0,
156 .buffer = {0},
157 },
158 },
159 };
160
161 TPM2B_DATA outsideInfo = {
162 .size = 0,
163 .buffer = {},
164 };
165
166 TPML_PCR_SELECTION creationPCR = {
167 .count = 0,
168 };
169
170 TPM2B_AUTH authValue = {
171 .size = 0,
172 .buffer = {}
173 };
174
175 r = Esys_TR_SetAuth(esys_context, ESYS_TR_RH_OWNER, &authValue);
176 goto_if_error(r, "Error: TR_SetAuth", error);
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_TR_SetAuth(esys_context, primaryHandle, &authValuePrimary);
186 goto_if_error(r, "Setting the Primary's AuthValue", error);
187
188 TPM2B_AUTH authValueObject = {
189 .size = 5,
190 .buffer = {6, 7, 8, 9, 10}
191 };
192
193 TPM2B_SENSITIVE_CREATE inSensitiveObject = {
194 .size = 0,
195 .sensitive = {
196 .userAuth = authValueObject,
197 .data = {
198 .size = 0,
199 .buffer = {0},
200 },
201 },
202 };
203
204 TPM2B_TEMPLATE inPublic_template = {0};
205 TPMT_PUBLIC inPublic2 = {
206 .type = TPM2_ALG_ECC,
207 .nameAlg = TPM2_ALG_SHA256,
208 .objectAttributes = (TPMA_OBJECT_USERWITHAUTH |
209 TPMA_OBJECT_RESTRICTED |
210 TPMA_OBJECT_SIGN_ENCRYPT |
211 TPMA_OBJECT_FIXEDTPM |
212 TPMA_OBJECT_FIXEDPARENT |
213 TPMA_OBJECT_SENSITIVEDATAORIGIN),
214 .authPolicy = {
215 .size = 0,
216 },
217 .parameters.eccDetail = {
218 .symmetric = {
219 .algorithm = TPM2_ALG_NULL,
220 .keyBits.aes = 128,
221 .mode.aes = TPM2_ALG_CFB,
222 },
223 .scheme = {
224 .scheme = TPM2_ALG_ECDSA,
225 .details = {.ecdsa =
226 {.hashAlg = TPM2_ALG_SHA1}
227 }
228 },
229 .curveID = TPM2_ECC_NIST_P256,
230 .kdf = {.scheme =
231 TPM2_ALG_NULL,.details = {}
232 }
233 },
234 .unique.ecc = {
235 .x = {.size = 0,.buffer = {}},
236 .y = {.size = 0,.buffer = {}}
237 },
238 };
239
240 size_t offset = 0;
241
242 r = Tss2_MU_TPMT_PUBLIC_Marshal(&inPublic2, &inPublic_template.buffer[0],
243 sizeof(TPMT_PUBLIC), &offset);
244 goto_if_error(r, "Error Tss2_MU_TPMT_PUBLIC_Marshal", error);
245
246 inPublic_template.size = offset;
247
248 r = Esys_CreateLoaded(
249 esys_context,
250 primaryHandle,
251 #ifdef TEST_SESSION
252 session,
253 #else
254 ESYS_TR_PASSWORD,
255 #endif
256 ESYS_TR_NONE,
257 ESYS_TR_NONE,
258 &inSensitiveObject,
259 &inPublic_template,
260 &objectHandle,
261 &outPrivate2,
262 &outPublic2
263 );
264 if ((r == TPM2_RC_COMMAND_CODE) ||
265 (r == (TPM2_RC_COMMAND_CODE | TSS2_RESMGR_RC_LAYER)) ||
266 (r == (TPM2_RC_COMMAND_CODE | TSS2_RESMGR_TPM_RC_LAYER))) {
267 LOG_WARNING("Command TPM2_CreateLoaded not supported by TPM.");
268 failure_return = EXIT_SKIP;
269 goto error;
270 }
271
272 goto_if_error(r, "Error During CreateLoaded", error);
273
274 bool names_match = check_name(esys_context, objectHandle);
275 if (!names_match) {
276 goto error;
277 }
278
279 r = Esys_FlushContext(esys_context, primaryHandle);
280 goto_if_error(r, "Flushing context", error);
281
282 primaryHandle = ESYS_TR_NONE;
283
284 r = Esys_FlushContext(esys_context, objectHandle);
285 goto_if_error(r, "Flushing context", error);
286
287 objectHandle = ESYS_TR_NONE;
288
289 #ifdef TEST_SESSION
290 r = Esys_FlushContext(esys_context, session);
291 goto_if_error(r, "Error: FlushContext", error);
292 #endif
293
294 SAFE_FREE(outPublic);
295 SAFE_FREE(creationData);
296 SAFE_FREE(creationHash);
297 SAFE_FREE(creationTicket);
298 SAFE_FREE(outPrivate2);
299 SAFE_FREE(outPublic2);
300 return EXIT_SUCCESS;
301
302 error:
303
304 #ifdef TEST_SESSION
305 if (session != ESYS_TR_NONE) {
306 if (Esys_FlushContext(esys_context, session) != TSS2_RC_SUCCESS) {
307 LOG_ERROR("Cleanup session failed.");
308 }
309 }
310 #endif
311
312 if (objectHandle != ESYS_TR_NONE) {
313 if (Esys_FlushContext(esys_context, objectHandle) != TSS2_RC_SUCCESS) {
314 LOG_ERROR("Cleanup objectHandle failed.");
315 }
316 }
317
318 if (primaryHandle != ESYS_TR_NONE) {
319 if (Esys_FlushContext(esys_context, primaryHandle) != TSS2_RC_SUCCESS) {
320 LOG_ERROR("Cleanup primaryHandle failed.");
321 }
322 }
323
324 SAFE_FREE(outPublic);
325 SAFE_FREE(creationData);
326 SAFE_FREE(creationHash);
327 SAFE_FREE(creationTicket);
328 SAFE_FREE(outPrivate2);
329 SAFE_FREE(outPublic2);
330 return failure_return;
331 }
332
333 int
test_invoke_esapi(ESYS_CONTEXT * esys_context)334 test_invoke_esapi(ESYS_CONTEXT * esys_context) {
335 return test_esys_createloaded(esys_context);
336 }
337