Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add unit test for SPDM 1.3 MEASUREMENTS: context field. #2439

Merged
merged 1 commit into from
Nov 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
315 changes: 315 additions & 0 deletions unit_test/test_spdm_requester/get_measurements.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ static uint8_t m_libspdm_msg_log_buffer[LIBSPDM_MAX_MESSAGE_L1L2_BUFFER_SIZE * 2
static size_t m_libspdm_opaque_data_size;
static uint8_t m_libspdm_opaque_data[SPDM_MAX_OPAQUE_DATA_SIZE];

static uint8_t m_requester_context[SPDM_REQ_CONTEXT_SIZE];

static size_t libspdm_test_get_measurement_request_size(const void *spdm_context,
const void *buffer,
size_t buffer_size)
Expand Down Expand Up @@ -450,6 +452,16 @@ static libspdm_return_t libspdm_requester_get_measurements_test_send_message(
(const uint8_t *)request + header_size, message_size);
m_libspdm_local_buffer_size += message_size;
return LIBSPDM_STATUS_SUCCESS;
case 0x28:
case 0x29:
m_libspdm_local_buffer_size = 0;
message_size = libspdm_test_get_measurement_request_size(
spdm_context, (const uint8_t *)request + header_size,
request_size - header_size);
libspdm_copy_mem(m_libspdm_local_buffer, sizeof(m_libspdm_local_buffer),
(const uint8_t *)request + header_size, message_size);
m_libspdm_local_buffer_size += message_size;
return LIBSPDM_STATUS_SUCCESS;
default:
return LIBSPDM_STATUS_SEND_FAIL;
}
Expand Down Expand Up @@ -3115,6 +3127,143 @@ static libspdm_return_t libspdm_requester_get_measurements_test_receive_message(
ptr, &sig_size);
ptr += sig_size;

