1 /* SPDX-License-Identifier: BSD-2-Clause */
2 /***********************************************************************
3 * Copyright (c) 2017-2018, Intel Corporation
4 *
5 * All rights reserved.
6 ***********************************************************************/
7 #ifdef HAVE_CONFIG_H
8 #include <config.h>
9 #endif
10
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <inttypes.h>
15
16 #include "tss2_sys.h"
17 #include "context-util.h"
18 #include "sapi-util.h"
19 #include "session-util.h"
20 #define LOGMODULE test
21 #include "util/log.h"
22 #include "test.h"
23
24 #define TEST_DATA "test data to encrypt"
25 #define TEST_DATA_LEN 21
26
27 int
test_invoke(TSS2_SYS_CONTEXT * sapi_context)28 test_invoke (TSS2_SYS_CONTEXT *sapi_context)
29 {
30 TSS2_RC rc, rc2;
31 SESSION *session;
32 TSS2_TCTI_CONTEXT *tcti_ctx;
33 TPM2B_MAX_NV_BUFFER data_to_write, data_read;
34 TPM2B_MAX_BUFFER encrypted_param, decrypted_param;
35 TPMI_RH_NV_INDEX nv_index = TPM2_HR_NV_INDEX | 0x01;
36 size_t decrypt_param_size, encrypt_param_size;
37 const uint8_t *decrypt_param_ptr, *encrypt_param_ptr;
38 TPM2B_AUTH nv_auth;
39 TPM2B_NV_PUBLIC nv_public;
40 TPM2B_DIGEST policy_auth;
41 TPMA_NV nv_attribs;
42 TPM2B_NONCE nonce_caller;
43 TPMT_SYM_DEF symmetric;
44 TSS2L_SYS_AUTH_COMMAND req_auth = {
45 .auths = {{ .sessionHandle = TPM2_RS_PW }},
46 .count = 1
47 };
48 TSS2L_SYS_AUTH_RESPONSE resp_auth = {
49 .count = 0
50 };
51
52 nv_attribs = TPMA_NV_AUTHREAD |
53 TPMA_NV_AUTHWRITE |
54 TPMA_NV_ORDERLY;
55
56 nonce_caller.size = 0;
57 policy_auth.size = 0;
58 nv_auth.size = 0;
59
60 LOG_INFO("param-encrypt-decrypt test");
61
62 rc = Tss2_Sys_GetTctiContext(sapi_context, &tcti_ctx);
63 if (rc) {
64 LOG_ERROR("Tss2_Sys_GetTctiContext failed 0x%" PRIx32, rc);
65 return rc;
66 }
67
68 nv_public.size = 0;
69 nv_public.nvPublic.attributes = nv_attribs;
70 CopySizedByteBuffer((TPM2B *)&nv_public.nvPublic.authPolicy, (TPM2B *)&policy_auth);
71 nv_public.nvPublic.dataSize = TEST_DATA_LEN;
72 nv_public.nvPublic.nvIndex = nv_index;
73 nv_public.nvPublic.nameAlg = TPM2_ALG_SHA256;
74
75 rc = Tss2_Sys_NV_DefineSpace(sapi_context, TPM2_RH_OWNER, &req_auth,
76 &nv_auth, &nv_public, &resp_auth);
77 if (rc) {
78 LOG_ERROR("Tss2_Sys_NV_DefineSpace failed 0x%" PRIx32, rc);
79 return rc;
80 }
81
82 symmetric.algorithm = TPM2_ALG_AES;
83 symmetric.keyBits.aes = 128;
84 symmetric.mode.aes = TPM2_ALG_CFB;
85
86 retry:
87 rc = create_auth_session(&session, TPM2_RH_NULL, 0,
88 TPM2_RH_NULL, 0, &nonce_caller, 0, TPM2_SE_POLICY,
89 &symmetric, TPM2_ALG_SHA256, tcti_ctx);
90 if (rc) {
91 LOG_ERROR("create_auth_session failed 0x%" PRIx32, rc);
92 goto clean;
93 }
94
95 memcpy(data_to_write.buffer, TEST_DATA, TEST_DATA_LEN);
96 data_to_write.size = TEST_DATA_LEN;
97
98 rc = Tss2_Sys_NV_Write_Prepare(sapi_context, nv_index, nv_index,
99 &data_to_write, 0);
100 if (rc) {
101 LOG_ERROR("Tss2_Sys_NV_Write_Prepare failed 0x%" PRIx32, rc);
102 goto clean;
103 }
104
105 req_auth.count = 2;
106 /* Set up auth session structure */
107 req_auth.auths[0].sessionHandle = TPM2_RS_PW;
108 req_auth.auths[0].nonce.size = 0;
109 req_auth.auths[0].sessionAttributes = 0;
110 req_auth.auths[0].hmac.size = nv_auth.size;
111 memcpy(req_auth.auths[0].hmac.buffer, nv_auth.buffer,
112 req_auth.auths[0].hmac.size);
113
114 /* Set up encrypt/decrypt session structure */
115 req_auth.auths[1].sessionHandle = session->sessionHandle;
116 req_auth.auths[1].nonce.size = 0;
117 req_auth.auths[1].sessionAttributes = TPMA_SESSION_CONTINUESESSION | TPMA_SESSION_DECRYPT;
118 req_auth.auths[1].hmac.size = 0;
119
120 rc = Tss2_Sys_SetCmdAuths(sapi_context, &req_auth);
121 if (rc) {
122 LOG_ERROR("Tss2_Sys_SetCmdAuths failed 0x%" PRIx32, rc);
123 goto clean;
124 }
125
126 rc = Tss2_Sys_GetDecryptParam(sapi_context, &decrypt_param_size, &decrypt_param_ptr);
127 if (rc) {
128 LOG_ERROR("Tss2_Sys_GetDecryptParam failed 0x%" PRIx32, rc);
129 goto clean;
130 }
131
132 if (decrypt_param_size != TEST_DATA_LEN) {
133 rc = 99;
134 LOG_ERROR("Invalid decrypt_param_size %d", (int)decrypt_param_size);
135 goto clean;
136 }
137
138 roll_nonces(session, &req_auth.auths[1].nonce);
139
140 rc = encrypt_command_param(session, &encrypted_param,
141 (TPM2B_MAX_BUFFER *)&data_to_write, &nv_auth);
142 if (rc) {
143 LOG_ERROR("encrypt_command_param failed 0x%" PRIx32, rc);
144 goto clean;
145 }
146
147 rc = Tss2_Sys_SetDecryptParam(sapi_context, encrypted_param.size,
148 encrypted_param.buffer);
149 if (rc) {
150 LOG_ERROR("Tss2_Sys_SetDecryptParam failed 0x%" PRIx32, rc);
151 goto clean;
152 }
153
154 rc = Tss2_Sys_Execute(sapi_context);
155 if (rc) {
156 if ((rc & 0x0000ffff) == TPM2_RC_RETRY) {
157 LOG_INFO("Tss2_Sys_Execute returned retry 0x%" PRIx32, rc);
158 Tss2_Sys_FlushContext(sapi_context, session->sessionHandle);
159 end_auth_session(session);
160 goto retry;
161 }
162
163 LOG_ERROR("Tss2_Sys_Execute failed 0x%" PRIx32, rc);
164 goto clean;
165 }
166
167 rc = Tss2_Sys_GetRspAuths(sapi_context, &resp_auth);
168 if (rc) {
169 LOG_ERROR("Tss2_Sys_GetRspAuths failed 0x%" PRIx32, rc);
170 goto clean;
171 }
172
173 /* Roll the nonces for response */
174 roll_nonces(session, &resp_auth.auths[1].nonce);
175
176 /* Roll the nonces for next command */
177 roll_nonces(session, &req_auth.auths[1].nonce);
178
179 req_auth.count = 1;
180
181 rc = Tss2_Sys_NV_Read(sapi_context, nv_index, nv_index, &req_auth,
182 TEST_DATA_LEN, 0, &data_read, &resp_auth);
183 if (rc) {
184 LOG_ERROR("Tss2_Sys_NV_Read failed 0x%" PRIx32, rc);
185 goto clean;
186 }
187
188 roll_nonces(session, &resp_auth.auths[1].nonce);
189
190 if (memcmp(data_read.buffer, data_to_write.buffer, data_read.size)) {
191 LOG_ERROR("Read data not equal to written data");
192 LOGBLOB_ERROR(data_to_write.buffer, data_to_write.size, "written");
193 LOGBLOB_ERROR(data_read.buffer, data_read.size, "read");
194 rc = 99;
195 goto clean;
196 }
197
198 rc = Tss2_Sys_NV_Read_Prepare(sapi_context, nv_index, nv_index, TEST_DATA_LEN, 0);
199 if (rc) {
200 LOG_ERROR("Tss2_Sys_NV_Read_Prepare failed 0x%" PRIx32, rc);
201 goto clean;
202 }
203
204 roll_nonces(session, &req_auth.auths[1].nonce);
205
206 req_auth.count = 2;
207 req_auth.auths[1].sessionAttributes &= ~TPMA_SESSION_DECRYPT;
208 req_auth.auths[1].sessionAttributes |= TPMA_SESSION_ENCRYPT;
209 req_auth.auths[1].sessionAttributes |= TPMA_SESSION_CONTINUESESSION;
210
211 rc = Tss2_Sys_SetCmdAuths(sapi_context, &req_auth);
212 if (rc) {
213 LOG_ERROR("Tss2_Sys_SetCmdAuths failed 0x%" PRIx32, rc);
214 goto clean;
215 }
216
217 rc = Tss2_Sys_Execute(sapi_context);
218 if (rc) {
219 LOG_ERROR("Tss2_Sys_Execute failed 0x%" PRIx32, rc);
220 goto clean;
221 }
222
223 rc = Tss2_Sys_GetEncryptParam(sapi_context, &encrypt_param_size, &encrypt_param_ptr);
224 if (rc) {
225 LOG_ERROR("Tss2_Sys_GetEncryptParam failed 0x%" PRIx32, rc);
226 goto clean;
227 }
228
229 rc = Tss2_Sys_GetRspAuths(sapi_context, &resp_auth);
230 if (rc) {
231 LOG_ERROR("Tss2_Sys_GetRspAuths failed 0x%" PRIx32, rc);
232 goto clean;
233 }
234
235 roll_nonces(session, &resp_auth.auths[1].nonce);
236
237 encrypted_param.size = encrypt_param_size;
238 memcpy(encrypted_param.buffer, encrypt_param_ptr, encrypt_param_size);
239
240 rc = decrypt_response_param(session, &decrypted_param,
241 &encrypted_param, &nv_auth);
242 if (rc) {
243 LOG_ERROR("decrypt_response_param failed 0x%" PRIx32, rc);
244 goto clean;
245 }
246
247 roll_nonces(session, &resp_auth.auths[1].nonce);
248
249 rc = Tss2_Sys_SetEncryptParam(sapi_context, decrypted_param.size,
250 decrypted_param.buffer);
251 if (rc) {
252 LOG_ERROR("Tss2_Sys_SetEncryptParam failed 0x%" PRIx32, rc);
253 goto clean;
254 }
255
256 rc = Tss2_Sys_NV_Read_Complete(sapi_context, &data_read);
257 if (rc) {
258 LOG_ERROR("Tss2_Sys_NV_Read_Complete failed 0x%" PRIx32, rc);
259 goto clean;
260 }
261
262 LOGBLOB_DEBUG(data_read.buffer, (UINT32)data_read.size, "Decrypted read data = ");
263
264 if (memcmp(data_read.buffer, data_to_write.buffer, data_read.size)) {
265 LOG_ERROR("Read data not equal to written data");
266 rc = 99;
267 goto clean;
268 }
269
270 rc = Tss2_Sys_FlushContext(sapi_context, session->sessionHandle);
271 if (rc)
272 LOG_ERROR("Tss2_Sys_FlushContext failed 0x%" PRIx32, rc);
273
274 end_auth_session(session);
275
276 clean:
277 req_auth.count = 1;
278 req_auth.auths[0].sessionHandle = TPM2_RS_PW;
279
280 rc2 = Tss2_Sys_NV_UndefineSpace(sapi_context, TPM2_RH_OWNER,
281 nv_index, &req_auth, 0);
282 if (rc2)
283 LOG_ERROR("Tss2_Sys_NV_UndefineSpace failed 0x%" PRIx32, rc);
284
285 if (rc == 0)
286 LOG_INFO("param-encrypt-decrypt test PASSED");
287
288 return rc;
289 }
290