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
15 #include "esys_iutil.h"
16 #include "test-esapi.h"
17 #define LOGMODULE test
18 #include "util/log.h"
19 #include "util/aux_util.h"
20
21 /** This test is intended to test Esys_ECDH_ZGen.
22 *
23 * The test is based on an ECC key created with Esys_CreatePrimary
24 * and data produced by the command Esys_EC_Ephemeral.
25 *
26 * Tested ESAPI commands:
27 * - Esys_CreatePrimary() (M)
28 * - Esys_ECDH_ZGen() (M)
29 * - Esys_EC_Ephemeral() (F)
30 * - Esys_FlushContext() (M)
31 * - Esys_StartAuthSession() (M)
32 * - Esys_ZGen_2Phase() (O)
33 *
34 * @param[in,out] esys_context The ESYS_CONTEXT.
35 * @retval EXIT_FAILURE
36 * @retval EXIT_SKIP
37 * @retval EXIT_SUCCESS
38 */
39
40 int
test_esys_zgen_2phase(ESYS_CONTEXT * esys_context)41 test_esys_zgen_2phase(ESYS_CONTEXT * esys_context)
42 {
43 TSS2_RC r;
44 ESYS_TR eccHandle = ESYS_TR_NONE;
45 int failure_return = EXIT_FAILURE;
46 ESYS_TR session = ESYS_TR_NONE;
47 TPMT_SYM_DEF symmetric = {
48 .algorithm = TPM2_ALG_AES,
49 .keyBits = { .aes = 128 },
50 .mode = {.aes = TPM2_ALG_CFB}
51 };
52 TPMA_SESSION sessionAttributes;
53 TPM2B_NONCE nonceCaller = {
54 .size = 20,
55 .buffer = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
56 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}
57 };
58
59 TPM2B_PUBLIC *outPublic = NULL;
60 TPM2B_CREATION_DATA *creationData = NULL;
61 TPM2B_DIGEST *creationHash = NULL;
62 TPMT_TK_CREATION *creationTicket = NULL;
63 TPM2B_ECC_POINT *outZ1 = NULL;
64 TPM2B_ECC_POINT *outZ2 = NULL;
65 TPM2B_ECC_POINT *Q = NULL;
66
67 memset(&sessionAttributes, 0, sizeof sessionAttributes);
68
69 r = Esys_StartAuthSession(esys_context, ESYS_TR_NONE, ESYS_TR_NONE,
70 ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
71 &nonceCaller,
72 TPM2_SE_HMAC, &symmetric, TPM2_ALG_SHA1,
73 &session);
74 goto_if_error(r, "Error: During initialization of session", error);
75
76 TPM2B_SENSITIVE_CREATE inSensitive = {
77 .size = 0,
78 .sensitive = {
79 .userAuth = {
80 .size = 0,
81 .buffer = {0}
82 },
83 .data = {
84 .size = 0,
85 .buffer = {0}
86 }
87 }
88 };
89 TPM2B_PUBLIC inPublicECC = {
90 .size = 0,
91 .publicArea = {
92 .type = TPM2_ALG_ECC,
93 .nameAlg = TPM2_ALG_SHA1,
94 .objectAttributes = (TPMA_OBJECT_USERWITHAUTH |
95 TPMA_OBJECT_DECRYPT |
96 TPMA_OBJECT_FIXEDTPM |
97 TPMA_OBJECT_FIXEDPARENT |
98 TPMA_OBJECT_SENSITIVEDATAORIGIN),
99 .authPolicy = {
100 .size = 0,
101 },
102 .parameters.eccDetail = {
103 .symmetric = {
104 .algorithm = TPM2_ALG_NULL,
105 .keyBits.aes = 128,
106 .mode.aes = TPM2_ALG_CFB,
107 },
108 .scheme = {
109 .scheme = TPM2_ALG_ECDH,
110 .details = {.ecdh = {.hashAlg = TPM2_ALG_SHA1}
111 }
112 },
113 .curveID = TPM2_ECC_NIST_P256,
114 .kdf = {.scheme = TPM2_ALG_NULL }
115 },
116 .unique.ecc = {
117 .x = {.size = 0,.buffer = {}},
118 .y = {.size = 0,.buffer = {}}
119 }
120 ,
121 }
122 };
123 LOG_INFO("\nECC key will be created.");
124 TPM2B_PUBLIC inPublic = inPublicECC;
125
126 TPM2B_DATA outsideInfo = {
127 .size = 0,
128 .buffer = {}
129 ,
130 };
131
132 TPML_PCR_SELECTION creationPCR = {
133 .count = 0,
134 };
135
136 TPM2B_AUTH authValue = {
137 .size = 0,
138 .buffer = {}
139 };
140
141 r = Esys_TR_SetAuth(esys_context, ESYS_TR_RH_OWNER, &authValue);
142 goto_if_error(r, "Error: TR_SetAuth", error);
143
144 r = Esys_CreatePrimary(esys_context, ESYS_TR_RH_OWNER, session,
145 ESYS_TR_NONE, ESYS_TR_NONE, &inSensitive, &inPublic,
146 &outsideInfo, &creationPCR, &eccHandle,
147 &outPublic, &creationData, &creationHash,
148 &creationTicket);
149 goto_if_error(r, "Error esapi create primary", error);
150
151 TPMI_ECC_CURVE curveID = TPM2_ECC_NIST_P256;
152 UINT16 counter;
153
154 r = Esys_EC_Ephemeral(
155 esys_context,
156 ESYS_TR_NONE,
157 ESYS_TR_NONE,
158 ESYS_TR_NONE,
159 curveID,
160 &Q,
161 &counter);
162
163 if ((r == TPM2_RC_COMMAND_CODE) ||
164 (r == (TPM2_RC_COMMAND_CODE | TSS2_RESMGR_RC_LAYER)) ||
165 (r == (TPM2_RC_COMMAND_CODE | TSS2_RESMGR_TPM_RC_LAYER))) {
166 LOG_WARNING("Command TPM2_Ephemeral not supported by TPM.");
167 failure_return = EXIT_SKIP;
168 goto error;
169 }
170
171 goto_if_error(r, "Error: EC_Ephemeral", error);
172
173 TPM2B_ECC_POINT inQsB = {
174 .size = 0,
175 .point = outPublic->publicArea.unique.ecc
176 };
177 TPMI_ECC_KEY_EXCHANGE inScheme = TPM2_ALG_ECDH;
178 TPM2B_ECC_POINT inQeB = *Q;
179
180 r = Esys_ZGen_2Phase(
181 esys_context,
182 eccHandle,
183 ESYS_TR_PASSWORD,
184 ESYS_TR_NONE,
185 ESYS_TR_NONE,
186 &inQsB,
187 &inQeB,
188 inScheme,
189 counter,
190 &outZ1,
191 &outZ2);
192
193 if ((r == TPM2_RC_COMMAND_CODE) ||
194 (r == (TPM2_RC_COMMAND_CODE | TSS2_RESMGR_RC_LAYER)) ||
195 (r == (TPM2_RC_COMMAND_CODE | TSS2_RESMGR_TPM_RC_LAYER))) {
196 LOG_WARNING("Command TPM2_ZGen_2Phase not supported by TPM.");
197 failure_return = EXIT_SKIP;
198 goto error;
199 }
200
201 goto_if_error(r, "Error: ZGen_2Phase", error);
202
203 r = Esys_FlushContext(esys_context, eccHandle);
204 goto_if_error(r, "Flushing context", error);
205
206 r = Esys_FlushContext(esys_context, session);
207 goto_if_error(r, "Flushing context", error);
208
209 Esys_Free(outPublic);
210 Esys_Free(creationData);
211 Esys_Free(creationHash);
212 Esys_Free(creationTicket);
213 Esys_Free(outZ1);
214 Esys_Free(outZ2);
215 Esys_Free(Q);
216 return EXIT_SUCCESS;
217
218 error:
219 LOG_ERROR("\nError Code: %x\n", r);
220
221 if (eccHandle != ESYS_TR_NONE) {
222 if (Esys_FlushContext(esys_context, eccHandle) != TSS2_RC_SUCCESS) {
223 LOG_ERROR("Cleanup eccHandle failed.");
224 }
225 }
226
227 if (session != ESYS_TR_NONE) {
228 if (Esys_FlushContext(esys_context, session) != TSS2_RC_SUCCESS) {
229 LOG_ERROR("Cleanup session failed.");
230 }
231 }
232
233 Esys_Free(outPublic);
234 Esys_Free(creationData);
235 Esys_Free(creationHash);
236 Esys_Free(creationTicket);
237 Esys_Free(outZ1);
238 Esys_Free(outZ2);
239 Esys_Free(Q);
240 return failure_return;
241 }
242
243 int
test_invoke_esapi(ESYS_CONTEXT * esys_context)244 test_invoke_esapi(ESYS_CONTEXT * esys_context) {
245 return test_esys_zgen_2phase(esys_context);
246 }
247