libspdm_transport_test_encode_message(spdm_context, NULL, false,
false, spdm_response_size,
spdm_response, response_size,
response);
}
return LIBSPDM_STATUS_SUCCESS;
case 0x28: {
spdm_measurements_response_t *spdm_response;
spdm_measurement_block_dmtf_t *measurment_block;
size_t spdm_response_size;
size_t transport_header_size;
uint8_t *ptr;
((libspdm_context_t *)spdm_context)
->connection_info.algorithm.measurement_hash_algo =
m_libspdm_use_measurement_hash_algo;
spdm_response_size = sizeof(spdm_measurements_response_t) +
sizeof(spdm_measurement_block_dmtf_t) +
libspdm_get_measurement_hash_size(m_libspdm_use_measurement_hash_algo)
+ SPDM_NONCE_SIZE + sizeof(uint16_t) + SPDM_REQ_CONTEXT_SIZE;

transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
spdm_response = (void *)((uint8_t *)*response + transport_header_size);

spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_13;
spdm_response->header.request_response_code = SPDM_MEASUREMENTS;
spdm_response->header.param1 = 0;
spdm_response->header.param2 = 0;
spdm_response->number_of_blocks = 1;
libspdm_write_uint24(
spdm_response->measurement_record_length,
(uint32_t)(sizeof(spdm_measurement_block_dmtf_t) +
libspdm_get_measurement_hash_size( m_libspdm_use_measurement_hash_algo)));

measurment_block = (void *)(spdm_response + 1);
libspdm_set_mem(measurment_block,
sizeof(spdm_measurement_block_dmtf_t) +
libspdm_get_measurement_hash_size(
m_libspdm_use_measurement_hash_algo),
1);

measurment_block->measurement_block_common_header
.measurement_specification =
SPDM_MEASUREMENT_SPECIFICATION_DMTF;
measurment_block->measurement_block_common_header
.measurement_size =
(uint16_t)(sizeof(spdm_measurement_block_dmtf_header_t) +
libspdm_get_measurement_hash_size(
m_libspdm_use_measurement_hash_algo));

ptr = (uint8_t *)spdm_response +
sizeof(spdm_measurements_response_t) +
sizeof(spdm_measurement_block_dmtf_t) +
libspdm_get_measurement_hash_size(
m_libspdm_use_measurement_hash_algo);
libspdm_get_random_number(SPDM_NONCE_SIZE,ptr);

ptr += SPDM_NONCE_SIZE;
*(uint16_t *)ptr = 0;

ptr += sizeof(uint16_t);
libspdm_copy_mem(ptr, SPDM_REQ_CONTEXT_SIZE, m_requester_context, SPDM_REQ_CONTEXT_SIZE);

libspdm_copy_mem(m_libspdm_local_buffer + m_libspdm_local_buffer_size,
sizeof(m_libspdm_local_buffer) - m_libspdm_local_buffer_size,
spdm_response, spdm_response_size);

m_libspdm_local_buffer_size += spdm_response_size;

libspdm_transport_test_encode_message(spdm_context, NULL, false,
false, spdm_response_size,
spdm_response, response_size,
response);
}
return LIBSPDM_STATUS_SUCCESS;
case 0x29: {
spdm_measurements_response_t *spdm_response;
spdm_measurement_block_dmtf_t *measurment_block;
size_t spdm_response_size;
size_t transport_header_size;
uint8_t *ptr;
((libspdm_context_t *)spdm_context)
->connection_info.algorithm.measurement_hash_algo =
m_libspdm_use_measurement_hash_algo;
spdm_response_size = sizeof(spdm_measurements_response_t) +
sizeof(spdm_measurement_block_dmtf_t) +
libspdm_get_measurement_hash_size(m_libspdm_use_measurement_hash_algo)
+
SPDM_NONCE_SIZE + sizeof(uint16_t) + SPDM_REQ_CONTEXT_SIZE;

transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
spdm_response = (void *)((uint8_t *)*response + transport_header_size);

spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_13;
spdm_response->header.request_response_code = SPDM_MEASUREMENTS;
spdm_response->header.param1 = 0;
spdm_response->header.param2 = 0;
spdm_response->number_of_blocks = 1;
libspdm_write_uint24(
spdm_response->measurement_record_length,
(uint32_t)(sizeof(spdm_measurement_block_dmtf_t) +
libspdm_get_measurement_hash_size( m_libspdm_use_measurement_hash_algo)));

measurment_block = (void *)(spdm_response + 1);
libspdm_set_mem(measurment_block,
sizeof(spdm_measurement_block_dmtf_t) +
libspdm_get_measurement_hash_size(
m_libspdm_use_measurement_hash_algo),
1);

measurment_block->measurement_block_common_header
.measurement_specification =
SPDM_MEASUREMENT_SPECIFICATION_DMTF;
measurment_block->measurement_block_common_header
.measurement_size =
(uint16_t)(sizeof(spdm_measurement_block_dmtf_header_t) +
libspdm_get_measurement_hash_size(
m_libspdm_use_measurement_hash_algo));

ptr = (uint8_t *)spdm_response +
sizeof(spdm_measurements_response_t) +
sizeof(spdm_measurement_block_dmtf_t) +
libspdm_get_measurement_hash_size(
m_libspdm_use_measurement_hash_algo);
libspdm_get_random_number(SPDM_NONCE_SIZE,ptr);

ptr += SPDM_NONCE_SIZE;
*(uint16_t *)ptr = 0;

ptr += sizeof(uint16_t);
libspdm_get_random_number(SPDM_REQ_CONTEXT_SIZE,ptr);

libspdm_copy_mem(m_libspdm_local_buffer + m_libspdm_local_buffer_size,
sizeof(m_libspdm_local_buffer) - m_libspdm_local_buffer_size,
spdm_response, spdm_response_size);

m_libspdm_local_buffer_size += spdm_response_size;

libspdm_transport_test_encode_message(spdm_context, NULL, false,
false, spdm_response_size,
spdm_response, response_size,
Expand Down Expand Up @@ -6033,6 +6182,170 @@ static void libspdm_test_requester_get_measurements_case39(void **state)
free(data);
}

/**
* Test 40: Successful case , correct measuerments context field , without signature
* Expected Behavior: client returns a status of RETURN_SUCCESS.
**/
static void libspdm_test_requester_get_measurements_case40(void **state)
{
libspdm_return_t status;
libspdm_test_context_t *spdm_test_context;
libspdm_context_t *spdm_context;
uint8_t number_of_block;
uint32_t measurement_record_length;
uint8_t measurement_record[LIBSPDM_MAX_MEASUREMENT_RECORD_SIZE];
uint8_t request_attribute;
void *data;
size_t data_size;
void *hash;
size_t hash_size;

spdm_test_context = *state;
spdm_context = spdm_test_context->spdm_context;
spdm_test_context->case_id = 0x28;
spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_13 <<
SPDM_VERSION_NUMBER_SHIFT_BIT;
spdm_context->connection_info.connection_state =
LIBSPDM_CONNECTION_STATE_AUTHENTICATED;
spdm_context->connection_info.capability.flags |=
SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP_SIG;
libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
m_libspdm_use_asym_algo, &data,
&data_size, &hash, &hash_size);
libspdm_reset_message_m(spdm_context, NULL);
spdm_context->connection_info.algorithm.measurement_spec =
m_libspdm_use_measurement_spec;
spdm_context->connection_info.algorithm.measurement_hash_algo =
m_libspdm_use_measurement_hash_algo;
spdm_context->connection_info.algorithm.base_hash_algo =
m_libspdm_use_hash_algo;
spdm_context->connection_info.algorithm.base_asym_algo =
m_libspdm_use_asym_algo;
spdm_context->local_context.algorithm.measurement_spec =
SPDM_MEASUREMENT_SPECIFICATION_DMTF;

#if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
spdm_context->connection_info.peer_used_cert_chain[0].buffer_size = data_size;
libspdm_copy_mem(spdm_context->connection_info.peer_used_cert_chain[0].buffer,
sizeof(spdm_context->connection_info.peer_used_cert_chain[0].buffer),
data, data_size);
#else
libspdm_hash_all(
spdm_context->connection_info.algorithm.base_hash_algo,
data, data_size,
spdm_context->connection_info.peer_used_cert_chain[0].buffer_hash);
spdm_context->connection_info.peer_used_cert_chain[0].buffer_hash_size =
libspdm_get_hash_size(spdm_context->connection_info.algorithm.base_hash_algo);
libspdm_get_leaf_cert_public_key_from_cert_chain(
spdm_context->connection_info.algorithm.base_hash_algo,
spdm_context->connection_info.algorithm.base_asym_algo,
data, data_size,
&spdm_context->connection_info.peer_used_cert_chain[0].leaf_cert_public_key);
#endif

measurement_record_length = sizeof(measurement_record);

libspdm_set_mem(m_requester_context, SPDM_REQ_CONTEXT_SIZE, 0xAA);

request_attribute = 0; /* Do not request a signature. */

status = libspdm_get_measurement_ex2(spdm_context, NULL, request_attribute, 1,
0, m_requester_context, NULL, &number_of_block,
&measurement_record_length,
measurement_record, NULL, NULL, NULL, NULL, NULL);

assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);

