1 /* SPDX-License-Identifier: BSD-2-Clause */
2 /***********************************************************************
3  * Copyright (c) 2017-2018, Intel Corporation
4  *
5  * All rights reserved.
6  ***********************************************************************/
7 #ifdef HAVE_CONFIG_H
8 #include <config.h>
9 #endif
10 
11 #include <stdarg.h>
12 #include <stddef.h>
13 #include <setjmp.h>
14 #include <cmocka.h>
15 #include <stdio.h>
16 #include "tss2_mu.h"
17 #include "util/tss2_endian.h"
18 
19 /*
20  * Success case
21  */
22 static void
tpms_marshal_success(void ** state)23 tpms_marshal_success(void **state)
24 {
25     TPMS_ALG_PROPERTY alg = {0};
26     TPMS_CAPABILITY_DATA cap = {0};
27     uint8_t buffer[sizeof(alg)] = { 0 };
28     size_t  buffer_size = sizeof(buffer);
29     uint8_t buffer2[sizeof(cap)] = { 0 };
30     size_t  buffer_size2 = sizeof(buffer2);
31     uint16_t *alg_ptr;
32     uint32_t *alg_properties_ptr;
33     TPMS_CAPABILITY_DATA *ptr2;
34     uint16_t alg_expected = HOST_TO_BE_16(TPM2_ALG_ECDSA);
35     uint32_t algprop_expected = HOST_TO_BE_32(TPMA_ALGORITHM_ASYMMETRIC | TPMA_ALGORITHM_SIGNING);
36     uint32_t capability = HOST_TO_BE_32(TPM2_CAP_ECC_CURVES);
37     TSS2_RC rc;
38 
39     alg.alg = TPM2_ALG_ECDSA;
40     alg.algProperties |= TPMA_ALGORITHM_ASYMMETRIC;
41     alg.algProperties |= TPMA_ALGORITHM_SIGNING;
42     alg_ptr = (uint16_t *)buffer;
43     alg_properties_ptr = (uint32_t *)(buffer + sizeof(uint16_t));
44     rc = Tss2_MU_TPMS_ALG_PROPERTY_Marshal(&alg, buffer, buffer_size, NULL);
45     assert_int_equal (rc, TSS2_RC_SUCCESS);
46     assert_int_equal (*alg_ptr, alg_expected);
47     assert_int_equal (*alg_properties_ptr, algprop_expected);
48 
49     cap.capability = TPM2_CAP_ECC_CURVES;
50     cap.data.eccCurves.count = 3;
51     cap.data.eccCurves.eccCurves[0] = TPM2_ECC_NIST_P256;
52     cap.data.eccCurves.eccCurves[1] = TPM2_ECC_NIST_P384;
53     cap.data.eccCurves.eccCurves[2] = TPM2_ECC_NIST_P521;
54     ptr2 = (TPMS_CAPABILITY_DATA *)buffer2;
55 
56     rc = Tss2_MU_TPMS_CAPABILITY_DATA_Marshal(&cap, buffer2, buffer_size2, NULL);
57     assert_int_equal (rc, TSS2_RC_SUCCESS);
58     assert_int_equal (ptr2->capability, capability);
59     assert_int_equal (ptr2->data.eccCurves.count, HOST_TO_BE_32(3));
60     assert_int_equal (ptr2->data.eccCurves.eccCurves[0], HOST_TO_BE_16(TPM2_ECC_NIST_P256));
61     assert_int_equal (ptr2->data.eccCurves.eccCurves[1], HOST_TO_BE_16(TPM2_ECC_NIST_P384));
62     assert_int_equal (ptr2->data.eccCurves.eccCurves[2], HOST_TO_BE_16(TPM2_ECC_NIST_P521));
63 }
64 
65 /*
66  * Success case with a valid offset
67  */
68 static void
tpms_marshal_success_offset(void ** state)69 tpms_marshal_success_offset(void **state)
70 {
71     TPMS_ALG_PROPERTY alg = {0};
72     TPMS_CAPABILITY_DATA cap = {0};
73     uint8_t buffer[sizeof(alg) + sizeof(cap) + 10] = { 0 };
74     size_t  buffer_size = sizeof(buffer);
75     uint16_t *alg_ptr;
76     uint32_t *alg_properties_ptr;
77     TPMS_CAPABILITY_DATA *ptr2;
78     uint16_t alg_expected = HOST_TO_BE_16(TPM2_ALG_ECDSA);
79     uint32_t algprop_expected = HOST_TO_BE_32(TPMA_ALGORITHM_ASYMMETRIC | TPMA_ALGORITHM_SIGNING);
80     uint32_t capability = HOST_TO_BE_32(TPM2_CAP_ECC_CURVES);
81     size_t offset = 10;
82     TSS2_RC rc;
83 
84     alg.alg = TPM2_ALG_ECDSA;
85     alg.algProperties |= TPMA_ALGORITHM_ASYMMETRIC;
86     alg.algProperties |= TPMA_ALGORITHM_SIGNING;
87     alg_ptr = (uint16_t *)(buffer + 10);
88     alg_properties_ptr = (uint32_t *)(buffer + sizeof(*alg_ptr) + 10);
89 
90     rc = Tss2_MU_TPMS_ALG_PROPERTY_Marshal(&alg, buffer, buffer_size, &offset);
91     assert_int_equal (rc, TSS2_RC_SUCCESS);
92     assert_int_equal (*alg_ptr, alg_expected);
93     assert_int_equal (*alg_properties_ptr, algprop_expected);
94 
95     cap.capability = TPM2_CAP_ECC_CURVES;
96     cap.data.eccCurves.count = 3;
97     cap.data.eccCurves.eccCurves[0] = TPM2_ECC_NIST_P256;
98     cap.data.eccCurves.eccCurves[1] = TPM2_ECC_NIST_P384;
99     cap.data.eccCurves.eccCurves[2] = TPM2_ECC_NIST_P521;
100     ptr2 = (TPMS_CAPABILITY_DATA *)(buffer + 10 + sizeof(*alg_ptr) + sizeof(*alg_properties_ptr));
101 
102     rc = Tss2_MU_TPMS_CAPABILITY_DATA_Marshal(&cap, buffer, buffer_size, &offset);
103     assert_int_equal (rc, TSS2_RC_SUCCESS);
104     assert_int_equal (ptr2->capability, capability);
105     assert_int_equal (ptr2->data.eccCurves.count, HOST_TO_BE_32(3));
106     assert_int_equal (ptr2->data.eccCurves.eccCurves[0], HOST_TO_BE_16(TPM2_ECC_NIST_P256));
107     assert_int_equal (ptr2->data.eccCurves.eccCurves[1], HOST_TO_BE_16(TPM2_ECC_NIST_P384));
108     assert_int_equal (ptr2->data.eccCurves.eccCurves[2], HOST_TO_BE_16(TPM2_ECC_NIST_P521));
109     assert_int_equal (offset, 10 + sizeof(*alg_ptr) + sizeof(*alg_properties_ptr) + sizeof(capability) + 4 + (3 * 2));
110 }
111 
112 /*
113  * Success case with a null buffer
114  */
115 static void
tpms_marshal_buffer_null_with_offset(void ** state)116 tpms_marshal_buffer_null_with_offset(void **state)
117 {
118     TPMS_ALG_PROPERTY alg = {0};
119     TPMS_CAPABILITY_DATA cap = {0};
120     uint16_t *alg_ptr;
121     uint32_t *alg_properties_ptr;
122     size_t offset = 100;
123     TSS2_RC rc;
124 
125     alg.alg = TPM2_ALG_ECDSA;
126     alg.algProperties |= TPMA_ALGORITHM_ASYMMETRIC;
127     alg.algProperties |= TPMA_ALGORITHM_SIGNING;
128 
129     rc = Tss2_MU_TPMS_ALG_PROPERTY_Marshal(&alg, NULL, sizeof(alg), &offset);
130     assert_int_equal (rc, TSS2_RC_SUCCESS);
131     assert_int_equal (offset, 100 + sizeof(*alg_ptr) + sizeof(*alg_properties_ptr));
132 
133     cap.capability = TPM2_CAP_ECC_CURVES;
134     cap.data.eccCurves.count = 3;
135     cap.data.eccCurves.eccCurves[0] = TPM2_ECC_NIST_P256;
136     cap.data.eccCurves.eccCurves[1] = TPM2_ECC_NIST_P384;
137     cap.data.eccCurves.eccCurves[2] = TPM2_ECC_NIST_P521;
138 
139     rc = Tss2_MU_TPMS_CAPABILITY_DATA_Marshal(&cap, NULL, sizeof(cap), &offset);
140     assert_int_equal (rc, TSS2_RC_SUCCESS);
141     assert_int_equal (offset, 100 + sizeof(*alg_ptr) + sizeof(*alg_properties_ptr) + 4 + 4 + (3 * 2));
142 }
143 
144 /*
145  * Invalid case with a null buffer and a null offset
146  */
147 static void
tpms_marshal_buffer_null_offset_null(void ** state)148 tpms_marshal_buffer_null_offset_null(void **state)
149 {
150     TPMS_ALG_PROPERTY alg = {0};
151     TPMS_CAPABILITY_DATA cap = {0};
152     TSS2_RC rc;
153 
154     rc = Tss2_MU_TPMS_ALG_PROPERTY_Marshal(&alg, NULL, sizeof(alg), NULL);
155     assert_int_equal (rc, TSS2_MU_RC_BAD_REFERENCE);
156 
157     rc = Tss2_MU_TPMS_CAPABILITY_DATA_Marshal(&cap, NULL, sizeof(cap), NULL);
158     assert_int_equal (rc, TSS2_MU_RC_BAD_REFERENCE);
159 }
160 
161 /*
162  * Invalid case with not big enough buffer
163  */
164 static void
tpms_marshal_buffer_size_lt_data_nad_lt_offset(void ** state)165 tpms_marshal_buffer_size_lt_data_nad_lt_offset(void **state)
166 {
167     TPMS_ALG_PROPERTY alg = {0};
168     TPMS_CAPABILITY_DATA cap = {0};
169     uint8_t buffer[sizeof(alg) + sizeof(cap)] = { 0 };
170     size_t  buffer_size = sizeof(alg);
171     size_t offset = 10;
172     TSS2_RC rc;
173 
174     alg.alg = TPM2_ALG_ECDSA;
175     alg.algProperties |= TPMA_ALGORITHM_ASYMMETRIC;
176     alg.algProperties |= TPMA_ALGORITHM_SIGNING;
177     rc = Tss2_MU_TPMS_ALG_PROPERTY_Marshal(&alg, buffer, buffer_size, &offset);
178     assert_int_equal (rc, TSS2_MU_RC_INSUFFICIENT_BUFFER);
179     assert_int_equal (offset, 10);
180 
181     buffer_size = 4;
182     offset = 2;
183     cap.capability = TPM2_CAP_ECC_CURVES;
184     cap.data.eccCurves.count = 3;
185     cap.data.eccCurves.eccCurves[0] = TPM2_ECC_NIST_P256;
186     cap.data.eccCurves.eccCurves[1] = TPM2_ECC_NIST_P384;
187     cap.data.eccCurves.eccCurves[2] = TPM2_ECC_NIST_P521;
188     rc = Tss2_MU_TPMS_CAPABILITY_DATA_Marshal(&cap, buffer, buffer_size, &offset);
189     assert_int_equal (rc, TSS2_MU_RC_INSUFFICIENT_BUFFER);
190     assert_int_equal (offset, 2);
191 }
192 
193 /*
194  * Success case
195  */
196 static void
tpms_unmarshal_success(void ** state)197 tpms_unmarshal_success(void **state)
198 {
199     TPMS_ALG_PROPERTY alg = {0};
200     TPMS_CAPABILITY_DATA cap = {0};
201     uint8_t buffer[sizeof(alg) + sizeof(cap)] = { 0 };
202     size_t  buffer_size = sizeof(buffer);
203     uint16_t *alg_ptr;
204     uint32_t *alg_properties_ptr;
205     TPMS_CAPABILITY_DATA *ptr2;
206     uint16_t alg_expected = TPM2_ALG_ECDSA;
207     uint32_t algprop_expected = TPMA_ALGORITHM_ASYMMETRIC | TPMA_ALGORITHM_SIGNING;
208     uint32_t capability = TPM2_CAP_ECC_CURVES;
209     size_t offset = 0;
210     TSS2_RC rc;
211 
212     alg_ptr = (uint16_t *) buffer;
213     *alg_ptr = HOST_TO_BE_16(TPM2_ALG_ECDSA);
214     alg_properties_ptr = (uint32_t *) (buffer + sizeof(*alg_ptr));
215     *alg_properties_ptr = HOST_TO_BE_32(TPMA_ALGORITHM_ASYMMETRIC | TPMA_ALGORITHM_SIGNING);
216 
217     rc = Tss2_MU_TPMS_ALG_PROPERTY_Unmarshal(buffer, buffer_size, &offset, &alg);
218     assert_int_equal (rc, TSS2_RC_SUCCESS);
219     assert_int_equal (alg.alg, alg_expected);
220     assert_int_equal (alg.algProperties, algprop_expected);
221 
222     ptr2 = (TPMS_CAPABILITY_DATA *)(buffer + sizeof(alg));
223     ptr2->capability = HOST_TO_BE_32(TPM2_CAP_ECC_CURVES);
224     ptr2->data.eccCurves.count = HOST_TO_BE_32(3);
225     ptr2->data.eccCurves.eccCurves[0] = HOST_TO_BE_16(TPM2_ECC_NIST_P256);
226     ptr2->data.eccCurves.eccCurves[1] = HOST_TO_BE_16(TPM2_ECC_NIST_P384);
227     ptr2->data.eccCurves.eccCurves[2] = HOST_TO_BE_16(TPM2_ECC_NIST_P521);
228 
229     offset = sizeof(alg);
230     rc = Tss2_MU_TPMS_CAPABILITY_DATA_Unmarshal(buffer, buffer_size, &offset, &cap);
231     assert_int_equal (rc, TSS2_RC_SUCCESS);
232     assert_int_equal (cap.capability, capability);
233     assert_int_equal (cap.data.eccCurves.count, 3);
234     assert_int_equal (cap.data.eccCurves.eccCurves[0], TPM2_ECC_NIST_P256);
235     assert_int_equal (cap.data.eccCurves.eccCurves[1], TPM2_ECC_NIST_P384);
236     assert_int_equal (cap.data.eccCurves.eccCurves[2], TPM2_ECC_NIST_P521);
237     assert_int_equal (offset, sizeof(alg) + sizeof(capability) + 4 + (3 * 2));
238 }
239 
240 /*
241  * Invalid test case with buffer null and dest null
242  */
243 static void
tpms_unmarshal_dest_null_buff_null(void ** state)244 tpms_unmarshal_dest_null_buff_null(void **state)
245 {
246     size_t offset = 1;
247     TSS2_RC rc;
248 
249     rc = Tss2_MU_TPMS_ALG_PROPERTY_Unmarshal(NULL, 120, &offset, NULL);
250     assert_int_equal (rc, TSS2_MU_RC_BAD_REFERENCE);
251     assert_int_equal (offset, 1);
252 
253     rc = Tss2_MU_TPMS_CAPABILITY_DATA_Unmarshal(NULL, 120, &offset, NULL);
254     assert_int_equal (rc, TSS2_MU_RC_BAD_REFERENCE);
255     assert_int_equal (offset, 1);
256 }
257 
258 /*
259  * Invalid test case with offset null and dest null
260  */
261 static void
tpms_unmarshal_buffer_null_offset_null(void ** state)262 tpms_unmarshal_buffer_null_offset_null(void **state)
263 {
264     uint8_t buffer[sizeof(TPMS_ALG_PROPERTY) + sizeof(TPMS_CAPABILITY_DATA)] = { 0 };
265     size_t  buffer_size = sizeof(buffer);
266     TSS2_RC rc;
267 
268     rc = Tss2_MU_TPMS_ALG_PROPERTY_Unmarshal(buffer, buffer_size, NULL, NULL);
269     assert_int_equal (rc, TSS2_MU_RC_BAD_REFERENCE);
270 
271     rc = Tss2_MU_TPMS_CAPABILITY_DATA_Unmarshal(buffer, buffer_size, NULL, NULL);
272     assert_int_equal (rc, TSS2_MU_RC_BAD_REFERENCE);
273 }
274 
275 /*
276  * Test case ensures the offset is updated when dest is NULL
277  * and offset is valid
278  */
279 static void
tpms_unmarshal_dest_null_offset_valid(void ** state)280 tpms_unmarshal_dest_null_offset_valid(void **state)
281 {
282     uint8_t buffer[sizeof(TPMS_ALG_PROPERTY) + sizeof(TPMS_CAPABILITY_DATA)] = { 0 };
283     size_t  buffer_size = sizeof(buffer);
284     uint16_t *alg_ptr;
285     uint32_t *alg_properties_ptr;
286     TPMS_CAPABILITY_DATA *ptr2;
287     size_t offset = 0;
288     TSS2_RC rc;
289 
290     alg_ptr = (uint16_t *) buffer;
291     *alg_ptr = HOST_TO_BE_16(TPM2_ALG_ECDSA);
292     alg_properties_ptr = (uint32_t *) (buffer + sizeof(*alg_ptr));
293     *alg_properties_ptr = HOST_TO_BE_32(TPMA_ALGORITHM_ASYMMETRIC | TPMA_ALGORITHM_SIGNING);
294 
295     rc = Tss2_MU_TPMS_ALG_PROPERTY_Unmarshal(buffer, buffer_size, &offset, NULL);
296     assert_int_equal (rc, TSS2_RC_SUCCESS);
297     assert_int_equal (offset, sizeof(*alg_ptr) + sizeof(*alg_properties_ptr));
298 
299     ptr2 = (TPMS_CAPABILITY_DATA *)(buffer + sizeof(TPMS_ALG_PROPERTY));
300     ptr2->capability = HOST_TO_BE_32(TPM2_CAP_ECC_CURVES);
301     ptr2->data.eccCurves.count = HOST_TO_BE_32(3);
302     ptr2->data.eccCurves.eccCurves[0] = HOST_TO_BE_16(TPM2_ECC_NIST_P256);
303     ptr2->data.eccCurves.eccCurves[1] = HOST_TO_BE_16(TPM2_ECC_NIST_P384);
304     ptr2->data.eccCurves.eccCurves[2] = HOST_TO_BE_16(TPM2_ECC_NIST_P521);
305 
306     offset = sizeof(TPMS_ALG_PROPERTY);
307     rc = Tss2_MU_TPMS_CAPABILITY_DATA_Unmarshal(buffer, buffer_size, &offset, NULL);
308     assert_int_equal (rc, TSS2_RC_SUCCESS);
309     assert_int_equal (offset, sizeof(TPMS_ALG_PROPERTY) + 4 + 4 + (3 * 2));
310 }
311 
312 /*
313  * Invalid case with not big enough buffer. Make sure offest is untouched.
314  */
315 static void
tpms_unmarshal_buffer_size_lt_data_nad_lt_offset(void ** state)316 tpms_unmarshal_buffer_size_lt_data_nad_lt_offset(void **state)
317 {
318     TPMS_ALG_PROPERTY alg = {0};
319     TPMS_CAPABILITY_DATA cap = {0};
320     uint8_t buffer[sizeof(alg) + sizeof(cap) + 1] = { 0 };
321     TPMS_ALG_PROPERTY *ptr;
322     TPMS_CAPABILITY_DATA *ptr2;
323     size_t offset = 3;
324     TSS2_RC rc;
325 
326     ptr = (TPMS_ALG_PROPERTY *) buffer;
327     ptr->alg = HOST_TO_BE_16(TPM2_ALG_ECDSA);
328     ptr->algProperties = HOST_TO_BE_32(TPMA_ALGORITHM_ASYMMETRIC | TPMA_ALGORITHM_SIGNING);
329     rc = Tss2_MU_TPMS_ALG_PROPERTY_Unmarshal(buffer, sizeof(alg), &offset, &alg);
330     assert_int_equal (rc, TSS2_MU_RC_INSUFFICIENT_BUFFER);
331     assert_int_equal (offset, 3);
332 
333     offset = sizeof(alg);
334     ptr2 = (TPMS_CAPABILITY_DATA *)(buffer + sizeof(alg) + 3);
335     ptr2->capability = HOST_TO_BE_32(TPM2_CAP_ECC_CURVES);
336     ptr2->data.eccCurves.count = HOST_TO_BE_32(3);
337     ptr2->data.eccCurves.eccCurves[0] = HOST_TO_BE_16(TPM2_ECC_NIST_P256);
338     ptr2->data.eccCurves.eccCurves[1] = HOST_TO_BE_16(TPM2_ECC_NIST_P384);
339     ptr2->data.eccCurves.eccCurves[2] = HOST_TO_BE_16(TPM2_ECC_NIST_P521);
340     rc = Tss2_MU_TPMS_CAPABILITY_DATA_Unmarshal(buffer, 14, &offset, &cap);
341     assert_int_equal (rc, TSS2_MU_RC_INSUFFICIENT_BUFFER);
342     assert_int_equal (offset, sizeof(alg));
343 }
344 
main(void)345 int main(void) {
346     const struct CMUnitTest tests[] = {
347         cmocka_unit_test (tpms_marshal_success),
348         cmocka_unit_test (tpms_marshal_success_offset),
349         cmocka_unit_test (tpms_marshal_buffer_null_with_offset),
350         cmocka_unit_test (tpms_marshal_buffer_null_offset_null),
351         cmocka_unit_test (tpms_marshal_buffer_size_lt_data_nad_lt_offset),
352         cmocka_unit_test (tpms_unmarshal_success),
353         cmocka_unit_test (tpms_unmarshal_dest_null_buff_null),
354         cmocka_unit_test (tpms_unmarshal_buffer_null_offset_null),
355         cmocka_unit_test (tpms_unmarshal_dest_null_offset_valid),
356         cmocka_unit_test (tpms_unmarshal_buffer_size_lt_data_nad_lt_offset),
357     };
358     return cmocka_run_group_tests(tests, NULL, NULL);
359 }
360