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 #include <stdio.h>
13 #include <inttypes.h>
14 #include <string.h>
15 #include <errno.h>
16 #include <fcntl.h>
17 #include <unistd.h>
18
19
20 #include "tss2_fapi.h"
21 #include "tss2_esys.h"
22 #include "tss2_tcti.h"
23
24 #include "test-fapi.h"
25
26 #define LOGMODULE test
27 #include "util/log.h"
28 #include "util/aux_util.h"
29
30 #define NV_SIZE 34
31 #define PASSWORD ""
32 #define SIGN_TEMPLATE "sign"
33
34 static TSS2_RC
check_tpm_cmd(FAPI_CONTEXT * context,TPM2_CC command_code)35 check_tpm_cmd(FAPI_CONTEXT *context, TPM2_CC command_code)
36 {
37 TSS2_RC r;
38 TSS2_TCTI_CONTEXT *tcti;
39 ESYS_CONTEXT *esys;
40 TPMS_CAPABILITY_DATA *cap_data;
41
42 r = Fapi_GetTcti(context, &tcti);
43 goto_if_error(r, "Error Fapi_GetTcti", error);
44
45 r = Esys_Initialize(&esys, tcti, NULL);
46 goto_if_error(r, "Error Fapi_GetTcti", error);
47
48 r = Esys_GetCapability(esys,
49 ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
50 TPM2_CAP_COMMANDS, command_code, 1, NULL, &cap_data);
51 Esys_Finalize(&esys);
52 return_if_error(r, "Error: GetCapabilities");
53
54 if ((cap_data->data.command.commandAttributes[0] & TPMA_CC_COMMANDINDEX_MASK) ==
55 command_code) {
56 free(cap_data);
57 return TSS2_RC_SUCCESS;
58 } else {
59 free(cap_data);
60 return TSS2_FAPI_RC_NOT_IMPLEMENTED;
61 }
62
63 error:
64 return r;
65 }
66
67 static char *
read_policy(FAPI_CONTEXT * context,char * policy_name)68 read_policy(FAPI_CONTEXT *context, char *policy_name)
69 {
70 FILE *stream = NULL;
71 long policy_size;
72 char *json_policy = NULL;
73 char policy_file[1024];
74
75 if (snprintf(&policy_file[0], 1023, TOP_SOURCEDIR "/test/data/fapi/%s.json", policy_name) < 0)
76 return NULL;
77
78 stream = fopen(policy_file, "r");
79 if (!stream) {
80 LOG_ERROR("File %s does not exist", policy_file);
81 return NULL;
82 }
83 fseek(stream, 0L, SEEK_END);
84 policy_size = ftell(stream);
85 fclose(stream);
86 json_policy = malloc(policy_size + 1);
87 stream = fopen(policy_file, "r");
88 ssize_t ret = read(fileno(stream), json_policy, policy_size);
89 if (ret != policy_size) {
90 LOG_ERROR("IO error %s.", policy_file);
91 return NULL;
92 }
93 json_policy[policy_size] = '\0';
94 return json_policy;
95 }
96
97 /** Test the FAPI key signing with PolicyAuthorizeNV.
98 *
99 * Tested FAPI commands:
100 * - Fapi_GetTcti()
101 * - Fapi_Provision()
102 * - Fapi_CreateNv()
103 * - Fapi_Import()
104 * - Fapi_WriteAuthorizeNv()
105 * - Fapi_CreateKey()
106 * - Fapi_Sign()
107 * - Fapi_Delete()
108 *
109 * Tested Policies:
110 * - PolicyAuthorizeNv
111 *
112 * @param[in,out] context The FAPI_CONTEXT.
113 * @retval EXIT_FAILURE
114 * @retval EXIT_SUCCESS
115 */
116 int
test_fapi_key_create_policy_authorize_nv(FAPI_CONTEXT * context)117 test_fapi_key_create_policy_authorize_nv(FAPI_CONTEXT *context)
118 {
119 TSS2_RC r;
120 char *nvPathPolicy = "/nv/Owner/myNV";
121 char *policy_authorize_nv = "/policy/pol_authorize_nv";
122 char *policy_pcr2 = "/policy/pol_pcr16_0";
123 char *json_policy = NULL;
124
125 uint8_t *signature = NULL;
126 char *publicKey = NULL;
127
128 if (check_tpm_cmd(context, TPM2_CC_PolicyAuthorizeNV) != TPM2_RC_SUCCESS) {
129 LOG_WARNING("Command PolicyAuthorizeNV not available.");
130 return EXIT_SKIP;
131 }
132
133 r = Fapi_Provision(context, NULL, NULL, NULL);
134 goto_if_error(r, "Error Fapi_Provision", error);
135
136 /* Create NV object for storing the policy */
137 r = Fapi_CreateNv(context, nvPathPolicy, "noda", 34, "", "");
138 goto_if_error(r, "Error Fapi_CreateNv", error);
139
140 r = pcr_reset(context, 16);
141 goto_if_error(r, "Error pcr_reset", error);
142
143 json_policy = read_policy(context, policy_authorize_nv);
144 if (!json_policy)
145 goto error;
146
147 r = Fapi_Import(context, policy_authorize_nv, json_policy);
148 goto_if_error(r, "Error Fapi_Import", error);
149 SAFE_FREE(json_policy);
150
151 json_policy = read_policy(context, policy_pcr2);
152 if (!json_policy)
153 goto error;
154
155 r = Fapi_Import(context, policy_pcr2, json_policy);
156 goto_if_error(r, "Error Fapi_Import", error);
157
158 r = Fapi_WriteAuthorizeNv(context,nvPathPolicy, policy_pcr2);
159 goto_if_error(r, "Error Fapi_WriteAuthorizeNv", error);
160
161 r = Fapi_CreateKey(context, "/HS/SRK/myPolicySignKey", "sign",
162 "", PASSWORD);
163 goto_if_error(r, "Error Fapi_CreateKey", error);
164
165 r = Fapi_CreateKey(context, "/HS/SRK/mySignKey", SIGN_TEMPLATE,
166 policy_authorize_nv, PASSWORD);
167 goto_if_error(r, "Error Fapi_CreateKey", error);
168
169 size_t signatureSize = 0;
170
171 TPM2B_DIGEST digest = {
172 .size = 20,
173 .buffer = {
174 0x67, 0x68, 0x03, 0x3e, 0x21, 0x64, 0x68, 0x24, 0x7b, 0xd0,
175 0x31, 0xa0, 0xa2, 0xd9, 0x87, 0x6d, 0x79, 0x81, 0x8f, 0x8f,
176 0x31, 0xa0, 0xa2, 0xd9, 0x87, 0x6d, 0x79, 0x81, 0x8f, 0x8f,
177 0x41, 0x42
178 }
179 };
180
181 r = Fapi_Sign(context, "/HS/SRK/mySignKey", NULL,
182 &digest.buffer[0], digest.size, &signature, &signatureSize,
183 &publicKey, NULL);
184 goto_if_error(r, "Error Fapi_Sign", error);
185
186 r = Fapi_Delete(context, nvPathPolicy);
187 goto_if_error(r, "Error Fapi_NV_Undefine", error);
188
189 r = Fapi_Delete(context, "/");
190 goto_if_error(r, "Error Fapi_Delete", error);
191
192 SAFE_FREE(json_policy);
193 SAFE_FREE(signature);
194 SAFE_FREE(publicKey);
195 return EXIT_SUCCESS;
196
197 error:
198 SAFE_FREE(json_policy);
199 SAFE_FREE(signature);
200 SAFE_FREE(publicKey);
201 return EXIT_FAILURE;
202 }
203
204 int
test_invoke_fapi(FAPI_CONTEXT * context)205 test_invoke_fapi(FAPI_CONTEXT *context)
206 {
207 return test_fapi_key_create_policy_authorize_nv(context);
208 }
209