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 policy commands related to
23 * signed authorization actions.
24 *
25 * Esys_PolicySigned, Esys_PolicyTicket, and Esys_PolicySecret.
26 *
27 * Tested ESAPI commands:
28 * - Esys_CreatePrimary() (M)
29 * - Esys_FlushContext() (M)
30 * - Esys_HashSequenceStart() (M)
31 * - Esys_PolicySecret() (M)
32 * - Esys_PolicySigned() (M)
33 * - Esys_PolicyTicket() (O)
34 * - Esys_ReadPublic() (M)
35 * - Esys_SequenceComplete() (M)
36 * - Esys_SequenceUpdate() (M)
37 * - Esys_Sign() (M)
38 * - Esys_StartAuthSession() (M)
39 *
40 * @param[in,out] esys_context The ESYS_CONTEXT.
41 * @retval EXIT_FAILURE
42 * @retval EXIT_SUCCESS
43 */
44
45 int
test_esys_policy_ticket(ESYS_CONTEXT * esys_context)46 test_esys_policy_ticket(ESYS_CONTEXT * esys_context)
47 {
48 TSS2_RC r;
49 ESYS_TR primaryHandle = ESYS_TR_NONE;
50 ESYS_TR session = ESYS_TR_NONE;
51 ESYS_TR sessionTrial = ESYS_TR_NONE;
52 int failure_return = EXIT_FAILURE;
53
54 TPM2B_NONCE *nonceTPM = NULL;
55 TPM2B_PUBLIC *outPublic = NULL;
56 TPM2B_CREATION_DATA *creationData = NULL;
57 TPM2B_DIGEST *creationHash = NULL;
58 TPMT_TK_CREATION *creationTicket = NULL;
59 TPM2B_NAME *nameKeySign = NULL;
60 TPM2B_NAME *keyQualifiedName = NULL;
61 TPM2B_DIGEST *signed_digest = NULL;
62 TPM2B_TIMEOUT *timeout = NULL;
63 TPMT_TK_AUTH *policySignedTicket = NULL;
64 TPMT_TK_HASHCHECK *validation = NULL;
65 TPMT_TK_AUTH *policySecretTicket = NULL;
66 TPMT_SIGNATURE *signature = NULL;
67
68 /*
69 * 1. Create Primary. This primary will be used as signing key.
70 */
71
72 TPM2B_AUTH authValuePrimary = {
73 .size = 5,
74 .buffer = {1, 2, 3, 4, 5}
75 };
76
77 TPM2B_SENSITIVE_CREATE inSensitivePrimary = {
78 .size = 0,
79 .sensitive = {
80 .userAuth = authValuePrimary,
81 .data = {
82 .size = 0,
83 .buffer = {0},
84 },
85 },
86 };
87
88 TPM2B_PUBLIC inPublic = {
89 .size = 0,
90 .publicArea = {
91 .type = TPM2_ALG_RSA,
92 .nameAlg = TPM2_ALG_SHA1,
93 .objectAttributes = (TPMA_OBJECT_USERWITHAUTH |
94 TPMA_OBJECT_SIGN_ENCRYPT |
95 TPMA_OBJECT_FIXEDTPM |
96 TPMA_OBJECT_FIXEDPARENT |
97 TPMA_OBJECT_SENSITIVEDATAORIGIN),
98 .authPolicy = {
99 .size = 0,
100 },
101 .parameters.rsaDetail = {
102 .symmetric = {
103 .algorithm = TPM2_ALG_NULL,
104 .keyBits.aes = 128,
105 .mode.aes = TPM2_ALG_CFB},
106 .scheme = {
107 .scheme = TPM2_ALG_RSAPSS,
108 .details = {
109 .rsapss = { .hashAlg = TPM2_ALG_SHA1 }
110 }
111 },
112 .keyBits = 2048,
113 .exponent = 0,
114 },
115 .unique.rsa = {
116 .size = 0,
117 .buffer = {},
118 },
119 },
120 };
121 LOG_INFO("\nRSA key will be created.");
122
123 TPM2B_DATA outsideInfo = {
124 .size = 0,
125 .buffer = {},
126 };
127
128 TPML_PCR_SELECTION creationPCR = {
129 .count = 0,
130 };
131
132 TPM2B_AUTH authValue = {
133 .size = 0,
134 .buffer = {}
135 };
136
137 r = Esys_TR_SetAuth(esys_context, ESYS_TR_RH_OWNER, &authValue);
138 goto_if_error(r, "Error: TR_SetAuth", error);
139
140 r = Esys_CreatePrimary(esys_context, ESYS_TR_RH_OWNER, ESYS_TR_PASSWORD,
141 ESYS_TR_NONE, ESYS_TR_NONE,
142 &inSensitivePrimary, &inPublic,
143 &outsideInfo, &creationPCR, &primaryHandle,
144 &outPublic, &creationData, &creationHash,
145 &creationTicket);
146 goto_if_error(r, "Error esys create primary", error);
147 Esys_Free(outPublic);
148 Esys_Free(creationData);
149 Esys_Free(creationHash);
150 Esys_Free(creationTicket);
151
152 r = Esys_ReadPublic(esys_context,
153 primaryHandle,
154 ESYS_TR_NONE,
155 ESYS_TR_NONE,
156 ESYS_TR_NONE,
157 &outPublic,
158 &nameKeySign,
159 &keyQualifiedName);
160 goto_if_error(r, "Error: ReadPublic", error);
161
162 /*
163 * 2. A policy session will be created. Based on the signed policy the
164 * ticket policySignedTicket will be created.
165 * With this ticket the function Esys_PolicyTicket will be tested.
166 */
167 INT32 expiration = -(10*365*24*60*60); /* Expiration ten years */
168
169 TPM2B_DIGEST expiration2b;
170 TPMT_SYM_DEF symmetric = {.algorithm = TPM2_ALG_AES,
171 .keyBits = {.aes = 128},
172 .mode = {.aes = TPM2_ALG_CFB}
173 };
174 TPM2B_NONCE nonceCaller = {
175 .size = 20,
176 .buffer = {11, 12, 13, 14, 15, 16, 17, 18, 19, 11,
177 21, 22, 23, 24, 25, 26, 27, 28, 29, 30}
178 };
179
180 size_t offset = 0;
181
182 r = Tss2_MU_INT32_Marshal(expiration, &expiration2b.buffer[0],
183 4, &offset);
184 goto_if_error(r, "Marshaling name", error);
185 expiration2b.size = offset;
186
187 r = Esys_StartAuthSession(esys_context, ESYS_TR_NONE, ESYS_TR_NONE,
188 ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
189 &nonceCaller,
190 TPM2_SE_POLICY, &symmetric, TPM2_ALG_SHA1,
191 &session);
192 goto_if_error(r, "Error: During initialization of policy trial session", error);
193
194 TPM2B_NONCE policyRef = {0};
195 TPM2B_DIGEST cpHashA = {0};
196
197 r = Esys_TRSess_GetNonceTPM(esys_context, session, &nonceTPM);
198 goto_if_error(r, "Error: During initialization of policy trial session", error);
199
200 /* Compute hash from nonceTPM||expiration */
201
202 TPMI_ALG_HASH hashAlg = TPM2_ALG_SHA1;
203 ESYS_TR sequenceHandle_handle;
204 TPM2B_AUTH auth = {0};
205
206 r = Esys_HashSequenceStart(esys_context,
207 ESYS_TR_NONE,
208 ESYS_TR_NONE,
209 ESYS_TR_NONE,
210 &auth,
211 hashAlg,
212 &sequenceHandle_handle
213 );
214 goto_if_error(r, "Error: HashSequenceStart", error);
215
216 r = Esys_TR_SetAuth(esys_context, sequenceHandle_handle, &auth);
217 goto_if_error(r, "Error esys TR_SetAuth ", error);
218
219 r = Esys_SequenceUpdate(esys_context,
220 sequenceHandle_handle,
221 ESYS_TR_PASSWORD,
222 ESYS_TR_NONE,
223 ESYS_TR_NONE,
224 (const TPM2B_MAX_BUFFER *)nonceTPM
225 );
226 goto_if_error(r, "Error: SequenceUpdate", error);
227
228 r = Esys_SequenceComplete(esys_context,
229 sequenceHandle_handle,
230 ESYS_TR_PASSWORD,
231 ESYS_TR_NONE,
232 ESYS_TR_NONE,
233 (const TPM2B_MAX_BUFFER *)&expiration2b,
234 TPM2_RH_OWNER,
235 &signed_digest,
236 &validation
237 );
238 goto_if_error(r, "Error: SequenceComplete", error);
239
240 TPMT_SIG_SCHEME inScheme = { .scheme = TPM2_ALG_NULL };
241 TPMT_TK_HASHCHECK hash_validation = {
242 .tag = TPM2_ST_HASHCHECK,
243 .hierarchy = TPM2_RH_OWNER,
244 .digest = {0}
245 };
246
247 /* Policy expiration of ten years will be signed */
248
249 r = Esys_Sign(
250 esys_context,
251 primaryHandle,
252 ESYS_TR_PASSWORD,
253 ESYS_TR_NONE,
254 ESYS_TR_NONE,
255 signed_digest,
256 &inScheme,
257 &hash_validation,
258 &signature);
259 goto_if_error(r, "Error: Sign", error);
260
261 r = Esys_PolicySigned(
262 esys_context,
263 primaryHandle,
264 session,
265 ESYS_TR_NONE,
266 ESYS_TR_NONE,
267 ESYS_TR_NONE,
268 nonceTPM,
269 &cpHashA,
270 &policyRef,
271 expiration,
272 signature,
273 &timeout,
274 &policySignedTicket);
275 goto_if_error(r, "Error: PolicySigned", error);
276
277 r = Esys_FlushContext(esys_context, session);
278 goto_if_error(r, "Error: FlushContext", error);
279
280 session = ESYS_TR_NONE;
281
282 r = Esys_StartAuthSession(esys_context, ESYS_TR_NONE, ESYS_TR_NONE,
283 ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
284 &nonceCaller,
285 TPM2_SE_POLICY, &symmetric, TPM2_ALG_SHA1,
286 &session);
287 goto_if_error(r, "Error: During initialization of policy session", error);
288
289 r = Esys_PolicyTicket(
290 esys_context,
291 session,
292 ESYS_TR_NONE,
293 ESYS_TR_NONE,
294 ESYS_TR_NONE,
295 timeout,
296 &cpHashA,
297 &policyRef,
298 nameKeySign,
299 policySignedTicket);
300
301 if ((r == TPM2_RC_COMMAND_CODE) ||
302 (r == (TPM2_RC_COMMAND_CODE | TSS2_RESMGR_RC_LAYER)) ||
303 (r == (TPM2_RC_COMMAND_CODE | TSS2_RESMGR_TPM_RC_LAYER))) {
304 LOG_WARNING("Command TPM2_PolicyTicket not supported by TPM all other tests PASSED.");
305 r = Esys_FlushContext(esys_context, session);
306 goto_if_error(r, "Error: FlushContext", error);
307 } else {
308 goto_if_error(r, "Error: PolicyTicket", error);
309
310 r = Esys_FlushContext(esys_context, session);
311 goto_if_error(r, "Error: FlushContext", error);
312
313 session = ESYS_TR_NONE;
314 }
315 Esys_Free(timeout);
316
317 /*
318 * 3. A policy tial session will be created. With this trial policy the
319 * function Esys_PolicySecret will be tested.
320 */
321
322 TPMT_SYM_DEF symmetricTrial = {.algorithm = TPM2_ALG_AES,
323 .keyBits = {.aes = 128},
324 .mode = {.aes = TPM2_ALG_CFB}
325 };
326 TPM2B_NONCE nonceCallerTrial = {
327 .size = 20,
328 .buffer = {11, 12, 13, 14, 15, 16, 17, 18, 19, 11,
329 21, 22, 23, 24, 25, 26, 27, 28, 29, 30}
330 };
331
332 r = Esys_StartAuthSession(esys_context, ESYS_TR_NONE, ESYS_TR_NONE,
333 ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
334 &nonceCallerTrial,
335 TPM2_SE_TRIAL, &symmetricTrial, TPM2_ALG_SHA1,
336 &sessionTrial);
337 goto_if_error(r, "Error: During initialization of policy trial session", error);
338
339 r = Esys_PolicySecret(
340 esys_context,
341 primaryHandle,
342 sessionTrial,
343 ESYS_TR_PASSWORD,
344 ESYS_TR_NONE,
345 ESYS_TR_NONE,
346 nonceTPM,
347 &cpHashA,
348 &policyRef,
349 expiration,
350 &timeout,
351 &policySecretTicket);
352 goto_if_error(r, "Error: PolicySecret", error);
353
354 r = Esys_FlushContext(esys_context, sessionTrial);
355 goto_if_error(r, "Error: FlushContext", error);
356
357 sessionTrial = ESYS_TR_NONE;
358
359 r = Esys_FlushContext(esys_context, primaryHandle);
360 goto_if_error(r, "Error: FlushContext", error);
361
362 Esys_Free(outPublic);
363 Esys_Free(nameKeySign);
364 Esys_Free(keyQualifiedName);
365 Esys_Free(signed_digest);
366 Esys_Free(timeout);
367 Esys_Free(policySignedTicket);
368 Esys_Free(validation);
369 Esys_Free(policySecretTicket);
370 Esys_Free(nonceTPM);
371 Esys_Free(signature);
372 return EXIT_SUCCESS;
373
374 error:
375
376 if (session != ESYS_TR_NONE) {
377 if (Esys_FlushContext(esys_context, session) != TSS2_RC_SUCCESS) {
378 LOG_ERROR("Cleanup session failed.");
379 }
380 }
381
382 if (sessionTrial != ESYS_TR_NONE) {
383 if (Esys_FlushContext(esys_context, sessionTrial) != TSS2_RC_SUCCESS) {
384 LOG_ERROR("Cleanup sessionTrial failed.");
385 }
386 }
387
388 if (primaryHandle != ESYS_TR_NONE) {
389 if (Esys_FlushContext(esys_context, primaryHandle) != TSS2_RC_SUCCESS) {
390 LOG_ERROR("Cleanup primaryHandle failed.");
391 }
392 }
393
394 Esys_Free(outPublic);
395 Esys_Free(creationData);
396 Esys_Free(creationHash);
397 Esys_Free(creationTicket);
398 Esys_Free(nameKeySign);
399 Esys_Free(keyQualifiedName);
400 Esys_Free(signed_digest);
401 Esys_Free(timeout);
402 Esys_Free(policySignedTicket);
403 Esys_Free(validation);
404 Esys_Free(policySecretTicket);
405 Esys_Free(nonceTPM);
406 Esys_Free(signature);
407
408 return failure_return;
409 }
410
411 int
test_invoke_esapi(ESYS_CONTEXT * esys_context)412 test_invoke_esapi(ESYS_CONTEXT * esys_context) {
413 return test_esys_policy_ticket(esys_context);
414 }
415