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 
13 #include "tss2_esys.h"
14 
15 #include "esys_iutil.h"
16 #define LOGMODULE test
17 #include "util/log.h"
18 #include "util/aux_util.h"
19 
20 /** This test is intended to test the ESYS nv define space, nv extend, and
21  *  nv read command.
22  *  The names stored in the ESYS resource are compared
23  * with the names delivered from the TPM by the command ReadPublic.
24  *
25  * Tested ESYS commands:
26  *  - Esys_FlushContext() (M)
27  *  - Esys_NV_DefineSpace() (M)
28  *  - Esys_NV_Extend() (M)
29  *  - Esys_NV_Read() (M)
30  *  - Esys_NV_ReadPublic() (M)
31  *  - Esys_NV_UndefineSpace() (M)
32  *  - Esys_StartAuthSession() (M)
33  *
34  * Used compiler defines: TEST_SESSION
35  *
36  * @param[in,out] esys_context The ESYS_CONTEXT.
37  * @retval EXIT_FAILURE
38  * @retval EXIT_SUCCESS
39  */
40 
41 int
test_esys_nv_ram_extend_index(ESYS_CONTEXT * esys_context)42 test_esys_nv_ram_extend_index(ESYS_CONTEXT * esys_context)
43 {
44 
45     TSS2_RC r;
46     ESYS_TR nvHandle = ESYS_TR_NONE;
47 
48     TPM2B_NV_PUBLIC *nvPublic = NULL;
49     TPM2B_NAME *nvName = NULL;
50     TPM2B_MAX_NV_BUFFER *nv_test_data2 = NULL;
51 
52 #ifdef TEST_SESSION
53     ESYS_TR session = ESYS_TR_NONE;
54     TPMT_SYM_DEF symmetric = {.algorithm = TPM2_ALG_AES,
55                               .keyBits = {.aes = 128},
56                               .mode = {.aes = TPM2_ALG_CFB}
57     };
58     TPMA_SESSION sessionAttributes;
59     TPM2B_NONCE nonceCaller = {
60         .size = 32,
61         .buffer = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,11, 12, 13, 14, 15, 16, 17,
62                     18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32 }
63     };
64 
65     memset(&sessionAttributes, 0, sizeof sessionAttributes);
66 
67     r = Esys_StartAuthSession(esys_context, ESYS_TR_NONE, ESYS_TR_NONE,
68                               ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE,
69                               &nonceCaller,
70                               TPM2_SE_HMAC, &symmetric, TPM2_ALG_SHA256,
71                               &session);
72     goto_if_error(r, "Error: During initialization of session", error);
73 #endif /* TEST_SESSION */
74 
75     TPM2B_AUTH auth = {.size = 20,
76                        .buffer={10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
77                                 20, 21, 22, 23, 24, 25, 26, 27, 28, 29}};
78 
79     TPM2B_NV_PUBLIC publicInfo = {
80         .size = 0,
81         .nvPublic = {
82             .nvIndex =TPM2_NV_INDEX_FIRST,
83             .nameAlg = TPM2_ALG_SHA256,
84             .attributes = (
85                 TPMA_NV_OWNERWRITE |
86                 TPMA_NV_AUTHWRITE |
87                 TPMA_NV_WRITE_STCLEAR |
88                 TPMA_NV_AUTHREAD |
89                 TPMA_NV_OWNERREAD |
90                 TPM2_NT_EXTEND << TPMA_NV_TPM2_NT_SHIFT
91                 ),
92             .authPolicy = {
93                  .size = 0,
94                  .buffer = {},
95              },
96             .dataSize = 32,
97         }
98     };
99 
100     r = Esys_NV_DefineSpace (
101         esys_context,
102         ESYS_TR_RH_OWNER,
103 #ifdef TEST_SESSION
104         session,
105 #else
106         ESYS_TR_PASSWORD,
107 #endif
108         ESYS_TR_NONE,
109         ESYS_TR_NONE,
110         &auth,
111         &publicInfo,
112         &nvHandle);
113 
114     goto_if_error(r, "Error esys define nv space", error);
115 
116     TPM2B_MAX_NV_BUFFER nv_test_data = { .size = 20,
117                                          .buffer={0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0,
118                                                   1, 2, 3, 4, 5, 6, 7, 8, 9}};
119 
120     r = Esys_NV_ReadPublic(
121         esys_context,
122         nvHandle,
123         ESYS_TR_NONE,
124         ESYS_TR_NONE,
125         ESYS_TR_NONE,
126         &nvPublic,
127         &nvName);
128     goto_if_error(r, "Error: nv read public", error);
129 
130     RSRC_NODE_T *nvHandleNode;
131 
132     r = esys_GetResourceObject(esys_context, nvHandle, &nvHandleNode);
133     goto_if_error(r, "Error: nv get resource object", error);
134 
135     if (nvName->size != nvHandleNode->rsrc.name.size ||
136         memcmp(&nvName->name, &nvHandleNode->rsrc.name.name, nvName->size) != 0) {
137         LOG_ERROR("Error: define space name not equal");
138         goto error;
139     }
140     r = Esys_NV_Extend (
141         esys_context,
142         nvHandle,
143         nvHandle,
144 #ifdef TEST_SESSION
145         session,
146 #else
147         ESYS_TR_PASSWORD,
148 #endif
149         ESYS_TR_NONE,
150         ESYS_TR_NONE,
151         &nv_test_data);
152 
153     goto_if_error(r, "Error esys nv write", error);
154     Esys_Free(nvPublic);
155     Esys_Free(nvName);
156 
157     r = Esys_NV_ReadPublic(
158         esys_context,
159         nvHandle,
160         ESYS_TR_NONE,
161         ESYS_TR_NONE,
162         ESYS_TR_NONE,
163         &nvPublic,
164         &nvName);
165     goto_if_error(r, "Error: nv read public", error);
166 
167     r = esys_GetResourceObject(esys_context, nvHandle, &nvHandleNode);
168     goto_if_error(r, "Error: nv get resource object", error);
169 
170     if (nvName->size != nvHandleNode->rsrc.name.size ||
171         memcmp(&nvName->name, &nvHandleNode->rsrc.name.name, nvName->size) != 0) {
172         LOG_ERROR("Error: nv write name not equal");
173         goto error;
174     }
175 
176     r = Esys_NV_Read(
177         esys_context,
178         nvHandle,
179         nvHandle,
180 #ifdef TEST_SESSION
181         session,
182 #else
183         ESYS_TR_PASSWORD,
184 #endif
185         ESYS_TR_NONE,
186         ESYS_TR_NONE,
187         20,
188         0,
189         &nv_test_data2);
190 
191     goto_if_error(r, "Error esys nv read", error);
192 
193     Esys_Free(nvPublic);
194     Esys_Free(nvName);
195 
196     r = Esys_NV_ReadPublic(
197         esys_context,
198         nvHandle,
199         ESYS_TR_NONE,
200         ESYS_TR_NONE,
201         ESYS_TR_NONE,
202         &nvPublic,
203         &nvName);
204     goto_if_error(r, "Error: nv read public", error);
205 
206     r = esys_GetResourceObject(esys_context, nvHandle, &nvHandleNode);
207     goto_if_error(r, "Error: nv get resource object", error);
208 
209     if (nvName->size != nvHandleNode->rsrc.name.size ||
210         memcmp(&nvName->name, &nvHandleNode->rsrc.name.name, nvName->size) != 0) {
211         LOG_ERROR("Error: nv read name not equal");
212         goto error;
213     }
214 
215     r = Esys_NV_UndefineSpace(esys_context,
216                               ESYS_TR_RH_OWNER,
217                               nvHandle,
218 #ifdef TEST_SESSION
219                               session,
220 #else
221                               ESYS_TR_PASSWORD,
222 #endif
223                               ESYS_TR_NONE,
224                               ESYS_TR_NONE
225                               );
226     goto_if_error(r, "Error: NV_UndefineSpace", error);
227 
228 #ifdef TEST_SESSION
229     r = Esys_FlushContext(esys_context, session);
230     goto_if_error(r, "Flushing context", error);
231 #endif
232 
233     Esys_Free(nvPublic);
234     Esys_Free(nvName);
235     Esys_Free(nv_test_data2);
236     return EXIT_SUCCESS;
237 
238  error:
239 
240     if (nvHandle != ESYS_TR_NONE) {
241         if (Esys_NV_UndefineSpace(esys_context,
242                                   ESYS_TR_RH_OWNER,
243                                   nvHandle,
244 #ifdef TEST_SESSION
245                                   session,
246 #else
247                                   ESYS_TR_PASSWORD,
248 #endif
249                                   ESYS_TR_NONE,
250                                   ESYS_TR_NONE) != TSS2_RC_SUCCESS) {
251             LOG_ERROR("Cleanup nvHandle failed.");
252         }
253     }
254 
255 #ifdef TEST_SESSION
256     if (session != ESYS_TR_NONE) {
257         if (Esys_FlushContext(esys_context, session) != TSS2_RC_SUCCESS) {
258             LOG_ERROR("Cleanup session failed.");
259         }
260     }
261 #endif
262 
263     Esys_Free(nvPublic);
264     Esys_Free(nvName);
265     Esys_Free(nv_test_data2);
266     return EXIT_FAILURE;
267 }
268 
269 int
test_invoke_esys(ESYS_CONTEXT * esys_context)270 test_invoke_esys(ESYS_CONTEXT * esys_context) {
271     return test_esys_nv_ram_extend_index(esys_context);
272 }
273