#if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
assert_int_equal(spdm_context->transcript.message_m.buffer_size,
sizeof(spdm_message_header_t) + SPDM_REQ_CONTEXT_SIZE +
sizeof(spdm_measurements_response_t) +
sizeof(spdm_measurement_block_dmtf_t) +
libspdm_get_measurement_hash_size(m_libspdm_use_measurement_hash_algo) +
SPDM_NONCE_SIZE + sizeof(uint16_t) + SPDM_REQ_CONTEXT_SIZE);
#endif
free(data);
}

/**
* Test 41: Error case , Measurement context fields are inconsistent , without signature
* Expected Behavior: get a LIBSPDM_STATUS_INVALID_MSG_FIELD return code
**/
static void libspdm_test_requester_get_measurements_case41(void **state)
{
libspdm_return_t status;
libspdm_test_context_t *spdm_test_context;
libspdm_context_t *spdm_context;
uint8_t number_of_block;
uint32_t measurement_record_length;
uint8_t measurement_record[LIBSPDM_MAX_MEASUREMENT_RECORD_SIZE];
uint8_t request_attribute;
void *data;
size_t data_size;
void *hash;
size_t hash_size;

spdm_test_context = *state;
spdm_context = spdm_test_context->spdm_context;
spdm_test_context->case_id = 0x29;
spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_13 <<
SPDM_VERSION_NUMBER_SHIFT_BIT;
spdm_context->connection_info.connection_state =
LIBSPDM_CONNECTION_STATE_AUTHENTICATED;
spdm_context->connection_info.capability.flags |=
SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP_SIG;
libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
m_libspdm_use_asym_algo, &data,
&data_size, &hash, &hash_size);
libspdm_reset_message_m(spdm_context, NULL);
spdm_context->connection_info.algorithm.measurement_spec =
m_libspdm_use_measurement_spec;
spdm_context->connection_info.algorithm.measurement_hash_algo =
m_libspdm_use_measurement_hash_algo;
spdm_context->connection_info.algorithm.base_hash_algo =
m_libspdm_use_hash_algo;
spdm_context->connection_info.algorithm.base_asym_algo =
m_libspdm_use_asym_algo;
spdm_context->local_context.algorithm.measurement_spec =
SPDM_MEASUREMENT_SPECIFICATION_DMTF;

