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