diff --git a/unit_test/test_spdm_requester/get_measurements.c b/unit_test/test_spdm_requester/get_measurements.c index 57099d291f5..a5085e0f8c0 100644 --- a/unit_test/test_spdm_requester/get_measurements.c +++ b/unit_test/test_spdm_requester/get_measurements.c @@ -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) @@ -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; } @@ -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, @@ -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, @@ -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); diff --git a/unit_test/test_spdm_responder/measurements.c b/unit_test/test_spdm_responder/measurements.c index bd29488d98a..c0cb2b55a31 100644 --- a/unit_test/test_spdm_responder/measurements.c +++ b/unit_test/test_spdm_responder/measurements.c @@ -109,6 +109,12 @@ spdm_get_measurements_request_t m_libspdm_get_measurements_request16 = { }; size_t m_libspdm_get_measurements_request16_size = sizeof(m_libspdm_get_measurements_request16); +spdm_get_measurements_request_t m_libspdm_get_measurements_request17 = { + { SPDM_MESSAGE_VERSION_13, SPDM_GET_MEASUREMENTS, 0, + SPDM_GET_MEASUREMENTS_REQUEST_MEASUREMENT_OPERATION_TOTAL_NUMBER_OF_MEASUREMENTS }, +}; +size_t m_libspdm_get_measurements_request17_size = sizeof(spdm_message_header_t); + extern size_t libspdm_secret_lib_meas_opaque_data_size; /** @@ -2507,6 +2513,72 @@ void libspdm_test_responder_measurements_case34(void** state) #endif } +/** + * Test 35: Successful response V1.3 to get a number of measurements without signature + * Expected Behavior: get a RETURN_SUCCESS return code, correct context field + **/ +void libspdm_test_responder_measurements_case35(void **state) +{ + libspdm_return_t status; + libspdm_test_context_t *spdm_test_context; + libspdm_context_t *spdm_context; + size_t response_size; + uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE]; + spdm_measurements_response_t *spdm_response; + uint8_t *requester_context; + uint8_t *responder_context; + + spdm_test_context = *state; + spdm_context = spdm_test_context->spdm_context; + spdm_test_context->case_id = 35; + 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->local_context.capability.flags |= + SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP_SIG; + 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->connection_info.algorithm.measurement_spec = + m_libspdm_use_measurement_spec; + spdm_context->connection_info.algorithm.measurement_hash_algo = + m_libspdm_use_measurement_hash_algo; + libspdm_reset_message_m(spdm_context, NULL); + + libspdm_secret_lib_meas_opaque_data_size = 0; + + response_size = sizeof(response); + + requester_context = ((uint8_t *)&m_libspdm_get_measurements_request17) + + m_libspdm_get_measurements_request17_size; + libspdm_set_mem(requester_context, SPDM_REQ_CONTEXT_SIZE, 0xAA); + m_libspdm_get_measurements_request17_size += SPDM_REQ_CONTEXT_SIZE; + + status = libspdm_get_response_measurements( + spdm_context, m_libspdm_get_measurements_request17_size, + &m_libspdm_get_measurements_request17, &response_size, response); + + assert_int_equal(status, LIBSPDM_STATUS_SUCCESS); + assert_int_equal(response_size, + sizeof(spdm_measurements_response_t) + SPDM_NONCE_SIZE + sizeof(uint16_t) + + SPDM_REQ_CONTEXT_SIZE); + spdm_response = (void *)response; + assert_int_equal(spdm_response->header.request_response_code, + SPDM_MEASUREMENTS); + responder_context = (void *)response; + responder_context += sizeof(spdm_measurements_response_t) + SPDM_NONCE_SIZE + sizeof(uint16_t); + assert_memory_equal((void *)requester_context, responder_context, SPDM_REQ_CONTEXT_SIZE); +#if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT + assert_int_equal(spdm_context->transcript.message_m.buffer_size, + m_libspdm_get_measurements_request17_size + + sizeof(spdm_measurements_response_t) + + SPDM_NONCE_SIZE + + sizeof(uint16_t) + + SPDM_REQ_CONTEXT_SIZE); +#endif +} libspdm_test_context_t m_libspdm_responder_measurements_test_context = { LIBSPDM_TEST_CONTEXT_VERSION, @@ -2587,6 +2659,8 @@ int libspdm_responder_measurements_test_main(void) cmocka_unit_test(libspdm_test_responder_measurements_case33), /* Success Case: Little Endian Signature. Big or Little Endian Verify */ cmocka_unit_test(libspdm_test_responder_measurements_case34), + /* Success Case: V1.3 get a correct context field */ + cmocka_unit_test(libspdm_test_responder_measurements_case35), }; libspdm_setup_test_context(&m_libspdm_responder_measurements_test_context);