1 #include <stdio.h>
2 #include <string.h>
3 #include "TPM_Types.h"
4
5 void BasicTypesSuccessTest();
6 void BasicTypesFailureTest();
7 void TypedefSuccessTest();
8 void TypedefFailureTest();
9 void ConstantTypeSuccessTest();
10 void ConstantTypeFailureTest();
11 void AttributeStructSuccessTest();
12 void AttributeStructFailureTest();
13 void InterfaceSuccessTest();
14 void InterfaceRangeFailureTest();
15 void InterfaceNullFailureTest();
16 void InterfaceValueFailureTest();
17 void InterfaceKeyBitsTest();
18 void StructureSuccessNormalTest();
19 void StructureSuccessValueTest();
20 void StructureFailureNullTest();
21 void StructureSuccessArrayTest();
22 void StructureSuccessNullTest();
23 void StructureFailureTagTest();
24 void StructureSuccessSizeCheckTest();
25
26 /* gtest like macro */
27 #define CHECK_EQ(a, b) if (a != b) printf("[ERROR:%d] CHECK_EQ(%s == %s) failed\n", __LINE__, #a, #b);
28
29 #define SETUP_TYPE(type, val) \
30 const uint16_t num_bytes = sizeof(type); \
31 INT32 size = num_bytes; \
32 BYTE buffer[size]; \
33 BYTE *buffer_ptr = buffer; \
34 type value = val;
35
36 #define SETUP_STRUCT(type, val) \
37 const uint16_t num_bytes = sizeof(type); \
38 INT32 size = num_bytes; \
39 BYTE buffer[size]; \
40 BYTE *buffer_ptr = buffer; \
41 type value; \
42 memset(&value, val, sizeof(type));
43
44 #define RESET_TYPE(val) \
45 value = val; \
46 buffer_ptr = buffer; \
47 size = num_bytes;
48
49 #define RESET_STRUCT(type, val) \
50 memset(&value, val, sizeof(type)); \
51 buffer_ptr = buffer; \
52 size = num_bytes;
53
main()54 int main() {
55 printf("\nRunning marshal unit tests.\n\n");
56 BasicTypesSuccessTest();
57 BasicTypesFailureTest();
58 TypedefSuccessTest();
59 TypedefFailureTest();
60 ConstantTypeSuccessTest();
61 ConstantTypeFailureTest();
62 AttributeStructSuccessTest();
63 AttributeStructFailureTest();
64 InterfaceSuccessTest();
65 InterfaceRangeFailureTest();
66 InterfaceNullFailureTest();
67 InterfaceValueFailureTest();
68 InterfaceKeyBitsTest();
69 StructureSuccessNormalTest();
70 StructureSuccessValueTest();
71 StructureFailureNullTest();
72 StructureSuccessArrayTest();
73 StructureSuccessNullTest();
74 StructureFailureTagTest();
75 StructureSuccessSizeCheckTest();
76 printf("\nFinished all tests.\n\n");
77 }
78
79
BasicTypesSuccessTest()80 void BasicTypesSuccessTest() {
81 printf("Running BasicTypesSuccessTest.\n");
82 SETUP_TYPE(uint32_t, 12345)
83 UINT16 bytes_marshalled = uint32_t_Marshal(&value, &buffer_ptr, &size);
84 CHECK_EQ(bytes_marshalled, num_bytes)
85 CHECK_EQ(size, 0)
86 CHECK_EQ(buffer_ptr, buffer+num_bytes)
87
88 RESET_TYPE(0)
89 TPM_RC rc = uint32_t_Unmarshal(&value, &buffer_ptr, &size);
90 CHECK_EQ(rc, TPM_RC_SUCCESS);
91 CHECK_EQ(size, 0);
92 CHECK_EQ(buffer_ptr, buffer+num_bytes);
93 /* Checking that value was marshalled then unmarshalled successfully */
94 CHECK_EQ(value, 12345);
95 }
96
BasicTypesFailureTest()97 void BasicTypesFailureTest() {
98 printf("Running BasicTypesFailureTest.\n");
99 SETUP_TYPE(uint32_t, 12345)
100 --size;
101 UINT16 bytes_marshalled = uint32_t_Marshal(&value, &buffer_ptr, &size);
102 CHECK_EQ(size, num_bytes-1);
103 CHECK_EQ(bytes_marshalled, num_bytes);
104 CHECK_EQ(buffer, buffer_ptr);
105
106 bytes_marshalled = uint32_t_Marshal(&value, &buffer_ptr, NULL);
107 CHECK_EQ(bytes_marshalled, num_bytes);
108 CHECK_EQ(buffer, buffer_ptr);
109
110 TPM_RC rc = uint32_t_Unmarshal(&value, &buffer_ptr, &size);
111 CHECK_EQ(rc, TPM_RC_INSUFFICIENT);
112
113 rc = uint32_t_Unmarshal(&value, &buffer_ptr, NULL);
114 CHECK_EQ(rc, TPM_RC_INSUFFICIENT);
115 }
116
TypedefSuccessTest()117 void TypedefSuccessTest() {
118 printf("Running TypedefSuccessTest.\n");
119 SETUP_TYPE(TPM_KEY_BITS, 12345)
120 UINT16 bytes_marshalled = TPM_KEY_BITS_Marshal(&value, &buffer_ptr, &size);
121 CHECK_EQ(bytes_marshalled, num_bytes);
122 CHECK_EQ(size, 0);
123 CHECK_EQ(buffer_ptr, buffer+num_bytes);
124
125 RESET_TYPE(0)
126 TPM_RC rc = TPM_KEY_BITS_Unmarshal(&value, &buffer_ptr, &size);
127 CHECK_EQ(rc, TPM_RC_SUCCESS);
128 CHECK_EQ(size, 0);
129 CHECK_EQ(buffer_ptr, buffer+num_bytes);
130 /* Checking that value was marshalled then unmarshalled successfully */
131 CHECK_EQ(value, 12345);
132 }
133
TypedefFailureTest()134 void TypedefFailureTest() {
135 printf("Running TypedefFailureTest.\n");
136 SETUP_TYPE(TPM_KEY_BITS, 12345)
137 --size;
138 UINT16 bytes_marshalled = TPM_KEY_BITS_Marshal(&value, &buffer_ptr, &size);
139 CHECK_EQ(size, num_bytes-1);
140 CHECK_EQ(bytes_marshalled, num_bytes);
141 CHECK_EQ(buffer, buffer_ptr);
142
143 bytes_marshalled = TPM_KEY_BITS_Marshal(&value, &buffer_ptr, NULL);
144 CHECK_EQ(bytes_marshalled, num_bytes);
145 CHECK_EQ(buffer, buffer_ptr);
146
147 TPM_RC rc = TPM_KEY_BITS_Unmarshal(&value, &buffer_ptr, &size);
148 CHECK_EQ(rc, TPM_RC_INSUFFICIENT);
149
150 rc = TPM_KEY_BITS_Unmarshal(&value, &buffer_ptr, NULL);
151 CHECK_EQ(rc, TPM_RC_INSUFFICIENT);
152 }
153
ConstantTypeSuccessTest()154 void ConstantTypeSuccessTest() {
155 printf("Runnint ConstantTypeSuccessTest.\n");
156 SETUP_TYPE(TPM_ST, TPM_ST_ATTEST_NV)
157 UINT16 bytes_marshalled = TPM_ST_Marshal(&value, &buffer_ptr, &size);
158 CHECK_EQ(bytes_marshalled, num_bytes);
159 CHECK_EQ(size, 0);
160 CHECK_EQ(buffer_ptr, buffer+num_bytes);
161
162 RESET_TYPE(0)
163 TPM_RC rc = TPM_ST_Unmarshal(&value, &buffer_ptr, &size);
164 CHECK_EQ(rc, TPM_RC_SUCCESS);
165 CHECK_EQ(size, 0);
166 CHECK_EQ(buffer_ptr, buffer+num_bytes);
167 CHECK_EQ(value, TPM_ST_ATTEST_NV);
168 }
169
ConstantTypeFailureTest()170 void ConstantTypeFailureTest() {
171 printf("Running ConstantTypeFailureTest.\n");
172 SETUP_TYPE(TPM_ECC_CURVE, 12345)
173
174 TPM_RC rc = TPM_ECC_CURVE_Unmarshal(&value, &buffer_ptr, &size);
175 CHECK_EQ(rc, TPM_RC_CURVE);
176 CHECK_EQ(size, 0);
177 }
178
AttributeStructSuccessTest()179 void AttributeStructSuccessTest() {
180 printf("Running AttributeStructSuccessTest.\n");
181 SETUP_STRUCT(TPMA_OBJECT, 0)
182 /* Set some bits to ensure validity */
183 value.fixedTPM = 1;
184 value.fixedParent = 1;
185 UINT16 bytes_marshalled = TPMA_OBJECT_Marshal(&value, &buffer_ptr, &size);
186 CHECK_EQ(bytes_marshalled, num_bytes);
187 CHECK_EQ(size, 0);
188 CHECK_EQ(buffer_ptr, buffer+num_bytes);
189
190 RESET_STRUCT(TPMA_OBJECT, 0)
191 TPM_RC rc = TPMA_OBJECT_Unmarshal(&value, &buffer_ptr, &size);
192 CHECK_EQ(rc, TPM_RC_SUCCESS);
193 CHECK_EQ(size, 0);
194 CHECK_EQ(buffer_ptr, buffer+num_bytes);
195 CHECK_EQ(value.fixedTPM, 1);
196 CHECK_EQ(value.fixedParent, 1);
197 }
198
AttributeStructFailureTest()199 void AttributeStructFailureTest() {
200 printf("Running AttributeStructFailureTest.\n");
201 SETUP_STRUCT(TPMA_OBJECT, 0)
202 /* Failure occurs when reserved bit is set */
203 value.reserved8_9 = 1;
204 TPMA_OBJECT_Marshal(&value, &buffer_ptr, &size);
205 RESET_STRUCT(TPMA_OBJECT, 0)
206 TPM_RC rc = TPMA_OBJECT_Unmarshal(&value, &buffer_ptr, &size);
207 CHECK_EQ(rc, TPM_RC_RESERVED_BITS);
208 CHECK_EQ(size, 0);
209 }
210
InterfaceSuccessTest()211 void InterfaceSuccessTest() {
212 printf("Running InterfaceSuccessTest.\n");
213 SETUP_TYPE(TPMI_DH_ENTITY, TRANSIENT_FIRST+1)
214 /* Value has valid value from table */
215 UINT16 bytes_marshalled = TPMI_DH_ENTITY_Marshal(&value, &buffer_ptr, &size);
216 CHECK_EQ(bytes_marshalled, num_bytes);
217 CHECK_EQ(size, 0);
218 CHECK_EQ(buffer_ptr, buffer+num_bytes);
219
220 RESET_TYPE(0)
221 TPM_RC rc = TPMI_DH_ENTITY_Unmarshal(&value, &buffer_ptr, &size, FALSE);
222 CHECK_EQ(rc, TPM_RC_SUCCESS);
223 CHECK_EQ(size, 0);
224 CHECK_EQ(buffer_ptr, buffer+num_bytes);
225 CHECK_EQ(value, TRANSIENT_FIRST+1);
226
227 /* Value is optional value and TRUE is passed in as flag parameter*/
228 RESET_TYPE(TPM_RH_NULL)
229 bytes_marshalled = TPMI_DH_ENTITY_Marshal(&value, &buffer_ptr, &size);
230 CHECK_EQ(bytes_marshalled, num_bytes);
231 CHECK_EQ(size, 0);
232 CHECK_EQ(buffer_ptr, buffer+num_bytes);
233
234 RESET_TYPE(0)
235 rc = TPMI_DH_ENTITY_Unmarshal(&value, &buffer_ptr, &size, TRUE);
236 CHECK_EQ(rc, TPM_RC_SUCCESS);
237 CHECK_EQ(size, 0);
238 CHECK_EQ(buffer_ptr, buffer+num_bytes);
239 CHECK_EQ(value, TPM_RH_NULL);
240
241 /* Value has valid value from table */
242 RESET_TYPE(TPM_RH_OWNER)
243 bytes_marshalled = TPMI_DH_ENTITY_Marshal(&value, &buffer_ptr, &size);
244 CHECK_EQ(bytes_marshalled, num_bytes);
245 CHECK_EQ(size, 0);
246 CHECK_EQ(buffer_ptr, buffer+num_bytes);
247
248 RESET_TYPE(0)
249 rc = TPMI_DH_ENTITY_Unmarshal(&value, &buffer_ptr, &size, FALSE);
250 CHECK_EQ(rc, TPM_RC_SUCCESS);
251 CHECK_EQ(size, 0);
252 CHECK_EQ(buffer_ptr, buffer+num_bytes);
253 CHECK_EQ(value, TPM_RH_OWNER);
254 }
255
InterfaceRangeFailureTest()256 void InterfaceRangeFailureTest() {
257 printf("Running InterfaceRangeFailureTest.\n");
258 /* Value is out of range */
259 SETUP_TYPE(TPMI_DH_OBJECT, TRANSIENT_FIRST-1)
260 TPMI_DH_OBJECT_Marshal(&value, &buffer_ptr, &size);
261
262 RESET_TYPE(0)
263 TPM_RC rc = TPMI_DH_OBJECT_Unmarshal(&value, &buffer_ptr, &size, FALSE);
264 CHECK_EQ(rc, TPM_RC_VALUE);
265
266 RESET_TYPE(PERSISTENT_LAST+1)
267 TPMI_DH_OBJECT_Marshal(&value, &buffer_ptr, &size);
268 RESET_TYPE(0)
269 rc = TPMI_DH_OBJECT_Unmarshal(&value, &buffer_ptr, &size, FALSE);
270 CHECK_EQ(rc, TPM_RC_VALUE);
271 }
272
InterfaceNullFailureTest()273 void InterfaceNullFailureTest() {
274 printf("Running InterfaceNullFailureTest.\n");
275 SETUP_TYPE(TPMI_DH_OBJECT, TPM_RH_NULL)
276 TPMI_DH_OBJECT_Marshal(&value, &buffer_ptr, &size);
277 RESET_TYPE(0)
278 TPM_RC rc = TPMI_DH_OBJECT_Unmarshal(&value, &buffer_ptr, &size, FALSE);
279 CHECK_EQ(rc, TPM_RC_VALUE);
280 }
281
InterfaceValueFailureTest()282 void InterfaceValueFailureTest() {
283 printf("Running InterfaceValueFailureTest.\n");
284 SETUP_TYPE(TPMI_DH_ENTITY, TPM_RH_REVOKE)
285 TPMI_DH_ENTITY_Marshal(&value, &buffer_ptr, &size);
286 RESET_TYPE(0)
287 TPM_RC rc = TPMI_DH_ENTITY_Unmarshal(&value, &buffer_ptr, &size, TRUE);
288 CHECK_EQ(rc, TPM_RC_VALUE);
289 }
290
InterfaceKeyBitsTest()291 void InterfaceKeyBitsTest() {
292 printf("Running InterfaceKeyBitsTest\n");
293 uint16_t vals[] = AES_KEY_SIZES_BITS;
294 SETUP_TYPE(TPMI_AES_KEY_BITS, vals[0])
295 TPMI_AES_KEY_BITS_Marshal(&value, &buffer_ptr, &size);
296 UINT16 bytes_marshalled = TPMI_AES_KEY_BITS_Marshal(&value, &buffer_ptr, &size);
297 CHECK_EQ(bytes_marshalled, num_bytes);
298 CHECK_EQ(size, 0);
299 CHECK_EQ(buffer_ptr, buffer+num_bytes);
300 RESET_TYPE(0)
301 TPM_RC rc = TPMI_AES_KEY_BITS_Unmarshal(&value, &buffer_ptr, &size, TRUE);
302 CHECK_EQ(rc, TPM_RC_SUCCESS);
303 CHECK_EQ(value, vals[0]);
304 }
305
StructureSuccessNormalTest()306 void StructureSuccessNormalTest() {
307 /* Basic success case of structure marshalling */
308 printf("Running StructureSuccessNormalTest.\n");
309 SETUP_STRUCT(TPMS_CLOCK_INFO, 0)
310 value.clock = 12345;
311 value.resetCount = 123;
312 value.restartCount = 45;
313 value.safe = YES;
314 TPMS_CLOCK_INFO_Marshal(&value, &buffer_ptr, &size);
315 RESET_STRUCT(TPMS_CLOCK_INFO, 0)
316 TPM_RC rc = TPMS_CLOCK_INFO_Unmarshal(&value, &buffer_ptr, &size);
317 CHECK_EQ(rc, TPM_RC_SUCCESS);
318 CHECK_EQ(value.safe, YES);
319 CHECK_EQ(value.clock, 12345);
320 CHECK_EQ(value.resetCount, 123);
321 CHECK_EQ(value.restartCount, 45);
322 }
323
StructureSuccessValueTest()324 void StructureSuccessValueTest() {
325 /* Success case of structure marshalling involving field value checking */
326 printf("Running StructureSuccessValueTest\n");
327 SETUP_STRUCT(TPML_DIGEST, 0)
328 value.count = 4;
329 UINT16 bytes_marshalled = TPML_DIGEST_Marshal(&value, &buffer_ptr, &size);
330 CHECK_EQ(bytes_marshalled, sizeof(UINT32)+4*sizeof(UINT16));
331 RESET_STRUCT(TPML_DIGEST, 0)
332 TPM_RC rc = TPML_DIGEST_Unmarshal(&value, &buffer_ptr, &size);
333 CHECK_EQ(rc, TPM_RC_SUCCESS);
334 CHECK_EQ(value.count, 4);
335 }
336
StructureFailureNullTest()337 void StructureFailureNullTest() {
338 /* Failure case of structure marshalling where TPMI field is NULL */
339 printf("Running StructureFailureNullTest\n");
340 SETUP_STRUCT(TPMS_PCR_SELECTION, 0)
341 value.hash = TPM_ALG_NULL;
342 value.sizeofSelect = PCR_SELECT_MIN;
343 TPMS_PCR_SELECTION_Marshal(&value, &buffer_ptr, &size);
344 RESET_STRUCT(TPMS_PCR_SELECTION, 0)
345 TPM_RC rc = TPMS_PCR_SELECTION_Unmarshal(&value, &buffer_ptr, &size);
346 CHECK_EQ(rc, TPM_RC_HASH);
347 }
348
StructureSuccessArrayTest()349 void StructureSuccessArrayTest() {
350 /* Success case of structure marshalling involving array */
351 printf("Running StructureSuccessArrayTest\n");
352 SETUP_STRUCT(TPM2B_DIGEST, 0)
353 value.t.size = sizeof(TPMU_HA)-1;
354 UINT16 bytes_marshalled = TPM2B_DIGEST_Marshal(&value, &buffer_ptr, &size);
355 UINT16 expected_bytes = sizeof(UINT16)+(sizeof(TPMU_HA)-1)*sizeof(BYTE);
356 CHECK_EQ(bytes_marshalled, expected_bytes);
357 RESET_STRUCT(TPM2B_DIGEST, 0)
358 TPM_RC rc = TPM2B_DIGEST_Unmarshal(&value, &buffer_ptr, &size);
359 CHECK_EQ(size, sizeof(TPM2B_DIGEST)-expected_bytes);
360 CHECK_EQ(rc, TPM_RC_SUCCESS);
361 }
362
StructureSuccessNullTest()363 void StructureSuccessNullTest() {
364 /* Success case of structure marshalling involving valid null value and
365 * valid tag value
366 */
367 printf("Running StructureSuccessNullTest\n");
368 SETUP_STRUCT(TPMT_TK_HASHCHECK, 0)
369 value.tag = TPM_ST_HASHCHECK;
370 value.hierarchy = TPM_RH_NULL;
371 UINT16 bytes_marshalled = TPMT_TK_HASHCHECK_Marshal(&value, &buffer_ptr, &size);
372 UINT16 expected_bytes = sizeof(TPM_ST)+sizeof(TPMI_RH_HIERARCHY)+sizeof(UINT16);
373 CHECK_EQ(bytes_marshalled, expected_bytes);
374 RESET_STRUCT(TPMT_TK_HASHCHECK, 0)
375 TPM_RC rc = TPMT_TK_HASHCHECK_Unmarshal(&value, &buffer_ptr, &size);
376 CHECK_EQ(size, sizeof(TPMT_TK_HASHCHECK)-expected_bytes);
377 CHECK_EQ(rc, TPM_RC_SUCCESS);
378 }
379
StructureFailureTagTest()380 void StructureFailureTagTest() {
381 /* Failure case of structure marshalling with invalid tag value */
382 printf("Running StructureFailureTagTest\n");
383 SETUP_STRUCT(TPMT_TK_HASHCHECK, 0)
384 value.tag = TPM_ST_RSP_COMMAND;
385 UINT16 bytes_marshalled = TPMT_TK_HASHCHECK_Marshal(&value, &buffer_ptr, &size);
386 UINT16 expected_bytes = sizeof(TPM_ST)+sizeof(TPMI_RH_HIERARCHY)+sizeof(UINT16);
387 CHECK_EQ(bytes_marshalled, expected_bytes);
388 RESET_STRUCT(TPMT_TK_HASHCHECK, 0)
389 TPM_RC rc = TPMT_TK_HASHCHECK_Unmarshal(&value, &buffer_ptr, &size);
390 CHECK_EQ(rc, TPM_RC_TAG);
391 }
392
StructureSuccessSizeCheckTest()393 void StructureSuccessSizeCheckTest() {
394 /* Success case of structure marshalling with size= field */
395 printf("Running StructureSuccessSizeCheckTest\n");
396 SETUP_STRUCT(TPM2B_NV_PUBLIC, 0)
397 value.t.size = sizeof(TPMI_RH_NV_INDEX)+sizeof(TPMI_ALG_HASH)+sizeof(TPMA_NV)+sizeof(UINT16)+sizeof(UINT16);
398 value.t.nvPublic.nvIndex = NV_INDEX_FIRST;
399 value.t.nvPublic.nameAlg = TPM_ALG_SHA1;
400 UINT16 bytes_marshalled = TPM2B_NV_PUBLIC_Marshal(&value, &buffer_ptr, &size);
401 RESET_STRUCT(TPM2B_NV_PUBLIC, 0)
402 TPM_RC rc = TPM2B_NV_PUBLIC_Unmarshal(&value, &buffer_ptr, &size);
403 CHECK_EQ(rc, TPM_RC_SUCCESS)
404 }
405