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