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 #define LOGDEFAULT LOGLEVEL_INFO
18 #define LOGMODULE test
19 #include "util/log.h"
20 #include "util/aux_util.h"
21
22 extern TSS2_RC
23 (*transmit_hook) (const uint8_t *command_buffer, size_t command_size);
24
25 size_t handles;
26 TPMA_SESSION session1_attributes;
27 static TSS2_RC
28 hookcheck_session1 (const uint8_t *command_buffer, size_t command_size);
29
30 /** Test encrypt / decrypt session flags propagation
31 *
32 * Testing that the command decrypt and response encrypt session flags that are
33 * set in Esys are actually propagated to the TPM command's session flags, if
34 * the command allows this. Using TPM2_CreatePrimary as a candidate.
35 *
36 * @param[in,out] esys_context The ESYS_CONTEXT.
37 * @retval EXIT_FAILURE
38 * @retval EXIT_SUCCESS
39 */
40 int
test_esys_session_attributes(ESYS_CONTEXT * esys_context)41 test_esys_session_attributes(ESYS_CONTEXT * esys_context)
42 {
43 TSS2_RC r;
44 ESYS_TR objectHandle = ESYS_TR_NONE;
45 ESYS_TR session = ESYS_TR_NONE;
46 TPM2B_DIGEST *rdata = NULL;
47
48 TPMT_SYM_DEF symmetric = {.algorithm = TPM2_ALG_XOR,
49 .keyBits = { .exclusiveOr = TPM2_ALG_SHA1 },
50 .mode = {.aes = TPM2_ALG_CFB}};
51
52 TPM2B_SENSITIVE_CREATE inSensitive = {
53 .size = 0,
54 .sensitive = {
55 .userAuth = {
56 .size = 0,
57 .buffer = {0}
58 ,
59 },
60 .data = {
61 .size = 0,
62 .buffer = {0}
63 }
64 }
65 };
66
67 TPM2B_PUBLIC inPublic = {
68 .size = 0,
69 .publicArea = {
70 .type = TPM2_ALG_RSA,
71 .nameAlg = TPM2_ALG_SHA1,
72 .objectAttributes = (TPMA_OBJECT_USERWITHAUTH |
73 TPMA_OBJECT_RESTRICTED |
74 TPMA_OBJECT_DECRYPT |
75 TPMA_OBJECT_FIXEDTPM |
76 TPMA_OBJECT_FIXEDPARENT |
77 TPMA_OBJECT_SENSITIVEDATAORIGIN),
78 .authPolicy = {
79 .size = 0,
80 },
81 .parameters.rsaDetail = {
82 .symmetric = {
83 .algorithm = TPM2_ALG_AES,
84 .keyBits.aes = 128,
85 .mode.aes = TPM2_ALG_CFB,
86 },
87 .scheme = {
88 .scheme =
89 TPM2_ALG_NULL,
90 },
91 .keyBits = 2048,
92 .exponent = 0,
93 },
94 .unique.rsa = {
95 .size = 0,
96 .buffer = {}
97 ,
98 }
99 }
100 };
101
102 TPM2B_DATA outsideInfo = {
103 .size = 0,
104 .buffer = {}
105 ,
106 };
107
108 TPML_PCR_SELECTION creationPCR = {
109 .count = 0,
110 };
111
112 r = Esys_StartAuthSession(esys_context, ESYS_TR_NONE, ESYS_TR_NONE,
113 ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
114 NULL,
115 TPM2_SE_HMAC, &symmetric, TPM2_ALG_SHA1,
116 &session);
117 goto_if_error(r, "Error: During initialization of session", error);
118
119 /* Testing Encrypt and Decrypt, both set */
120 r = Esys_TRSess_SetAttributes(esys_context, session,
121 TPMA_SESSION_DECRYPT | TPMA_SESSION_ENCRYPT,
122 TPMA_SESSION_DECRYPT | TPMA_SESSION_ENCRYPT);
123 goto_if_error(r, "Error: During initialization of attributes", error);
124
125 handles = 1;
126 session1_attributes = TPMA_SESSION_CONTINUESESSION | TPMA_SESSION_DECRYPT |
127 TPMA_SESSION_ENCRYPT;
128 transmit_hook = hookcheck_session1;
129
130 r = Esys_CreatePrimary(esys_context, ESYS_TR_RH_OWNER, session,
131 ESYS_TR_NONE, ESYS_TR_NONE, &inSensitive, &inPublic,
132 &outsideInfo, &creationPCR, &objectHandle,
133 NULL, NULL, NULL, NULL);
134 transmit_hook = NULL;
135 goto_if_error(r, "Error esapi create primary", error);
136
137 r = Esys_FlushContext(esys_context, objectHandle);
138 goto_if_error(r, "Error during FlushContext", error);
139
140 r = Esys_FlushContext(esys_context, session);
141 goto_if_error(r, "Flushing context", error);
142
143 /* Testing only Encrypt, i.e. responses, set */
144 r = Esys_StartAuthSession(esys_context, ESYS_TR_NONE, ESYS_TR_NONE,
145 ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
146 NULL,
147 TPM2_SE_HMAC, &symmetric, TPM2_ALG_SHA1,
148 &session);
149 goto_if_error(r, "Error: During initialization of session", error);
150
151 r = Esys_TRSess_SetAttributes(esys_context, session,
152 TPMA_SESSION_ENCRYPT,
153 TPMA_SESSION_DECRYPT | TPMA_SESSION_ENCRYPT);
154 goto_if_error(r, "Error: During initialization of attributes", error);
155
156 handles = 0;
157 session1_attributes = TPMA_SESSION_CONTINUESESSION | TPMA_SESSION_ENCRYPT;
158 transmit_hook = hookcheck_session1;
159
160 r = Esys_GetRandom(esys_context, session, ESYS_TR_NONE, ESYS_TR_NONE,
161 10, &rdata);
162 Esys_Free(rdata);
163 transmit_hook = NULL;
164 goto_if_error(r, "Error esapi create primary", error);
165
166 transmit_hook = hookcheck_session1;
167
168 r = Esys_GetRandom(esys_context, session, ESYS_TR_NONE, ESYS_TR_NONE,
169 10, &rdata);
170 transmit_hook = NULL;
171 goto_if_error(r, "Error esapi create primary", error);
172
173 LOGBLOB_INFO(&rdata->buffer[0], rdata->size, "rdata");
174
175 /* Cleanup */
176 r = Esys_FlushContext(esys_context, session);
177 goto_if_error(r, "Flushing context", error);
178
179 Esys_Free(rdata);
180 return EXIT_SUCCESS;
181
182 error:
183 LOG_ERROR("\nError Code: %x\n", r);
184
185 if (session != ESYS_TR_NONE) {
186 if (Esys_FlushContext(esys_context, session) != TSS2_RC_SUCCESS) {
187 LOG_ERROR("Cleanup session failed.");
188 }
189 }
190
191 if (objectHandle != ESYS_TR_NONE) {
192 if (Esys_FlushContext(esys_context, objectHandle) != TSS2_RC_SUCCESS) {
193 LOG_ERROR("Cleanup objectHandle failed.");
194 }
195 }
196
197 Esys_Free(rdata);
198 return EXIT_FAILURE;
199 }
200
201 int
test_invoke_esapi(ESYS_CONTEXT * esys_context)202 test_invoke_esapi(ESYS_CONTEXT * esys_context) {
203 return test_esys_session_attributes(esys_context);
204 }
205
206 static TSS2_RC
hookcheck_session1(const uint8_t * command_buffer,size_t command_size)207 hookcheck_session1 (const uint8_t *command_buffer, size_t command_size)
208 {
209 TSS2_RC r;
210 size_t offset = 10; /* header */;
211 TPM2_ST tag;
212 TPMS_AUTH_COMMAND session1;
213
214 LOGBLOB_INFO(command_buffer, command_size, "command");
215
216 r = Tss2_MU_UINT16_Unmarshal(command_buffer, command_size, NULL, &tag);
217 return_if_error(r, "Unmarshalling AuthSize failed");
218 if (tag != TPM2_ST_SESSIONS) {
219 LOG_ERROR("Bad Tag. Expected TPM2_ST_SESSION Got: 0x%04x", tag);
220 return TSS2_TCTI_RC_BAD_VALUE;
221 }
222
223 offset += sizeof(TPM2_HANDLE) * handles;
224
225 /* TPM2_AUTHORIZATION_SIZE authorizationSize */
226 r = Tss2_MU_UINT32_Unmarshal(command_buffer, command_size, &offset, NULL);
227 return_if_error(r, "Unmarshalling AuthSize failed");
228
229 r = Tss2_MU_TPMS_AUTH_COMMAND_Unmarshal(command_buffer, command_size, &offset,
230 &session1);
231 return_if_error(r, "Unmarshalling first session failed");
232
233 if (session1.sessionAttributes != session1_attributes) {
234 LOG_ERROR("Session Attribute mismatch. Expected: 0x%08x Got: 0x%08x",
235 session1_attributes, session1.sessionAttributes);
236 return TSS2_TCTI_RC_BAD_VALUE;
237 }
238
239 return TSS2_RC_SUCCESS;
240 }
241