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 <stdbool.h>
12 #include <stdlib.h>
13 #include <stdio.h>
14 #include <string.h>
15 #include <errno.h>
16 #include <fcntl.h>
17 #include <unistd.h>
18
19 #include "tss2_fapi.h"
20
21 #include "test-fapi.h"
22
23 #define LOGMODULE test
24 #include "util/log.h"
25 #include "util/aux_util.h"
26
27 static bool cb_called = false;
28
29 static TSS2_RC
branch_callback(FAPI_CONTEXT * context,char const * description,char const ** branchNames,size_t numBranches,size_t * selectedBranch,void * userData)30 branch_callback(
31 FAPI_CONTEXT *context,
32 char const *description,
33 char const **branchNames,
34 size_t numBranches,
35 size_t *selectedBranch,
36 void *userData)
37 {
38 (void) description;
39 (void) userData;
40
41 if (numBranches != 2) {
42 LOG_ERROR("Wrong number of branches");
43 return TSS2_FAPI_RC_GENERAL_FAILURE;
44 }
45
46 if (!strcmp(branchNames[0], "/policy/pol_name_hash"))
47 *selectedBranch = 0;
48 else if (!strcmp(branchNames[1], "/policy/pol_name_hash"))
49 *selectedBranch = 1;
50 else {
51 LOG_ERROR("BranchName not found. Got \"%s\" and \"%s\"",
52 branchNames[0], branchNames[1]);
53 return TSS2_FAPI_RC_GENERAL_FAILURE;
54 }
55
56 cb_called = true;
57
58 return TSS2_RC_SUCCESS;
59 }
60
61 /** Test the FAPI functions for PolicyAuthoirze with signing.
62 *
63 * Tested FAPI commands:
64 * - Fapi_Provision()
65 * - Fapi_SetBranchCB()
66 * - Fapi_Import()
67 * - Fapi_CreateKey()
68 * - Fapi_AuthorizePolicy()
69 * - Fapi_Sign()
70 * - Fapi_List()
71 * - Fapi_Delete()
72 *
73 * Tested Policies:
74 * - PolicyNameHash
75 * - PolicyAuthorize
76 * - PolicyCpHash (Not entered, only as alternative branch)
77 *
78 * @param[in,out] context The FAPI_CONTEXT.
79 * @retval EXIT_FAILURE
80 * @retval EXIT_SUCCESS
81 */
82 int
test_fapi_key_create_policy_authorize_sign(FAPI_CONTEXT * context)83 test_fapi_key_create_policy_authorize_sign(FAPI_CONTEXT *context)
84 {
85 TSS2_RC r;
86 char *policy_name_hash = "/policy/pol_name_hash";
87 char *policy_file_name_hash = TOP_SOURCEDIR "/test/data/fapi/policy/pol_name_hash.json";
88
89 /* This policy cannot succeed, but that's the intention. We authorize it but then choose
90 the other policy from branch selection. */
91 char *policy_cphash = "/policy/pol_cphash";
92 char *policy_file_cphash = TOP_SOURCEDIR "/test/data/fapi/policy/pol_cphash.json";
93 char *policy_name_authorize = "/policy/pol_authorize";
94 char *policy_file_authorize = TOP_SOURCEDIR "/test/data/fapi/policy/pol_authorize.json";
95 char *policy_name_authorize_outer = "/policy/pol_authorize_outer";
96 char *policy_file_authorize_outer = TOP_SOURCEDIR
97 "/test/data/fapi/policy/pol_authorize_outer.json";
98 uint8_t policyRef[] = { 1, 2, 3, 4, 5 };
99 FILE *stream = NULL;
100 char *json_policy = NULL;
101 long policy_size;
102
103 uint8_t *signature = NULL;
104 char *publicKey = NULL;
105 char *pathList = NULL;
106
107
108 r = Fapi_Provision(context, NULL, NULL, NULL);
109 goto_if_error(r, "Error Fapi_Provision", error);
110
111 r = pcr_reset(context, 16);
112 goto_if_error(r, "Error pcr_reset", error);
113
114 r = Fapi_SetBranchCB(context, branch_callback, NULL);
115 goto_if_error(r, "Error SetPolicybranchselectioncallback", error);
116
117 /* Read in the first policy */
118 stream = fopen(policy_file_name_hash, "r");
119 if (!stream) {
120 LOG_ERROR("File %s does not exist", policy_file_name_hash);
121 goto error;
122 }
123 fseek(stream, 0L, SEEK_END);
124 policy_size = ftell(stream);
125 fclose(stream);
126 json_policy = malloc(policy_size + 1);
127 goto_if_null(json_policy,
128 "Could not allocate memory for the JSON policy",
129 TSS2_FAPI_RC_MEMORY, error);
130 stream = fopen(policy_file_name_hash, "r");
131 ssize_t ret = read(fileno(stream), json_policy, policy_size);
132 if (ret != policy_size) {
133 LOG_ERROR("IO error %s.", policy_file_name_hash);
134 goto error;
135 }
136 json_policy[policy_size] = '\0';
137
138 r = Fapi_Import(context, policy_name_hash, json_policy);
139 SAFE_FREE(json_policy);
140 goto_if_error(r, "Error Fapi_List", error);
141
142 /* Read in the second policy */
143 stream = fopen(policy_file_cphash, "r");
144 if (!stream) {
145 LOG_ERROR("File %s does not exist", policy_file_name_hash);
146 goto error;
147 }
148 fseek(stream, 0L, SEEK_END);
149 policy_size = ftell(stream);
150 fclose(stream);
151 json_policy = malloc(policy_size + 1);
152 goto_if_null(json_policy,
153 "Could not allocate memory for the JSON policy",
154 TSS2_FAPI_RC_MEMORY, error);
155 stream = fopen(policy_file_cphash, "r");
156 ret = read(fileno(stream), json_policy, policy_size);
157 if (ret != policy_size) {
158 LOG_ERROR("IO error %s.", policy_file_name_hash);
159 goto error;
160 }
161 json_policy[policy_size] = '\0';
162
163 r = Fapi_Import(context, policy_cphash, json_policy);
164 SAFE_FREE(json_policy);
165 goto_if_error(r, "Error Fapi_List", error);
166
167 /* Read in the third policy */
168 stream = fopen(policy_file_authorize, "r");
169 if (!stream) {
170 LOG_ERROR("File %s does not exist", policy_file_authorize);
171 goto error;
172 }
173 fseek(stream, 0L, SEEK_END);
174 policy_size = ftell(stream);
175 fclose(stream);
176 json_policy = malloc(policy_size + 1);
177 goto_if_null(json_policy,
178 "Could not allocate memory for the JSON policy",
179 TSS2_FAPI_RC_MEMORY, error);
180 stream = fopen(policy_file_authorize, "r");
181 ret = read(fileno(stream), json_policy, policy_size);
182 if (ret != policy_size) {
183 LOG_ERROR("IO error %s.", policy_file_authorize);
184 goto error;
185 }
186 json_policy[policy_size] = '\0';
187
188 r = Fapi_Import(context, policy_name_authorize, json_policy);
189 SAFE_FREE(json_policy);
190 goto_if_error(r, "Error Fapi_Import", error);
191
192 /* Read in the fourth policy */
193 stream = fopen(policy_file_authorize_outer, "r");
194 if (!stream) {
195 LOG_ERROR("File %s does not exist", policy_file_authorize_outer);
196 goto error;
197 }
198 fseek(stream, 0L, SEEK_END);
199 policy_size = ftell(stream);
200 fclose(stream);
201 json_policy = malloc(policy_size + 1);
202 goto_if_null(json_policy,
203 "Could not allocate memory for the JSON policy",
204 TSS2_FAPI_RC_MEMORY, error);
205 stream = fopen(policy_file_authorize_outer, "r");
206 ret = read(fileno(stream), json_policy, policy_size);
207 if (ret != policy_size) {
208 LOG_ERROR("IO error %s.", policy_file_authorize_outer);
209 goto error;
210 }
211 json_policy[policy_size] = '\0';
212
213 r = Fapi_Import(context, policy_name_authorize_outer, json_policy);
214 SAFE_FREE(json_policy);
215 goto_if_error(r, "Error Fapi_Import", error);
216
217 /* Create keys and use them to authorize the authorize policy */
218 r = Fapi_CreateKey(context, "HS/SRK/myPolicySignKeyOuter", "sign,noDa",
219 "", NULL);
220 goto_if_error(r, "Error Fapi_CreateKey", error);
221
222 /* Create keys and use them to authorize policies */
223 r = Fapi_CreateKey(context, "HS/SRK/myPolicySignKey", "sign,noDa",
224 "", NULL);
225 goto_if_error(r, "Error Fapi_CreateKey", error);
226
227 /* Create the actual key */
228 r = Fapi_CreateKey(context, "HS/SRK/mySignKey", "sign, noda",
229 policy_name_authorize_outer, NULL);
230 goto_if_error(r, "Error Fapi_CreateKey", error);
231
232 /* Authorize the policies in sequence. */
233 r = Fapi_AuthorizePolicy(context, policy_name_authorize,
234 "HS/SRK/myPolicySignKeyOuter", NULL, 0);
235 goto_if_error(r, "Authorize policy", error);
236
237 r = Fapi_AuthorizePolicy(context, policy_name_hash,
238 "HS/SRK/myPolicySignKey", policyRef, sizeof(policyRef));
239 goto_if_error(r, "Authorize policy", error);
240
241 r = Fapi_AuthorizePolicy(context, policy_cphash,
242 "HS/SRK/myPolicySignKey", policyRef, sizeof(policyRef));
243 goto_if_error(r, "Authorize policy", error);
244
245 /* The policy is authorized twice with idfferent keys in order to test the code that
246 stores multiple authorizations inside the policy statements. */
247 r = Fapi_CreateKey(context, "HS/SRK/myPolicySignKey2", "sign,noDa",
248 "", NULL);
249 goto_if_error(r, "Error Fapi_CreateKey", error);
250
251 /* Use the key */
252 size_t signatureSize = 0;
253
254 TPM2B_DIGEST digest = {
255 .size = 32,
256 .buffer = {
257 0x67, 0x68, 0x03, 0x3e, 0x21, 0x64, 0x68, 0x24, 0x7b, 0xd0,
258 0x31, 0xa0, 0xa2, 0xd9, 0x87, 0x6d, 0x79, 0x81, 0x8f, 0x8f,
259 0x31, 0xa0, 0xa2, 0xd9, 0x87, 0x6d, 0x79, 0x81, 0x8f, 0x8f,
260 0x41, 0x42
261 }
262 };
263
264 r = Fapi_Sign(context, "HS/SRK/mySignKey", NULL,
265 &digest.buffer[0], digest.size, &signature, &signatureSize,
266 &publicKey, NULL);
267 goto_if_error(r, "Error Fapi_Sign", error);
268
269 r = Fapi_List(context, "/", &pathList);
270 goto_if_error(r, "Error Fapi_List", error);
271 SAFE_FREE(pathList);
272
273 r = Fapi_List(context, "/SRK/", &pathList);
274 goto_if_error(r, "Error Fapi_List", error);
275 fprintf(stderr, "\n%s\n", pathList);
276 SAFE_FREE(pathList);
277
278 r = Fapi_List(context, "/HS/", &pathList);
279 goto_if_error(r, "Error Fapi_List", error);
280 fprintf(stderr, "\n%s\n", pathList);
281 SAFE_FREE(pathList);
282
283 LOG_WARNING("Next is a failure-test, and we expect errors in the log");
284 r = Fapi_List(context, "XXX", &pathList);
285 if (r == TSS2_RC_SUCCESS) {
286 LOG_ERROR("Path XXX was found");
287 goto error;
288 }
289 SAFE_FREE(pathList);
290
291 r = Fapi_List(context, "/HS/", &pathList);
292 goto_if_error(r, "Error Fapi_List", error);
293 fprintf(stderr, "\n%s\n", pathList);
294 SAFE_FREE(pathList);
295
296 /* Cleanup */
297 r = Fapi_Delete(context, "/HS/SRK");
298 goto_if_error(r, "Error Fapi_Delete", error);
299
300 SAFE_FREE(signature);
301 SAFE_FREE(publicKey);
302
303 if (!cb_called) {
304 LOG_ERROR("Branch selection callback was not called.");
305 return EXIT_FAILURE;
306 }
307
308 return EXIT_SUCCESS;
309
310 error:
311 SAFE_FREE(json_policy);
312 SAFE_FREE(signature);
313 SAFE_FREE(publicKey);
314 SAFE_FREE(pathList);
315 Fapi_Delete(context, "/HS/SRK");
316 return EXIT_FAILURE;
317 }
318
319 int
test_invoke_fapi(FAPI_CONTEXT * fapi_context)320 test_invoke_fapi(FAPI_CONTEXT *fapi_context)
321 {
322 return test_fapi_key_create_policy_authorize_sign(fapi_context);
323 }
324