xref: /aosp_15_r20/external/tpm2-tss/test/unit/TPMT-marshal.c (revision 758e9fba6fc9adbf15340f70c73baee7b168b1c9)
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