#include <stdio.h> #include <string.h> #include "TPM_Types.h" void BasicTypesSuccessTest(); void BasicTypesFailureTest(); void TypedefSuccessTest(); void TypedefFailureTest(); void ConstantTypeSuccessTest(); void ConstantTypeFailureTest(); void AttributeStructSuccessTest(); void AttributeStructFailureTest(); void InterfaceSuccessTest(); void InterfaceRangeFailureTest(); void InterfaceNullFailureTest(); void InterfaceValueFailureTest(); void InterfaceKeyBitsTest(); void StructureSuccessNormalTest(); void StructureSuccessValueTest(); void StructureFailureNullTest(); void StructureSuccessArrayTest(); void StructureSuccessNullTest(); void StructureFailureTagTest(); void StructureSuccessSizeCheckTest(); /* gtest like macro */ #define CHECK_EQ(a, b) if (a != b) printf("[ERROR:%d] CHECK_EQ(%s == %s) failed\n", __LINE__, #a, #b); #define SETUP_TYPE(type, val) \ const uint16_t num_bytes = sizeof(type); \ INT32 size = num_bytes; \ BYTE buffer[size]; \ BYTE *buffer_ptr = buffer; \ type value = val; #define SETUP_STRUCT(type, val) \ const uint16_t num_bytes = sizeof(type); \ INT32 size = num_bytes; \ BYTE buffer[size]; \ BYTE *buffer_ptr = buffer; \ type value; \ memset(&value, val, sizeof(type)); #define RESET_TYPE(val) \ value = val; \ buffer_ptr = buffer; \ size = num_bytes; #define RESET_STRUCT(type, val) \ memset(&value, val, sizeof(type)); \ buffer_ptr = buffer; \ size = num_bytes; int main() { printf("\nRunning marshal unit tests.\n\n"); BasicTypesSuccessTest(); BasicTypesFailureTest(); TypedefSuccessTest(); TypedefFailureTest(); ConstantTypeSuccessTest(); ConstantTypeFailureTest(); AttributeStructSuccessTest(); AttributeStructFailureTest(); InterfaceSuccessTest(); InterfaceRangeFailureTest(); InterfaceNullFailureTest(); InterfaceValueFailureTest(); InterfaceKeyBitsTest(); StructureSuccessNormalTest(); StructureSuccessValueTest(); StructureFailureNullTest(); StructureSuccessArrayTest(); StructureSuccessNullTest(); StructureFailureTagTest(); StructureSuccessSizeCheckTest(); printf("\nFinished all tests.\n\n"); } void BasicTypesSuccessTest() { printf("Running BasicTypesSuccessTest.\n"); SETUP_TYPE(uint32_t, 12345) UINT16 bytes_marshalled = uint32_t_Marshal(&value, &buffer_ptr, &size); CHECK_EQ(bytes_marshalled, num_bytes) CHECK_EQ(size, 0) CHECK_EQ(buffer_ptr, buffer+num_bytes) RESET_TYPE(0) TPM_RC rc = uint32_t_Unmarshal(&value, &buffer_ptr, &size); CHECK_EQ(rc, TPM_RC_SUCCESS); CHECK_EQ(size, 0); CHECK_EQ(buffer_ptr, buffer+num_bytes); /* Checking that value was marshalled then unmarshalled successfully */ CHECK_EQ(value, 12345); } void BasicTypesFailureTest() { printf("Running BasicTypesFailureTest.\n"); SETUP_TYPE(uint32_t, 12345) --size; UINT16 bytes_marshalled = uint32_t_Marshal(&value, &buffer_ptr, &size); CHECK_EQ(size, num_bytes-1); CHECK_EQ(bytes_marshalled, num_bytes); CHECK_EQ(buffer, buffer_ptr); bytes_marshalled = uint32_t_Marshal(&value, &buffer_ptr, NULL); CHECK_EQ(bytes_marshalled, num_bytes); CHECK_EQ(buffer, buffer_ptr); TPM_RC rc = uint32_t_Unmarshal(&value, &buffer_ptr, &size); CHECK_EQ(rc, TPM_RC_INSUFFICIENT); rc = uint32_t_Unmarshal(&value, &buffer_ptr, NULL); CHECK_EQ(rc, TPM_RC_INSUFFICIENT); } void TypedefSuccessTest() { printf("Running TypedefSuccessTest.\n"); SETUP_TYPE(TPM_KEY_BITS, 12345) UINT16 bytes_marshalled = TPM_KEY_BITS_Marshal(&value, &buffer_ptr, &size); CHECK_EQ(bytes_marshalled, num_bytes); CHECK_EQ(size, 0); CHECK_EQ(buffer_ptr, buffer+num_bytes); RESET_TYPE(0) TPM_RC rc = TPM_KEY_BITS_Unmarshal(&value, &buffer_ptr, &size); CHECK_EQ(rc, TPM_RC_SUCCESS); CHECK_EQ(size, 0); CHECK_EQ(buffer_ptr, buffer+num_bytes); /* Checking that value was marshalled then unmarshalled successfully */ CHECK_EQ(value, 12345); } void TypedefFailureTest() { printf("Running TypedefFailureTest.\n"); SETUP_TYPE(TPM_KEY_BITS, 12345) --size; UINT16 bytes_marshalled = TPM_KEY_BITS_Marshal(&value, &buffer_ptr, &size); CHECK_EQ(size, num_bytes-1); CHECK_EQ(bytes_marshalled, num_bytes); CHECK_EQ(buffer, buffer_ptr); bytes_marshalled = TPM_KEY_BITS_Marshal(&value, &buffer_ptr, NULL); CHECK_EQ(bytes_marshalled, num_bytes); CHECK_EQ(buffer, buffer_ptr); TPM_RC rc = TPM_KEY_BITS_Unmarshal(&value, &buffer_ptr, &size); CHECK_EQ(rc, TPM_RC_INSUFFICIENT); rc = TPM_KEY_BITS_Unmarshal(&value, &buffer_ptr, NULL); CHECK_EQ(rc, TPM_RC_INSUFFICIENT); } void ConstantTypeSuccessTest() { printf("Runnint ConstantTypeSuccessTest.\n"); SETUP_TYPE(TPM_ST, TPM_ST_ATTEST_NV) UINT16 bytes_marshalled = TPM_ST_Marshal(&value, &buffer_ptr, &size); CHECK_EQ(bytes_marshalled, num_bytes); CHECK_EQ(size, 0); CHECK_EQ(buffer_ptr, buffer+num_bytes); RESET_TYPE(0) TPM_RC rc = TPM_ST_Unmarshal(&value, &buffer_ptr, &size); CHECK_EQ(rc, TPM_RC_SUCCESS); CHECK_EQ(size, 0); CHECK_EQ(buffer_ptr, buffer+num_bytes); CHECK_EQ(value, TPM_ST_ATTEST_NV); } void ConstantTypeFailureTest() { printf("Running ConstantTypeFailureTest.\n"); SETUP_TYPE(TPM_ECC_CURVE, 12345) TPM_RC rc = TPM_ECC_CURVE_Unmarshal(&value, &buffer_ptr, &size); CHECK_EQ(rc, TPM_RC_CURVE); CHECK_EQ(size, 0); } void AttributeStructSuccessTest() { printf("Running AttributeStructSuccessTest.\n"); SETUP_STRUCT(TPMA_OBJECT, 0) /* Set some bits to ensure validity */ value.fixedTPM = 1; value.fixedParent = 1; UINT16 bytes_marshalled = TPMA_OBJECT_Marshal(&value, &buffer_ptr, &size); CHECK_EQ(bytes_marshalled, num_bytes); CHECK_EQ(size, 0); CHECK_EQ(buffer_ptr, buffer+num_bytes); RESET_STRUCT(TPMA_OBJECT, 0) TPM_RC rc = TPMA_OBJECT_Unmarshal(&value, &buffer_ptr, &size); CHECK_EQ(rc, TPM_RC_SUCCESS); CHECK_EQ(size, 0); CHECK_EQ(buffer_ptr, buffer+num_bytes); CHECK_EQ(value.fixedTPM, 1); CHECK_EQ(value.fixedParent, 1); } void AttributeStructFailureTest() { printf("Running AttributeStructFailureTest.\n"); SETUP_STRUCT(TPMA_OBJECT, 0) /* Failure occurs when reserved bit is set */ value.reserved8_9 = 1; TPMA_OBJECT_Marshal(&value, &buffer_ptr, &size); RESET_STRUCT(TPMA_OBJECT, 0) TPM_RC rc = TPMA_OBJECT_Unmarshal(&value, &buffer_ptr, &size); CHECK_EQ(rc, TPM_RC_RESERVED_BITS); CHECK_EQ(size, 0); } void InterfaceSuccessTest() { printf("Running InterfaceSuccessTest.\n"); SETUP_TYPE(TPMI_DH_ENTITY, TRANSIENT_FIRST+1) /* Value has valid value from table */ UINT16 bytes_marshalled = TPMI_DH_ENTITY_Marshal(&value, &buffer_ptr, &size); CHECK_EQ(bytes_marshalled, num_bytes); CHECK_EQ(size, 0); CHECK_EQ(buffer_ptr, buffer+num_bytes); RESET_TYPE(0) TPM_RC rc = TPMI_DH_ENTITY_Unmarshal(&value, &buffer_ptr, &size, FALSE); CHECK_EQ(rc, TPM_RC_SUCCESS); CHECK_EQ(size, 0); CHECK_EQ(buffer_ptr, buffer+num_bytes); CHECK_EQ(value, TRANSIENT_FIRST+1); /* Value is optional value and TRUE is passed in as flag parameter*/ RESET_TYPE(TPM_RH_NULL) bytes_marshalled = TPMI_DH_ENTITY_Marshal(&value, &buffer_ptr, &size); CHECK_EQ(bytes_marshalled, num_bytes); CHECK_EQ(size, 0); CHECK_EQ(buffer_ptr, buffer+num_bytes); RESET_TYPE(0) rc = TPMI_DH_ENTITY_Unmarshal(&value, &buffer_ptr, &size, TRUE); CHECK_EQ(rc, TPM_RC_SUCCESS); CHECK_EQ(size, 0); CHECK_EQ(buffer_ptr, buffer+num_bytes); CHECK_EQ(value, TPM_RH_NULL); /* Value has valid value from table */ RESET_TYPE(TPM_RH_OWNER) bytes_marshalled = TPMI_DH_ENTITY_Marshal(&value, &buffer_ptr, &size); CHECK_EQ(bytes_marshalled, num_bytes); CHECK_EQ(size, 0); CHECK_EQ(buffer_ptr, buffer+num_bytes); RESET_TYPE(0) rc = TPMI_DH_ENTITY_Unmarshal(&value, &buffer_ptr, &size, FALSE); CHECK_EQ(rc, TPM_RC_SUCCESS); CHECK_EQ(size, 0); CHECK_EQ(buffer_ptr, buffer+num_bytes); CHECK_EQ(value, TPM_RH_OWNER); } void InterfaceRangeFailureTest() { printf("Running InterfaceRangeFailureTest.\n"); /* Value is out of range */ SETUP_TYPE(TPMI_DH_OBJECT, TRANSIENT_FIRST-1) TPMI_DH_OBJECT_Marshal(&value, &buffer_ptr, &size); RESET_TYPE(0) TPM_RC rc = TPMI_DH_OBJECT_Unmarshal(&value, &buffer_ptr, &size, FALSE); CHECK_EQ(rc, TPM_RC_VALUE); RESET_TYPE(PERSISTENT_LAST+1) TPMI_DH_OBJECT_Marshal(&value, &buffer_ptr, &size); RESET_TYPE(0) rc = TPMI_DH_OBJECT_Unmarshal(&value, &buffer_ptr, &size, FALSE); CHECK_EQ(rc, TPM_RC_VALUE); } void InterfaceNullFailureTest() { printf("Running InterfaceNullFailureTest.\n"); SETUP_TYPE(TPMI_DH_OBJECT, TPM_RH_NULL) TPMI_DH_OBJECT_Marshal(&value, &buffer_ptr, &size); RESET_TYPE(0) TPM_RC rc = TPMI_DH_OBJECT_Unmarshal(&value, &buffer_ptr, &size, FALSE); CHECK_EQ(rc, TPM_RC_VALUE); } void InterfaceValueFailureTest() { printf("Running InterfaceValueFailureTest.\n"); SETUP_TYPE(TPMI_DH_ENTITY, TPM_RH_REVOKE) TPMI_DH_ENTITY_Marshal(&value, &buffer_ptr, &size); RESET_TYPE(0) TPM_RC rc = TPMI_DH_ENTITY_Unmarshal(&value, &buffer_ptr, &size, TRUE); CHECK_EQ(rc, TPM_RC_VALUE); } void InterfaceKeyBitsTest() { printf("Running InterfaceKeyBitsTest\n"); uint16_t vals[] = AES_KEY_SIZES_BITS; SETUP_TYPE(TPMI_AES_KEY_BITS, vals[0]) TPMI_AES_KEY_BITS_Marshal(&value, &buffer_ptr, &size); UINT16 bytes_marshalled = TPMI_AES_KEY_BITS_Marshal(&value, &buffer_ptr, &size); CHECK_EQ(bytes_marshalled, num_bytes); CHECK_EQ(size, 0); CHECK_EQ(buffer_ptr, buffer+num_bytes); RESET_TYPE(0) TPM_RC rc = TPMI_AES_KEY_BITS_Unmarshal(&value, &buffer_ptr, &size, TRUE); CHECK_EQ(rc, TPM_RC_SUCCESS); CHECK_EQ(value, vals[0]); } void StructureSuccessNormalTest() { /* Basic success case of structure marshalling */ printf("Running StructureSuccessNormalTest.\n"); SETUP_STRUCT(TPMS_CLOCK_INFO, 0) value.clock = 12345; value.resetCount = 123; value.restartCount = 45; value.safe = YES; TPMS_CLOCK_INFO_Marshal(&value, &buffer_ptr, &size); RESET_STRUCT(TPMS_CLOCK_INFO, 0) TPM_RC rc = TPMS_CLOCK_INFO_Unmarshal(&value, &buffer_ptr, &size); CHECK_EQ(rc, TPM_RC_SUCCESS); CHECK_EQ(value.safe, YES); CHECK_EQ(value.clock, 12345); CHECK_EQ(value.resetCount, 123); CHECK_EQ(value.restartCount, 45); } void StructureSuccessValueTest() { /* Success case of structure marshalling involving field value checking */ printf("Running StructureSuccessValueTest\n"); SETUP_STRUCT(TPML_DIGEST, 0) value.count = 4; UINT16 bytes_marshalled = TPML_DIGEST_Marshal(&value, &buffer_ptr, &size); CHECK_EQ(bytes_marshalled, sizeof(UINT32)+4*sizeof(UINT16)); RESET_STRUCT(TPML_DIGEST, 0) TPM_RC rc = TPML_DIGEST_Unmarshal(&value, &buffer_ptr, &size); CHECK_EQ(rc, TPM_RC_SUCCESS); CHECK_EQ(value.count, 4); } void StructureFailureNullTest() { /* Failure case of structure marshalling where TPMI field is NULL */ printf("Running StructureFailureNullTest\n"); SETUP_STRUCT(TPMS_PCR_SELECTION, 0) value.hash = TPM_ALG_NULL; value.sizeofSelect = PCR_SELECT_MIN; TPMS_PCR_SELECTION_Marshal(&value, &buffer_ptr, &size); RESET_STRUCT(TPMS_PCR_SELECTION, 0) TPM_RC rc = TPMS_PCR_SELECTION_Unmarshal(&value, &buffer_ptr, &size); CHECK_EQ(rc, TPM_RC_HASH); } void StructureSuccessArrayTest() { /* Success case of structure marshalling involving array */ printf("Running StructureSuccessArrayTest\n"); SETUP_STRUCT(TPM2B_DIGEST, 0) value.t.size = sizeof(TPMU_HA)-1; UINT16 bytes_marshalled = TPM2B_DIGEST_Marshal(&value, &buffer_ptr, &size); UINT16 expected_bytes = sizeof(UINT16)+(sizeof(TPMU_HA)-1)*sizeof(BYTE); CHECK_EQ(bytes_marshalled, expected_bytes); RESET_STRUCT(TPM2B_DIGEST, 0) TPM_RC rc = TPM2B_DIGEST_Unmarshal(&value, &buffer_ptr, &size); CHECK_EQ(size, sizeof(TPM2B_DIGEST)-expected_bytes); CHECK_EQ(rc, TPM_RC_SUCCESS); } void StructureSuccessNullTest() { /* Success case of structure marshalling involving valid null value and * valid tag value */ printf("Running StructureSuccessNullTest\n"); SETUP_STRUCT(TPMT_TK_HASHCHECK, 0) value.tag = TPM_ST_HASHCHECK; value.hierarchy = TPM_RH_NULL; UINT16 bytes_marshalled = TPMT_TK_HASHCHECK_Marshal(&value, &buffer_ptr, &size); UINT16 expected_bytes = sizeof(TPM_ST)+sizeof(TPMI_RH_HIERARCHY)+sizeof(UINT16); CHECK_EQ(bytes_marshalled, expected_bytes); RESET_STRUCT(TPMT_TK_HASHCHECK, 0) TPM_RC rc = TPMT_TK_HASHCHECK_Unmarshal(&value, &buffer_ptr, &size); CHECK_EQ(size, sizeof(TPMT_TK_HASHCHECK)-expected_bytes); CHECK_EQ(rc, TPM_RC_SUCCESS); } void StructureFailureTagTest() { /* Failure case of structure marshalling with invalid tag value */ printf("Running StructureFailureTagTest\n"); SETUP_STRUCT(TPMT_TK_HASHCHECK, 0) value.tag = TPM_ST_RSP_COMMAND; UINT16 bytes_marshalled = TPMT_TK_HASHCHECK_Marshal(&value, &buffer_ptr, &size); UINT16 expected_bytes = sizeof(TPM_ST)+sizeof(TPMI_RH_HIERARCHY)+sizeof(UINT16); CHECK_EQ(bytes_marshalled, expected_bytes); RESET_STRUCT(TPMT_TK_HASHCHECK, 0) TPM_RC rc = TPMT_TK_HASHCHECK_Unmarshal(&value, &buffer_ptr, &size); CHECK_EQ(rc, TPM_RC_TAG); } void StructureSuccessSizeCheckTest() { /* Success case of structure marshalling with size= field */ printf("Running StructureSuccessSizeCheckTest\n"); SETUP_STRUCT(TPM2B_NV_PUBLIC, 0) value.t.size = sizeof(TPMI_RH_NV_INDEX)+sizeof(TPMI_ALG_HASH)+sizeof(TPMA_NV)+sizeof(UINT16)+sizeof(UINT16); value.t.nvPublic.nvIndex = NV_INDEX_FIRST; value.t.nvPublic.nameAlg = TPM_ALG_SHA1; UINT16 bytes_marshalled = TPM2B_NV_PUBLIC_Marshal(&value, &buffer_ptr, &size); RESET_STRUCT(TPM2B_NV_PUBLIC, 0) TPM_RC rc = TPM2B_NV_PUBLIC_Unmarshal(&value, &buffer_ptr, &size); CHECK_EQ(rc, TPM_RC_SUCCESS) }