From d2aad4dcb30c0e7ebeeeec831109ea84b0affe8e Mon Sep 17 00:00:00 2001 From: Xiaohanjlll Date: Fri, 12 Jan 2024 16:17:03 +0800 Subject: [PATCH] add unit test for SPDM 1.3 When the corresponding key usage is not set Signed-off-by: Xiaohanjlll --- .../test_spdm_responder/challenge_auth.c | 80 +++++++++++++ unit_test/test_spdm_responder/key_exchange.c | 105 +++++++++++++++++- unit_test/test_spdm_responder/measurements.c | 83 ++++++++++++++ 3 files changed, 267 insertions(+), 1 deletion(-) diff --git a/unit_test/test_spdm_responder/challenge_auth.c b/unit_test/test_spdm_responder/challenge_auth.c index c7a03a1df57..bf6bfc8c44d 100644 --- a/unit_test/test_spdm_responder/challenge_auth.c +++ b/unit_test/test_spdm_responder/challenge_auth.c @@ -1137,6 +1137,83 @@ void libspdm_test_responder_challenge_auth_case18(void **state) free(data1); } +/** + * Test 19: The key usage bit mask is not set, the SlotID fields in CHALLENGE and CHALLENGE_AUTH shall not specify this certificate slot + * Expected behavior: the responder accepts the request, but produces an ERROR message + * indicating the invalid state. + **/ +void libspdm_test_responder_challenge_auth_case19(void **state) +{ + libspdm_return_t status; + libspdm_test_context_t *spdm_test_context; + libspdm_context_t *spdm_context; + size_t response_size; + spdm_challenge_auth_response_t *spdm_response; + void *data1; + size_t data_size1; + uint8_t *requester_context; + uint8_t request[LIBSPDM_MAX_SPDM_MSG_SIZE]; + uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE]; + uint8_t slot_id; + + spdm_test_context = *state; + spdm_context = spdm_test_context->spdm_context; + spdm_test_context->case_id = 0x13; + spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED; + spdm_context->local_context.capability.flags = 0; + spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHAL_CAP; + 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; + spdm_context->connection_info.multi_key_conn_rsp = true; + + spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_13 << + SPDM_VERSION_NUMBER_SHIFT_BIT; + libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo, + m_libspdm_use_asym_algo, &data1, + &data_size1, NULL, NULL); + spdm_context->local_context.local_cert_chain_provision[0] = data1; + spdm_context->local_context.local_cert_chain_provision_size[0] = data_size1; + + libspdm_secret_lib_challenge_opaque_data_size = 0; + libspdm_reset_message_c(spdm_context); +#if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT + spdm_context->transcript.message_m.buffer_size = + spdm_context->transcript.message_m.max_buffer_size; +#endif + + /* If set, the SlotID fields in CHALLENGE and CHALLENGE_AUTH can specify this certificate slot. If not set, the + * SlotID fields in CHALLENGE and CHALLENGE_AUTH shall not specify this certificate slot. */ + slot_id = 0; + m_libspdm_challenge_request8.header.param1 = slot_id; + spdm_context->local_context.local_key_usage_bit_mask[slot_id] = + SPDM_KEY_USAGE_BIT_MASK_KEY_EX_USE | + SPDM_KEY_USAGE_BIT_MASK_MEASUREMENT_USE; + + libspdm_get_random_number(SPDM_NONCE_SIZE, m_libspdm_challenge_request8.nonce); + + libspdm_zero_mem(request, sizeof(request)); + libspdm_copy_mem(request, sizeof(spdm_challenge_request_t), + &m_libspdm_challenge_request8, sizeof(m_libspdm_challenge_request8)); + requester_context = request + sizeof(m_libspdm_challenge_request8); + libspdm_set_mem(requester_context, SPDM_REQ_CONTEXT_SIZE, 0xAA); + m_libspdm_challenge_request8_size = sizeof(m_libspdm_challenge_request8) + + SPDM_REQ_CONTEXT_SIZE; + + response_size = sizeof(response); + status = libspdm_get_response_challenge_auth( + spdm_context, m_libspdm_challenge_request8_size, + request, &response_size, response); + assert_int_equal(status, LIBSPDM_STATUS_SUCCESS); + assert_int_equal (response_size, sizeof(spdm_error_response_t)); + spdm_response = (void *)response; + assert_int_equal (spdm_response->header.request_response_code, SPDM_ERROR); + assert_int_equal (spdm_response->header.param1, SPDM_ERROR_CODE_INVALID_REQUEST); + assert_int_equal (spdm_response->header.param2, 0); + free(data1); +} libspdm_test_context_t m_libspdm_responder_challenge_auth_test_context = { LIBSPDM_TEST_CONTEXT_VERSION, false, @@ -1174,6 +1251,9 @@ int libspdm_responder_challenge_auth_test_main(void) cmocka_unit_test(libspdm_test_responder_challenge_auth_case17), /* Success Case: V1.3 get a correct context field */ cmocka_unit_test(libspdm_test_responder_challenge_auth_case18), + /* The key usage bit mask is not set, failed Case*/ + cmocka_unit_test(libspdm_test_responder_challenge_auth_case19), + }; libspdm_setup_test_context(&m_libspdm_responder_challenge_auth_test_context); diff --git a/unit_test/test_spdm_responder/key_exchange.c b/unit_test/test_spdm_responder/key_exchange.c index 119027dc1e4..5a21beb067b 100644 --- a/unit_test/test_spdm_responder/key_exchange.c +++ b/unit_test/test_spdm_responder/key_exchange.c @@ -82,6 +82,12 @@ libspdm_key_exchange_request_mine_t m_libspdm_key_exchange_request9 = { }; size_t m_libspdm_key_exchange_request9_size = sizeof(m_libspdm_key_exchange_request9); +libspdm_key_exchange_request_mine_t m_libspdm_key_exchange_request10 = { + { SPDM_MESSAGE_VERSION_13, SPDM_KEY_EXCHANGE, + SPDM_KEY_EXCHANGE_REQUEST_NO_MEASUREMENT_SUMMARY_HASH, 0 }, +}; +size_t m_libspdm_key_exchange_request10_size = sizeof(m_libspdm_key_exchange_request10); + void libspdm_test_responder_key_exchange_case1(void **state) { libspdm_return_t status; @@ -1801,6 +1807,102 @@ void libspdm_test_responder_key_exchange_case20(void **state) free(data1); } +/** + * Test 36: The key usage bit mask is not set, the SlotID fields in KEY_EXCHANGE and KEY_EXCHANGE_RSP shall not specify this certificate slot + * Expected Behavior: get a SPDM_ERROR_CODE_INVALID_REQUEST return code + **/ +void libspdm_test_responder_key_exchange_case21(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_key_exchange_response_t *spdm_response; + void *data1; + size_t data_size1; + uint8_t *ptr; + size_t dhe_key_size; + void *dhe_context; + size_t opaque_key_exchange_req_size; + uint8_t slot_id; + + spdm_test_context = *state; + spdm_context = spdm_test_context->spdm_context; + spdm_test_context->case_id = 0x15; + spdm_context->connection_info.connection_state = + LIBSPDM_CONNECTION_STATE_NEGOTIATED; + spdm_context->connection_info.capability.flags |= + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_KEY_EX_CAP; + spdm_context->local_context.capability.flags |= + SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_KEY_EX_CAP; + 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; + spdm_context->connection_info.algorithm.dhe_named_group = m_libspdm_use_dhe_algo; + spdm_context->connection_info.algorithm.aead_cipher_suite = m_libspdm_use_aead_algo; + spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_13 << + SPDM_VERSION_NUMBER_SHIFT_BIT; + spdm_context->connection_info.algorithm.other_params_support = + SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_1; + spdm_context->local_context.secured_message_version.spdm_version_count = 1; + spdm_context->connection_info.multi_key_conn_rsp = true; + + libspdm_session_info_init(spdm_context, + spdm_context->session_info, + INVALID_SESSION_ID, false); + libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo, + m_libspdm_use_asym_algo, &data1, + &data_size1, NULL, NULL); + spdm_context->local_context.local_cert_chain_provision[0] = data1; + spdm_context->local_context.local_cert_chain_provision_size[0] = data_size1; + + libspdm_reset_message_a(spdm_context); + spdm_context->local_context.mut_auth_requested = 0; + + /* If set, the SlotID fields in KEY_EXCHANGE and KEY_EXCHANGE_RSP can specify this certificate slot. If not set, + * the SlotID fields in KEY_EXCHANGE and KEY_EXCHANGE_RSP shall not specify this certificate slot */ + slot_id = 0; + m_libspdm_key_exchange_request10.header.param2 = slot_id; + spdm_context->local_context.local_key_usage_bit_mask[slot_id] = + SPDM_KEY_USAGE_BIT_MASK_CHALLENGE_USE | + SPDM_KEY_USAGE_BIT_MASK_MEASUREMENT_USE; + + libspdm_get_random_number(SPDM_RANDOM_DATA_SIZE, m_libspdm_key_exchange_request10.random_data); + m_libspdm_key_exchange_request10.req_session_id = 0xFFFF; + m_libspdm_key_exchange_request10.reserved = 0; + m_libspdm_key_exchange_request10.session_policy = 0xFF; + ptr = m_libspdm_key_exchange_request10.exchange_data; + dhe_key_size = libspdm_get_dhe_pub_key_size(m_libspdm_use_dhe_algo); + dhe_context = libspdm_dhe_new(spdm_context->connection_info.version, m_libspdm_use_dhe_algo, + false); + libspdm_dhe_generate_key(m_libspdm_use_dhe_algo, dhe_context, ptr, &dhe_key_size); + ptr += dhe_key_size; + libspdm_dhe_free(m_libspdm_use_dhe_algo, dhe_context); + opaque_key_exchange_req_size = + libspdm_get_opaque_data_supported_version_data_size(spdm_context); + *(uint16_t *)ptr = (uint16_t)opaque_key_exchange_req_size; + ptr += sizeof(uint16_t); + libspdm_build_opaque_data_supported_version_data( + spdm_context, &opaque_key_exchange_req_size, ptr); + ptr += opaque_key_exchange_req_size; + response_size = sizeof(response); + status = libspdm_get_response_key_exchange( + spdm_context, m_libspdm_key_exchange_request10_size, + &m_libspdm_key_exchange_request10, &response_size, response); + + assert_int_equal(status, LIBSPDM_STATUS_SUCCESS); + assert_int_equal (response_size, sizeof(spdm_error_response_t)); + spdm_response = (void *)response; + assert_int_equal (spdm_response->header.request_response_code, SPDM_ERROR); + assert_int_equal (spdm_response->header.param1, SPDM_ERROR_CODE_INVALID_REQUEST); + assert_int_equal (spdm_response->header.param2, 0); + + free(data1); +} + libspdm_test_context_t m_libspdm_responder_key_exchange_test_context = { LIBSPDM_TEST_CONTEXT_VERSION, false, @@ -1847,7 +1949,8 @@ int libspdm_responder_key_exchange_test_main(void) cmocka_unit_test(libspdm_test_responder_key_exchange_case19), /* OpaqueData only supports OpaqueDataFmt1, Success Case */ cmocka_unit_test(libspdm_test_responder_key_exchange_case20), - + /* The key usage bit mask is not set, failed Case*/ + cmocka_unit_test(libspdm_test_responder_key_exchange_case21), }; libspdm_setup_test_context(&m_libspdm_responder_key_exchange_test_context); diff --git a/unit_test/test_spdm_responder/measurements.c b/unit_test/test_spdm_responder/measurements.c index 0f443cb9df6..f5e64c93fde 100644 --- a/unit_test/test_spdm_responder/measurements.c +++ b/unit_test/test_spdm_responder/measurements.c @@ -2630,6 +2630,87 @@ void libspdm_test_responder_measurements_case35(void **state) #endif } +/** + * Test 36: The key usage bit mask is not set, the SlotID fields in GET_MEASUREMENTS and MEASUREMENTS shall not specify this certificate slot + * Expected Behavior: get a SPDM_ERROR_CODE_INVALID_REQUEST return code + **/ +void libspdm_test_responder_measurements_case36(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 slot_id; + void *data; + size_t data_size; + + spdm_test_context = *state; + spdm_context = spdm_test_context->spdm_context; + spdm_test_context->case_id = 36; + 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->local_context.capability.flags |= + SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_PUB_KEY_ID_CAP; + 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_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.measurement_spec = + m_libspdm_use_measurement_spec; + spdm_context->connection_info.multi_key_conn_rsp = true; + libspdm_reset_message_m(spdm_context, NULL); + + libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo, + m_libspdm_use_asym_algo, &data, + &data_size, NULL, NULL); + for (int i = 0; i < SPDM_MAX_SLOT_COUNT; i++) { + spdm_context->local_context.local_cert_chain_provision_size[i] = data_size; + spdm_context->local_context.local_cert_chain_provision[i] = data; + } + + /* If set, the SlotID fields in GET_MEASUREMENTS and MEASUREMENTS can specify this certificate slot. If not set, + * the SlotID fields in GET_MEASUREMENTS and MEASUREMENTS shall not specify this certificate slot. */ + slot_id = 0; + m_libspdm_get_measurements_request17.slot_id_param = slot_id; + spdm_context->local_context.local_key_usage_bit_mask[slot_id] = + SPDM_KEY_USAGE_BIT_MASK_KEY_EX_USE | + SPDM_KEY_USAGE_BIT_MASK_CHALLENGE_USE; + + libspdm_get_random_number(SPDM_NONCE_SIZE, + m_libspdm_get_measurements_request17.nonce); + m_libspdm_get_measurements_request17.header.param1 = + SPDM_GET_MEASUREMENTS_REQUEST_ATTRIBUTES_GENERATE_SIGNATURE; + m_libspdm_get_measurements_request17.header.param2 = 1; + + requester_context = ((uint8_t *)&m_libspdm_get_measurements_request17) + + sizeof(m_libspdm_get_measurements_request17); + libspdm_set_mem(requester_context, SPDM_REQ_CONTEXT_SIZE, 0xAA); + m_libspdm_get_measurements_request17_size = sizeof(m_libspdm_get_measurements_request17) + + SPDM_REQ_CONTEXT_SIZE; + + response_size = sizeof(response); + 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_error_response_t)); + spdm_response = (void *)response; + assert_int_equal(spdm_response->header.request_response_code, SPDM_ERROR); + assert_int_equal(spdm_response->header.param1, SPDM_ERROR_CODE_INVALID_REQUEST); + assert_int_equal(spdm_response->header.param2, 0); +} + libspdm_test_context_t m_libspdm_responder_measurements_test_context = { LIBSPDM_TEST_CONTEXT_VERSION, false, @@ -2711,6 +2792,8 @@ int libspdm_responder_measurements_test_main(void) 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), + /* The key usage bit mask is not set, failed Case*/ + cmocka_unit_test(libspdm_test_responder_measurements_case36), }; libspdm_setup_test_context(&m_libspdm_responder_measurements_test_context);