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 test is intended to test parameter encryption/decryption, session management,
20 * hmac computation, and session key generation.
21 *
22 * We start by creating a primary key (Esys_CreatePrimary).
23 * The primary key will be used as tpmKey for Esys_StartAuthSession. Parameter
24 * encryption and decryption will be activated for the session.
25 * The session will be used to Create a second key by Eys_Create (with password)
26 * This key will be Loaded to and a third key will be created with the second
27 * key as parent key (Esys_Create).
28 * The type of encryptin can be selected by the compiler variables (-D option):
29 * TEST_XOR_OBFUSCATION or TEST_AES_ENCRYPTION.
30 * Secret exchange with a ECC key can be activated with the compiler variable
31 * -D TEST_ECC.
32 *
33 * Tested ESAPI commands:
34 * - Esys_ContextLoad() (M)
35 * - Esys_ContextSave() (M)
36 * - Esys_Create() (M)
37 * - Esys_CreatePrimary() (M)
38 * - Esys_FlushContext() (M)
39 * - Esys_Load() (M)
40 * - Esys_StartAuthSession() (M)
41 *
42 * Used compiler defines: TEST_ECC, TEST_AES_ENCRYPTION, TEST_BOUND_SESSION
43 * TEST_XOR_OBFUSCATION
44 *
45 * @param[in,out] esys_context The ESYS_CONTEXT.
46 * @retval EXIT_FAILURE
47 * @retval EXIT_SUCCESS
48 */
49
50 int
test_esys_create_session_auth(ESYS_CONTEXT * esys_context)51 test_esys_create_session_auth(ESYS_CONTEXT * esys_context)
52 {
53 TSS2_RC r;
54 ESYS_TR primaryHandle = ESYS_TR_NONE;
55 ESYS_TR loadedKeyHandle = ESYS_TR_NONE;
56 ESYS_TR primaryHandle_AuthSession = ESYS_TR_NONE;
57 ESYS_TR session = ESYS_TR_NONE;
58 ESYS_TR outerSession = ESYS_TR_NONE;
59
60 TPM2B_PUBLIC *outPublic = NULL;
61 TPM2B_CREATION_DATA *creationData = NULL;
62 TPM2B_DIGEST *creationHash = NULL;
63 TPMT_TK_CREATION *creationTicket = NULL;
64
65 #ifdef TEST_ECC
66 TPM2B_PUBLIC *outPublicEcc = NULL;
67 TPM2B_CREATION_DATA *creationDataEcc = NULL;
68 TPM2B_DIGEST *creationHashEcc = NULL;
69 TPMT_TK_CREATION *creationTicketEcc = NULL;
70 #endif
71
72 TPM2B_PUBLIC *outPublic2 = NULL;
73 TPM2B_PRIVATE *outPrivate2 = NULL;
74 TPM2B_CREATION_DATA *creationData2 = NULL;
75 TPM2B_DIGEST *creationHash2 = NULL;
76 TPMT_TK_CREATION *creationTicket2 = NULL;
77
78 TPM2B_AUTH authValuePrimary = {
79 .size = 5,
80 .buffer = {1, 2, 3, 4, 5}
81 };
82
83 TPM2B_SENSITIVE_CREATE inSensitivePrimary = {
84 .size = 0,
85 .sensitive = {
86 .userAuth = {
87 .size = 0,
88 .buffer = {0 },
89 },
90 .data = {
91 .size = 0,
92 .buffer = {0},
93 },
94 },
95 };
96
97 inSensitivePrimary.sensitive.userAuth = authValuePrimary;
98
99 #ifdef TEST_ECC
100 TPM2B_PUBLIC inPublicEcc = {
101 .size = 0,
102 .publicArea = {
103 .type = TPM2_ALG_ECC,
104 .nameAlg = TPM2_ALG_SHA256,
105 .objectAttributes = (TPMA_OBJECT_USERWITHAUTH |
106 TPMA_OBJECT_DECRYPT |
107 TPMA_OBJECT_FIXEDTPM |
108 TPMA_OBJECT_FIXEDPARENT |
109 TPMA_OBJECT_SENSITIVEDATAORIGIN),
110 .authPolicy = {
111 .size = 0,
112 },
113 .parameters.eccDetail = {
114 .symmetric = {
115 .algorithm = TPM2_ALG_NULL,
116 .keyBits.aes = 128,
117 .mode.aes = TPM2_ALG_CFB,
118 },
119 .scheme = {
120 .scheme = TPM2_ALG_ECDH,
121 .details = {
122 .ecdh = {.hashAlg = TPM2_ALG_SHA1}},
123 },
124 .curveID = TPM2_ECC_NIST_P256,
125 .kdf = {
126 .scheme = TPM2_ALG_NULL,
127 .details = {}}
128 },
129 .unique.ecc = {
130 .x = {.size = 0,.buffer = {}},
131 .y = {.size = 0,.buffer = {}},
132 },
133 },
134 };
135 LOG_INFO("\nECC key will be created.");
136 #endif
137 TPM2B_PUBLIC inPublic = {
138 .size = 0,
139 .publicArea = {
140 .type = TPM2_ALG_RSA,
141 .nameAlg = TPM2_ALG_SHA256,
142 .objectAttributes = (TPMA_OBJECT_USERWITHAUTH |
143 TPMA_OBJECT_RESTRICTED |
144 TPMA_OBJECT_DECRYPT |
145 TPMA_OBJECT_FIXEDTPM |
146 TPMA_OBJECT_FIXEDPARENT |
147 TPMA_OBJECT_SENSITIVEDATAORIGIN),
148 .authPolicy = {
149 .size = 0,
150 },
151 .parameters.rsaDetail = {
152 .symmetric = {
153 .algorithm = TPM2_ALG_AES,
154 .keyBits.aes = 128,
155 .mode.aes = TPM2_ALG_CFB},
156 .scheme = {
157 .scheme = TPM2_ALG_NULL
158 },
159 .keyBits = 2048,
160 .exponent = 0,
161 },
162 .unique.rsa = {
163 .size = 0,
164 .buffer = {},
165 },
166 },
167 };
168
169 TPM2B_DATA outsideInfo = {
170 .size = 0,
171 .buffer = {},
172 };
173
174 TPML_PCR_SELECTION creationPCR = {
175 .count = 0,
176 };
177
178 TPM2B_AUTH authValue = {
179 .size = 0,
180 .buffer = {}
181 };
182
183 r = Esys_TR_SetAuth(esys_context, ESYS_TR_RH_OWNER, &authValue);
184 goto_if_error(r, "Error: TR_SetAuth", error);
185
186 RSRC_NODE_T *primaryHandle_node;
187
188 r = Esys_CreatePrimary(esys_context, ESYS_TR_RH_OWNER, ESYS_TR_PASSWORD,
189 ESYS_TR_NONE, ESYS_TR_NONE, &inSensitivePrimary, &inPublic,
190 &outsideInfo, &creationPCR, &primaryHandle,
191 &outPublic, &creationData, &creationHash,
192 &creationTicket);
193 goto_if_error(r, "Error esys create primary", error);
194
195 r = esys_GetResourceObject(esys_context, primaryHandle,
196 &primaryHandle_node);
197 goto_if_error(r, "Error Esys GetResourceObject", error);
198
199 LOG_INFO("Created Primary with handle 0x%08x...",
200 primaryHandle_node->rsrc.handle);
201
202 r = Esys_TR_SetAuth(esys_context, primaryHandle, &authValuePrimary);
203 goto_if_error(r, "Error: TR_SetAuth", error);
204
205
206 #ifdef TEST_ECC
207 r = Esys_CreatePrimary(esys_context, ESYS_TR_RH_OWNER, ESYS_TR_PASSWORD,
208 ESYS_TR_NONE, ESYS_TR_NONE, &inSensitivePrimary, &inPublicEcc,
209 &outsideInfo, &creationPCR, &primaryHandle_AuthSession,
210 &outPublicEcc, &creationDataEcc, &creationHashEcc,
211 &creationTicketEcc);
212 goto_if_error(r, "Error esys create primary", error);
213
214 r = Esys_TR_SetAuth(esys_context, primaryHandle_AuthSession, &authValuePrimary);
215 goto_if_error(r, "Error: TR_SetAuth", error);
216 #else
217 primaryHandle_AuthSession = primaryHandle;
218 #endif /* TEST_ECC */
219
220 #if TEST_XOR_OBFUSCATION
221 TPMT_SYM_DEF symmetric = {.algorithm = TPM2_ALG_XOR,
222 .keyBits = { .exclusiveOr = TPM2_ALG_SHA1 },
223 .mode = {.aes = TPM2_ALG_CFB}};
224 #elif TEST_AES_ENCRYPTION
225 TPMT_SYM_DEF symmetric = {.algorithm = TPM2_ALG_AES,
226 .keyBits = {.aes = 128},
227 .mode = {.aes = TPM2_ALG_CFB}};
228 #else
229 #error "TEST_XOR_OBFUSCATION or TEST_PARAM_ENCRYPTION not set"
230 #endif
231
232 TPMA_SESSION sessionAttributes;
233 TPMA_SESSION sessionAttributes2;
234 sessionAttributes = (TPMA_SESSION_DECRYPT |
235 TPMA_SESSION_ENCRYPT |
236 TPMA_SESSION_CONTINUESESSION);
237 TPM2_SE sessionType = TPM2_SE_HMAC;
238 TPMI_ALG_HASH authHash = TPM2_ALG_SHA256;
239
240 r = Esys_StartAuthSession(esys_context,
241 ESYS_TR_NONE, ESYS_TR_NONE,
242 ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
243 NULL,
244 TPM2_SE_HMAC, &symmetric, TPM2_ALG_SHA256,
245 &outerSession);
246 goto_if_error(r, "Error during Esys_StartAuthSession", error);
247
248 r = Esys_TRSess_SetAttributes(esys_context, outerSession, TPMA_SESSION_AUDIT,
249 TPMA_SESSION_AUDIT);
250 goto_if_error(r, "Error Esys_TRSess_SetAttributes", error);
251
252 r = Esys_StartAuthSession(esys_context,
253 primaryHandle_AuthSession,
254 #if TEST_BOUND_SESSION
255 primaryHandle_AuthSession,
256 #else
257 ESYS_TR_NONE,
258 #endif
259 outerSession, ESYS_TR_NONE, ESYS_TR_NONE,
260 NULL,
261 sessionType, &symmetric, authHash, &session);
262 Esys_FlushContext(esys_context, outerSession);
263 goto_if_error(r, "Error during Esys_StartAuthSession", error);
264
265 #ifdef TEST_ECC
266 r = Esys_FlushContext(esys_context, primaryHandle_AuthSession);
267 goto_if_error(r, "Error during FlushContext", error);
268 #endif
269
270 goto_if_error(r, "Error Esys_StartAuthSessiony", error);
271 r = Esys_TRSess_SetAttributes(esys_context, session, sessionAttributes,
272 0xff);
273 goto_if_error(r, "Error Esys_TRSess_SetAttributes", error);
274
275 r = Esys_TRSess_GetAttributes(esys_context, session, &sessionAttributes2);
276 goto_if_error(r, "Error Esys_TRSess_SetAttributes", error);
277
278 if (sessionAttributes != sessionAttributes2) {
279 LOG_ERROR("Session Attributes differ");
280 goto error;
281 }
282
283 /* Save and load the session and test if the attributes are still OK. */
284 TPMS_CONTEXT *contextBlob;
285 r = Esys_ContextSave(esys_context, session, &contextBlob);
286 goto_if_error(r, "Error during ContextSave", error);
287
288 session = ESYS_TR_NONE;
289
290 r = Esys_ContextLoad(esys_context, contextBlob, &session);
291 goto_if_error(r, "Error during ContextLoad", error);
292
293 free(contextBlob);
294
295 r = Esys_TRSess_GetAttributes(esys_context, session, &sessionAttributes2);
296 goto_if_error(r, "Error Esys_TRSess_SetAttributes", error);
297
298 if (sessionAttributes != sessionAttributes2) {
299 LOG_ERROR("Session Attributes differ");
300 goto error;
301 }
302
303 TPM2B_AUTH authKey2 = {
304 .size = 6,
305 .buffer = {6, 7, 8, 9, 10, 11}
306 };
307
308 TPM2B_SENSITIVE_CREATE inSensitive2 = {
309 .size = 0,
310 .sensitive = {
311 .userAuth = {
312 .size = 0,
313 .buffer = {0}
314 },
315 .data = {
316 .size = 0,
317 .buffer = {}
318 }
319 }
320 };
321
322 inSensitive2.sensitive.userAuth = authKey2;
323
324 TPM2B_SENSITIVE_CREATE inSensitive3 = {
325 .size = 0,
326 .sensitive = {
327 .userAuth = {
328 .size = 0,
329 .buffer = {}
330 },
331 .data = {
332 .size = 0,
333 .buffer = {}
334 }
335 }
336 };
337
338 TPM2B_PUBLIC inPublic2 = {
339 .size = 0,
340 .publicArea = {
341 .type = TPM2_ALG_RSA,
342 .nameAlg = TPM2_ALG_SHA256,
343 .objectAttributes = (TPMA_OBJECT_USERWITHAUTH |
344 TPMA_OBJECT_RESTRICTED |
345 TPMA_OBJECT_DECRYPT |
346 TPMA_OBJECT_FIXEDTPM |
347 TPMA_OBJECT_FIXEDPARENT |
348 TPMA_OBJECT_SENSITIVEDATAORIGIN),
349
350 .authPolicy = {
351 .size = 0,
352 },
353 .parameters.rsaDetail = {
354 .symmetric = {
355 .algorithm = TPM2_ALG_AES,
356 .keyBits.aes = 128,
357 .mode.aes = TPM2_ALG_CFB
358 },
359 .scheme = {
360 .scheme =
361 TPM2_ALG_NULL,
362 },
363 .keyBits = 2048,
364 .exponent = 0
365 },
366 .unique.rsa = {
367 .size = 0,
368 .buffer = {}
369 ,
370 }
371 }
372 };
373
374 TPM2B_DATA outsideInfo2 = {
375 .size = 0,
376 .buffer = {}
377 ,
378 };
379
380 TPML_PCR_SELECTION creationPCR2 = {
381 .count = 0,
382 };
383
384 r = Esys_Create(esys_context,
385 primaryHandle,
386 session, ESYS_TR_NONE, ESYS_TR_NONE,
387 &inSensitive2,
388 &inPublic2,
389 &outsideInfo2,
390 &creationPCR2,
391 &outPrivate2,
392 &outPublic2,
393 &creationData2, &creationHash2, &creationTicket2);
394 goto_if_error(r, "Error esys create ", error);
395
396 LOG_INFO("\nSecond key created.");
397
398 r = Esys_Load(esys_context,
399 primaryHandle,
400 session,
401 ESYS_TR_NONE,
402 ESYS_TR_NONE, outPrivate2, outPublic2, &loadedKeyHandle);
403 goto_if_error(r, "Error esys load ", error);
404
405 LOG_INFO("\nSecond Key loaded.");
406
407 r = Esys_TR_SetAuth(esys_context, loadedKeyHandle, &authKey2);
408 goto_if_error(r, "Error esys TR_SetAuth ", error);
409
410 Esys_Free(outPublic2);
411 Esys_Free(outPrivate2);
412 Esys_Free(creationData2);
413 Esys_Free(creationHash2);
414 Esys_Free(creationTicket2);
415
416 r = Esys_Create(esys_context,
417 loadedKeyHandle,
418 session, ESYS_TR_NONE, ESYS_TR_NONE,
419 &inSensitive3,
420 &inPublic2,
421 &outsideInfo2,
422 &creationPCR2,
423 &outPrivate2,
424 &outPublic2,
425 &creationData2, &creationHash2, &creationTicket2);
426 goto_if_error(r, "Error esys second create ", error);
427
428 r = Esys_FlushContext(esys_context, primaryHandle);
429 goto_if_error(r, "Error during FlushContext", error);
430
431 r = Esys_FlushContext(esys_context, loadedKeyHandle);
432 goto_if_error(r, "Error during FlushContext", error);
433
434 r = Esys_FlushContext(esys_context, session);
435 goto_if_error(r, "Flushing context", error);
436
437 Esys_Free(outPublic);
438 Esys_Free(creationData);
439 Esys_Free(creationHash);
440 Esys_Free(creationTicket);
441
442 #ifdef TEST_ECC
443 Esys_Free(outPublicEcc);
444 Esys_Free(creationDataEcc);
445 Esys_Free(creationHashEcc);
446 Esys_Free(creationTicketEcc);
447 #endif
448
449 Esys_Free(outPublic2);
450 Esys_Free(outPrivate2);
451 Esys_Free(creationData2);
452 Esys_Free(creationHash2);
453 Esys_Free(creationTicket2);
454 return EXIT_SUCCESS;
455
456 error:
457
458 if (session != ESYS_TR_NONE) {
459 if (Esys_FlushContext(esys_context, session) != TSS2_RC_SUCCESS) {
460 LOG_ERROR("Cleanup session failed.");
461 }
462 }
463
464 if (loadedKeyHandle != ESYS_TR_NONE) {
465 if (Esys_FlushContext(esys_context, loadedKeyHandle) != TSS2_RC_SUCCESS) {
466 LOG_ERROR("Cleanup loadedKeyHandle failed.");
467 }
468 }
469
470 if (primaryHandle != ESYS_TR_NONE) {
471 if (Esys_FlushContext(esys_context, primaryHandle) != TSS2_RC_SUCCESS) {
472 LOG_ERROR("Cleanup primaryHandle failed.");
473 }
474 }
475
476 #ifdef TEST_ECC
477 if (primaryHandle_AuthSession != ESYS_TR_NONE) {
478 if (Esys_FlushContext(esys_context, primaryHandle_AuthSession) != TSS2_RC_SUCCESS) {
479 LOG_ERROR("Cleanup primaryHandle_AuthSession failed.");
480 }
481 }
482 #endif
483
484 Esys_Free(outPublic);
485 Esys_Free(creationData);
486 Esys_Free(creationHash);
487 Esys_Free(creationTicket);
488
489 #ifdef TEST_ECC
490 Esys_Free(outPublicEcc);
491 Esys_Free(creationDataEcc);
492 Esys_Free(creationHashEcc);
493 Esys_Free(creationTicketEcc);
494 #endif
495
496 Esys_Free(outPublic2);
497 Esys_Free(outPrivate2);
498 Esys_Free(creationData2);
499 Esys_Free(creationHash2);
500 Esys_Free(creationTicket2);
501 return EXIT_FAILURE;
502 }
503
504 int
test_invoke_esapi(ESYS_CONTEXT * esys_context)505 test_invoke_esapi(ESYS_CONTEXT * esys_context) {
506 return test_esys_create_session_auth(esys_context);
507 }
508