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 <string.h>
14 #include <setjmp.h>
15 #include <cmocka.h>
16 #include <stdio.h>
17 #include "tss2_mu.h"
18 #include "util/tss2_endian.h"
19
20 /*
21 * Success case
22 */
23 static void
tpmu_marshal_success(void ** state)24 tpmu_marshal_success(void **state)
25 {
26 TPMU_HA ha = {0};
27 TPMU_SIGNATURE sig = {0};
28 uint8_t buffer[sizeof(ha) + sizeof(sig)] = { 0 };
29 size_t buffer_size = sizeof(buffer);
30 TPMS_SIGNATURE_ECDSA *ptr;
31 TPM2B_ECC_PARAMETER *ptr2;
32 TSS2_RC rc;
33
34 memset(ha.sha512, 'a', TPM2_SHA512_DIGEST_SIZE);
35 rc = Tss2_MU_TPMU_HA_Marshal(&ha, TPM2_ALG_SHA512, buffer, buffer_size, NULL);
36 assert_int_equal (rc, TSS2_RC_SUCCESS);
37 assert_int_equal (memcmp(buffer, ha.sha512, TPM2_SHA512_DIGEST_SIZE), 0);
38
39 sig.ecdsa.hash = TPM2_ALG_SHA1;
40 sig.ecdsa.signatureR.size = 4;
41 sig.ecdsa.signatureR.buffer[0] = 'a';
42 sig.ecdsa.signatureR.buffer[1] = 'b';
43 sig.ecdsa.signatureR.buffer[2] = 'c';
44 sig.ecdsa.signatureR.buffer[3] = 'd';
45 sig.ecdsa.signatureS.size = 4;
46 sig.ecdsa.signatureS.buffer[0] = 'e';
47 sig.ecdsa.signatureS.buffer[1] = 'd';
48 sig.ecdsa.signatureS.buffer[2] = 'f';
49 sig.ecdsa.signatureS.buffer[3] = 'g';
50
51 rc = Tss2_MU_TPMU_SIGNATURE_Marshal(&sig, TPM2_ALG_ECDSA, buffer, buffer_size, NULL);
52 assert_int_equal (rc, TSS2_RC_SUCCESS);
53 ptr = (TPMS_SIGNATURE_ECDSA *) buffer;
54 assert_int_equal (ptr->hash, HOST_TO_BE_16(TPM2_ALG_SHA1));
55 assert_int_equal (ptr->signatureR.size, HOST_TO_BE_16(4));
56 assert_int_equal (ptr->signatureR.buffer[0], 'a');
57 assert_int_equal (ptr->signatureR.buffer[1], 'b');
58 assert_int_equal (ptr->signatureR.buffer[2], 'c');
59 assert_int_equal (ptr->signatureR.buffer[3], 'd');
60 ptr2 = (TPM2B_ECC_PARAMETER *) (buffer + 8);
61 assert_int_equal (ptr2->size, HOST_TO_BE_16(4));
62 assert_int_equal (ptr2->buffer[0], 'e');
63 assert_int_equal (ptr2->buffer[1], 'd');
64 assert_int_equal (ptr2->buffer[2], 'f');
65 assert_int_equal (ptr2->buffer[3], 'g');
66
67 }
68 /*
69 * Success case with a valid offset
70 */
71 static void
tpmu_marshal_success_offset(void ** state)72 tpmu_marshal_success_offset(void **state)
73 {
74 TPMU_HA ha = {0};
75 TPMU_SIGNATURE sig = {0};
76 uint8_t buffer[sizeof(ha) + sizeof(sig) + 10] = { 0 };
77 size_t buffer_size = sizeof(buffer);
78 TPMS_SIGNATURE_ECDSA *ptr;
79 TPM2B_ECC_PARAMETER *ptr2;
80 size_t offset = 10;
81 TSS2_RC rc;
82
83 memset(ha.sha512, 'a', TPM2_SHA512_DIGEST_SIZE);
84 rc = Tss2_MU_TPMU_HA_Marshal(&ha, TPM2_ALG_SHA512, buffer, buffer_size, &offset);
85 assert_int_equal (rc, TSS2_RC_SUCCESS);
86 assert_int_equal (memcmp(buffer + 10, ha.sha512, TPM2_SHA512_DIGEST_SIZE), 0);
87 assert_int_equal (offset, 10 + TPM2_SHA512_DIGEST_SIZE);
88
89 sig.ecdsa.hash = TPM2_ALG_SHA1;
90 sig.ecdsa.signatureR.size = 4;
91 sig.ecdsa.signatureR.buffer[0] = 'a';
92 sig.ecdsa.signatureR.buffer[1] = 'b';
93 sig.ecdsa.signatureR.buffer[2] = 'c';
94 sig.ecdsa.signatureR.buffer[3] = 'd';
95 sig.ecdsa.signatureS.size = 4;
96 sig.ecdsa.signatureS.buffer[0] = 'e';
97 sig.ecdsa.signatureS.buffer[1] = 'd';
98 sig.ecdsa.signatureS.buffer[2] = 'f';
99 sig.ecdsa.signatureS.buffer[3] = 'g';
100
101 rc = Tss2_MU_TPMU_SIGNATURE_Marshal(&sig, TPM2_ALG_ECDSA, buffer, buffer_size, &offset);
102 assert_int_equal (rc, TSS2_RC_SUCCESS);
103 ptr = (TPMS_SIGNATURE_ECDSA *) (buffer + 10 + TPM2_SHA512_DIGEST_SIZE);
104 assert_int_equal (ptr->hash, HOST_TO_BE_16(TPM2_ALG_SHA1));
105 assert_int_equal (ptr->signatureR.size, HOST_TO_BE_16(4));
106 assert_int_equal (ptr->signatureR.buffer[0], 'a');
107 assert_int_equal (ptr->signatureR.buffer[1], 'b');
108 assert_int_equal (ptr->signatureR.buffer[2], 'c');
109 assert_int_equal (ptr->signatureR.buffer[3], 'd');
110 ptr2 = (TPM2B_ECC_PARAMETER *) (buffer + 10 + TPM2_SHA512_DIGEST_SIZE + 8);
111 assert_int_equal (ptr2->size, HOST_TO_BE_16(4));
112 assert_int_equal (ptr2->buffer[0], 'e');
113 assert_int_equal (ptr2->buffer[1], 'd');
114 assert_int_equal (ptr2->buffer[2], 'f');
115 assert_int_equal (ptr2->buffer[3], 'g');
116 assert_int_equal (offset, 10 + TPM2_SHA512_DIGEST_SIZE + 2 + ((2 + 1 + 1 + 1 + 1) * 2));
117 }
118
119 /*
120 * Success case with a null buffer
121 */
122 static void
tpmu_marshal_buffer_null_with_offset(void ** state)123 tpmu_marshal_buffer_null_with_offset(void **state)
124 {
125 TPMU_HA ha = {0};
126 TPMU_SIGNATURE sig = {0};
127 size_t buffer_size = sizeof(ha) + sizeof(sig) + 10;
128 size_t offset = 10;
129 TSS2_RC rc;
130
131 memset(ha.sha512, 'a', TPM2_SHA512_DIGEST_SIZE);
132 rc = Tss2_MU_TPMU_HA_Marshal(&ha, TPM2_ALG_SHA512, NULL, buffer_size, &offset);
133 assert_int_equal (rc, TSS2_RC_SUCCESS);
134 assert_int_equal (offset, 10 + TPM2_SHA512_DIGEST_SIZE);
135
136 sig.ecdsa.hash = TPM2_ALG_SHA1;
137 sig.ecdsa.signatureR.size = 4;
138 sig.ecdsa.signatureR.buffer[0] = 'a';
139 sig.ecdsa.signatureR.buffer[1] = 'b';
140 sig.ecdsa.signatureR.buffer[2] = 'c';
141 sig.ecdsa.signatureR.buffer[3] = 'd';
142 sig.ecdsa.signatureS.size = 4;
143 sig.ecdsa.signatureS.buffer[0] = 'e';
144 sig.ecdsa.signatureS.buffer[1] = 'd';
145 sig.ecdsa.signatureS.buffer[2] = 'f';
146 sig.ecdsa.signatureS.buffer[3] = 'g';
147
148 rc = Tss2_MU_TPMU_SIGNATURE_Marshal(&sig, TPM2_ALG_ECDSA, NULL, buffer_size, &offset);
149 assert_int_equal (rc, TSS2_RC_SUCCESS);
150 assert_int_equal (offset, 10 + TPM2_SHA512_DIGEST_SIZE + 2 + ((2 + 1 + 1 + 1 + 1) * 2));
151 }
152
153 /*
154 * Invalid case with a null buffer and a null offset
155 */
156 static void
tpmu_marshal_buffer_null_offset_null(void ** state)157 tpmu_marshal_buffer_null_offset_null(void **state)
158 {
159 TPMU_HA ha = {0};
160 TPMU_SIGNATURE sig = {0};
161 TSS2_RC rc;
162
163 rc = Tss2_MU_TPMU_HA_Marshal(&ha, TPM2_ALG_SHA512, NULL, sizeof(ha), NULL);
164 assert_int_equal (rc, TSS2_MU_RC_BAD_REFERENCE);
165
166 rc = Tss2_MU_TPMU_SIGNATURE_Marshal(&sig, TPM2_ALG_ECDSA, NULL, sizeof(sig), NULL);
167 assert_int_equal (rc, TSS2_MU_RC_BAD_REFERENCE);
168 }
169
170 /*
171 * Invalid case with not big enough buffer
172 */
173 static void
tpmu_marshal_buffer_size_lt_data_nad_lt_offset(void ** state)174 tpmu_marshal_buffer_size_lt_data_nad_lt_offset(void **state)
175 {
176 TPMU_HA ha = {0};
177 TPMU_SIGNATURE sig = {0};
178 uint8_t buffer[sizeof(ha) + sizeof(sig) + 10] = { 0 };
179 size_t offset = 10;
180 TSS2_RC rc;
181
182 memset(ha.sha512, 'a', TPM2_SHA512_DIGEST_SIZE);
183 rc = Tss2_MU_TPMU_HA_Marshal(&ha, TPM2_ALG_SHA512, buffer, TPM2_SHA512_DIGEST_SIZE - 1, &offset);
184 assert_int_equal (rc, TSS2_MU_RC_INSUFFICIENT_BUFFER);
185 assert_int_equal (offset, 10);
186
187 sig.ecdsa.hash = TPM2_ALG_SHA1;
188 sig.ecdsa.signatureR.size = 4;
189 sig.ecdsa.signatureR.buffer[0] = 'a';
190 sig.ecdsa.signatureR.buffer[1] = 'b';
191 sig.ecdsa.signatureR.buffer[2] = 'c';
192 sig.ecdsa.signatureR.buffer[3] = 'd';
193 sig.ecdsa.signatureS.size = 4;
194 sig.ecdsa.signatureS.buffer[0] = 'e';
195 sig.ecdsa.signatureS.buffer[1] = 'd';
196 sig.ecdsa.signatureS.buffer[2] = 'f';
197 sig.ecdsa.signatureS.buffer[3] = 'g';
198
199 rc = Tss2_MU_TPMU_SIGNATURE_Marshal(&sig, TPM2_ALG_ECDSA, buffer, 12, &offset);
200 assert_int_equal (rc, TSS2_MU_RC_INSUFFICIENT_BUFFER);
201 assert_int_equal (offset, 10);
202 }
203
204 /*
205 * Success case
206 */
207 static void
tpmu_unmarshal_success(void ** state)208 tpmu_unmarshal_success(void **state)
209 {
210 TPMU_HA ha = {0};
211 TPMU_SIGNATURE sig = {0};
212 uint8_t buffer[sizeof(ha) + sizeof(sig)] = { 0 };
213 size_t buffer_size = sizeof(buffer);
214 TPMS_SIGNATURE_ECDSA *ptr;
215 TPM2B_ECC_PARAMETER *ptr2;
216 size_t offset = 0;
217 TSS2_RC rc;
218
219 memset(buffer, 'a', TPM2_SHA512_DIGEST_SIZE);
220 rc = Tss2_MU_TPMU_HA_Unmarshal(buffer, buffer_size, &offset, TPM2_ALG_SHA512, &ha);
221 assert_int_equal (rc, TSS2_RC_SUCCESS);
222 assert_int_equal (offset, TPM2_SHA512_DIGEST_SIZE);
223 assert_int_equal (memcmp(buffer, ha.sha512, TPM2_SHA512_DIGEST_SIZE), 0);
224
225 offset = 0;
226 ptr = (TPMS_SIGNATURE_ECDSA *) buffer;
227 ptr2 = (TPM2B_ECC_PARAMETER *) (buffer + 8);
228 ptr->hash = HOST_TO_BE_16(TPM2_ALG_SHA1);
229 ptr->signatureR.size = HOST_TO_BE_16(4);
230 ptr->signatureR.buffer[0] = 'a';
231 ptr->signatureR.buffer[1] = 'b';
232 ptr->signatureR.buffer[2] = 'c';
233 ptr->signatureR.buffer[3] = 'd';
234 ptr2->size = HOST_TO_BE_16(4);
235 ptr2->buffer[0] = 'e';
236 ptr2->buffer[1] = 'd';
237 ptr2->buffer[2] = 'f';
238 ptr2->buffer[3] = 'g';
239
240 rc = Tss2_MU_TPMU_SIGNATURE_Unmarshal(buffer, buffer_size, &offset, TPM2_ALG_ECDSA, &sig);
241 assert_int_equal (rc, TSS2_RC_SUCCESS);
242 assert_int_equal (offset, 14);
243 assert_int_equal (sig.ecdsa.hash, TPM2_ALG_SHA1);
244 assert_int_equal (sig.ecdsa.signatureR.size, 4);
245 assert_int_equal (sig.ecdsa.signatureR.buffer[0], 'a');
246 assert_int_equal (sig.ecdsa.signatureR.buffer[1], 'b');
247 assert_int_equal (sig.ecdsa.signatureR.buffer[2], 'c');
248 assert_int_equal (sig.ecdsa.signatureR.buffer[3], 'd');
249 assert_int_equal (sig.ecdsa.signatureS.size, 4);
250 assert_int_equal (sig.ecdsa.signatureS.buffer[0], 'e');
251 assert_int_equal (sig.ecdsa.signatureS.buffer[1], 'd');
252 assert_int_equal (sig.ecdsa.signatureS.buffer[2], 'f');
253 assert_int_equal (sig.ecdsa.signatureS.buffer[3], 'g');
254 }
255
256 /*
257 * Invalid test case with buffer null and dest null
258 */
259 static void
tpmu_unmarshal_dest_null_buff_null(void ** state)260 tpmu_unmarshal_dest_null_buff_null(void **state)
261 {
262 size_t offset = 1;
263 TSS2_RC rc;
264
265 rc = Tss2_MU_TPMU_HA_Unmarshal(NULL, TPM2_SHA512_DIGEST_SIZE, &offset, TPM2_ALG_SHA512, NULL);
266 assert_int_equal (rc, TSS2_MU_RC_BAD_REFERENCE);
267 assert_int_equal (offset, 1);
268
269 rc = Tss2_MU_TPMU_SIGNATURE_Unmarshal(NULL, 32, &offset, TPM2_ALG_ECDSA, NULL);
270 assert_int_equal (rc, TSS2_MU_RC_BAD_REFERENCE);
271 assert_int_equal (offset, 1);
272 }
273
274 /*
275 * Invalid test case with offset null and dest null
276 */
277 static void
tpmu_unmarshal_buffer_null_offset_null(void ** state)278 tpmu_unmarshal_buffer_null_offset_null(void **state)
279 {
280 uint8_t buffer[sizeof(TPMU_HA) + sizeof(TPMU_SIGNATURE)] = { 0 };
281 size_t buffer_size = sizeof(buffer);
282 TSS2_RC rc;
283
284 rc = Tss2_MU_TPMU_HA_Unmarshal(buffer, buffer_size, NULL, TPM2_ALG_SHA512, NULL);
285 assert_int_equal (rc, TSS2_MU_RC_BAD_REFERENCE);
286
287 rc = Tss2_MU_TPMU_SIGNATURE_Unmarshal(buffer, buffer_size, NULL, TPM2_ALG_ECDSA, NULL);
288 assert_int_equal (rc, TSS2_MU_RC_BAD_REFERENCE);
289 }
290
291 /*
292 * Test case ensures the offset is updated when dest is NULL
293 * and offset is valid
294 */
295 static void
tpmu_unmarshal_dest_null_offset_valid(void ** state)296 tpmu_unmarshal_dest_null_offset_valid(void **state)
297 {
298 uint8_t buffer[sizeof(TPMU_HA) + sizeof(TPMU_SIGNATURE)] = { 0 };
299 size_t buffer_size = sizeof(buffer);
300 TPMS_SIGNATURE_ECDSA *ptr;
301 TPM2B_ECC_PARAMETER *ptr2;
302 size_t offset = 0;
303 TSS2_RC rc;
304
305 memset(buffer, 'a', TPM2_SHA512_DIGEST_SIZE);
306 rc = Tss2_MU_TPMU_HA_Unmarshal(buffer, buffer_size, &offset, TPM2_ALG_SHA512, NULL);
307 assert_int_equal (rc, TSS2_RC_SUCCESS);
308 assert_int_equal (offset, TPM2_SHA512_DIGEST_SIZE);
309
310 offset = 0;
311 ptr = (TPMS_SIGNATURE_ECDSA *) buffer;
312 ptr2 = (TPM2B_ECC_PARAMETER *) (buffer + 8);
313 ptr->hash = HOST_TO_BE_16(TPM2_ALG_SHA1);
314 ptr->signatureR.size = HOST_TO_BE_16(4);
315 ptr->signatureR.buffer[0] = 'a';
316 ptr->signatureR.buffer[1] = 'b';
317 ptr->signatureR.buffer[2] = 'c';
318 ptr->signatureR.buffer[3] = 'd';
319 ptr2->size = HOST_TO_BE_16(4);
320 ptr2->buffer[0] = 'e';
321 ptr2->buffer[1] = 'd';
322 ptr2->buffer[2] = 'f';
323 ptr2->buffer[3] = 'g';
324
325 rc = Tss2_MU_TPMU_SIGNATURE_Unmarshal(buffer, buffer_size, &offset, TPM2_ALG_ECDSA, NULL);
326 assert_int_equal (rc, TSS2_RC_SUCCESS);
327 assert_int_equal (offset, 14);
328 }
329
330 /*
331 * Invalid case with not big enough buffer. Make sure offest is untouched.
332 */
333 static void
tpmu_unmarshal_buffer_size_lt_data_nad_lt_offset(void ** state)334 tpmu_unmarshal_buffer_size_lt_data_nad_lt_offset(void **state)
335 {
336 TPMU_HA ha = {0};
337 TPMU_SIGNATURE sig = {0};
338 uint8_t buffer[sizeof(ha) + sizeof(sig)] = { 0 };
339 TPMS_SIGNATURE_ECDSA *ptr;
340 TPM2B_ECC_PARAMETER *ptr2;
341 size_t offset = 5;
342 TSS2_RC rc;
343
344 memset(buffer, 'a', TPM2_SHA512_DIGEST_SIZE);
345 rc = Tss2_MU_TPMU_HA_Unmarshal(buffer, TPM2_SHA512_DIGEST_SIZE - 1, &offset, TPM2_ALG_SHA512, &ha);
346 assert_int_equal (rc, TSS2_MU_RC_INSUFFICIENT_BUFFER);
347 assert_int_equal (offset, 5);
348
349 ptr = (TPMS_SIGNATURE_ECDSA *) buffer;
350 ptr2 = (TPM2B_ECC_PARAMETER *) (buffer + 8);
351 ptr->hash = HOST_TO_BE_16(TPM2_ALG_SHA1);
352 ptr->signatureR.size = HOST_TO_BE_16(4);
353 ptr->signatureR.buffer[0] = 'a';
354 ptr->signatureR.buffer[1] = 'b';
355 ptr->signatureR.buffer[2] = 'c';
356 ptr->signatureR.buffer[3] = 'd';
357 ptr2->size = HOST_TO_BE_16(4);
358 ptr2->buffer[0] = 'e';
359 ptr2->buffer[1] = 'd';
360 ptr2->buffer[2] = 'f';
361 ptr2->buffer[3] = 'g';
362
363 rc = Tss2_MU_TPMU_SIGNATURE_Unmarshal(buffer, 14, &offset, TPM2_ALG_ECDSA, &sig);
364 assert_int_equal (rc, TSS2_MU_RC_INSUFFICIENT_BUFFER);
365 assert_int_equal (offset, 5);
366 }
367
368 static void
tpmu_name_marshal(void ** state)369 tpmu_name_marshal(void **state)
370 {
371 TPMU_NAME name = {0};
372 TPMT_HA ha = {0};
373 uint8_t buf[256] = {0};
374 TPM2_HANDLE hdl = TPM2_RS_PW;
375 TPM2_HANDLE hdl_expected = HOST_TO_BE_32(TPM2_RS_PW);
376 TPM2_ALG_ID id_expected = HOST_TO_BE_16(TPM2_ALG_SHA1);
377 size_t size = sizeof(hdl), offset = 0;
378 const char digest[] = {0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x01, 0x02,
379 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
380 0x10, 0x11, 0x12, 0x13, 0x14};
381 TPM2_RC rc;
382
383 /* Handle case */
384 size = sizeof(hdl);
385 name.handle = hdl;
386
387 rc = Tss2_MU_TPMU_NAME_Marshal(&name, size, buf, sizeof(hdl), &offset);
388 assert_int_equal (rc, TSS2_RC_SUCCESS);
389 assert_int_equal (offset, sizeof(hdl));
390 assert_memory_equal ((void *) buf, &hdl_expected, sizeof(hdl));
391
392 /* Digest case */
393 offset = 0;
394 size = sizeof(TPM2_ALG_ID) + TPM2_SHA1_DIGEST_SIZE;
395 ha.hashAlg = TPM2_ALG_SHA1;
396 memcpy(&ha.digest, digest, TPM2_SHA1_DIGEST_SIZE);
397 memcpy(&name.digest, &ha, sizeof(ha));
398 rc = Tss2_MU_TPMU_NAME_Marshal(&name, size, buf, TPM2_SHA1_DIGEST_SIZE + 2, &offset);
399 assert_int_equal (rc, TSS2_RC_SUCCESS);
400 assert_int_equal (offset, TPM2_SHA1_DIGEST_SIZE + 2);
401 assert_memory_equal (buf, &id_expected, sizeof(TPM2_ALG_ID));
402 assert_memory_equal (buf + 2, digest, TPM2_SHA1_DIGEST_SIZE);
403 }
404
main(void)405 int main(void) {
406 const struct CMUnitTest tests[] = {
407 cmocka_unit_test (tpmu_marshal_success),
408 cmocka_unit_test (tpmu_marshal_success_offset),
409 cmocka_unit_test (tpmu_marshal_buffer_null_with_offset),
410 cmocka_unit_test (tpmu_marshal_buffer_null_offset_null),
411 cmocka_unit_test (tpmu_marshal_buffer_size_lt_data_nad_lt_offset),
412 cmocka_unit_test (tpmu_unmarshal_success),
413 cmocka_unit_test (tpmu_unmarshal_dest_null_buff_null),
414 cmocka_unit_test (tpmu_unmarshal_buffer_null_offset_null),
415 cmocka_unit_test (tpmu_unmarshal_dest_null_offset_valid),
416 cmocka_unit_test (tpmu_unmarshal_buffer_size_lt_data_nad_lt_offset),
417 cmocka_unit_test (tpmu_name_marshal),
418 };
419 return cmocka_run_group_tests(tests, NULL, NULL);
420 }
421