404 lines
14 KiB
C
404 lines
14 KiB
C
#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)
|
|
}
|