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 <unistd.h>
16 
17 #include "tss2_fapi.h"
18 #include "tss2_esys.h"
19 
20 #include "test-fapi.h"
21 #define LOGMODULE test
22 #include "util/log.h"
23 #include "util/aux_util.h"
24 
25 static TSS2_RC
check_tpm_cmd(FAPI_CONTEXT * context,TPM2_CC command_code)26 check_tpm_cmd(FAPI_CONTEXT *context, TPM2_CC command_code)
27 {
28     TSS2_RC r;
29     TSS2_TCTI_CONTEXT *tcti;
30     ESYS_CONTEXT *esys;
31     TPMS_CAPABILITY_DATA *cap_data;
32 
33     r = Fapi_GetTcti(context, &tcti);
34     goto_if_error(r, "Error Fapi_GetTcti", error);
35 
36     r = Esys_Initialize(&esys, tcti, NULL);
37     goto_if_error(r, "Error Fapi_GetTcti", error);
38 
39     r = Esys_GetCapability(esys,
40                            ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
41                            TPM2_CAP_COMMANDS, command_code, 1, NULL, &cap_data);
42     Esys_Finalize(&esys);
43     return_if_error(r, "Error: GetCapabilities");
44 
45     if ((cap_data->data.command.commandAttributes[0] & TPMA_CC_COMMANDINDEX_MASK) ==
46             command_code) {
47         free(cap_data);
48         return TSS2_RC_SUCCESS;
49     } else {
50         free(cap_data);
51         return TSS2_FAPI_RC_NOT_IMPLEMENTED;
52     }
53 
54 error:
55     return r;
56 }
57 
58 /** Test the FAPI PolicyCpHash but means of AuthorizeNv.
59  *
60  * Tested FAPI commands:
61  *  - Fapi_GetTcti()
62  *  - Fapi_Provision()
63  *  - Fapi_Import()
64  *  - Fapi_CreateNv()
65  *  - Fapi_WriteAuthorizeNv
66  *  - Fapi_NvWrite()
67  *
68  * Tested Policies:
69  *  - PolicyAuthorize
70  *  - PolicyCpHash
71  *
72  * @param[in,out] context The FAPI_CONTEXT.
73  * @retval EXIT_FAILURE
74  * @retval EXIT_SUCCESS
75  */
76 int
test_fapi_nv_authorizenv_cphash(FAPI_CONTEXT * context)77 test_fapi_nv_authorizenv_cphash(FAPI_CONTEXT *context)
78 {
79     TSS2_RC r;
80     ssize_t ret;
81     uint8_t data[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
82     char *policy1_name = "/policy/pol_authorize_nv";
83     char *policy1_file = TOP_SOURCEDIR "/test/data/fapi/policy/pol_authorize_nv.json";
84     char *policy2_name = "/policy/pol_cphash";
85     char *policy2_file = TOP_SOURCEDIR "/test/data/fapi/policy/pol_cphash.json";
86     FILE *stream = NULL;
87     char json[1024];
88 
89     if (check_tpm_cmd(context, TPM2_CC_PolicyAuthorizeNV) != TPM2_RC_SUCCESS) {
90         LOG_WARNING("Command PolicyAuthorizeNV not available.");
91         return EXIT_SKIP;
92     }
93 
94     r = Fapi_Provision(context, NULL, NULL, NULL);
95     goto_if_error(r, "Error Fapi_Provision", error);
96 
97     memset(&json[0], 0, sizeof(json));
98     stream = fopen(policy1_file, "r");
99     ret = read(fileno(stream), &json[0], sizeof(json));
100     fclose(stream);
101     if (ret < 0) {
102         LOG_ERROR("IO error %s.", policy1_file);
103         goto error;
104     }
105     json[ret] = '\0';
106     r = Fapi_Import(context, policy1_name, json);
107     goto_if_error(r, "Error Fapi_Import", error);
108 
109     memset(&json[0], 0, sizeof(json));
110     stream = fopen(policy2_file, "r");
111     ret = read(fileno(stream), &json[0], sizeof(json));
112     fclose(stream);
113     if (ret < 0) {
114         LOG_ERROR("IO error %s.", policy2_file);
115         goto error;
116     }
117     json[ret] = '\0';
118     r = Fapi_Import(context, policy2_name, json);
119     goto_if_error(r, "Error Fapi_Import", error);
120 
121     /* Start the test */
122 
123     r = Fapi_CreateNv(context, "/nv/Owner/myNV", "", 34, "", "");
124     goto_if_error(r, "Error Fapi_CreateNv", error);
125 
126 
127     r = Fapi_CreateNv(context, "/nv/Owner/myNV2", "", sizeof(data), policy1_name, "");
128     goto_if_error(r, "Error Fapi_CreateNv", error);
129 
130     r = Fapi_WriteAuthorizeNv(context, "/nv/Owner/myNV", policy2_name);
131     goto_if_error(r, "Error Fapi_WriteAuthorizeNv", error);
132 
133     r = Fapi_NvWrite(context, "/nv/Owner/myNV2", &data[0], sizeof(data));
134     goto_if_error(r, "Error Fapi_NvWrite", error);
135 
136     /* Cleanup */
137 
138     r = Fapi_Delete(context, "/nv/Owner/myNV");
139     goto_if_error(r, "Error Fapi_NV_Undefine", error);
140 
141     r = Fapi_Delete(context, "/nv/Owner/myNV2");
142     goto_if_error(r, "Error Fapi_NV_Undefine", error);
143 
144     r = Fapi_Delete(context, "/");
145     goto_if_error(r, "Error Fapi_Delete", error);
146 
147     return EXIT_SUCCESS;
148 
149 error:
150     return EXIT_FAILURE;
151 }
152 
153 int
test_invoke_fapi(FAPI_CONTEXT * context)154 test_invoke_fapi(FAPI_CONTEXT *context)
155 {
156     return test_fapi_nv_authorizenv_cphash(context);
157 }
158