#if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
spdm_context->connection_info.peer_used_cert_chain[0].buffer_size = data_size;
libspdm_copy_mem(spdm_context->connection_info.peer_used_cert_chain[0].buffer,
sizeof(spdm_context->connection_info.peer_used_cert_chain[0].buffer),
data, data_size);
#else
libspdm_hash_all(
spdm_context->connection_info.algorithm.base_hash_algo,
data, data_size,
spdm_context->connection_info.peer_used_cert_chain[0].buffer_hash);
spdm_context->connection_info.peer_used_cert_chain[0].buffer_hash_size =
libspdm_get_hash_size(spdm_context->connection_info.algorithm.base_hash_algo);
libspdm_get_leaf_cert_public_key_from_cert_chain(
spdm_context->connection_info.algorithm.base_hash_algo,
spdm_context->connection_info.algorithm.base_asym_algo,
data, data_size,
&spdm_context->connection_info.peer_used_cert_chain[0].leaf_cert_public_key);
#endif

measurement_record_length = sizeof(measurement_record);

libspdm_set_mem(m_requester_context, SPDM_REQ_CONTEXT_SIZE, 0xAA);

request_attribute = 0; /* Do not request a signature. */

status = libspdm_get_measurement_ex2(spdm_context, NULL, request_attribute, 1,
0, m_requester_context, NULL, &number_of_block,
&measurement_record_length,
measurement_record, NULL, NULL, NULL, NULL, NULL);

assert_int_equal(status, LIBSPDM_STATUS_INVALID_MSG_FIELD);

#if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
assert_int_equal(spdm_context->transcript.message_m.buffer_size, 0);
#endif
free(data);
}
libspdm_test_context_t m_libspdm_requester_get_measurements_test_context = {
LIBSPDM_TEST_CONTEXT_VERSION,
true,
Expand Down Expand Up @@ -6082,6 +6395,8 @@ int libspdm_requester_get_measurements_test_main(void)
cmocka_unit_test(libspdm_test_requester_get_measurements_case37),
cmocka_unit_test(libspdm_test_requester_get_measurements_case38),
cmocka_unit_test(libspdm_test_requester_get_measurements_case39),
cmocka_unit_test(libspdm_test_requester_get_measurements_case40),
cmocka_unit_test(libspdm_test_requester_get_measurements_case41),
};

libspdm_setup_test_context(&m_libspdm_requester_get_measurements_test_context);
Expand Down
Loading