• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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