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
tpmt_marshal_success(void ** state)23 tpmt_marshal_success(void **state)
24 {
25 TPMT_TK_CREATION tkt = {0};
26 TPMT_PUBLIC pub = {0};
27 uint8_t buffer[sizeof(tkt) + sizeof(pub)] = { 0 };
28 size_t buffer_size = sizeof(buffer);
29 TPMT_TK_CREATION *ptr;
30 TPMI_RH_HIERARCHY *ptr2;
31 TPM2B_DIGEST *ptr3;
32 TPMT_PUBLIC *ptr4;
33 TPMU_PUBLIC_PARMS *ptr5;
34 TSS2_RC rc;
35
36 tkt.tag = 0xbeef;
37 tkt.hierarchy = TPM2_RH_OWNER;
38 tkt.digest.size = 4;
39 tkt.digest.buffer[0] = 0xde;
40 tkt.digest.buffer[1] = 0xad;
41 tkt.digest.buffer[2] = 0xbe;
42 tkt.digest.buffer[3] = 0xef;
43 rc = Tss2_MU_TPMT_TK_CREATION_Marshal(&tkt, buffer, buffer_size, NULL);
44 assert_int_equal (rc, TSS2_RC_SUCCESS);
45
46 ptr = (TPMT_TK_CREATION *)buffer;
47 ptr2 = (TPMI_RH_HIERARCHY *)(buffer + sizeof(tkt.tag));
48 ptr3 = (TPM2B_DIGEST *)(buffer + sizeof(tkt.tag) + sizeof(tkt.hierarchy));
49
50 assert_int_equal (ptr->tag, HOST_TO_BE_16(0xbeef));
51 assert_int_equal (*ptr2, HOST_TO_BE_32(TPM2_RH_OWNER));
52 assert_int_equal (ptr3->size, HOST_TO_BE_16(4));
53 assert_int_equal (ptr3->buffer[0], 0xde);
54 assert_int_equal (ptr3->buffer[1], 0xad);
55 assert_int_equal (ptr3->buffer[2], 0xbe);
56 assert_int_equal (ptr3->buffer[3], 0xef);
57
58 pub.type = TPM2_ALG_RSA;
59 pub.parameters.rsaDetail.symmetric.algorithm = TPM2_ALG_AES;
60 pub.parameters.rsaDetail.symmetric.keyBits.aes = 128;
61 pub.parameters.rsaDetail.symmetric.mode.aes = TPM2_ALG_CBC;
62 rc = Tss2_MU_TPMT_PUBLIC_Marshal(&pub, buffer, buffer_size, NULL);
63 assert_int_equal (rc, TSS2_RC_SUCCESS);
64 ptr4 = (TPMT_PUBLIC *)buffer;
65 ptr5 = (TPMU_PUBLIC_PARMS *)(buffer + sizeof(TPMI_ALG_PUBLIC) + sizeof(TPMI_ALG_HASH) + sizeof(TPMA_OBJECT) + 2);
66 assert_int_equal (ptr4->type, HOST_TO_BE_16(TPM2_ALG_RSA));
67 assert_int_equal (ptr5->rsaDetail.symmetric.algorithm, HOST_TO_BE_16(TPM2_ALG_AES));
68 assert_int_equal (ptr5->rsaDetail.symmetric.keyBits.aes, HOST_TO_BE_16(128));
69 assert_int_equal (ptr5->rsaDetail.symmetric.mode.aes, HOST_TO_BE_16(TPM2_ALG_CBC));
70 }
71 /*
72 * Success case with a valid offset
73 */
74 static void
tpmt_marshal_success_offset(void ** state)75 tpmt_marshal_success_offset(void **state)
76 {
77 TPMT_TK_CREATION tkt = {0};
78 TPMT_PUBLIC_PARMS pub = {0};
79 uint8_t buffer[sizeof(tkt) + sizeof(pub) + 10] = { 0 };
80 size_t buffer_size = sizeof(buffer);
81 TPMT_TK_CREATION *ptr;
82 TPMI_RH_HIERARCHY *ptr2;
83 TPM2B_DIGEST *ptr3;
84 TPMT_PUBLIC_PARMS *ptr4;
85 TPMS_KEYEDHASH_PARMS *ptr5;
86 size_t offset = 10;
87 TSS2_RC rc;
88
89 tkt.tag = 0xbeef;
90 tkt.hierarchy = TPM2_RH_OWNER;
91 tkt.digest.size = 4;
92 tkt.digest.buffer[0] = 0xde;
93 tkt.digest.buffer[1] = 0xad;
94 tkt.digest.buffer[2] = 0xbe;
95 tkt.digest.buffer[3] = 0xef;
96 rc = Tss2_MU_TPMT_TK_CREATION_Marshal(&tkt, buffer, buffer_size, &offset);
97 assert_int_equal (rc, TSS2_RC_SUCCESS);
98
99 ptr = (TPMT_TK_CREATION *)(buffer + 10);
100 ptr2 = (TPMI_RH_HIERARCHY *)(buffer + 10 + sizeof(tkt.tag));
101 ptr3 = (TPM2B_DIGEST *)(buffer + 10 + sizeof(tkt.tag) + sizeof(tkt.hierarchy));
102
103 assert_int_equal (ptr->tag, HOST_TO_BE_16(0xbeef));
104 assert_int_equal (*ptr2, HOST_TO_BE_32(TPM2_RH_OWNER));
105 assert_int_equal (ptr3->size, HOST_TO_BE_16(4));
106 assert_int_equal (ptr3->buffer[0], 0xde);
107 assert_int_equal (ptr3->buffer[1], 0xad);
108 assert_int_equal (ptr3->buffer[2], 0xbe);
109 assert_int_equal (ptr3->buffer[3], 0xef);
110 assert_int_equal (offset, 10 + 2 + 4 + 2 + 1 + 1 + 1 + 1);
111
112 offset = 10;
113 pub.type = TPM2_ALG_KEYEDHASH;
114 pub.parameters.keyedHashDetail.scheme.scheme = TPM2_ALG_HMAC;
115 pub.parameters.keyedHashDetail.scheme.details.hmac.hashAlg = TPM2_ALG_SHA256;
116
117 rc = Tss2_MU_TPMT_PUBLIC_PARMS_Marshal(&pub, buffer, buffer_size, &offset);
118 assert_int_equal (rc, TSS2_RC_SUCCESS);
119 ptr4 = (TPMT_PUBLIC_PARMS *)(buffer + 10);
120 ptr5 = (TPMS_KEYEDHASH_PARMS *)(buffer + 10 + 2);
121 assert_int_equal (ptr4->type, HOST_TO_BE_16(TPM2_ALG_KEYEDHASH));
122 assert_int_equal (ptr5->scheme.scheme, HOST_TO_BE_16(TPM2_ALG_HMAC));
123 assert_int_equal (ptr5->scheme.details.hmac.hashAlg, HOST_TO_BE_16(TPM2_ALG_SHA256));
124 assert_int_equal (offset, 10 + 2 + 2 + 2);
125 }
126
127 /*
128 * Success case with a null buffer
129 */
130 static void
tpmt_marshal_buffer_null_with_offset(void ** state)131 tpmt_marshal_buffer_null_with_offset(void **state)
132 {
133 TPMT_TK_CREATION tkt = {0};
134 TPMT_PUBLIC_PARMS pub = {0};
135 size_t buffer_size = sizeof(tkt) + sizeof(pub) + 10;
136 size_t offset = 10;
137 TSS2_RC rc;
138
139 tkt.tag = 0xbeef;
140 tkt.hierarchy = TPM2_RH_OWNER;
141 tkt.digest.size = 4;
142 tkt.digest.buffer[0] = 0xde;
143 tkt.digest.buffer[1] = 0xad;
144 tkt.digest.buffer[2] = 0xbe;
145 tkt.digest.buffer[3] = 0xef;
146 rc = Tss2_MU_TPMT_TK_CREATION_Marshal(&tkt, NULL, buffer_size, &offset);
147 assert_int_equal (rc, TSS2_RC_SUCCESS);
148 assert_int_equal (offset, 10 + 2 + 4 + 2 + 1 + 1 + 1 + 1);
149
150 offset = 10;
151 pub.type = TPM2_ALG_KEYEDHASH;
152 pub.parameters.keyedHashDetail.scheme.scheme = TPM2_ALG_HMAC;
153 pub.parameters.keyedHashDetail.scheme.details.hmac.hashAlg = TPM2_ALG_SHA256;
154
155 rc = Tss2_MU_TPMT_PUBLIC_PARMS_Marshal(&pub, NULL, buffer_size, &offset);
156 assert_int_equal (rc, TSS2_RC_SUCCESS);
157 assert_int_equal (offset, 10 + 2 + 2 + 2);
158 }
159
160 /*
161 * Invalid case with a null buffer and a null offset
162 */
163 static void
tpmt_marshal_buffer_null_offset_null(void ** state)164 tpmt_marshal_buffer_null_offset_null(void **state)
165 {
166 TPMT_TK_CREATION tkt = {0};
167 TPMT_PUBLIC_PARMS pub = {0};
168 TSS2_RC rc;
169
170 rc = Tss2_MU_TPMT_TK_CREATION_Marshal(&tkt, NULL, sizeof(tkt), NULL);
171 assert_int_equal (rc, TSS2_MU_RC_BAD_REFERENCE);
172
173 rc = Tss2_MU_TPMT_PUBLIC_PARMS_Marshal(&pub, NULL, sizeof(pub), NULL);
174 assert_int_equal (rc, TSS2_MU_RC_BAD_REFERENCE);
175 }
176
177 /*
178 * Invalid case with not big enough buffer
179 */
180 static void
tpmt_marshal_buffer_size_lt_data_nad_lt_offset(void ** state)181 tpmt_marshal_buffer_size_lt_data_nad_lt_offset(void **state)
182 {
183 TPMT_TK_CREATION tkt = {0};
184 TPMT_PUBLIC_PARMS pub = {0};
185 uint8_t buffer[sizeof(tkt) + sizeof(pub) + 10] = { 0 };
186 size_t offset = 10;
187 TSS2_RC rc;
188
189 tkt.tag = 0xbeef;
190 tkt.hierarchy = TPM2_RH_OWNER;
191 tkt.digest.size = 4;
192 tkt.digest.buffer[0] = 0xde;
193 tkt.digest.buffer[1] = 0xad;
194 tkt.digest.buffer[2] = 0xbe;
195 tkt.digest.buffer[3] = 0xef;
196 rc = Tss2_MU_TPMT_TK_CREATION_Marshal(&tkt, buffer, 10, &offset);
197 assert_int_equal (rc, TSS2_MU_RC_INSUFFICIENT_BUFFER);
198 assert_int_equal (offset, 10);
199
200 pub.type = TPM2_ALG_KEYEDHASH;
201 pub.parameters.keyedHashDetail.scheme.scheme = TPM2_ALG_HMAC;
202 pub.parameters.keyedHashDetail.scheme.details.hmac.hashAlg = TPM2_ALG_SHA256;
203
204 rc = Tss2_MU_TPMT_PUBLIC_PARMS_Marshal(&pub, buffer, 8, &offset);
205 assert_int_equal (rc, TSS2_MU_RC_INSUFFICIENT_BUFFER);
206 assert_int_equal (offset, 10);
207 }
208
209 /*
210 * Success case
211 */
212 static void
tpmt_unmarshal_success(void ** state)213 tpmt_unmarshal_success(void **state)
214 {
215 TPMT_TK_CREATION tkt = {0};
216 TPMT_PUBLIC_PARMS pub = {0};
217 uint8_t buffer[sizeof(tkt) + sizeof(pub)] = { 0 };
218 size_t buffer_size = sizeof(buffer);
219 TPMT_TK_CREATION *ptr;
220 TPMI_RH_HIERARCHY *ptr2;
221 TPM2B_DIGEST *ptr3;
222 TPMT_PUBLIC_PARMS *ptr4;
223 TPMS_KEYEDHASH_PARMS *ptr5;
224 size_t offset = 0;
225 TSS2_RC rc;
226
227 ptr = (TPMT_TK_CREATION *)(buffer);
228 ptr2 = (TPMI_RH_HIERARCHY *)(buffer + sizeof(tkt.tag));
229 ptr3 = (TPM2B_DIGEST *)(buffer + sizeof(tkt.tag) + sizeof(tkt.hierarchy));
230
231 ptr->tag = HOST_TO_BE_16(0xbeef);
232 *ptr2 = HOST_TO_BE_32(TPM2_RH_OWNER);
233 ptr3->size = HOST_TO_BE_16(4);
234 ptr3->buffer[0] = 0xde;
235 ptr3->buffer[1] = 0xad;
236 ptr3->buffer[2] = 0xbe;
237 ptr3->buffer[3] = 0xef;
238
239 rc = Tss2_MU_TPMT_TK_CREATION_Unmarshal(buffer, buffer_size, &offset, &tkt);
240 assert_int_equal (rc, TSS2_RC_SUCCESS);
241 assert_int_equal (tkt.tag, 0xbeef);
242 assert_int_equal (tkt.hierarchy, TPM2_RH_OWNER);
243 assert_int_equal (tkt.digest.size, 4);
244 assert_int_equal (tkt.digest.buffer[0], 0xde);
245 assert_int_equal (tkt.digest.buffer[1], 0xad);
246 assert_int_equal (tkt.digest.buffer[2], 0xbe);
247 assert_int_equal (tkt.digest.buffer[3], 0xef);
248 assert_int_equal (offset, 2 + 4 + 2 + 1 + 1 + 1 + 1);
249
250 offset = 0;
251 ptr4 = (TPMT_PUBLIC_PARMS *)(buffer);
252 ptr5 = (TPMS_KEYEDHASH_PARMS *)(buffer + 2);
253 ptr4->type = HOST_TO_BE_16(TPM2_ALG_KEYEDHASH);
254 ptr5->scheme.scheme = HOST_TO_BE_16(TPM2_ALG_HMAC);
255 ptr5->scheme.details.hmac.hashAlg = HOST_TO_BE_16(TPM2_ALG_SHA256);
256
257 rc = Tss2_MU_TPMT_PUBLIC_PARMS_Unmarshal(buffer, buffer_size, &offset, &pub);
258 assert_int_equal (rc, TSS2_RC_SUCCESS);
259 assert_int_equal (pub.type, TPM2_ALG_KEYEDHASH);
260 assert_int_equal (pub.parameters.keyedHashDetail.scheme.scheme, TPM2_ALG_HMAC);
261 assert_int_equal (pub.parameters.keyedHashDetail.scheme.details.hmac.hashAlg, TPM2_ALG_SHA256);
262 assert_int_equal (offset, 2 + 2 + 2);
263 }
264
265 /*
266 * Invalid test case with buffer null and dest null
267 */
268 static void
tpmt_unmarshal_dest_null_buff_null(void ** state)269 tpmt_unmarshal_dest_null_buff_null(void **state)
270 {
271 size_t offset = 1;
272 TSS2_RC rc;
273
274 rc = Tss2_MU_TPMT_TK_CREATION_Unmarshal(NULL, 120, &offset, NULL);
275 assert_int_equal (rc, TSS2_MU_RC_BAD_REFERENCE);
276 assert_int_equal (offset, 1);
277
278 rc = Tss2_MU_TPMT_PUBLIC_PARMS_Unmarshal(NULL, 120, &offset, NULL);
279 assert_int_equal (rc, TSS2_MU_RC_BAD_REFERENCE);
280 assert_int_equal (offset, 1);
281 }
282
283 /*
284 * Invalid test case with offset null and dest null
285 */
286 static void
tpmt_unmarshal_buffer_null_offset_null(void ** state)287 tpmt_unmarshal_buffer_null_offset_null(void **state)
288 {
289 uint8_t buffer[sizeof(TPMT_TK_CREATION) + sizeof(TPMT_PUBLIC_PARMS)] = { 0 };
290 size_t buffer_size = sizeof(buffer);
291 TSS2_RC rc;
292
293 rc = Tss2_MU_TPMT_TK_CREATION_Unmarshal(buffer, buffer_size, NULL, NULL);
294 assert_int_equal (rc, TSS2_MU_RC_BAD_REFERENCE);
295
296 rc = Tss2_MU_TPMT_PUBLIC_PARMS_Unmarshal(buffer, buffer_size, NULL, NULL);
297 assert_int_equal (rc, TSS2_MU_RC_BAD_REFERENCE);
298 }
299
300 /*
301 * Test case ensures the offset is updated when dest is NULL
302 * and offset is valid
303 */
304 static void
tpmt_unmarshal_dest_null_offset_valid(void ** state)305 tpmt_unmarshal_dest_null_offset_valid(void **state)
306 {
307 TPMT_TK_CREATION tkt;
308 uint8_t buffer[sizeof(tkt) + sizeof(TPMT_PUBLIC_PARMS)] = { 0 };
309 size_t buffer_size = sizeof(buffer);
310 TPMT_TK_CREATION *ptr;
311 TPMI_RH_HIERARCHY *ptr2;
312 TPM2B_DIGEST *ptr3;
313 TPMT_PUBLIC_PARMS *ptr4;
314 TPMS_KEYEDHASH_PARMS *ptr5;
315 size_t offset = 0;
316 TSS2_RC rc;
317
318 ptr = (TPMT_TK_CREATION *)(buffer);
319 ptr2 = (TPMI_RH_HIERARCHY *)(buffer + sizeof(tkt.tag));
320 ptr3 = (TPM2B_DIGEST *)(buffer + sizeof(tkt.tag) + sizeof(tkt.hierarchy));
321
322 ptr->tag = HOST_TO_BE_16(0xbeef);
323 *ptr2 = HOST_TO_BE_32(TPM2_RH_OWNER);
324 ptr3->size = HOST_TO_BE_16(4);
325 ptr3->buffer[0] = 0xde;
326 ptr3->buffer[1] = 0xad;
327 ptr3->buffer[2] = 0xbe;
328 ptr3->buffer[3] = 0xef;
329
330 rc = Tss2_MU_TPMT_TK_CREATION_Unmarshal(buffer, buffer_size, &offset, NULL);
331 assert_int_equal (rc, TSS2_RC_SUCCESS);
332 assert_int_equal (offset, 2 + 4 + 2 + 1 + 1 + 1 + 1);
333
334 offset = 0;
335 ptr4 = (TPMT_PUBLIC_PARMS *)(buffer);
336 ptr5 = (TPMS_KEYEDHASH_PARMS *)(buffer + 2);
337 ptr4->type = HOST_TO_BE_16(TPM2_ALG_KEYEDHASH);
338 ptr5->scheme.scheme = HOST_TO_BE_16(TPM2_ALG_HMAC);
339 ptr5->scheme.details.hmac.hashAlg = HOST_TO_BE_16(TPM2_ALG_SHA256);
340
341 rc = Tss2_MU_TPMT_PUBLIC_PARMS_Unmarshal(buffer, buffer_size, &offset, NULL);
342 assert_int_equal (rc, TSS2_RC_SUCCESS);
343 assert_int_equal (offset, 2 + 2 + 2);
344 }
345
346 /*
347 * Invalid case with not big enough buffer. Make sure offest is untouched.
348 */
349 static void
tpmt_unmarshal_buffer_size_lt_data_nad_lt_offset(void ** state)350 tpmt_unmarshal_buffer_size_lt_data_nad_lt_offset(void **state)
351 {
352 TPMT_TK_CREATION tkt;
353 uint8_t buffer[sizeof(tkt) + sizeof(TPMT_PUBLIC_PARMS)] = { 0 };
354 TPMT_TK_CREATION *ptr;
355 TPMI_RH_HIERARCHY *ptr2;
356 TPM2B_DIGEST *ptr3;
357 TPMT_PUBLIC_PARMS *ptr4;
358 TPMS_KEYEDHASH_PARMS *ptr5;
359 size_t offset = 5;
360 TSS2_RC rc;
361
362 ptr = (TPMT_TK_CREATION *)(buffer);
363 ptr2 = (TPMI_RH_HIERARCHY *)(buffer + sizeof(tkt.tag));
364 ptr3 = (TPM2B_DIGEST *)(buffer + sizeof(tkt.tag) + sizeof(tkt.hierarchy));
365
366 ptr->tag = HOST_TO_BE_16(0xbeef);
367 *ptr2 = HOST_TO_BE_32(TPM2_RH_OWNER);
368 ptr3->size = HOST_TO_BE_16(4);
369 ptr3->buffer[0] = 0xde;
370 ptr3->buffer[1] = 0xad;
371 ptr3->buffer[2] = 0xbe;
372 ptr3->buffer[3] = 0xef;
373 rc = Tss2_MU_TPMT_TK_CREATION_Unmarshal(buffer, 15, &offset, NULL);
374 assert_int_equal (rc, TSS2_MU_RC_INSUFFICIENT_BUFFER);
375 assert_int_equal (offset, 5);
376
377 offset = 5;
378 ptr4 = (TPMT_PUBLIC_PARMS *)(buffer);
379 ptr5 = (TPMS_KEYEDHASH_PARMS *)(buffer + 2);
380 ptr4->type = HOST_TO_BE_16(TPM2_ALG_KEYEDHASH);
381 ptr5->scheme.scheme = HOST_TO_BE_16(TPM2_ALG_HMAC);
382 ptr5->scheme.details.hmac.hashAlg = HOST_TO_BE_16(TPM2_ALG_SHA256);
383
384 rc = Tss2_MU_TPMT_PUBLIC_PARMS_Unmarshal(buffer, 6, &offset, NULL);
385 assert_int_equal (rc, TSS2_MU_RC_INSUFFICIENT_BUFFER);
386 assert_int_equal (offset, 5);
387 }
388
main(void)389 int main(void) {
390 const struct CMUnitTest tests[] = {
391 cmocka_unit_test (tpmt_marshal_success),
392 cmocka_unit_test (tpmt_marshal_success_offset),
393 cmocka_unit_test (tpmt_marshal_buffer_null_with_offset),
394 cmocka_unit_test (tpmt_marshal_buffer_null_offset_null),
395 cmocka_unit_test (tpmt_marshal_buffer_size_lt_data_nad_lt_offset),
396 cmocka_unit_test (tpmt_unmarshal_success),
397 cmocka_unit_test (tpmt_unmarshal_dest_null_buff_null),
398 cmocka_unit_test (tpmt_unmarshal_buffer_null_offset_null),
399 cmocka_unit_test (tpmt_unmarshal_dest_null_offset_valid),
400 cmocka_unit_test (tpmt_unmarshal_buffer_size_lt_data_nad_lt_offset),
401 };
402 return cmocka_run_group_tests(tests, NULL, NULL);
403 }
404