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