From 65216ed8f286d2222a79f1a62efbcdb746527e7d Mon Sep 17 00:00:00 2001 From: Wenxing Hou Date: Tue, 27 Sep 2022 17:17:42 +0800 Subject: [PATCH 1/2] Move the spdm_device_validator_sample to SPDM-Responder-Validator Fix the issue: #148 Make the SPDM-Responder-Validator independent. The SPDM-Responder-Validator will not be submodule after this PR. Signed-off-by: Wenxing Hou --- .gitmodules | 3 - CMakeLists.txt | 7 +- SPDM-Responder-Validator | 1 - include/library/common_test_utility_lib.h | 175 ++ .../spdm_responder_conformance_test_lib.h | 132 + .../common_test_utility_lib/CMakeLists.txt | 13 + .../common_test_utility_lib.c | 504 ++++ .../CMakeLists.txt | 26 + .../spdm_responder_test.c | 50 + .../spdm_responder_test.h | 51 + .../spdm_responder_test_12_heartbeat_ack.c | 611 +++++ .../spdm_responder_test_13_key_update_ack.c | 1076 ++++++++ .../spdm_responder_test_16_end_session_ack.c | 611 +++++ .../spdm_responder_test_1_version.c | 206 ++ .../spdm_responder_test_2_capabilities.c | 1136 +++++++++ .../spdm_responder_test_3_algorithms.c | 2180 +++++++++++++++++ .../spdm_responder_test_4_digests.c | 525 ++++ .../spdm_responder_test_5_certificate.c | 750 ++++++ .../spdm_responder_test_6_challenge_auth.c | 1056 ++++++++ .../spdm_responder_test_7_measurements.c | 1816 ++++++++++++++ .../spdm_responder_test_8_key_exchange_rsp.c | 1382 +++++++++++ .../spdm_responder_test_9_finish_rsp.c | 1498 +++++++++++ .../spdm_responder_test_support.c | 36 + .../CMakeLists.txt | 72 - .../spdm_device_validator_config.c | 155 -- .../spdm_device_validator_pci_doe.c | 33 - .../spdm_device_validator_sample.c | 161 -- .../spdm_device_validator_sample.h | 26 - .../spdm_device_validator_spdm.c | 171 -- 29 files changed, 13836 insertions(+), 627 deletions(-) delete mode 160000 SPDM-Responder-Validator create mode 100644 include/library/common_test_utility_lib.h create mode 100644 include/library/spdm_responder_conformance_test_lib.h create mode 100644 library/common_test_utility_lib/CMakeLists.txt create mode 100644 library/common_test_utility_lib/common_test_utility_lib.c create mode 100644 library/spdm_responder_conformance_test_lib/CMakeLists.txt create mode 100644 library/spdm_responder_conformance_test_lib/spdm_responder_test.c create mode 100644 library/spdm_responder_conformance_test_lib/spdm_responder_test.h create mode 100644 library/spdm_responder_conformance_test_lib/spdm_responder_test_12_heartbeat_ack.c create mode 100644 library/spdm_responder_conformance_test_lib/spdm_responder_test_13_key_update_ack.c create mode 100644 library/spdm_responder_conformance_test_lib/spdm_responder_test_16_end_session_ack.c create mode 100644 library/spdm_responder_conformance_test_lib/spdm_responder_test_1_version.c create mode 100644 library/spdm_responder_conformance_test_lib/spdm_responder_test_2_capabilities.c create mode 100644 library/spdm_responder_conformance_test_lib/spdm_responder_test_3_algorithms.c create mode 100644 library/spdm_responder_conformance_test_lib/spdm_responder_test_4_digests.c create mode 100644 library/spdm_responder_conformance_test_lib/spdm_responder_test_5_certificate.c create mode 100644 library/spdm_responder_conformance_test_lib/spdm_responder_test_6_challenge_auth.c create mode 100644 library/spdm_responder_conformance_test_lib/spdm_responder_test_7_measurements.c create mode 100644 library/spdm_responder_conformance_test_lib/spdm_responder_test_8_key_exchange_rsp.c create mode 100644 library/spdm_responder_conformance_test_lib/spdm_responder_test_9_finish_rsp.c create mode 100644 library/spdm_responder_conformance_test_lib/spdm_responder_test_support.c delete mode 100644 spdm_emu/spdm_device_validator_sample/CMakeLists.txt delete mode 100644 spdm_emu/spdm_device_validator_sample/spdm_device_validator_config.c delete mode 100644 spdm_emu/spdm_device_validator_sample/spdm_device_validator_pci_doe.c delete mode 100644 spdm_emu/spdm_device_validator_sample/spdm_device_validator_sample.c delete mode 100644 spdm_emu/spdm_device_validator_sample/spdm_device_validator_sample.h delete mode 100644 spdm_emu/spdm_device_validator_sample/spdm_device_validator_spdm.c diff --git a/.gitmodules b/.gitmodules index 09eaa77..e56b00b 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,3 @@ [submodule "libspdm"] path = libspdm url = https://github.com/DMTF/libspdm -[submodule "SPDM-Responder-Validator"] - path = SPDM-Responder-Validator - url = https://github.com/DMTF/SPDM-Responder-Validator diff --git a/CMakeLists.txt b/CMakeLists.txt index 5dfc830..d23c85d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,7 +20,6 @@ if(NOT GCOV) endif() SET(LIBSPDM_DIR ${PROJECT_SOURCE_DIR}/libspdm) -SET(SPDM_RESPONDER_VALIDATOR_DIR ${PROJECT_SOURCE_DIR}/SPDM-Responder-Validator) SET(COMMON_TEST_FRAMEWORK_DIR ${PROJECT_SOURCE_DIR}/SPDM-Responder-Validator/common_test_framework) # @@ -548,11 +547,9 @@ endif() ADD_SUBDIRECTORY(library/cxl_ide_km_requester_lib) ADD_SUBDIRECTORY(library/cxl_ide_km_responder_lib) ADD_SUBDIRECTORY(library/cxl_ide_km_device_lib_sample) + ADD_SUBDIRECTORY(library/common_test_utility_lib) + ADD_SUBDIRECTORY(library/spdm_responder_conformance_test_lib) ADD_SUBDIRECTORY(spdm_emu/spdm_requester_emu) ADD_SUBDIRECTORY(spdm_emu/spdm_responder_emu) - ADD_SUBDIRECTORY(${COMMON_TEST_FRAMEWORK_DIR}/library/common_test_utility_lib out/common_test_utility_lib.out) - ADD_SUBDIRECTORY(${SPDM_RESPONDER_VALIDATOR_DIR}/library/spdm_responder_conformance_test_lib out/spdm_responder_conformance_test_lib.out) - ADD_SUBDIRECTORY(spdm_emu/spdm_device_validator_sample) - ADD_SUBDIRECTORY(spdm_emu/spdm_device_attester_sample) diff --git a/SPDM-Responder-Validator b/SPDM-Responder-Validator deleted file mode 160000 index 61debbc..0000000 --- a/SPDM-Responder-Validator +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 61debbcffb1cd240f2908aee95ead1a974272322 diff --git a/include/library/common_test_utility_lib.h b/include/library/common_test_utility_lib.h new file mode 100644 index 0000000..dc29ead --- /dev/null +++ b/include/library/common_test_utility_lib.h @@ -0,0 +1,175 @@ +/** + * Copyright Notice: + * Copyright 2021 DMTF, Componolit. All rights reserved. + * License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/libspdm/blob/main/LICENSE.md + **/ + +#ifndef __COMMON_TEST_UTILITY_LIB_H__ +#define __COMMON_TEST_UTILITY_LIB_H__ + +#include "library/spdm_common_lib.h" + +#include +#include +#include +#include +#include +#include +#include + +typedef uint32_t common_test_group_id; +typedef uint32_t common_test_case_id; +typedef uint32_t common_test_assertion_id; + +/* This can be used as "end of list" indicator. */ +#define COMMON_TEST_ID_END 0 +/* This can be used as "test skip" indicator. */ +#define COMMON_TEST_ID_SKIP 0xFFFFFFFF + +typedef enum { + COMMON_TEST_RESULT_NOT_TESTED, + COMMON_TEST_RESULT_PASS, + COMMON_TEST_RESULT_FAIL, +} common_test_result_t; + +typedef void (*common_test_case_func_t) (void *test_context); + +/** + * @return true setup successfully + * @return false setup fail + **/ +typedef bool (*common_test_case_setup_func_t) (void *test_context); +typedef void (*common_test_case_teardown_func_t) (void *test_context); + +/** + * @return true setup successfully + * @return false setup fail + **/ +typedef bool (*common_test_group_setup_func_t) (void *test_context); +typedef void (*common_test_group_teardown_func_t) (void *test_context); + +/** + * + +------------+ + | test suite | + +------------+ + | +------------+ + +----------->| test group | + | +------------+ + | | +------------+ + | +----------->| test case | + | | +------------+ + | | + | | +------------+ + | +----------->| test case | + | +------------+ + | +------------+ + +----------->| test group | + +------------+ + | + **/ + +typedef struct { + uint32_t case_id; + char *case_name; + common_test_case_func_t case_func; + common_test_case_setup_func_t case_setup_func; + common_test_case_teardown_func_t case_teardown_func; +} common_test_case_t; + +typedef struct { + uint32_t group_id; + char *group_name; + common_test_case_t *test_cases; + common_test_group_setup_func_t group_setup_func; + common_test_group_teardown_func_t group_teardown_func; +} common_test_group_t; + +typedef struct { + char *name; + common_test_group_t *test_groups; +} common_test_suite_t; + +/** + * + +-------------------+ + | test suite config | + +-------------------+ + | +-------------------+ + +----------->| test group config | + | +-------------------+ + | | +-------------------+ + | +----------->| test case config | + | | +-------------------+ + | | + | | +-------------------+ + | +----------->| test case config | + | +-------------------+ + | +-------------------+ + +----------->| test group config | + +-------------------+ + | + | rules: + | 1) NULL == RUN + | 2) not-found == SKIP + | 3) SKIP + RUN == RUN + SKIP == SKIP + | + +==========================================+ + | suite | group | case | ACTION | + +==========================================+ + | NULL | - | - | RUN | + +------------------------------------------+ + | exist | NULL | - | RUN | + +------------------------------------------+ + | exist | not-found | - | SKIP | + +------------------------------------------+ + | exist | found:SKIP | - | SKIP | + +------------------------------------------+ + | exist | found:RUN | NULL | RUN | + +------------------------------------------+ + | exist | found:RUN | not-found | SKIP | + +------------------------------------------+ + | exist | found:RUN | found:SKIP | SKIP | + +------------------------------------------+ + | exist | found:RUN | found:RUN | RUN | + +==========================================+ + | + **/ + +typedef enum { + COMMON_TEST_ACTION_RUN, + COMMON_TEST_ACTION_SKIP, +} common_test_action_t; + +typedef struct { + uint32_t case_id; + common_test_action_t action; +} common_test_case_config_t; + +typedef struct { + uint32_t group_id; + common_test_action_t action; + common_test_case_config_t *test_case_configs; +} common_test_group_config_t; + +typedef struct { + char *config_name; + common_test_group_config_t *test_group_configs; +} common_test_suite_config_t; + +void common_test_run_test_suite ( + void *test_context, + const common_test_suite_t *test_suite, + const common_test_suite_config_t *test_suite_config); + +void common_test_record_test_assertion ( + common_test_group_id group_id, + common_test_case_id case_id, + common_test_assertion_id assertion_id, + common_test_result_t test_result, + const char *message_format, + ...); + +void common_test_record_test_message(const char *message_format, ...); + +#endif diff --git a/include/library/spdm_responder_conformance_test_lib.h b/include/library/spdm_responder_conformance_test_lib.h new file mode 100644 index 0000000..f1cd7f0 --- /dev/null +++ b/include/library/spdm_responder_conformance_test_lib.h @@ -0,0 +1,132 @@ +/** + * Copyright Notice: + * Copyright 2021 DMTF, Componolit. All rights reserved. + * License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/libspdm/blob/main/LICENSE.md + **/ + +#ifndef __SPDM_RESPONDER_CONFORMANCE_TEST_LIB_H__ +#define __SPDM_RESPONDER_CONFORMANCE_TEST_LIB_H__ + +#include "library/spdm_common_lib.h" +#include "library/common_test_utility_lib.h" + +void spdm_responder_conformance_test (void *spdm_context, + const common_test_suite_config_t *test_config); + +/* below definition should be aligned with test case description in doc dir */ + +#define SPDM_RESPONDER_TEST_GROUP_VERSION 1 +#define SPDM_RESPONDER_TEST_CASE_VERSION_SUCCESS_10 1 +#define SPDM_RESPONDER_TEST_CASE_VERSION_INVALID_REQUEST 2 + +#define SPDM_RESPONDER_TEST_GROUP_CAPABILITIES 2 +#define SPDM_RESPONDER_TEST_CASE_CAPABILITIES_SUCCESS_10 1 +#define SPDM_RESPONDER_TEST_CASE_CAPABILITIES_VERSION_MISMATCH 2 +#define SPDM_RESPONDER_TEST_CASE_CAPABILITIES_SUCCESS_11 3 +#define SPDM_RESPONDER_TEST_CASE_CAPABILITIES_INVALID_REQUEST 4 +#define SPDM_RESPONDER_TEST_CASE_CAPABILITIES_SUCCESS_12 5 +#define SPDM_RESPONDER_TEST_CASE_CAPABILITIES_UNEXPECTED_REQUEST_NON_IDENTICAL 6 + +#define SPDM_RESPONDER_TEST_GROUP_ALGORITHMS 3 +#define SPDM_RESPONDER_TEST_CASE_ALGORITHMS_SUCCESS_10 1 +#define SPDM_RESPONDER_TEST_CASE_ALGORITHMS_VERSION_MISMATCH 2 +#define SPDM_RESPONDER_TEST_CASE_ALGORITHMS_UNEXPECTED_REQUEST 3 +#define SPDM_RESPONDER_TEST_CASE_ALGORITHMS_INVALID_REQUEST 4 +#define SPDM_RESPONDER_TEST_CASE_ALGORITHMS_SUCCESS_11 5 +#define SPDM_RESPONDER_TEST_CASE_ALGORITHMS_SUCCESS_12 6 +#define SPDM_RESPONDER_TEST_CASE_ALGORITHMS_UNEXPECTED_REQUEST_NON_IDENTICAL 7 + +#define SPDM_RESPONDER_TEST_GROUP_DIGESTS 4 +#define SPDM_RESPONDER_TEST_CASE_DIGESTS_SUCCESS_10 1 +#define SPDM_RESPONDER_TEST_CASE_DIGESTS_VERSION_MISMATCH 2 +#define SPDM_RESPONDER_TEST_CASE_DIGESTS_UNEXPECTED_REQUEST 3 + +#define SPDM_RESPONDER_TEST_GROUP_CERTIFICATE 5 +#define SPDM_RESPONDER_TEST_CASE_CERTIFICATE_SUCCESS_10 1 +#define SPDM_RESPONDER_TEST_CASE_CERTIFICATE_VERSION_MISMATCH 2 +#define SPDM_RESPONDER_TEST_CASE_CERTIFICATE_UNEXPECTED_REQUEST 3 +#define SPDM_RESPONDER_TEST_CASE_CERTIFICATE_INVALID_REQUEST 4 +#define SPDM_RESPONDER_TEST_CASE_CERTIFICATE_SPDM_X509_CERTIFICATE 5 + +#define SPDM_RESPONDER_TEST_GROUP_CHALLENGE_AUTH 6 +#define SPDM_RESPONDER_TEST_CASE_CHALLENGE_AUTH_SUCCESS_10_A1B1C1 1 +#define SPDM_RESPONDER_TEST_CASE_CHALLENGE_AUTH_SUCCESS_10_A1B2C1 2 +#define SPDM_RESPONDER_TEST_CASE_CHALLENGE_AUTH_SUCCESS_10_A1B3C1 3 +#define SPDM_RESPONDER_TEST_CASE_CHALLENGE_AUTH_VERSION_MISMATCH 4 +#define SPDM_RESPONDER_TEST_CASE_CHALLENGE_AUTH_UNEXPECTED_REQUEST 5 +#define SPDM_RESPONDER_TEST_CASE_CHALLENGE_AUTH_INVALID_REQUEST 6 +#define SPDM_RESPONDER_TEST_CASE_CHALLENGE_AUTH_SUCCESS_12_A1B1C1 11 +#define SPDM_RESPONDER_TEST_CASE_CHALLENGE_AUTH_SUCCESS_12_A1B2C1 12 +#define SPDM_RESPONDER_TEST_CASE_CHALLENGE_AUTH_SUCCESS_12_A1B3C1 13 +#define SPDM_RESPONDER_TEST_CASE_CHALLENGE_AUTH_SUCCESS_12_A1B4C1 14 +#define SPDM_RESPONDER_TEST_CASE_CHALLENGE_AUTH_SUCCESS_12_A2B1C1 15 +#define SPDM_RESPONDER_TEST_CASE_CHALLENGE_AUTH_SUCCESS_12_A2B2C1 16 +#define SPDM_RESPONDER_TEST_CASE_CHALLENGE_AUTH_SUCCESS_12_A2B3C1 17 +#define SPDM_RESPONDER_TEST_CASE_CHALLENGE_AUTH_SUCCESS_12_A2B4C1 18 + +#define SPDM_RESPONDER_TEST_GROUP_MEASUREMENTS 7 +#define SPDM_RESPONDER_TEST_CASE_MEASUREMENTS_SUCCESS_10 1 +#define SPDM_RESPONDER_TEST_CASE_MEASUREMENTS_VERSION_MISMATCH 2 +#define SPDM_RESPONDER_TEST_CASE_MEASUREMENTS_UNEXPECTED_REQUEST 3 +#define SPDM_RESPONDER_TEST_CASE_MEASUREMENTS_INVALID_REQUEST 4 +#define SPDM_RESPONDER_TEST_CASE_MEASUREMENTS_SPDM_MEASUREMENT_BLOCK 5 +#define SPDM_RESPONDER_TEST_CASE_MEASUREMENTS_SUCCESS_11 6 +#define SPDM_RESPONDER_TEST_CASE_MEASUREMENTS_SUCCESS_11_IN_DHE_SESSION 7 +#define SPDM_RESPONDER_TEST_CASE_MEASUREMENTS_UNEXPECTED_REQUEST_IN_DHE_SESSION_HS 8 +#define SPDM_RESPONDER_TEST_CASE_MEASUREMENTS_SUCCESS_12 9 +#define SPDM_RESPONDER_TEST_CASE_MEASUREMENTS_SUCCESS_12_IN_DHE_SESSION 10 + +#define SPDM_RESPONDER_TEST_GROUP_KEY_EXCHANGE_RSP 8 +#define SPDM_RESPONDER_TEST_CASE_KEY_EXCHANGE_RSP_SUCCESS_11 1 +#define SPDM_RESPONDER_TEST_CASE_KEY_EXCHANGE_RSP_SUCCESS_11_HS_CLEAR 2 +#define SPDM_RESPONDER_TEST_CASE_KEY_EXCHANGE_RSP_VERSION_MISMATCH 3 +#define SPDM_RESPONDER_TEST_CASE_KEY_EXCHANGE_RSP_UNEXPECTED_REQUEST 4 +#define SPDM_RESPONDER_TEST_CASE_KEY_EXCHANGE_RSP_UNEXPECTED_REQUEST_IN_SESSION 5 +#define SPDM_RESPONDER_TEST_CASE_KEY_EXCHANGE_RSP_INVALID_REQUEST 6 +#define SPDM_RESPONDER_TEST_CASE_KEY_EXCHANGE_RSP_SUCCESS_12 7 +#define SPDM_RESPONDER_TEST_CASE_KEY_EXCHANGE_RSP_SUCCESS_12_HS_CLEAR 8 + +#define SPDM_RESPONDER_TEST_GROUP_FINISH_RSP 9 +#define SPDM_RESPONDER_TEST_CASE_FINISH_RSP_SUCCESS_11 \ + 1 +#define SPDM_RESPONDER_TEST_CASE_FINISH_RSP_SUCCESS_11_HS_CLEAR \ + 2 +#define SPDM_RESPONDER_TEST_CASE_FINISH_RSP_VERSION_MISMATCH \ + 3 +#define SPDM_RESPONDER_TEST_CASE_FINISH_RSP_UNEXPECTED_REQUEST \ + 4 +#define SPDM_RESPONDER_TEST_CASE_FINISH_RSP_UNEXPECTED_REQUEST_IN_SESSION \ + 5 +#define SPDM_RESPONDER_TEST_CASE_FINISH_RSP_INVALID_REQUEST \ + 6 +#define SPDM_RESPONDER_TEST_CASE_FINISH_RSP_DECRYPT_ERROR_INVALID_VERIFY_DATA \ + 7 +#define SPDM_RESPONDER_TEST_CASE_FINISH_RSP_DECRYPT_ERROR_INVALID_VERIFY_DATA_HS_CLEAR \ + 8 +#define SPDM_RESPONDER_TEST_CASE_FINISH_RSP_SUCCESS_12 \ + 9 +#define SPDM_RESPONDER_TEST_CASE_FINISH_RSP_SUCCESS_12_HS_CLEAR \ + 10 +#define SPDM_RESPONDER_TEST_CASE_FINISH_RSP_SESSION_REQUIRED \ + 11 + +#define SPDM_RESPONDER_TEST_GROUP_HEARTBEAT_ACK 12 +#define SPDM_RESPONDER_TEST_CASE_HEARTBEAT_ACK_SUCCESS_11_IN_DHE_SESSION 1 +#define SPDM_RESPONDER_TEST_CASE_HEARTBEAT_ACK_VERSION_MISMATCH_IN_DHE_SESSION 2 +#define SPDM_RESPONDER_TEST_CASE_HEARTBEAT_ACK_UNEXPECTED_REQUEST_IN_DHE_SESSION_HS 3 +#define SPDM_RESPONDER_TEST_CASE_HEARTBEAT_ACK_SESSION_REQUIRED 4 + +#define SPDM_RESPONDER_TEST_GROUP_KEY_UPDATE_ACK 13 +#define SPDM_RESPONDER_TEST_CASE_KEY_UPDATE_ACK_SUCCESS_11_IN_DHE_SESSION 1 +#define SPDM_RESPONDER_TEST_CASE_KEY_UPDATE_ACK_VERSION_MISMATCH_IN_DHE_SESSION 2 +#define SPDM_RESPONDER_TEST_CASE_KEY_UPDATE_ACK_INVALID_REQUEST_IN_DHE_SESSION 3 +#define SPDM_RESPONDER_TEST_CASE_KEY_UPDATE_ACK_UNEXPECTED_REQUEST_IN_DHE_SESSION_HS 4 +#define SPDM_RESPONDER_TEST_CASE_KEY_UPDATE_ACK_SESSION_REQUIRED 5 + +#define SPDM_RESPONDER_TEST_GROUP_END_SESSION_ACK 16 +#define SPDM_RESPONDER_TEST_CASE_END_SESSION_ACK_SUCCESS_11_IN_DHE_SESSION 1 +#define SPDM_RESPONDER_TEST_CASE_END_SESSION_ACK_VERSION_MISMATCH_IN_DHE_SESSION 2 +#define SPDM_RESPONDER_TEST_CASE_END_SESSION_ACK_UNEXPECTED_REQUEST_IN_DHE_SESSION_HS 3 +#define SPDM_RESPONDER_TEST_CASE_END_SESSION_ACK_SESSION_REQUIRED 4 + +#endif diff --git a/library/common_test_utility_lib/CMakeLists.txt b/library/common_test_utility_lib/CMakeLists.txt new file mode 100644 index 0000000..18fc811 --- /dev/null +++ b/library/common_test_utility_lib/CMakeLists.txt @@ -0,0 +1,13 @@ +cmake_minimum_required(VERSION 2.6) + +INCLUDE_DIRECTORIES(${LIBSPDM_DIR}/include + ${LIBSPDM_DIR}/include/hal/${ARCH} + ${COMMON_TEST_FRAMEWORK_DIR}/include + ${PROJECT_SOURCE_DIR}/include +) + +SET(src_common_test_utility_lib + common_test_utility_lib.c +) + +ADD_LIBRARY(common_test_utility_lib STATIC ${src_common_test_utility_lib}) diff --git a/library/common_test_utility_lib/common_test_utility_lib.c b/library/common_test_utility_lib/common_test_utility_lib.c new file mode 100644 index 0000000..698bb0b --- /dev/null +++ b/library/common_test_utility_lib/common_test_utility_lib.c @@ -0,0 +1,504 @@ +/** + * Copyright Notice: + * Copyright 2021 DMTF. All rights reserved. + * License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/spdm-emu/blob/main/LICENSE.md + **/ + +#include "library/common_test_utility_lib.h" +#include "stdio.h" + +/** + * + +-------------------+ + | test suite result | + +-------------------+ + | +-------------------+ + +----------->| test group result | + | +-------------------+ + | | +-------------------+ + | +----------->| test case result | + | | +-------------------+ + | | + | | +-------------------+ + | +----------->| test case result | + | +-------------------+ + | +-------------------+ + +----------->| test group result | + +-------------------+ + | + **/ + +typedef struct { + uint32_t case_id; + uint32_t total_pass; + uint32_t total_fail; +} common_test_case_result_t; + +typedef struct { + uint32_t group_id; + uint32_t total_pass; + uint32_t total_fail; + common_test_case_result_t *test_case_results; +} common_test_group_result_t; + +typedef struct { + uint32_t total_pass; + uint32_t total_fail; + common_test_group_result_t *test_group_results; +} common_test_suite_result_t; + +#define COMMON_TEST_MAX_MESSAGE_LENGTH 0x800 + +#define COMMON_TEST_LOG_FILE_NAME "test.log" + +FILE *m_log_file; +common_test_suite_result_t *m_test_suite_result; + +char *common_test_result_to_string (common_test_result_t test_result) +{ + switch (test_result) { + case COMMON_TEST_RESULT_NOT_TESTED: + return "NOT_TESTED"; + case COMMON_TEST_RESULT_PASS: + return "PASS"; + case COMMON_TEST_RESULT_FAIL: + return "FAIL"; + default: + assert (0); + return ""; + } +} + +common_test_suite_result_t *common_test_allocate_test_suite_result ( + const common_test_suite_t *test_suite) +{ + uint32_t group_index; + uint32_t case_index; + common_test_group_t *test_group; + common_test_case_t *test_case; + uint32_t group_count; + uint32_t case_count; + uint32_t total_size; + common_test_suite_result_t *test_suite_result; + common_test_group_result_t *test_group_result; + common_test_case_result_t *test_case_result; + uint8_t *ptr; + + group_count = 0; + case_count = 0; + for (group_index = 0; ; group_index++) { + group_count++; + test_group = &test_suite->test_groups[group_index]; + if (test_group->group_id == COMMON_TEST_ID_END) { + break; + } + for (case_index = 0; ; case_index++) { + case_count++; + test_case = &test_group->test_cases[case_index]; + if (test_case->case_id == COMMON_TEST_ID_END) { + break; + } + } + } + + total_size = sizeof(common_test_suite_result_t) + + (sizeof(common_test_group_result_t) * group_count) + + (sizeof(common_test_case_result_t) * case_count); + test_suite_result = (common_test_suite_result_t *)malloc(total_size); + if (test_suite_result == NULL) { + return NULL; + } + ptr = (uint8_t *)test_suite_result; + ptr += sizeof(common_test_suite_result_t); + + test_suite_result->test_group_results = (common_test_group_result_t *)ptr; + test_suite_result->total_pass = 0; + test_suite_result->total_fail = 0; + ptr += (sizeof(common_test_group_result_t) * group_count); + + for (group_index = 0; ; group_index++) { + test_group = &test_suite->test_groups[group_index]; + test_group_result = &test_suite_result->test_group_results[group_index]; + test_group_result->group_id = test_group->group_id; + test_group_result->total_pass = 0; + test_group_result->total_fail = 0; + test_group_result->test_case_results = NULL; + + if (test_group->group_id == COMMON_TEST_ID_END) { + break; + } + test_group_result->test_case_results = (common_test_case_result_t *)ptr; + + case_count = 0; + for (case_index = 0; ; case_index++) { + case_count++; + test_case = &test_group->test_cases[case_index]; + test_case_result = &test_group_result->test_case_results[case_index]; + test_case_result->case_id = test_case->case_id; + test_case_result->total_pass = 0; + test_case_result->total_fail = 0; + + if (test_case->case_id == COMMON_TEST_ID_END) { + break; + } + } + ptr += (sizeof(common_test_case_result_t) * case_count); + } + + return test_suite_result; +} + +void common_test_free_test_suite_result (common_test_suite_result_t *test_suite_result) +{ + free (test_suite_result); +} + +void common_test_print_test_suite_result ( + const common_test_suite_t *test_suite, + common_test_suite_result_t *test_suite_result) +{ + uint32_t group_index; + uint32_t case_index; + common_test_group_t *test_group; + common_test_case_t *test_case; + common_test_group_result_t *test_group_result; + common_test_case_result_t *test_case_result; + + fprintf (m_log_file, "\ntest suite (%s) - pass: %d, fail: %d\n", + test_suite->name, + test_suite_result->total_pass, + test_suite_result->total_fail); + + for (group_index = 0; ; group_index++) { + test_group = &test_suite->test_groups[group_index]; + test_group_result = &test_suite_result->test_group_results[group_index]; + if (test_group_result->group_id == COMMON_TEST_ID_END) { + break; + } + fprintf (m_log_file, + "test group %d (%s) - pass: %d, fail: %d\n", + test_group_result->group_id, + test_group->group_name, + test_group_result->total_pass, + test_group_result->total_fail); + for (case_index = 0; ; case_index++) { + test_case = &test_group->test_cases[case_index]; + test_case_result = &test_group_result->test_case_results[case_index]; + if (test_case_result->case_id == COMMON_TEST_ID_END) { + break; + } + fprintf (m_log_file, + " test case %d.%d (%s) - pass: %d, fail: %d\n", + test_group_result->group_id, + test_case_result->case_id, + test_case->case_name, + test_case_result->total_pass, + test_case_result->total_fail); + } + } + + fprintf (m_log_file, "test result done\n"); +} + +void common_test_record_test_suite_result ( + common_test_group_id group_id, + common_test_case_id case_id, + common_test_result_t test_result, + common_test_suite_result_t *test_suite_result) +{ + uint32_t group_index; + uint32_t case_index; + common_test_group_result_t *test_group_result; + common_test_case_result_t *test_case_result; + + if (test_result == COMMON_TEST_RESULT_PASS) { + test_suite_result->total_pass++; + } else if (test_result == COMMON_TEST_RESULT_FAIL) { + test_suite_result->total_fail++; + } + + for (group_index = 0; ; group_index++) { + test_group_result = &test_suite_result->test_group_results[group_index]; + if (test_group_result->group_id == COMMON_TEST_ID_END) { + break; + } + if (test_group_result->group_id == group_id) { + if (test_result == COMMON_TEST_RESULT_PASS) { + test_group_result->total_pass++; + } else if (test_result == COMMON_TEST_RESULT_FAIL) { + test_group_result->total_fail++; + } + for (case_index = 0; ; case_index++) { + test_case_result = &test_group_result->test_case_results[case_index]; + if (test_case_result->case_id == COMMON_TEST_ID_END) { + break; + } + if (test_case_result->case_id == case_id) { + if (test_result == COMMON_TEST_RESULT_PASS) { + test_case_result->total_pass++; + } else if (test_result == COMMON_TEST_RESULT_FAIL) { + test_case_result->total_fail++; + } + break; + } + } + break; + } + } +} + +void common_test_record_test_assertion ( + common_test_group_id group_id, + common_test_case_id case_id, + common_test_assertion_id assertion_id, + common_test_result_t test_result, + const char *message_format, + ...) +{ + char buffer[COMMON_TEST_MAX_MESSAGE_LENGTH]; + va_list marker; + + fprintf(m_log_file, + " test assertion %d.%d.%d - %s", + group_id, case_id, assertion_id, + common_test_result_to_string (test_result) + ); + + if (message_format != NULL) { + va_start(marker, message_format); + + vsnprintf(buffer, sizeof(buffer), message_format, marker); + + va_end(marker); + + fprintf(m_log_file, " %s", buffer); + } + fprintf(m_log_file, "\n"); + fflush(m_log_file); + + common_test_record_test_suite_result (group_id, case_id, test_result, m_test_suite_result); +} + +void common_test_record_test_message(const char *message_format, ...) +{ + char buffer[COMMON_TEST_MAX_MESSAGE_LENGTH]; + va_list marker; + + va_start(marker, message_format); + + vsnprintf(buffer, sizeof(buffer), message_format, marker); + + va_end(marker); + + fprintf(m_log_file, " test msg: %s", buffer); + fflush(m_log_file); +} + +common_test_action_t common_test_get_test_group_action ( + uint32_t group_id, + const common_test_suite_config_t *test_suite_config) +{ + uint32_t group_index; + common_test_group_config_t *test_group_config; + + if (test_suite_config == NULL) { + return COMMON_TEST_ACTION_RUN; + } + + if (test_suite_config->test_group_configs == NULL) { + return COMMON_TEST_ACTION_RUN; + } + for (group_index = 0; ; group_index++) { + test_group_config = &test_suite_config->test_group_configs[group_index]; + if (test_group_config->group_id == COMMON_TEST_ID_END) { + break; + } + if (test_group_config->group_id == COMMON_TEST_ID_SKIP) { + continue; + } + if (test_group_config->group_id == group_id) { + return test_group_config->action; + } + } + return COMMON_TEST_ACTION_SKIP; +} + +common_test_action_t common_test_get_test_case_action ( + uint32_t group_id, + uint32_t case_id, + const common_test_suite_config_t *test_suite_config) +{ + uint32_t group_index; + uint32_t case_index; + common_test_group_config_t *test_group_config; + common_test_case_config_t *test_case_config; + + if (test_suite_config == NULL) { + return COMMON_TEST_ACTION_RUN; + } + + for (group_index = 0; ; group_index++) { + test_group_config = &test_suite_config->test_group_configs[group_index]; + if (test_group_config->group_id == COMMON_TEST_ID_END) { + break; + } + if (test_group_config->group_id == COMMON_TEST_ID_SKIP) { + continue; + } + if (test_group_config->group_id == group_id) { + if (test_group_config->action == COMMON_TEST_ACTION_SKIP) { + return COMMON_TEST_ACTION_SKIP; + } + if (test_group_config->test_case_configs == NULL) { + return COMMON_TEST_ACTION_RUN; + } + for (case_index = 0; ; case_index++) { + test_case_config = &test_group_config->test_case_configs[case_index]; + if (test_case_config->case_id == COMMON_TEST_ID_END) { + break; + } + if (test_case_config->case_id == COMMON_TEST_ID_SKIP) { + continue; + } + if (test_case_config->case_id == case_id) { + return test_case_config->action; + } + } + } + } + return COMMON_TEST_ACTION_SKIP; +} + +void common_test_run_test_suite ( + void *test_context, + const common_test_suite_t *test_suite, + const common_test_suite_config_t *test_suite_config) +{ + uint32_t group_index; + uint32_t case_index; + common_test_group_t *test_group; + common_test_case_t *test_case; + common_test_action_t test_action; + bool result; + + m_log_file = fopen (COMMON_TEST_LOG_FILE_NAME, "w+"); + if (m_log_file == NULL) { + printf("fail to create log file: %s", COMMON_TEST_LOG_FILE_NAME); + return; + } + + m_test_suite_result = common_test_allocate_test_suite_result (test_suite); + + if (test_suite_config != NULL && test_suite_config->config_name != NULL) { + fprintf(m_log_file, "test_suite_config (%s)\n", test_suite_config->config_name); + } + + assert (test_suite != NULL); + assert (test_suite->test_groups != NULL); + fprintf(m_log_file, "test_suite (%s)\n", test_suite->name); + for (group_index = 0; ; group_index++) { + test_group = &test_suite->test_groups[group_index]; + if (test_group->group_id == COMMON_TEST_ID_END) { + break; + } + if (test_group->group_id == COMMON_TEST_ID_SKIP) { + continue; + } + test_action = common_test_get_test_group_action (test_group->group_id, test_suite_config); + if (test_action == COMMON_TEST_ACTION_SKIP) { + fprintf(m_log_file, "test group %d (%s) - skipped\n", test_group->group_id, + test_group->group_name); + continue; + } + assert (test_group->test_cases != NULL); + fprintf(m_log_file, "test group %d (%s) - start\n", test_group->group_id, + test_group->group_name); + if (test_group->group_setup_func != NULL) { + fprintf(m_log_file, "test group %d (%s) - setup enter\n", test_group->group_id, + test_group->group_name); + result = test_group->group_setup_func (test_context); + fprintf(m_log_file, "test group %d (%s) - setup exiit (%d)\n", test_group->group_id, + test_group->group_name, result); + if (!result) { + common_test_record_test_assertion (test_group->group_id, COMMON_TEST_ID_END, + COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, + "group_setup_func fail"); + continue; + } + } + for (case_index = 0; ; case_index++) { + test_case = &test_group->test_cases[case_index]; + if (test_case->case_id == COMMON_TEST_ID_END) { + break; + } + if (test_case->case_id == COMMON_TEST_ID_SKIP) { + continue; + } + test_action = common_test_get_test_case_action (test_group->group_id, + test_case->case_id, test_suite_config); + if (test_action == COMMON_TEST_ACTION_SKIP) { + fprintf(m_log_file, " test case %d.%d (%s) - skipped\n", + test_group->group_id, + test_case->case_id, + test_case->case_name); + continue; + } + if (test_case->case_setup_func != NULL) { + fprintf(m_log_file, " test case %d.%d (%s) - setup enter\n", + test_group->group_id, + test_case->case_id, + test_case->case_name); + result = test_case->case_setup_func (test_context); + fprintf(m_log_file, " test case %d.%d (%s) - setup exit (%d)\n", + test_group->group_id, + test_case->case_id, + test_case->case_name, + result); + if (!result) { + common_test_record_test_assertion (test_group->group_id, test_case->case_id, + COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, + "case_setup_func fail"); + continue; + } + } + fprintf(m_log_file, " test case %d.%d (%s) - start\n", + test_group->group_id, + test_case->case_id, + test_case->case_name); + test_case->case_func (test_context); + fprintf(m_log_file, " test case %d.%d (%s) - stop\n", + test_group->group_id, + test_case->case_id, + test_case->case_name); + if (test_case->case_teardown_func != NULL) { + fprintf(m_log_file, " test case %d.%d (%s) - teardown enter\n", + test_group->group_id, + test_case->case_id, + test_case->case_name); + test_case->case_teardown_func (test_context); + fprintf(m_log_file, " test case %d.%d (%s) - teardown exit\n", + test_group->group_id, + test_case->case_id, + test_case->case_name); + } + } + if (test_group->group_teardown_func != NULL) { + fprintf(m_log_file, "test group %d (%s) - teardown enter\n", test_group->group_id, + test_group->group_name); + test_group->group_teardown_func (test_context); + fprintf(m_log_file, "test group %d (%s) - teardown exit\n", test_group->group_id, + test_group->group_name); + } + fprintf(m_log_file, "test group %d (%s) - stop\n", test_group->group_id, + test_group->group_name); + } + + common_test_print_test_suite_result (test_suite, m_test_suite_result); + + common_test_free_test_suite_result (m_test_suite_result); + m_test_suite_result = NULL; + fclose (m_log_file); + m_log_file = NULL; +} diff --git a/library/spdm_responder_conformance_test_lib/CMakeLists.txt b/library/spdm_responder_conformance_test_lib/CMakeLists.txt new file mode 100644 index 0000000..6c3fdbd --- /dev/null +++ b/library/spdm_responder_conformance_test_lib/CMakeLists.txt @@ -0,0 +1,26 @@ +cmake_minimum_required(VERSION 2.6) + +INCLUDE_DIRECTORIES(${LIBSPDM_DIR}/include + ${LIBSPDM_DIR}/include/hal/${ARCH} + ${COMMON_TEST_FRAMEWORK_DIR}/include + ${PROJECT_SOURCE_DIR}/include +) + +SET(src_spdm_responder_conformance_test_lib + spdm_responder_test.c + spdm_responder_test_1_version.c + spdm_responder_test_2_capabilities.c + spdm_responder_test_3_algorithms.c + spdm_responder_test_4_digests.c + spdm_responder_test_5_certificate.c + spdm_responder_test_6_challenge_auth.c + spdm_responder_test_7_measurements.c + spdm_responder_test_8_key_exchange_rsp.c + spdm_responder_test_9_finish_rsp.c + spdm_responder_test_12_heartbeat_ack.c + spdm_responder_test_13_key_update_ack.c + spdm_responder_test_16_end_session_ack.c + spdm_responder_test_support.c +) + +ADD_LIBRARY(spdm_responder_conformance_test_lib STATIC ${src_spdm_responder_conformance_test_lib}) diff --git a/library/spdm_responder_conformance_test_lib/spdm_responder_test.c b/library/spdm_responder_conformance_test_lib/spdm_responder_test.c new file mode 100644 index 0000000..a61f994 --- /dev/null +++ b/library/spdm_responder_conformance_test_lib/spdm_responder_test.c @@ -0,0 +1,50 @@ +/** + * Copyright Notice: + * Copyright 2021 DMTF. All rights reserved. + * License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/spdm-emu/blob/main/LICENSE.md + **/ + +#include "spdm_responder_test.h" + +common_test_group_t m_spdm_test_groups[] = { + {SPDM_RESPONDER_TEST_GROUP_VERSION, "spdm_test_group_version", + m_spdm_test_group_version}, + {SPDM_RESPONDER_TEST_GROUP_CAPABILITIES, "spdm_test_group_capabilities", + m_spdm_test_group_capabilities}, + {SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, "spdm_test_group_algorithms", + m_spdm_test_group_algorithms}, + {SPDM_RESPONDER_TEST_GROUP_DIGESTS, "spdm_test_group_digests", + m_spdm_test_group_digests}, + {SPDM_RESPONDER_TEST_GROUP_CERTIFICATE, "spdm_test_group_certificate", + m_spdm_test_group_certificate}, + {SPDM_RESPONDER_TEST_GROUP_CHALLENGE_AUTH, "spdm_test_group_challenge_auth", + m_spdm_test_group_challenge_auth}, + {SPDM_RESPONDER_TEST_GROUP_MEASUREMENTS, "spdm_test_group_measurements", + m_spdm_test_group_measurements}, + {SPDM_RESPONDER_TEST_GROUP_KEY_EXCHANGE_RSP, "spdm_test_group_key_exchange_rsp", + m_spdm_test_group_key_exchange_rsp}, + {SPDM_RESPONDER_TEST_GROUP_FINISH_RSP, "spdm_test_group_finish_rsp", + m_spdm_test_group_finish_rsp}, + {SPDM_RESPONDER_TEST_GROUP_HEARTBEAT_ACK, "spdm_test_group_heartbeat_ack", + m_spdm_test_group_heartbeat_ack}, + {SPDM_RESPONDER_TEST_GROUP_KEY_UPDATE_ACK, "spdm_test_group_key_update_ack", + m_spdm_test_group_key_update_ack}, + {SPDM_RESPONDER_TEST_GROUP_END_SESSION_ACK, "spdm_test_group_end_session_ack", + m_spdm_test_group_end_session_ack}, + {COMMON_TEST_ID_END, NULL, NULL}, +}; + +common_test_suite_t m_spdm_test_suite = { + "spdm_responder_conformance_test", + m_spdm_test_groups, +}; + +void spdm_responder_conformance_test (void *spdm_context, + const common_test_suite_config_t *test_config) +{ + spdm_test_context_t spdm_test_context; + + libspdm_zero_mem(&spdm_test_context, sizeof(spdm_test_context_t)); + spdm_test_context.spdm_context = spdm_context; + common_test_run_test_suite (&spdm_test_context, &m_spdm_test_suite, test_config); +} diff --git a/library/spdm_responder_conformance_test_lib/spdm_responder_test.h b/library/spdm_responder_conformance_test_lib/spdm_responder_test.h new file mode 100644 index 0000000..4b88e30 --- /dev/null +++ b/library/spdm_responder_conformance_test_lib/spdm_responder_test.h @@ -0,0 +1,51 @@ +/** + * Copyright Notice: + * Copyright 2021 DMTF. All rights reserved. + * License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/spdm-emu/blob/main/LICENSE.md + **/ + +#ifndef _SPDM_RESPONDER_TEST_H_ +#define _SPDM_RESPONDER_TEST_H_ + +#include "library/spdm_requester_lib.h" +#include "internal/libspdm_requester_lib.h" + +#include "library/spdm_responder_conformance_test_lib.h" +#include "library/common_test_utility_lib.h" + +#define SPDM_TEST_VERSION_MASK_V10 0x00000001 +#define SPDM_TEST_VERSION_MASK_V11 0x00000002 +#define SPDM_TEST_VERSION_MASK_V12 0x00000004 + +#define SPDM_TEST_SCRATCH_BUFFER_SIZE 0x1000 + +typedef struct { + void *spdm_context; + /* test case specific scratch buffer between setup and case, avoid writable global variable */ + uint8_t test_scratch_buffer[SPDM_TEST_SCRATCH_BUFFER_SIZE]; + uint32_t test_scratch_buffer_size; +} spdm_test_context_t; + +/** + * return one bit in the data according to the mask + * + * @retval 0 if (data & mask) is 0. + * @retval 0xFFFFFFFF if (data & mask) includes more than one bit. + * @return (data & mask) if (data & mask) includes one bit. + **/ +uint32_t spdm_test_get_one_bit (uint32_t data, uint32_t mask); + +extern common_test_case_t m_spdm_test_group_version[]; +extern common_test_case_t m_spdm_test_group_capabilities[]; +extern common_test_case_t m_spdm_test_group_algorithms[]; +extern common_test_case_t m_spdm_test_group_digests[]; +extern common_test_case_t m_spdm_test_group_certificate[]; +extern common_test_case_t m_spdm_test_group_challenge_auth[]; +extern common_test_case_t m_spdm_test_group_measurements[]; +extern common_test_case_t m_spdm_test_group_key_exchange_rsp[]; +extern common_test_case_t m_spdm_test_group_finish_rsp[]; +extern common_test_case_t m_spdm_test_group_heartbeat_ack[]; +extern common_test_case_t m_spdm_test_group_key_update_ack[]; +extern common_test_case_t m_spdm_test_group_end_session_ack[]; + +#endif diff --git a/library/spdm_responder_conformance_test_lib/spdm_responder_test_12_heartbeat_ack.c b/library/spdm_responder_conformance_test_lib/spdm_responder_test_12_heartbeat_ack.c new file mode 100644 index 0000000..428c21f --- /dev/null +++ b/library/spdm_responder_conformance_test_lib/spdm_responder_test_12_heartbeat_ack.c @@ -0,0 +1,611 @@ +/** + * Copyright Notice: + * Copyright 2021 DMTF. All rights reserved. + * License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/spdm-emu/blob/main/LICENSE.md + **/ + +#include "spdm_responder_test.h" + +#pragma pack(1) +typedef struct { + uint8_t version; + uint8_t heartbeat_period; + uint8_t reserved[2]; + uint32_t session_id; +} spdm_heartbeat_ack_test_buffer_t; +#pragma pack() + +bool spdm_test_case_heartbeat_ack_setup_session (void *test_context, + spdm_version_number_t spdm_version, + bool need_session) +{ + spdm_test_context_t *spdm_test_context; + void *spdm_context; + libspdm_return_t status; + libspdm_data_parameter_t parameter; + uint32_t rsp_cap_flags; + size_t data_size; + uint32_t data32; + uint16_t data16; + uint8_t data8; + spdm_heartbeat_ack_test_buffer_t *test_buffer; + + spdm_test_context = test_context; + spdm_context = spdm_test_context->spdm_context; + + if (spdm_version != 0) { + libspdm_zero_mem(¶meter, sizeof(parameter)); + parameter.location = LIBSPDM_DATA_LOCATION_LOCAL; + libspdm_set_data(spdm_context, LIBSPDM_DATA_SPDM_VERSION, ¶meter, + &spdm_version, sizeof(spdm_version)); + } + + data32 = SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CERT_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHAL_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_ENCRYPT_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MAC_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_KEY_EX_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_ENCAP_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_HBEAT_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_KEY_UPD_CAP; + libspdm_set_data(spdm_context, LIBSPDM_DATA_CAPABILITY_FLAGS, ¶meter, + &data32, sizeof(data32)); + + data8 = SPDM_MEASUREMENT_BLOCK_HEADER_SPECIFICATION_DMTF; + libspdm_set_data(spdm_context, LIBSPDM_DATA_MEASUREMENT_SPEC, ¶meter, + &data8, sizeof(data8)); + data32 = SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_2048 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_3072 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_3072 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_4096 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_4096 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P384 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P521 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_SM2_ECC_SM2_P256 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED25519 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED448; + libspdm_set_data(spdm_context, LIBSPDM_DATA_BASE_ASYM_ALGO, ¶meter, + &data32, sizeof(data32)); + data32 = SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_256 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_384 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_512 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA3_256 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA3_384 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA3_512 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SM3_256; + libspdm_set_data(spdm_context, LIBSPDM_DATA_BASE_HASH_ALGO, ¶meter, + &data32, sizeof(data32)); + data16 = SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_2048 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_3072 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_4096 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_256_R1 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_384_R1 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_521_R1 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_SM2_P256; + libspdm_set_data(spdm_context, LIBSPDM_DATA_DHE_NAME_GROUP, ¶meter, + &data16, sizeof(data16)); + data16 = SPDM_ALGORITHMS_AEAD_CIPHER_SUITE_AES_128_GCM | + SPDM_ALGORITHMS_AEAD_CIPHER_SUITE_AES_256_GCM | + SPDM_ALGORITHMS_AEAD_CIPHER_SUITE_CHACHA20_POLY1305 | + SPDM_ALGORITHMS_AEAD_CIPHER_SUITE_AEAD_SM4_GCM; + libspdm_set_data(spdm_context, LIBSPDM_DATA_AEAD_CIPHER_SUITE, ¶meter, + &data16, sizeof(data16)); + data16 = SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_2048 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_3072 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_3072 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_4096 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_4096 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P384 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P521 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_SM2_ECC_SM2_P256 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED25519 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED448; + libspdm_set_data(spdm_context, LIBSPDM_DATA_REQ_BASE_ASYM_ALG, ¶meter, + &data16, sizeof(data16)); + data16 = SPDM_ALGORITHMS_KEY_SCHEDULE_HMAC_HASH; + libspdm_set_data(spdm_context, LIBSPDM_DATA_KEY_SCHEDULE, ¶meter, &data16, + sizeof(data16)); + data8 = SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_1; + libspdm_set_data(spdm_context, LIBSPDM_DATA_OTHER_PARAMS_SUPPORT, ¶meter, + &data8, sizeof(data8)); + + status = libspdm_init_connection (spdm_context, false); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + return false; + } + + test_buffer = (void *)spdm_test_context->test_scratch_buffer; + LIBSPDM_ASSERT(sizeof(spdm_test_context->test_scratch_buffer) >= + sizeof(spdm_heartbeat_ack_test_buffer_t)); + libspdm_zero_mem(test_buffer, sizeof(spdm_heartbeat_ack_test_buffer_t)); + spdm_test_context->test_scratch_buffer_size = sizeof(spdm_heartbeat_ack_test_buffer_t); + + spdm_version = 0; + data_size = sizeof(spdm_version); + libspdm_zero_mem(¶meter, sizeof(parameter)); + parameter.location = LIBSPDM_DATA_LOCATION_CONNECTION; + libspdm_get_data(spdm_context, LIBSPDM_DATA_SPDM_VERSION, ¶meter, &spdm_version, + &data_size); + test_buffer->version = (spdm_version >> SPDM_VERSION_NUMBER_SHIFT_BIT); + + rsp_cap_flags = 0; + data_size = sizeof(rsp_cap_flags); + libspdm_zero_mem(¶meter, sizeof(parameter)); + parameter.location = LIBSPDM_DATA_LOCATION_CONNECTION; + libspdm_get_data(spdm_context, LIBSPDM_DATA_CAPABILITY_FLAGS, ¶meter, &rsp_cap_flags, + &data_size); + if ((rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP) == 0) { + return false; + } + + if (((rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP) == 0) || + ((rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_KEY_EX_CAP) == 0) || + ((rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_HBEAT_CAP) == 0) ) { + return false; + } + + status = libspdm_get_certificate (spdm_context, 0, NULL, NULL); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + return false; + } + + if (need_session) { + status = libspdm_start_session (spdm_context, false, + SPDM_KEY_EXCHANGE_REQUEST_NO_MEASUREMENT_SUMMARY_HASH, + 0, 0, &test_buffer->session_id, + &test_buffer->heartbeat_period, NULL); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + return false; + } + + if (test_buffer->heartbeat_period == 0) { + return false; + } + } + + return true; +} + +bool spdm_test_case_heartbeat_ack_setup_version_any (void *test_context) +{ + return spdm_test_case_heartbeat_ack_setup_session (test_context, 0, true); +} + +bool spdm_test_case_heartbeat_ack_setup_version_12 (void *test_context) +{ + return spdm_test_case_heartbeat_ack_setup_session (test_context, + SPDM_MESSAGE_VERSION_12 << SPDM_VERSION_NUMBER_SHIFT_BIT, + true); +} + +bool spdm_test_case_heartbeat_ack_setup_version_any_session_cap (void *test_context) +{ + return spdm_test_case_heartbeat_ack_setup_session (test_context, 0, false); +} + +void spdm_test_case_heartbeat_ack_success_11_dhe (void *test_context) +{ + spdm_test_context_t *spdm_test_context; + void *spdm_context; + libspdm_return_t status; + spdm_heartbeat_request_t spdm_request; + spdm_heartbeat_response_t *spdm_response; + uint8_t message[LIBSPDM_MAX_MESSAGE_BUFFER_SIZE]; + size_t spdm_response_size; + common_test_result_t test_result; + spdm_heartbeat_ack_test_buffer_t *test_buffer; + + spdm_test_context = test_context; + spdm_context = spdm_test_context->spdm_context; + test_buffer = (void *)spdm_test_context->test_scratch_buffer; + LIBSPDM_ASSERT(spdm_test_context->test_scratch_buffer_size == + sizeof(spdm_heartbeat_ack_test_buffer_t)); + + libspdm_zero_mem(&spdm_request, sizeof(spdm_request)); + spdm_request.header.spdm_version = test_buffer->version; + spdm_request.header.request_response_code = SPDM_HEARTBEAT; + spdm_request.header.param1 = 0; + spdm_request.header.param2 = 0; + + spdm_response = (void *)message; + spdm_response_size = sizeof(message); + libspdm_zero_mem(message, sizeof(message)); + status = libspdm_send_receive_data(spdm_context, &test_buffer->session_id, false, + &spdm_request, sizeof(spdm_request), + spdm_response, &spdm_response_size); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_HEARTBEAT_ACK, + SPDM_RESPONDER_TEST_CASE_HEARTBEAT_ACK_SUCCESS_11_IN_DHE_SESSION, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "send/receive failure"); + return; + } + + if (spdm_response_size >= sizeof(spdm_heartbeat_response_t)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_HEARTBEAT_ACK, + SPDM_RESPONDER_TEST_CASE_HEARTBEAT_ACK_SUCCESS_11_IN_DHE_SESSION, 1, + test_result, "response size - %d", spdm_response_size); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.request_response_code == SPDM_HEARTBEAT_ACK) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_HEARTBEAT_ACK, + SPDM_RESPONDER_TEST_CASE_HEARTBEAT_ACK_SUCCESS_11_IN_DHE_SESSION, 2, + test_result, "response code - 0x%02x", spdm_response->header.request_response_code); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.spdm_version == test_buffer->version) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_HEARTBEAT_ACK, + SPDM_RESPONDER_TEST_CASE_HEARTBEAT_ACK_SUCCESS_11_IN_DHE_SESSION, 3, + test_result, "response version - 0x%02x", spdm_response->header.spdm_version); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } +} + +void spdm_test_case_heartbeat_ack_version_mismatch (void *test_context) +{ + spdm_test_context_t *spdm_test_context; + void *spdm_context; + libspdm_return_t status; + spdm_heartbeat_request_t spdm_request; + spdm_heartbeat_response_t *spdm_response; + uint8_t message[LIBSPDM_MAX_MESSAGE_BUFFER_SIZE]; + size_t spdm_response_size; + common_test_result_t test_result; + spdm_heartbeat_ack_test_buffer_t *test_buffer; + uint8_t mismatched_version[] = { + SPDM_MESSAGE_VERSION_10 - 1, + SPDM_MESSAGE_VERSION_12 + 1, + }; + size_t index; + + spdm_test_context = test_context; + spdm_context = spdm_test_context->spdm_context; + test_buffer = (void *)spdm_test_context->test_scratch_buffer; + LIBSPDM_ASSERT(spdm_test_context->test_scratch_buffer_size == + sizeof(spdm_heartbeat_ack_test_buffer_t)); + + mismatched_version[0] = (uint8_t)(test_buffer->version - 1); + mismatched_version[1] = (uint8_t)(test_buffer->version + 1); + + for (index = 0; index < LIBSPDM_ARRAY_SIZE(mismatched_version); index++) { + common_test_record_test_message ("test mismatched_version - 0x%02x\n", + mismatched_version[index]); + libspdm_zero_mem(&spdm_request, sizeof(spdm_request)); + spdm_request.header.spdm_version = mismatched_version[index]; + spdm_request.header.request_response_code = SPDM_HEARTBEAT; + spdm_request.header.param1 = 0; + spdm_request.header.param2 = 0; + + spdm_response = (void *)message; + spdm_response_size = sizeof(message); + libspdm_zero_mem(message, sizeof(message)); + status = libspdm_send_receive_data(spdm_context, &test_buffer->session_id, false, + &spdm_request, sizeof(spdm_request), + spdm_response, &spdm_response_size); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_HEARTBEAT_ACK, + SPDM_RESPONDER_TEST_CASE_HEARTBEAT_ACK_VERSION_MISMATCH_IN_DHE_SESSION, + COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "send/receive failure"); + continue; + } + + if (spdm_response_size >= sizeof(spdm_error_response_t)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_HEARTBEAT_ACK, + SPDM_RESPONDER_TEST_CASE_HEARTBEAT_ACK_VERSION_MISMATCH_IN_DHE_SESSION, 1, + test_result, "response size - %d", spdm_response_size); + if (test_result == COMMON_TEST_RESULT_FAIL) { + continue; + } + + if (spdm_response->header.request_response_code == SPDM_ERROR) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_HEARTBEAT_ACK, + SPDM_RESPONDER_TEST_CASE_HEARTBEAT_ACK_VERSION_MISMATCH_IN_DHE_SESSION, 2, + test_result, "response code - 0x%02x", spdm_response->header.request_response_code); + if (test_result == COMMON_TEST_RESULT_FAIL) { + continue; + } + + if (spdm_response->header.spdm_version == test_buffer->version) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_HEARTBEAT_ACK, + SPDM_RESPONDER_TEST_CASE_HEARTBEAT_ACK_VERSION_MISMATCH_IN_DHE_SESSION, 3, + test_result, "response version - 0x%02x", spdm_response->header.spdm_version); + if (test_result == COMMON_TEST_RESULT_FAIL) { + continue; + } + + if (spdm_response->header.param1 == SPDM_ERROR_CODE_VERSION_MISMATCH) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_HEARTBEAT_ACK, + SPDM_RESPONDER_TEST_CASE_HEARTBEAT_ACK_VERSION_MISMATCH_IN_DHE_SESSION, 4, + test_result, "response param1 - 0x%02x", spdm_response->header.param1); + + if (spdm_response->header.param2 == 0) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_HEARTBEAT_ACK, + SPDM_RESPONDER_TEST_CASE_HEARTBEAT_ACK_VERSION_MISMATCH_IN_DHE_SESSION, 5, + test_result, "response param2 - 0x%02x", spdm_response->header.param2); + } +} + +void spdm_test_case_heartbeat_ack_unexpected_request (void *test_context) +{ + spdm_test_context_t *spdm_test_context; + void *spdm_context; + libspdm_return_t status; + spdm_heartbeat_request_t spdm_request; + spdm_heartbeat_response_t *spdm_response; + size_t spdm_response_size; + uint8_t message[LIBSPDM_MAX_MESSAGE_BUFFER_SIZE]; + common_test_result_t test_result; + spdm_heartbeat_ack_test_buffer_t *test_buffer; + uint8_t req_slot_id_param; + + spdm_test_context = test_context; + spdm_context = spdm_test_context->spdm_context; + test_buffer = (void *)spdm_test_context->test_scratch_buffer; + LIBSPDM_ASSERT(spdm_test_context->test_scratch_buffer_size == + sizeof(spdm_heartbeat_ack_test_buffer_t)); + + status = libspdm_send_receive_key_exchange (spdm_context, + SPDM_KEY_EXCHANGE_REQUEST_NO_MEASUREMENT_SUMMARY_HASH, + 0, 0, &test_buffer->session_id, &test_buffer->heartbeat_period, + &req_slot_id_param, NULL); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_MEASUREMENTS, + SPDM_RESPONDER_TEST_CASE_MEASUREMENTS_UNEXPECTED_REQUEST_IN_DHE_SESSION_HS, + COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "key_exchange failure"); + return; + } + if (test_buffer->heartbeat_period == 0) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_MEASUREMENTS, + SPDM_RESPONDER_TEST_CASE_MEASUREMENTS_UNEXPECTED_REQUEST_IN_DHE_SESSION_HS, + COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "heartbeat_period is 0"); + return; + } + + libspdm_zero_mem(&spdm_request, sizeof(spdm_request)); + spdm_request.header.spdm_version = test_buffer->version; + spdm_request.header.request_response_code = SPDM_HEARTBEAT; + spdm_request.header.param1 = 0; + spdm_request.header.param2 = 0; + + spdm_response = (void *)message; + spdm_response_size = sizeof(message); + libspdm_zero_mem(message, sizeof(message)); + status = libspdm_send_receive_data(spdm_context, &test_buffer->session_id, false, + &spdm_request, sizeof(spdm_request), + spdm_response, &spdm_response_size); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_HEARTBEAT_ACK, + SPDM_RESPONDER_TEST_CASE_HEARTBEAT_ACK_UNEXPECTED_REQUEST_IN_DHE_SESSION_HS, + COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "send/receive failure"); + return; + } + + if (spdm_response_size >= sizeof(spdm_error_response_t)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_HEARTBEAT_ACK, + SPDM_RESPONDER_TEST_CASE_HEARTBEAT_ACK_UNEXPECTED_REQUEST_IN_DHE_SESSION_HS, 1, + test_result, "response size - %d", spdm_response_size); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.request_response_code == SPDM_ERROR) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_HEARTBEAT_ACK, + SPDM_RESPONDER_TEST_CASE_HEARTBEAT_ACK_UNEXPECTED_REQUEST_IN_DHE_SESSION_HS, 2, + test_result, "response code - 0x%02x", spdm_response->header.request_response_code); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.spdm_version == test_buffer->version) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_HEARTBEAT_ACK, + SPDM_RESPONDER_TEST_CASE_HEARTBEAT_ACK_UNEXPECTED_REQUEST_IN_DHE_SESSION_HS, 3, + test_result, "response version - 0x%02x", spdm_response->header.spdm_version); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.param1 == SPDM_ERROR_CODE_UNEXPECTED_REQUEST) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_HEARTBEAT_ACK, + SPDM_RESPONDER_TEST_CASE_HEARTBEAT_ACK_UNEXPECTED_REQUEST_IN_DHE_SESSION_HS, 4, + test_result, "response param1 - 0x%02x", spdm_response->header.param1); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.param2 == 0) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_HEARTBEAT_ACK, + SPDM_RESPONDER_TEST_CASE_HEARTBEAT_ACK_UNEXPECTED_REQUEST_IN_DHE_SESSION_HS, 5, + test_result, "response param2 - 0x%02x", spdm_response->header.param2); +} + +void spdm_test_case_heartbeat_ack_session_required (void *test_context) +{ + spdm_test_context_t *spdm_test_context; + void *spdm_context; + libspdm_return_t status; + spdm_heartbeat_request_t spdm_request; + spdm_heartbeat_response_t *spdm_response; + uint8_t message[LIBSPDM_MAX_MESSAGE_BUFFER_SIZE]; + size_t spdm_response_size; + common_test_result_t test_result; + spdm_heartbeat_ack_test_buffer_t *test_buffer; + + spdm_test_context = test_context; + spdm_context = spdm_test_context->spdm_context; + test_buffer = (void *)spdm_test_context->test_scratch_buffer; + LIBSPDM_ASSERT(spdm_test_context->test_scratch_buffer_size == + sizeof(spdm_heartbeat_ack_test_buffer_t)); + + libspdm_zero_mem(&spdm_request, sizeof(spdm_request)); + spdm_request.header.spdm_version = test_buffer->version; + spdm_request.header.request_response_code = SPDM_HEARTBEAT; + spdm_request.header.param1 = 0; + spdm_request.header.param2 = 0; + + spdm_response = (void *)message; + spdm_response_size = sizeof(message); + libspdm_zero_mem(message, sizeof(message)); + status = libspdm_send_receive_data(spdm_context, NULL, false, + &spdm_request, sizeof(spdm_request), + spdm_response, &spdm_response_size); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_HEARTBEAT_ACK, + SPDM_RESPONDER_TEST_CASE_HEARTBEAT_ACK_SESSION_REQUIRED, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "send/receive failure"); + return; + } + + if (spdm_response_size >= sizeof(spdm_error_response_t)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_HEARTBEAT_ACK, + SPDM_RESPONDER_TEST_CASE_HEARTBEAT_ACK_SESSION_REQUIRED, 1, + test_result, "response size - %d", spdm_response_size); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.request_response_code == SPDM_ERROR) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_HEARTBEAT_ACK, + SPDM_RESPONDER_TEST_CASE_HEARTBEAT_ACK_SESSION_REQUIRED, 2, + test_result, "response code - 0x%02x", spdm_response->header.request_response_code); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.spdm_version == test_buffer->version) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_HEARTBEAT_ACK, + SPDM_RESPONDER_TEST_CASE_HEARTBEAT_ACK_SESSION_REQUIRED, 3, + test_result, "response version - 0x%02x", spdm_response->header.spdm_version); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.param1 == SPDM_ERROR_CODE_SESSION_REQUIRED) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_HEARTBEAT_ACK, + SPDM_RESPONDER_TEST_CASE_HEARTBEAT_ACK_SESSION_REQUIRED, 4, + test_result, "response param1 - 0x%02x", spdm_response->header.param1); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } +} + +common_test_case_t m_spdm_test_group_heartbeat_ack[] = { + {SPDM_RESPONDER_TEST_CASE_HEARTBEAT_ACK_SUCCESS_11_IN_DHE_SESSION, + "spdm_test_case_heartbeat_ack_success_11_dhe", spdm_test_case_heartbeat_ack_success_11_dhe, + spdm_test_case_heartbeat_ack_setup_version_any}, + {SPDM_RESPONDER_TEST_CASE_HEARTBEAT_ACK_VERSION_MISMATCH_IN_DHE_SESSION, + "spdm_test_case_heartbeat_ack_version_mismatch", + spdm_test_case_heartbeat_ack_version_mismatch, + spdm_test_case_heartbeat_ack_setup_version_any}, + {SPDM_RESPONDER_TEST_CASE_HEARTBEAT_ACK_UNEXPECTED_REQUEST_IN_DHE_SESSION_HS, + "spdm_test_case_heartbeat_ack_unexpected_request", + spdm_test_case_heartbeat_ack_unexpected_request, + spdm_test_case_heartbeat_ack_setup_version_any_session_cap}, + {SPDM_RESPONDER_TEST_CASE_HEARTBEAT_ACK_SESSION_REQUIRED, + "spdm_test_case_heartbeat_ack_session_required", + spdm_test_case_heartbeat_ack_session_required, + spdm_test_case_heartbeat_ack_setup_version_12}, + {COMMON_TEST_ID_END, NULL, NULL}, +}; diff --git a/library/spdm_responder_conformance_test_lib/spdm_responder_test_13_key_update_ack.c b/library/spdm_responder_conformance_test_lib/spdm_responder_test_13_key_update_ack.c new file mode 100644 index 0000000..21c68cb --- /dev/null +++ b/library/spdm_responder_conformance_test_lib/spdm_responder_test_13_key_update_ack.c @@ -0,0 +1,1076 @@ +/** + * Copyright Notice: + * Copyright 2021 DMTF. All rights reserved. + * License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/spdm-emu/blob/main/LICENSE.md + **/ + +#include "spdm_responder_test.h" + +#pragma pack(1) +typedef struct { + uint8_t version; + uint8_t reserved[3]; + uint32_t session_id; +} spdm_key_update_ack_test_buffer_t; +#pragma pack() + +bool spdm_test_case_key_update_ack_setup_session (void *test_context, + spdm_version_number_t spdm_version, + bool need_session) +{ + spdm_test_context_t *spdm_test_context; + void *spdm_context; + libspdm_return_t status; + libspdm_data_parameter_t parameter; + uint32_t rsp_cap_flags; + size_t data_size; + uint32_t data32; + uint16_t data16; + uint8_t data8; + spdm_key_update_ack_test_buffer_t *test_buffer; + + spdm_test_context = test_context; + spdm_context = spdm_test_context->spdm_context; + + if (spdm_version != 0) { + libspdm_zero_mem(¶meter, sizeof(parameter)); + parameter.location = LIBSPDM_DATA_LOCATION_LOCAL; + libspdm_set_data(spdm_context, LIBSPDM_DATA_SPDM_VERSION, ¶meter, + &spdm_version, sizeof(spdm_version)); + } + + data32 = SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CERT_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHAL_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_ENCRYPT_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MAC_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_KEY_EX_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_PSK_CAP_REQUESTER | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_ENCAP_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_HBEAT_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_KEY_UPD_CAP; + libspdm_set_data(spdm_context, LIBSPDM_DATA_CAPABILITY_FLAGS, ¶meter, + &data32, sizeof(data32)); + + data8 = SPDM_MEASUREMENT_BLOCK_HEADER_SPECIFICATION_DMTF; + libspdm_set_data(spdm_context, LIBSPDM_DATA_MEASUREMENT_SPEC, ¶meter, + &data8, sizeof(data8)); + data32 = SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_2048 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_3072 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_3072 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_4096 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_4096 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P384 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P521 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_SM2_ECC_SM2_P256 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED25519 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED448; + libspdm_set_data(spdm_context, LIBSPDM_DATA_BASE_ASYM_ALGO, ¶meter, + &data32, sizeof(data32)); + data32 = SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_256 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_384 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_512 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA3_256 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA3_384 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA3_512 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SM3_256; + libspdm_set_data(spdm_context, LIBSPDM_DATA_BASE_HASH_ALGO, ¶meter, + &data32, sizeof(data32)); + data16 = SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_2048 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_3072 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_4096 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_256_R1 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_384_R1 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_521_R1 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_SM2_P256; + libspdm_set_data(spdm_context, LIBSPDM_DATA_DHE_NAME_GROUP, ¶meter, + &data16, sizeof(data16)); + data16 = SPDM_ALGORITHMS_AEAD_CIPHER_SUITE_AES_128_GCM | + SPDM_ALGORITHMS_AEAD_CIPHER_SUITE_AES_256_GCM | + SPDM_ALGORITHMS_AEAD_CIPHER_SUITE_CHACHA20_POLY1305 | + SPDM_ALGORITHMS_AEAD_CIPHER_SUITE_AEAD_SM4_GCM; + libspdm_set_data(spdm_context, LIBSPDM_DATA_AEAD_CIPHER_SUITE, ¶meter, + &data16, sizeof(data16)); + data16 = SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_2048 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_3072 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_3072 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_4096 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_4096 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P384 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P521 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_SM2_ECC_SM2_P256 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED25519 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED448; + libspdm_set_data(spdm_context, LIBSPDM_DATA_REQ_BASE_ASYM_ALG, ¶meter, + &data16, sizeof(data16)); + data16 = SPDM_ALGORITHMS_KEY_SCHEDULE_HMAC_HASH; + libspdm_set_data(spdm_context, LIBSPDM_DATA_KEY_SCHEDULE, ¶meter, &data16, + sizeof(data16)); + data8 = SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_1; + libspdm_set_data(spdm_context, LIBSPDM_DATA_OTHER_PARAMS_SUPPORT, ¶meter, + &data8, sizeof(data8)); + + status = libspdm_init_connection (spdm_context, false); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + return false; + } + + test_buffer = (void *)spdm_test_context->test_scratch_buffer; + LIBSPDM_ASSERT(sizeof(spdm_test_context->test_scratch_buffer) >= + sizeof(spdm_key_update_ack_test_buffer_t)); + libspdm_zero_mem(test_buffer, sizeof(spdm_key_update_ack_test_buffer_t)); + spdm_test_context->test_scratch_buffer_size = sizeof(spdm_key_update_ack_test_buffer_t); + + spdm_version = 0; + data_size = sizeof(spdm_version); + libspdm_zero_mem(¶meter, sizeof(parameter)); + parameter.location = LIBSPDM_DATA_LOCATION_CONNECTION; + libspdm_get_data(spdm_context, LIBSPDM_DATA_SPDM_VERSION, ¶meter, &spdm_version, + &data_size); + test_buffer->version = (spdm_version >> SPDM_VERSION_NUMBER_SHIFT_BIT); + + rsp_cap_flags = 0; + data_size = sizeof(rsp_cap_flags); + libspdm_zero_mem(¶meter, sizeof(parameter)); + parameter.location = LIBSPDM_DATA_LOCATION_CONNECTION; + libspdm_get_data(spdm_context, LIBSPDM_DATA_CAPABILITY_FLAGS, ¶meter, &rsp_cap_flags, + &data_size); + if ((rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP) == 0) { + return false; + } + + if (((rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP) == 0) || + ((rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_KEY_EX_CAP) == 0) || + ((rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_KEY_UPD_CAP) == 0) ) { + return false; + } + + status = libspdm_get_certificate (spdm_context, 0, NULL, NULL); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + return false; + } + + if (need_session) { + status = libspdm_start_session (spdm_context, false, + SPDM_KEY_EXCHANGE_REQUEST_NO_MEASUREMENT_SUMMARY_HASH, + 0, 0, &test_buffer->session_id, NULL, NULL); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + return false; + } + } + + return true; +} + +bool spdm_test_case_key_update_ack_setup_version_any (void *test_context) +{ + return spdm_test_case_key_update_ack_setup_session (test_context, 0, true); +} + +bool spdm_test_case_key_update_ack_setup_version_12 (void *test_context) +{ + return spdm_test_case_key_update_ack_setup_session (test_context, + SPDM_MESSAGE_VERSION_12 << SPDM_VERSION_NUMBER_SHIFT_BIT, + true); +} + +bool spdm_test_case_key_update_ack_setup_version_any_session_cap (void *test_context) +{ + return spdm_test_case_key_update_ack_setup_session (test_context, 0, false); +} + +void spdm_test_case_key_update_ack_success_11_dhe (void *test_context) +{ + spdm_test_context_t *spdm_test_context; + void *spdm_context; + libspdm_return_t status; + spdm_key_update_request_t spdm_request; + spdm_key_update_response_t *spdm_response; + uint8_t message[LIBSPDM_MAX_MESSAGE_BUFFER_SIZE]; + size_t spdm_response_size; + common_test_result_t test_result; + spdm_key_update_ack_test_buffer_t *test_buffer; + bool result; + libspdm_session_info_t *session_info; + + spdm_test_context = test_context; + spdm_context = spdm_test_context->spdm_context; + test_buffer = (void *)spdm_test_context->test_scratch_buffer; + LIBSPDM_ASSERT(spdm_test_context->test_scratch_buffer_size == + sizeof(spdm_key_update_ack_test_buffer_t)); + + session_info = + libspdm_get_session_info_via_session_id(spdm_context, test_buffer->session_id); + LIBSPDM_ASSERT (session_info != NULL); + + /* update key */ + common_test_record_test_message ("test update key\n"); + + libspdm_zero_mem(&spdm_request, sizeof(spdm_request)); + spdm_request.header.spdm_version = test_buffer->version; + spdm_request.header.request_response_code = SPDM_KEY_UPDATE; + spdm_request.header.param1 = SPDM_KEY_UPDATE_OPERATIONS_TABLE_UPDATE_KEY; + spdm_request.header.param2 = 0x0; + + spdm_response = (void *)message; + spdm_response_size = sizeof(message); + libspdm_zero_mem(message, sizeof(message)); + + status = libspdm_send_receive_data(spdm_context, &test_buffer->session_id, false, + &spdm_request, sizeof(spdm_request), + spdm_response, &spdm_response_size); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_UPDATE_ACK, + SPDM_RESPONDER_TEST_CASE_KEY_UPDATE_ACK_SUCCESS_11_IN_DHE_SESSION, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "send/receive failure"); + return; + } + + if (spdm_response_size >= sizeof(spdm_key_update_response_t)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_UPDATE_ACK, + SPDM_RESPONDER_TEST_CASE_KEY_UPDATE_ACK_SUCCESS_11_IN_DHE_SESSION, 1, + test_result, "response size - %d", spdm_response_size); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.request_response_code == SPDM_KEY_UPDATE_ACK) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_UPDATE_ACK, + SPDM_RESPONDER_TEST_CASE_KEY_UPDATE_ACK_SUCCESS_11_IN_DHE_SESSION, 2, + test_result, "response code - 0x%02x", spdm_response->header.request_response_code); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.spdm_version == test_buffer->version) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_UPDATE_ACK, + SPDM_RESPONDER_TEST_CASE_KEY_UPDATE_ACK_SUCCESS_11_IN_DHE_SESSION, 3, + test_result, "response version - 0x%02x", spdm_response->header.spdm_version); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.param1 == spdm_request.header.param1) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_UPDATE_ACK, + SPDM_RESPONDER_TEST_CASE_KEY_UPDATE_ACK_SUCCESS_11_IN_DHE_SESSION, 4, + test_result, "response param1 - 0x%02x", spdm_response->header.param1); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.param2 == spdm_request.header.param2) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_UPDATE_ACK, + SPDM_RESPONDER_TEST_CASE_KEY_UPDATE_ACK_SUCCESS_11_IN_DHE_SESSION, 5, + test_result, "response param2 - 0x%02x", spdm_response->header.param2); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + result = libspdm_create_update_session_data_key( + session_info->secured_message_context, + LIBSPDM_KEY_UPDATE_ACTION_REQUESTER); + if (!result) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_UPDATE_ACK, + SPDM_RESPONDER_TEST_CASE_KEY_UPDATE_ACK_SUCCESS_11_IN_DHE_SESSION, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "create_update_session_data_key(Req) failure"); + return; + } + result = libspdm_activate_update_session_data_key( + session_info->secured_message_context, + LIBSPDM_KEY_UPDATE_ACTION_REQUESTER, true); + if (!result) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_UPDATE_ACK, + SPDM_RESPONDER_TEST_CASE_KEY_UPDATE_ACK_SUCCESS_11_IN_DHE_SESSION, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "activate_update_session_data_key(Req) failure"); + return; + } + + /* update key */ + common_test_record_test_message ("test verify new key\n"); + + libspdm_zero_mem(&spdm_request, sizeof(spdm_request)); + spdm_request.header.spdm_version = test_buffer->version; + spdm_request.header.request_response_code = SPDM_KEY_UPDATE; + spdm_request.header.param1 = SPDM_KEY_UPDATE_OPERATIONS_TABLE_VERIFY_NEW_KEY; + spdm_request.header.param2 = 0x0; + + spdm_response = (void *)message; + spdm_response_size = sizeof(message); + libspdm_zero_mem(message, sizeof(message)); + status = libspdm_send_receive_data(spdm_context, &test_buffer->session_id, false, + &spdm_request, sizeof(spdm_request), + spdm_response, &spdm_response_size); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_UPDATE_ACK, + SPDM_RESPONDER_TEST_CASE_KEY_UPDATE_ACK_SUCCESS_11_IN_DHE_SESSION, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "send/receive failure"); + return; + } + + if (spdm_response_size >= sizeof(spdm_key_update_response_t)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_UPDATE_ACK, + SPDM_RESPONDER_TEST_CASE_KEY_UPDATE_ACK_SUCCESS_11_IN_DHE_SESSION, 6, + test_result, "response size - %d", spdm_response_size); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.request_response_code == SPDM_KEY_UPDATE_ACK) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_UPDATE_ACK, + SPDM_RESPONDER_TEST_CASE_KEY_UPDATE_ACK_SUCCESS_11_IN_DHE_SESSION, 7, + test_result, "response code - 0x%02x", spdm_response->header.request_response_code); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.spdm_version == test_buffer->version) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_UPDATE_ACK, + SPDM_RESPONDER_TEST_CASE_KEY_UPDATE_ACK_SUCCESS_11_IN_DHE_SESSION, 8, + test_result, "response version - 0x%02x", spdm_response->header.spdm_version); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.param1 == spdm_request.header.param1) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_UPDATE_ACK, + SPDM_RESPONDER_TEST_CASE_KEY_UPDATE_ACK_SUCCESS_11_IN_DHE_SESSION, 9, + test_result, "response param1 - 0x%02x", spdm_response->header.param1); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.param2 == spdm_request.header.param2) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_UPDATE_ACK, + SPDM_RESPONDER_TEST_CASE_KEY_UPDATE_ACK_SUCCESS_11_IN_DHE_SESSION, 10, + test_result, "response param2 - 0x%02x", spdm_response->header.param2); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + /* update all keys */ + common_test_record_test_message ("test update all keys\n"); + + libspdm_zero_mem(&spdm_request, sizeof(spdm_request)); + spdm_request.header.spdm_version = test_buffer->version; + spdm_request.header.request_response_code = SPDM_KEY_UPDATE; + spdm_request.header.param1 = SPDM_KEY_UPDATE_OPERATIONS_TABLE_UPDATE_ALL_KEYS; + spdm_request.header.param2 = 0x0; + + spdm_response = (void *)message; + spdm_response_size = sizeof(message); + libspdm_zero_mem(message, sizeof(message)); + + result = libspdm_create_update_session_data_key( + session_info->secured_message_context, + LIBSPDM_KEY_UPDATE_ACTION_RESPONDER); + if (!result) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_UPDATE_ACK, + SPDM_RESPONDER_TEST_CASE_KEY_UPDATE_ACK_SUCCESS_11_IN_DHE_SESSION, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "create_update_session_data_key(Rsp) failure"); + return; + } + + status = libspdm_send_receive_data(spdm_context, &test_buffer->session_id, false, + &spdm_request, sizeof(spdm_request), + spdm_response, &spdm_response_size); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_UPDATE_ACK, + SPDM_RESPONDER_TEST_CASE_KEY_UPDATE_ACK_SUCCESS_11_IN_DHE_SESSION, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "send/receive failure"); + return; + } + + if (spdm_response_size >= sizeof(spdm_key_update_response_t)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_UPDATE_ACK, + SPDM_RESPONDER_TEST_CASE_KEY_UPDATE_ACK_SUCCESS_11_IN_DHE_SESSION, 11, + test_result, "response size - %d", spdm_response_size); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.request_response_code == SPDM_KEY_UPDATE_ACK) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_UPDATE_ACK, + SPDM_RESPONDER_TEST_CASE_KEY_UPDATE_ACK_SUCCESS_11_IN_DHE_SESSION, 12, + test_result, "response code - 0x%02x", spdm_response->header.request_response_code); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.spdm_version == test_buffer->version) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_UPDATE_ACK, + SPDM_RESPONDER_TEST_CASE_KEY_UPDATE_ACK_SUCCESS_11_IN_DHE_SESSION, 13, + test_result, "response version - 0x%02x", spdm_response->header.spdm_version); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.param1 == spdm_request.header.param1) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_UPDATE_ACK, + SPDM_RESPONDER_TEST_CASE_KEY_UPDATE_ACK_SUCCESS_11_IN_DHE_SESSION, 14, + test_result, "response param1 - 0x%02x", spdm_response->header.param1); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.param2 == spdm_request.header.param2) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_UPDATE_ACK, + SPDM_RESPONDER_TEST_CASE_KEY_UPDATE_ACK_SUCCESS_11_IN_DHE_SESSION, 15, + test_result, "response param2 - 0x%02x", spdm_response->header.param2); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + result = libspdm_activate_update_session_data_key( + session_info->secured_message_context, + LIBSPDM_KEY_UPDATE_ACTION_RESPONDER, true); + if (!result) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_UPDATE_ACK, + SPDM_RESPONDER_TEST_CASE_KEY_UPDATE_ACK_SUCCESS_11_IN_DHE_SESSION, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "activate_update_session_data_key(Rsp) failure"); + return; + } + + result = libspdm_create_update_session_data_key( + session_info->secured_message_context, + LIBSPDM_KEY_UPDATE_ACTION_REQUESTER); + if (!result) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_UPDATE_ACK, + SPDM_RESPONDER_TEST_CASE_KEY_UPDATE_ACK_SUCCESS_11_IN_DHE_SESSION, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "create_update_session_data_key(Req) failure"); + return; + } + result = libspdm_activate_update_session_data_key( + session_info->secured_message_context, + LIBSPDM_KEY_UPDATE_ACTION_REQUESTER, true); + if (!result) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_UPDATE_ACK, + SPDM_RESPONDER_TEST_CASE_KEY_UPDATE_ACK_SUCCESS_11_IN_DHE_SESSION, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "activate_update_session_data_key(Req) failure"); + return; + } + + /* verify key */ + common_test_record_test_message ("test verify new key\n"); + + libspdm_zero_mem(&spdm_request, sizeof(spdm_request)); + spdm_request.header.spdm_version = test_buffer->version; + spdm_request.header.request_response_code = SPDM_KEY_UPDATE; + spdm_request.header.param1 = SPDM_KEY_UPDATE_OPERATIONS_TABLE_VERIFY_NEW_KEY; + spdm_request.header.param2 = 0x0; + + spdm_response = (void *)message; + spdm_response_size = sizeof(message); + libspdm_zero_mem(message, sizeof(message)); + status = libspdm_send_receive_data(spdm_context, &test_buffer->session_id, false, + &spdm_request, sizeof(spdm_request), + spdm_response, &spdm_response_size); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_UPDATE_ACK, + SPDM_RESPONDER_TEST_CASE_KEY_UPDATE_ACK_SUCCESS_11_IN_DHE_SESSION, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "send/receive failure"); + return; + } + + if (spdm_response_size >= sizeof(spdm_key_update_response_t)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_UPDATE_ACK, + SPDM_RESPONDER_TEST_CASE_KEY_UPDATE_ACK_SUCCESS_11_IN_DHE_SESSION, 16, + test_result, "response size - %d", spdm_response_size); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.request_response_code == SPDM_KEY_UPDATE_ACK) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_UPDATE_ACK, + SPDM_RESPONDER_TEST_CASE_KEY_UPDATE_ACK_SUCCESS_11_IN_DHE_SESSION, 17, + test_result, "response code - 0x%02x", spdm_response->header.request_response_code); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.spdm_version == test_buffer->version) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_UPDATE_ACK, + SPDM_RESPONDER_TEST_CASE_KEY_UPDATE_ACK_SUCCESS_11_IN_DHE_SESSION, 18, + test_result, "response version - 0x%02x", spdm_response->header.spdm_version); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.param1 == spdm_request.header.param1) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_UPDATE_ACK, + SPDM_RESPONDER_TEST_CASE_KEY_UPDATE_ACK_SUCCESS_11_IN_DHE_SESSION, 19, + test_result, "response param1 - 0x%02x", spdm_response->header.param1); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.param2 == spdm_request.header.param2) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_UPDATE_ACK, + SPDM_RESPONDER_TEST_CASE_KEY_UPDATE_ACK_SUCCESS_11_IN_DHE_SESSION, 20, + test_result, "response param2 - 0x%02x", spdm_response->header.param2); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } +} + +void spdm_test_case_key_update_ack_version_mismatch (void *test_context) +{ + spdm_test_context_t *spdm_test_context; + void *spdm_context; + libspdm_return_t status; + spdm_key_update_request_t spdm_request; + spdm_key_update_response_t *spdm_response; + uint8_t message[LIBSPDM_MAX_MESSAGE_BUFFER_SIZE]; + size_t spdm_response_size; + common_test_result_t test_result; + spdm_key_update_ack_test_buffer_t *test_buffer; + uint8_t mismatched_version[] = { + SPDM_MESSAGE_VERSION_10 - 1, + SPDM_MESSAGE_VERSION_12 + 1, + }; + size_t index; + + spdm_test_context = test_context; + spdm_context = spdm_test_context->spdm_context; + test_buffer = (void *)spdm_test_context->test_scratch_buffer; + LIBSPDM_ASSERT(spdm_test_context->test_scratch_buffer_size == + sizeof(spdm_key_update_ack_test_buffer_t)); + + mismatched_version[0] = (uint8_t)(test_buffer->version - 1); + mismatched_version[1] = (uint8_t)(test_buffer->version + 1); + + for (index = 0; index < LIBSPDM_ARRAY_SIZE(mismatched_version); index++) { + common_test_record_test_message ("test mismatched_version - 0x%02x\n", + mismatched_version[index]); + libspdm_zero_mem(&spdm_request, sizeof(spdm_request)); + spdm_request.header.spdm_version = mismatched_version[index]; + spdm_request.header.request_response_code = SPDM_KEY_UPDATE; + spdm_request.header.param1 = SPDM_KEY_UPDATE_OPERATIONS_TABLE_UPDATE_KEY; + spdm_request.header.param2 = 0; + + spdm_response = (void *)message; + spdm_response_size = sizeof(message); + libspdm_zero_mem(message, sizeof(message)); + status = libspdm_send_receive_data(spdm_context, &test_buffer->session_id, false, + &spdm_request, sizeof(spdm_request), + spdm_response, &spdm_response_size); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_UPDATE_ACK, + SPDM_RESPONDER_TEST_CASE_KEY_UPDATE_ACK_VERSION_MISMATCH_IN_DHE_SESSION, + COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "send/receive failure"); + continue; + } + + if (spdm_response_size >= sizeof(spdm_error_response_t)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_UPDATE_ACK, + SPDM_RESPONDER_TEST_CASE_KEY_UPDATE_ACK_VERSION_MISMATCH_IN_DHE_SESSION, 1, + test_result, "response size - %d", spdm_response_size); + if (test_result == COMMON_TEST_RESULT_FAIL) { + continue; + } + + if (spdm_response->header.request_response_code == SPDM_ERROR) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_UPDATE_ACK, + SPDM_RESPONDER_TEST_CASE_KEY_UPDATE_ACK_VERSION_MISMATCH_IN_DHE_SESSION, 2, + test_result, "response code - 0x%02x", spdm_response->header.request_response_code); + if (test_result == COMMON_TEST_RESULT_FAIL) { + continue; + } + + if (spdm_response->header.spdm_version == test_buffer->version) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_UPDATE_ACK, + SPDM_RESPONDER_TEST_CASE_KEY_UPDATE_ACK_VERSION_MISMATCH_IN_DHE_SESSION, 3, + test_result, "response version - 0x%02x", spdm_response->header.spdm_version); + if (test_result == COMMON_TEST_RESULT_FAIL) { + continue; + } + + if (spdm_response->header.param1 == SPDM_ERROR_CODE_VERSION_MISMATCH) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_UPDATE_ACK, + SPDM_RESPONDER_TEST_CASE_KEY_UPDATE_ACK_VERSION_MISMATCH_IN_DHE_SESSION, 4, + test_result, "response param1 - 0x%02x", spdm_response->header.param1); + + if (spdm_response->header.param2 == 0) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_UPDATE_ACK, + SPDM_RESPONDER_TEST_CASE_KEY_UPDATE_ACK_VERSION_MISMATCH_IN_DHE_SESSION, 5, + test_result, "response param2 - 0x%02x", spdm_response->header.param2); + } +} + +void spdm_test_case_key_update_ack_invalid_request (void *test_context) +{ + spdm_test_context_t *spdm_test_context; + void *spdm_context; + libspdm_return_t status; + spdm_key_update_request_t spdm_request; + spdm_key_update_response_t *spdm_response; + uint8_t message[LIBSPDM_MAX_MESSAGE_BUFFER_SIZE]; + size_t spdm_response_size; + common_test_result_t test_result; + spdm_key_update_ack_test_buffer_t *test_buffer; + uint8_t invalid_operation[] = { + SPDM_KEY_UPDATE_OPERATIONS_TABLE_UPDATE_KEY - 1, + SPDM_KEY_UPDATE_OPERATIONS_TABLE_VERIFY_NEW_KEY + 1, + }; + size_t index; + + spdm_test_context = test_context; + spdm_context = spdm_test_context->spdm_context; + test_buffer = (void *)spdm_test_context->test_scratch_buffer; + LIBSPDM_ASSERT(spdm_test_context->test_scratch_buffer_size == + sizeof(spdm_key_update_ack_test_buffer_t)); + + for (index = 0; index < LIBSPDM_ARRAY_SIZE(invalid_operation); index++) { + common_test_record_test_message ("test invalid_operation - 0x%02x\n", + invalid_operation[index]); + libspdm_zero_mem(&spdm_request, sizeof(spdm_request)); + spdm_request.header.spdm_version = test_buffer->version; + spdm_request.header.request_response_code = SPDM_KEY_UPDATE; + spdm_request.header.param1 = invalid_operation[index]; + spdm_request.header.param2 = 0; + + spdm_response = (void *)message; + spdm_response_size = sizeof(message); + libspdm_zero_mem(message, sizeof(message)); + status = libspdm_send_receive_data(spdm_context, &test_buffer->session_id, false, + &spdm_request, sizeof(spdm_request), + spdm_response, &spdm_response_size); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_UPDATE_ACK, + SPDM_RESPONDER_TEST_CASE_KEY_UPDATE_ACK_INVALID_REQUEST_IN_DHE_SESSION, + COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "send/receive failure"); + continue; + } + + if (spdm_response_size >= sizeof(spdm_error_response_t)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_UPDATE_ACK, + SPDM_RESPONDER_TEST_CASE_KEY_UPDATE_ACK_INVALID_REQUEST_IN_DHE_SESSION, 1, + test_result, "response size - %d", spdm_response_size); + if (test_result == COMMON_TEST_RESULT_FAIL) { + continue; + } + + if (spdm_response->header.request_response_code == SPDM_ERROR) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_UPDATE_ACK, + SPDM_RESPONDER_TEST_CASE_KEY_UPDATE_ACK_INVALID_REQUEST_IN_DHE_SESSION, 2, + test_result, "response code - 0x%02x", spdm_response->header.request_response_code); + if (test_result == COMMON_TEST_RESULT_FAIL) { + continue; + } + + if (spdm_response->header.spdm_version == test_buffer->version) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_UPDATE_ACK, + SPDM_RESPONDER_TEST_CASE_KEY_UPDATE_ACK_INVALID_REQUEST_IN_DHE_SESSION, 3, + test_result, "response version - 0x%02x", spdm_response->header.spdm_version); + if (test_result == COMMON_TEST_RESULT_FAIL) { + continue; + } + + if (spdm_response->header.param1 == SPDM_ERROR_CODE_INVALID_REQUEST) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_UPDATE_ACK, + SPDM_RESPONDER_TEST_CASE_KEY_UPDATE_ACK_INVALID_REQUEST_IN_DHE_SESSION, 4, + test_result, "response param1 - 0x%02x", spdm_response->header.param1); + + if (spdm_response->header.param2 == 0) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_UPDATE_ACK, + SPDM_RESPONDER_TEST_CASE_KEY_UPDATE_ACK_INVALID_REQUEST_IN_DHE_SESSION, 5, + test_result, "response param2 - 0x%02x", spdm_response->header.param2); + } +} + +void spdm_test_case_key_update_ack_unexpected_request (void *test_context) +{ + spdm_test_context_t *spdm_test_context; + void *spdm_context; + libspdm_return_t status; + spdm_key_update_request_t spdm_request; + spdm_key_update_response_t *spdm_response; + size_t spdm_response_size; + uint8_t message[LIBSPDM_MAX_MESSAGE_BUFFER_SIZE]; + common_test_result_t test_result; + spdm_key_update_ack_test_buffer_t *test_buffer; + uint8_t req_slot_id_param; + + spdm_test_context = test_context; + spdm_context = spdm_test_context->spdm_context; + test_buffer = (void *)spdm_test_context->test_scratch_buffer; + LIBSPDM_ASSERT(spdm_test_context->test_scratch_buffer_size == + sizeof(spdm_key_update_ack_test_buffer_t)); + + status = libspdm_send_receive_key_exchange (spdm_context, + SPDM_KEY_EXCHANGE_REQUEST_NO_MEASUREMENT_SUMMARY_HASH, + 0, 0, &test_buffer->session_id, NULL, + &req_slot_id_param, NULL); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_MEASUREMENTS, + SPDM_RESPONDER_TEST_CASE_MEASUREMENTS_UNEXPECTED_REQUEST_IN_DHE_SESSION_HS, + COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "key_exchange failure"); + return; + } + + libspdm_zero_mem(&spdm_request, sizeof(spdm_request)); + spdm_request.header.spdm_version = test_buffer->version; + spdm_request.header.request_response_code = SPDM_KEY_UPDATE; + spdm_request.header.param1 = SPDM_KEY_UPDATE_OPERATIONS_TABLE_UPDATE_KEY; + spdm_request.header.param2 = 0; + + spdm_response = (void *)message; + spdm_response_size = sizeof(message); + libspdm_zero_mem(message, sizeof(message)); + status = libspdm_send_receive_data(spdm_context, &test_buffer->session_id, false, + &spdm_request, sizeof(spdm_request), + spdm_response, &spdm_response_size); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_UPDATE_ACK, + SPDM_RESPONDER_TEST_CASE_KEY_UPDATE_ACK_UNEXPECTED_REQUEST_IN_DHE_SESSION_HS, + COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "send/receive failure"); + return; + } + + if (spdm_response_size >= sizeof(spdm_error_response_t)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_UPDATE_ACK, + SPDM_RESPONDER_TEST_CASE_KEY_UPDATE_ACK_UNEXPECTED_REQUEST_IN_DHE_SESSION_HS, 1, + test_result, "response size - %d", spdm_response_size); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.request_response_code == SPDM_ERROR) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_UPDATE_ACK, + SPDM_RESPONDER_TEST_CASE_KEY_UPDATE_ACK_UNEXPECTED_REQUEST_IN_DHE_SESSION_HS, 2, + test_result, "response code - 0x%02x", spdm_response->header.request_response_code); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.spdm_version == test_buffer->version) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_UPDATE_ACK, + SPDM_RESPONDER_TEST_CASE_KEY_UPDATE_ACK_UNEXPECTED_REQUEST_IN_DHE_SESSION_HS, 3, + test_result, "response version - 0x%02x", spdm_response->header.spdm_version); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.param1 == SPDM_ERROR_CODE_UNEXPECTED_REQUEST) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_UPDATE_ACK, + SPDM_RESPONDER_TEST_CASE_KEY_UPDATE_ACK_UNEXPECTED_REQUEST_IN_DHE_SESSION_HS, 4, + test_result, "response param1 - 0x%02x", spdm_response->header.param1); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.param2 == 0) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_UPDATE_ACK, + SPDM_RESPONDER_TEST_CASE_KEY_UPDATE_ACK_UNEXPECTED_REQUEST_IN_DHE_SESSION_HS, 5, + test_result, "response param2 - 0x%02x", spdm_response->header.param2); +} + +void spdm_test_case_key_update_ack_session_required (void *test_context) +{ + spdm_test_context_t *spdm_test_context; + void *spdm_context; + libspdm_return_t status; + spdm_key_update_request_t spdm_request; + spdm_key_update_response_t *spdm_response; + uint8_t message[LIBSPDM_MAX_MESSAGE_BUFFER_SIZE]; + size_t spdm_response_size; + common_test_result_t test_result; + spdm_key_update_ack_test_buffer_t *test_buffer; + + spdm_test_context = test_context; + spdm_context = spdm_test_context->spdm_context; + test_buffer = (void *)spdm_test_context->test_scratch_buffer; + LIBSPDM_ASSERT(spdm_test_context->test_scratch_buffer_size == + sizeof(spdm_key_update_ack_test_buffer_t)); + + libspdm_zero_mem(&spdm_request, sizeof(spdm_request)); + spdm_request.header.spdm_version = test_buffer->version; + spdm_request.header.request_response_code = SPDM_KEY_UPDATE; + spdm_request.header.param1 = SPDM_KEY_UPDATE_OPERATIONS_TABLE_UPDATE_KEY; + spdm_request.header.param2 = 0; + + spdm_response = (void *)message; + spdm_response_size = sizeof(message); + libspdm_zero_mem(message, sizeof(message)); + status = libspdm_send_receive_data(spdm_context, NULL, false, + &spdm_request, sizeof(spdm_request), + spdm_response, &spdm_response_size); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_UPDATE_ACK, + SPDM_RESPONDER_TEST_CASE_KEY_UPDATE_ACK_SESSION_REQUIRED, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "send/receive failure"); + return; + } + + if (spdm_response_size >= sizeof(spdm_error_response_t)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_UPDATE_ACK, + SPDM_RESPONDER_TEST_CASE_KEY_UPDATE_ACK_SESSION_REQUIRED, 1, + test_result, "response size - %d", spdm_response_size); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.request_response_code == SPDM_ERROR) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_UPDATE_ACK, + SPDM_RESPONDER_TEST_CASE_KEY_UPDATE_ACK_SESSION_REQUIRED, 2, + test_result, "response code - 0x%02x", spdm_response->header.request_response_code); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.spdm_version == test_buffer->version) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_UPDATE_ACK, + SPDM_RESPONDER_TEST_CASE_KEY_UPDATE_ACK_SESSION_REQUIRED, 3, + test_result, "response version - 0x%02x", spdm_response->header.spdm_version); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.param1 == SPDM_ERROR_CODE_SESSION_REQUIRED) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_UPDATE_ACK, + SPDM_RESPONDER_TEST_CASE_KEY_UPDATE_ACK_SESSION_REQUIRED, 4, + test_result, "response param1 - 0x%02x", spdm_response->header.param1); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } +} + +common_test_case_t m_spdm_test_group_key_update_ack[] = { + {SPDM_RESPONDER_TEST_CASE_KEY_UPDATE_ACK_SUCCESS_11_IN_DHE_SESSION, + "spdm_test_case_key_update_ack_success_11_dhe", + spdm_test_case_key_update_ack_success_11_dhe, + spdm_test_case_key_update_ack_setup_version_any}, + {SPDM_RESPONDER_TEST_CASE_KEY_UPDATE_ACK_VERSION_MISMATCH_IN_DHE_SESSION, + "spdm_test_case_key_update_ack_version_mismatch", + spdm_test_case_key_update_ack_version_mismatch, + spdm_test_case_key_update_ack_setup_version_any}, + {SPDM_RESPONDER_TEST_CASE_KEY_UPDATE_ACK_INVALID_REQUEST_IN_DHE_SESSION, + "spdm_test_case_key_update_ack_invalid_request", + spdm_test_case_key_update_ack_invalid_request, + spdm_test_case_key_update_ack_setup_version_any}, + {SPDM_RESPONDER_TEST_CASE_KEY_UPDATE_ACK_UNEXPECTED_REQUEST_IN_DHE_SESSION_HS, + "spdm_test_case_key_update_ack_unexpected_request", + spdm_test_case_key_update_ack_unexpected_request, + spdm_test_case_key_update_ack_setup_version_any_session_cap}, + {SPDM_RESPONDER_TEST_CASE_KEY_UPDATE_ACK_SESSION_REQUIRED, + "spdm_test_case_key_update_ack_session_required", + spdm_test_case_key_update_ack_session_required, + spdm_test_case_key_update_ack_setup_version_12}, + {COMMON_TEST_ID_END, NULL, NULL}, +}; diff --git a/library/spdm_responder_conformance_test_lib/spdm_responder_test_16_end_session_ack.c b/library/spdm_responder_conformance_test_lib/spdm_responder_test_16_end_session_ack.c new file mode 100644 index 0000000..1df9b1e --- /dev/null +++ b/library/spdm_responder_conformance_test_lib/spdm_responder_test_16_end_session_ack.c @@ -0,0 +1,611 @@ +/** + * Copyright Notice: + * Copyright 2021 DMTF. All rights reserved. + * License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/spdm-emu/blob/main/LICENSE.md + **/ + +#include "spdm_responder_test.h" + +#pragma pack(1) +typedef struct { + uint8_t version; + uint8_t heartbeat_period; + uint8_t reserved[2]; + uint32_t session_id; +} spdm_end_session_ack_test_buffer_t; +#pragma pack() + +bool spdm_test_case_end_session_ack_setup_session (void *test_context, + spdm_version_number_t spdm_version, + bool need_session) +{ + spdm_test_context_t *spdm_test_context; + void *spdm_context; + libspdm_return_t status; + libspdm_data_parameter_t parameter; + uint32_t rsp_cap_flags; + size_t data_size; + uint32_t data32; + uint16_t data16; + uint8_t data8; + spdm_end_session_ack_test_buffer_t *test_buffer; + + spdm_test_context = test_context; + spdm_context = spdm_test_context->spdm_context; + + if (spdm_version != 0) { + libspdm_zero_mem(¶meter, sizeof(parameter)); + parameter.location = LIBSPDM_DATA_LOCATION_LOCAL; + libspdm_set_data(spdm_context, LIBSPDM_DATA_SPDM_VERSION, ¶meter, + &spdm_version, sizeof(spdm_version)); + } + + data32 = SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CERT_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHAL_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_ENCRYPT_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MAC_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_KEY_EX_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_ENCAP_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_HBEAT_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_KEY_UPD_CAP; + libspdm_set_data(spdm_context, LIBSPDM_DATA_CAPABILITY_FLAGS, ¶meter, + &data32, sizeof(data32)); + + data8 = SPDM_MEASUREMENT_BLOCK_HEADER_SPECIFICATION_DMTF; + libspdm_set_data(spdm_context, LIBSPDM_DATA_MEASUREMENT_SPEC, ¶meter, + &data8, sizeof(data8)); + data32 = SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_2048 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_3072 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_3072 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_4096 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_4096 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P384 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P521 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_SM2_ECC_SM2_P256 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED25519 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED448; + libspdm_set_data(spdm_context, LIBSPDM_DATA_BASE_ASYM_ALGO, ¶meter, + &data32, sizeof(data32)); + data32 = SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_256 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_384 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_512 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA3_256 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA3_384 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA3_512 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SM3_256; + libspdm_set_data(spdm_context, LIBSPDM_DATA_BASE_HASH_ALGO, ¶meter, + &data32, sizeof(data32)); + data16 = SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_2048 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_3072 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_4096 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_256_R1 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_384_R1 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_521_R1 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_SM2_P256; + libspdm_set_data(spdm_context, LIBSPDM_DATA_DHE_NAME_GROUP, ¶meter, + &data16, sizeof(data16)); + data16 = SPDM_ALGORITHMS_AEAD_CIPHER_SUITE_AES_128_GCM | + SPDM_ALGORITHMS_AEAD_CIPHER_SUITE_AES_256_GCM | + SPDM_ALGORITHMS_AEAD_CIPHER_SUITE_CHACHA20_POLY1305 | + SPDM_ALGORITHMS_AEAD_CIPHER_SUITE_AEAD_SM4_GCM; + libspdm_set_data(spdm_context, LIBSPDM_DATA_AEAD_CIPHER_SUITE, ¶meter, + &data16, sizeof(data16)); + data16 = SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_2048 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_3072 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_3072 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_4096 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_4096 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P384 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P521 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_SM2_ECC_SM2_P256 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED25519 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED448; + libspdm_set_data(spdm_context, LIBSPDM_DATA_REQ_BASE_ASYM_ALG, ¶meter, + &data16, sizeof(data16)); + data16 = SPDM_ALGORITHMS_KEY_SCHEDULE_HMAC_HASH; + libspdm_set_data(spdm_context, LIBSPDM_DATA_KEY_SCHEDULE, ¶meter, &data16, + sizeof(data16)); + data8 = SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_1; + libspdm_set_data(spdm_context, LIBSPDM_DATA_OTHER_PARAMS_SUPPORT, ¶meter, + &data8, sizeof(data8)); + + status = libspdm_init_connection (spdm_context, false); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + return false; + } + + test_buffer = (void *)spdm_test_context->test_scratch_buffer; + LIBSPDM_ASSERT(sizeof(spdm_test_context->test_scratch_buffer) >= + sizeof(spdm_end_session_ack_test_buffer_t)); + libspdm_zero_mem(test_buffer, sizeof(spdm_end_session_ack_test_buffer_t)); + spdm_test_context->test_scratch_buffer_size = sizeof(spdm_end_session_ack_test_buffer_t); + + spdm_version = 0; + data_size = sizeof(spdm_version); + libspdm_zero_mem(¶meter, sizeof(parameter)); + parameter.location = LIBSPDM_DATA_LOCATION_CONNECTION; + libspdm_get_data(spdm_context, LIBSPDM_DATA_SPDM_VERSION, ¶meter, &spdm_version, + &data_size); + test_buffer->version = (spdm_version >> SPDM_VERSION_NUMBER_SHIFT_BIT); + + rsp_cap_flags = 0; + data_size = sizeof(rsp_cap_flags); + libspdm_zero_mem(¶meter, sizeof(parameter)); + parameter.location = LIBSPDM_DATA_LOCATION_CONNECTION; + libspdm_get_data(spdm_context, LIBSPDM_DATA_CAPABILITY_FLAGS, ¶meter, &rsp_cap_flags, + &data_size); + if ((rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP) == 0) { + return false; + } + + if (((rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP) == 0) || + ((rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_KEY_EX_CAP) == 0)) { + return false; + } + + status = libspdm_get_certificate (spdm_context, 0, NULL, NULL); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + return false; + } + + if (need_session) { + status = libspdm_start_session (spdm_context, false, + SPDM_KEY_EXCHANGE_REQUEST_NO_MEASUREMENT_SUMMARY_HASH, + 0, 0, &test_buffer->session_id, + &test_buffer->heartbeat_period, NULL); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + return false; + } + + if (test_buffer->heartbeat_period == 0) { + return false; + } + } + + return true; +} + +bool spdm_test_case_end_session_ack_setup_version_any (void *test_context) +{ + return spdm_test_case_end_session_ack_setup_session (test_context, 0, true); +} + +bool spdm_test_case_end_session_ack_setup_version_12 (void *test_context) +{ + return spdm_test_case_end_session_ack_setup_session (test_context, + SPDM_MESSAGE_VERSION_12 << SPDM_VERSION_NUMBER_SHIFT_BIT, + true); +} + +bool spdm_test_case_end_session_ack_setup_version_any_session_cap (void *test_context) +{ + return spdm_test_case_end_session_ack_setup_session (test_context, 0, false); +} + +void spdm_test_case_end_session_ack_success_11_dhe (void *test_context) +{ + spdm_test_context_t *spdm_test_context; + void *spdm_context; + libspdm_return_t status; + spdm_heartbeat_request_t spdm_request; + spdm_heartbeat_response_t *spdm_response; + uint8_t message[LIBSPDM_MAX_MESSAGE_BUFFER_SIZE]; + size_t spdm_response_size; + common_test_result_t test_result; + spdm_end_session_ack_test_buffer_t *test_buffer; + + spdm_test_context = test_context; + spdm_context = spdm_test_context->spdm_context; + test_buffer = (void *)spdm_test_context->test_scratch_buffer; + LIBSPDM_ASSERT(spdm_test_context->test_scratch_buffer_size == + sizeof(spdm_end_session_ack_test_buffer_t)); + + libspdm_zero_mem(&spdm_request, sizeof(spdm_request)); + spdm_request.header.spdm_version = test_buffer->version; + spdm_request.header.request_response_code = SPDM_END_SESSION; + spdm_request.header.param1 = 0; + spdm_request.header.param2 = 0; + + spdm_response = (void *)message; + spdm_response_size = sizeof(message); + libspdm_zero_mem(message, sizeof(message)); + status = libspdm_send_receive_data(spdm_context, &test_buffer->session_id, false, + &spdm_request, sizeof(spdm_request), + spdm_response, &spdm_response_size); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_END_SESSION_ACK, + SPDM_RESPONDER_TEST_CASE_END_SESSION_ACK_SUCCESS_11_IN_DHE_SESSION, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "send/receive failure"); + return; + } + + if (spdm_response_size >= sizeof(spdm_heartbeat_response_t)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_END_SESSION_ACK, + SPDM_RESPONDER_TEST_CASE_END_SESSION_ACK_SUCCESS_11_IN_DHE_SESSION, 1, + test_result, "response size - %d", spdm_response_size); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.request_response_code == SPDM_END_SESSION_ACK) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_END_SESSION_ACK, + SPDM_RESPONDER_TEST_CASE_END_SESSION_ACK_SUCCESS_11_IN_DHE_SESSION, 2, + test_result, "response code - 0x%02x", spdm_response->header.request_response_code); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.spdm_version == test_buffer->version) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_END_SESSION_ACK, + SPDM_RESPONDER_TEST_CASE_END_SESSION_ACK_SUCCESS_11_IN_DHE_SESSION, 3, + test_result, "response version - 0x%02x", spdm_response->header.spdm_version); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } +} + +void spdm_test_case_end_session_ack_version_mismatch (void *test_context) +{ + spdm_test_context_t *spdm_test_context; + void *spdm_context; + libspdm_return_t status; + spdm_heartbeat_request_t spdm_request; + spdm_heartbeat_response_t *spdm_response; + uint8_t message[LIBSPDM_MAX_MESSAGE_BUFFER_SIZE]; + size_t spdm_response_size; + common_test_result_t test_result; + spdm_end_session_ack_test_buffer_t *test_buffer; + uint8_t mismatched_version[] = { + SPDM_MESSAGE_VERSION_10 - 1, + SPDM_MESSAGE_VERSION_12 + 1, + }; + size_t index; + + spdm_test_context = test_context; + spdm_context = spdm_test_context->spdm_context; + test_buffer = (void *)spdm_test_context->test_scratch_buffer; + LIBSPDM_ASSERT(spdm_test_context->test_scratch_buffer_size == + sizeof(spdm_end_session_ack_test_buffer_t)); + + mismatched_version[0] = (uint8_t)(test_buffer->version - 1); + mismatched_version[1] = (uint8_t)(test_buffer->version + 1); + + for (index = 0; index < LIBSPDM_ARRAY_SIZE(mismatched_version); index++) { + common_test_record_test_message ("test mismatched_version - 0x%02x\n", + mismatched_version[index]); + libspdm_zero_mem(&spdm_request, sizeof(spdm_request)); + spdm_request.header.spdm_version = mismatched_version[index]; + spdm_request.header.request_response_code = SPDM_END_SESSION; + spdm_request.header.param1 = 0; + spdm_request.header.param2 = 0; + + spdm_response = (void *)message; + spdm_response_size = sizeof(message); + libspdm_zero_mem(message, sizeof(message)); + status = libspdm_send_receive_data(spdm_context, &test_buffer->session_id, false, + &spdm_request, sizeof(spdm_request), + spdm_response, &spdm_response_size); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_END_SESSION_ACK, + SPDM_RESPONDER_TEST_CASE_END_SESSION_ACK_VERSION_MISMATCH_IN_DHE_SESSION, + COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "send/receive failure"); + continue; + } + + if (spdm_response_size >= sizeof(spdm_error_response_t)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_END_SESSION_ACK, + SPDM_RESPONDER_TEST_CASE_END_SESSION_ACK_VERSION_MISMATCH_IN_DHE_SESSION, 1, + test_result, "response size - %d", spdm_response_size); + if (test_result == COMMON_TEST_RESULT_FAIL) { + continue; + } + + if (spdm_response->header.request_response_code == SPDM_ERROR) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_END_SESSION_ACK, + SPDM_RESPONDER_TEST_CASE_END_SESSION_ACK_VERSION_MISMATCH_IN_DHE_SESSION, 2, + test_result, "response code - 0x%02x", spdm_response->header.request_response_code); + if (test_result == COMMON_TEST_RESULT_FAIL) { + continue; + } + + if (spdm_response->header.spdm_version == test_buffer->version) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_END_SESSION_ACK, + SPDM_RESPONDER_TEST_CASE_END_SESSION_ACK_VERSION_MISMATCH_IN_DHE_SESSION, 3, + test_result, "response version - 0x%02x", spdm_response->header.spdm_version); + if (test_result == COMMON_TEST_RESULT_FAIL) { + continue; + } + + if (spdm_response->header.param1 == SPDM_ERROR_CODE_VERSION_MISMATCH) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_END_SESSION_ACK, + SPDM_RESPONDER_TEST_CASE_END_SESSION_ACK_VERSION_MISMATCH_IN_DHE_SESSION, 4, + test_result, "response param1 - 0x%02x", spdm_response->header.param1); + + if (spdm_response->header.param2 == 0) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_END_SESSION_ACK, + SPDM_RESPONDER_TEST_CASE_END_SESSION_ACK_VERSION_MISMATCH_IN_DHE_SESSION, 5, + test_result, "response param2 - 0x%02x", spdm_response->header.param2); + } +} + +void spdm_test_case_end_session_ack_unexpected_request (void *test_context) +{ + spdm_test_context_t *spdm_test_context; + void *spdm_context; + libspdm_return_t status; + spdm_heartbeat_request_t spdm_request; + spdm_heartbeat_response_t *spdm_response; + size_t spdm_response_size; + uint8_t message[LIBSPDM_MAX_MESSAGE_BUFFER_SIZE]; + common_test_result_t test_result; + spdm_end_session_ack_test_buffer_t *test_buffer; + uint8_t req_slot_id_param; + + spdm_test_context = test_context; + spdm_context = spdm_test_context->spdm_context; + test_buffer = (void *)spdm_test_context->test_scratch_buffer; + LIBSPDM_ASSERT(spdm_test_context->test_scratch_buffer_size == + sizeof(spdm_end_session_ack_test_buffer_t)); + + status = libspdm_send_receive_key_exchange (spdm_context, + SPDM_KEY_EXCHANGE_REQUEST_NO_MEASUREMENT_SUMMARY_HASH, + 0, 0, &test_buffer->session_id, &test_buffer->heartbeat_period, + &req_slot_id_param, NULL); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_MEASUREMENTS, + SPDM_RESPONDER_TEST_CASE_MEASUREMENTS_UNEXPECTED_REQUEST_IN_DHE_SESSION_HS, + COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "key_exchange failure"); + return; + } + if (test_buffer->heartbeat_period == 0) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_MEASUREMENTS, + SPDM_RESPONDER_TEST_CASE_MEASUREMENTS_UNEXPECTED_REQUEST_IN_DHE_SESSION_HS, + COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "heartbeat_period is 0"); + return; + } + + libspdm_zero_mem(&spdm_request, sizeof(spdm_request)); + spdm_request.header.spdm_version = test_buffer->version; + spdm_request.header.request_response_code = SPDM_END_SESSION; + spdm_request.header.param1 = 0; + spdm_request.header.param2 = 0; + + spdm_response = (void *)message; + spdm_response_size = sizeof(message); + libspdm_zero_mem(message, sizeof(message)); + status = libspdm_send_receive_data(spdm_context, &test_buffer->session_id, false, + &spdm_request, sizeof(spdm_request), + spdm_response, &spdm_response_size); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_END_SESSION_ACK, + SPDM_RESPONDER_TEST_CASE_END_SESSION_ACK_UNEXPECTED_REQUEST_IN_DHE_SESSION_HS, + COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "send/receive failure"); + return; + } + + if (spdm_response_size >= sizeof(spdm_error_response_t)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_END_SESSION_ACK, + SPDM_RESPONDER_TEST_CASE_END_SESSION_ACK_UNEXPECTED_REQUEST_IN_DHE_SESSION_HS, 1, + test_result, "response size - %d", spdm_response_size); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.request_response_code == SPDM_ERROR) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_END_SESSION_ACK, + SPDM_RESPONDER_TEST_CASE_END_SESSION_ACK_UNEXPECTED_REQUEST_IN_DHE_SESSION_HS, 2, + test_result, "response code - 0x%02x", spdm_response->header.request_response_code); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.spdm_version == test_buffer->version) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_END_SESSION_ACK, + SPDM_RESPONDER_TEST_CASE_END_SESSION_ACK_UNEXPECTED_REQUEST_IN_DHE_SESSION_HS, 3, + test_result, "response version - 0x%02x", spdm_response->header.spdm_version); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.param1 == SPDM_ERROR_CODE_UNEXPECTED_REQUEST) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_END_SESSION_ACK, + SPDM_RESPONDER_TEST_CASE_END_SESSION_ACK_UNEXPECTED_REQUEST_IN_DHE_SESSION_HS, 4, + test_result, "response param1 - 0x%02x", spdm_response->header.param1); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.param2 == 0) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_END_SESSION_ACK, + SPDM_RESPONDER_TEST_CASE_END_SESSION_ACK_UNEXPECTED_REQUEST_IN_DHE_SESSION_HS, 5, + test_result, "response param2 - 0x%02x", spdm_response->header.param2); +} + +void spdm_test_case_end_session_ack_session_required (void *test_context) +{ + spdm_test_context_t *spdm_test_context; + void *spdm_context; + libspdm_return_t status; + spdm_heartbeat_request_t spdm_request; + spdm_heartbeat_response_t *spdm_response; + uint8_t message[LIBSPDM_MAX_MESSAGE_BUFFER_SIZE]; + size_t spdm_response_size; + common_test_result_t test_result; + spdm_end_session_ack_test_buffer_t *test_buffer; + + spdm_test_context = test_context; + spdm_context = spdm_test_context->spdm_context; + test_buffer = (void *)spdm_test_context->test_scratch_buffer; + LIBSPDM_ASSERT(spdm_test_context->test_scratch_buffer_size == + sizeof(spdm_end_session_ack_test_buffer_t)); + + libspdm_zero_mem(&spdm_request, sizeof(spdm_request)); + spdm_request.header.spdm_version = test_buffer->version; + spdm_request.header.request_response_code = SPDM_END_SESSION; + spdm_request.header.param1 = 0; + spdm_request.header.param2 = 0; + + spdm_response = (void *)message; + spdm_response_size = sizeof(message); + libspdm_zero_mem(message, sizeof(message)); + status = libspdm_send_receive_data(spdm_context, NULL, false, + &spdm_request, sizeof(spdm_request), + spdm_response, &spdm_response_size); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_END_SESSION_ACK, + SPDM_RESPONDER_TEST_CASE_END_SESSION_ACK_SESSION_REQUIRED, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "send/receive failure"); + return; + } + + if (spdm_response_size >= sizeof(spdm_error_response_t)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_END_SESSION_ACK, + SPDM_RESPONDER_TEST_CASE_END_SESSION_ACK_SESSION_REQUIRED, 1, + test_result, "response size - %d", spdm_response_size); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.request_response_code == SPDM_ERROR) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_END_SESSION_ACK, + SPDM_RESPONDER_TEST_CASE_END_SESSION_ACK_SESSION_REQUIRED, 2, + test_result, "response code - 0x%02x", spdm_response->header.request_response_code); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.spdm_version == test_buffer->version) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_END_SESSION_ACK, + SPDM_RESPONDER_TEST_CASE_END_SESSION_ACK_SESSION_REQUIRED, 3, + test_result, "response version - 0x%02x", spdm_response->header.spdm_version); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.param1 == SPDM_ERROR_CODE_SESSION_REQUIRED) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_END_SESSION_ACK, + SPDM_RESPONDER_TEST_CASE_END_SESSION_ACK_SESSION_REQUIRED, 4, + test_result, "response param1 - 0x%02x", spdm_response->header.param1); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } +} + +common_test_case_t m_spdm_test_group_end_session_ack[] = { + {SPDM_RESPONDER_TEST_CASE_END_SESSION_ACK_SUCCESS_11_IN_DHE_SESSION, + "spdm_test_case_end_session_ack_success_11_dhe", + spdm_test_case_end_session_ack_success_11_dhe, + spdm_test_case_end_session_ack_setup_version_any}, + {SPDM_RESPONDER_TEST_CASE_END_SESSION_ACK_VERSION_MISMATCH_IN_DHE_SESSION, + "spdm_test_case_end_session_ack_version_mismatch", + spdm_test_case_end_session_ack_version_mismatch, + spdm_test_case_end_session_ack_setup_version_any}, + {SPDM_RESPONDER_TEST_CASE_END_SESSION_ACK_UNEXPECTED_REQUEST_IN_DHE_SESSION_HS, + "spdm_test_case_end_session_ack_unexpected_request", + spdm_test_case_end_session_ack_unexpected_request, + spdm_test_case_end_session_ack_setup_version_any_session_cap}, + {SPDM_RESPONDER_TEST_CASE_END_SESSION_ACK_SESSION_REQUIRED, + "spdm_test_case_end_session_ack_session_required", + spdm_test_case_end_session_ack_session_required, + spdm_test_case_end_session_ack_setup_version_12}, + {COMMON_TEST_ID_END, NULL, NULL}, +}; diff --git a/library/spdm_responder_conformance_test_lib/spdm_responder_test_1_version.c b/library/spdm_responder_conformance_test_lib/spdm_responder_test_1_version.c new file mode 100644 index 0000000..97ec8bb --- /dev/null +++ b/library/spdm_responder_conformance_test_lib/spdm_responder_test_1_version.c @@ -0,0 +1,206 @@ +/** + * Copyright Notice: + * Copyright 2021 DMTF. All rights reserved. + * License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/spdm-emu/blob/main/LICENSE.md + **/ + +#include "spdm_responder_test.h" + +void spdm_test_case_version_success (void *test_context) +{ + spdm_test_context_t *spdm_test_context; + void *spdm_context; + libspdm_return_t status; + spdm_get_version_request_t spdm_request; + spdm_version_response_t *spdm_response; + uint8_t message[LIBSPDM_MAX_MESSAGE_BUFFER_SIZE]; + spdm_version_number_t *version_number_entry; + size_t spdm_response_size; + common_test_result_t test_result; + size_t index; + spdm_version_number_t version; + + spdm_test_context = test_context; + spdm_context = spdm_test_context->spdm_context; + + spdm_request.header.spdm_version = SPDM_MESSAGE_VERSION_10; + spdm_request.header.request_response_code = SPDM_GET_VERSION; + spdm_request.header.param1 = 0; + spdm_request.header.param2 = 0; + + spdm_response = (void *)message; + spdm_response_size = sizeof(message); + libspdm_zero_mem(message, sizeof(message)); + status = libspdm_send_receive_data(spdm_context, NULL, false, + &spdm_request, sizeof(spdm_request), + spdm_response, &spdm_response_size); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_VERSION, SPDM_RESPONDER_TEST_CASE_VERSION_SUCCESS_10, + COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "send/receive failure"); + return; + } + + if (spdm_response_size > sizeof(spdm_version_response_t)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_VERSION, SPDM_RESPONDER_TEST_CASE_VERSION_SUCCESS_10, 1, + test_result, "response size - %d", spdm_response_size); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.request_response_code == SPDM_VERSION) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_VERSION, SPDM_RESPONDER_TEST_CASE_VERSION_SUCCESS_10, 2, + test_result, "response code - 0x%02x", spdm_response->header.request_response_code); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.spdm_version == SPDM_MESSAGE_VERSION_10) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_VERSION, SPDM_RESPONDER_TEST_CASE_VERSION_SUCCESS_10, 3, + test_result, "response version - 0x%02x", spdm_response->header.spdm_version); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if ((spdm_response->version_number_entry_count > 0) && + (spdm_response->version_number_entry_count <= + (spdm_response_size - sizeof(spdm_version_response_t)) / sizeof(spdm_version_number_t))) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_VERSION, SPDM_RESPONDER_TEST_CASE_VERSION_SUCCESS_10, 4, + test_result, "response version_number_entry_count - 0x%02x", + spdm_response->version_number_entry_count); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + version_number_entry = (void *)(spdm_response + 1); + for (index = 0; index < spdm_response->version_number_entry_count; index++) { + version = version_number_entry[index]; + version = version >> SPDM_VERSION_NUMBER_SHIFT_BIT; + if (version == SPDM_MESSAGE_VERSION_10 || version == SPDM_MESSAGE_VERSION_11 || + version == SPDM_MESSAGE_VERSION_12) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_VERSION, SPDM_RESPONDER_TEST_CASE_VERSION_SUCCESS_10, 5, + test_result, "response version_number_entry - 0x%04x", version_number_entry[index]); + } +} + +void spdm_test_case_version_invalid_request (void *test_context) +{ + spdm_test_context_t *spdm_test_context; + void *spdm_context; + libspdm_return_t status; + spdm_get_version_request_t spdm_request; + spdm_error_response_t *spdm_response; + uint8_t message[LIBSPDM_MAX_MESSAGE_BUFFER_SIZE]; + size_t spdm_response_size; + common_test_result_t test_result; + + spdm_test_context = test_context; + spdm_context = spdm_test_context->spdm_context; + + spdm_request.header.spdm_version = SPDM_MESSAGE_VERSION_10 + 1; + spdm_request.header.request_response_code = SPDM_GET_VERSION; + spdm_request.header.param1 = 0; + spdm_request.header.param2 = 0; + + spdm_response = (void *)message; + spdm_response_size = sizeof(message); + libspdm_zero_mem(message, sizeof(message)); + status = libspdm_send_receive_data(spdm_context, NULL, false, + &spdm_request, sizeof(spdm_request), + spdm_response, &spdm_response_size); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_VERSION, SPDM_RESPONDER_TEST_CASE_VERSION_INVALID_REQUEST, + COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "send/receive failure"); + return; + } + + if (spdm_response_size >= sizeof(spdm_error_response_t)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_VERSION, SPDM_RESPONDER_TEST_CASE_VERSION_INVALID_REQUEST, 1, + test_result, "response size - %d", spdm_response_size); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.request_response_code == SPDM_ERROR) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_VERSION, SPDM_RESPONDER_TEST_CASE_VERSION_INVALID_REQUEST, 2, + test_result, "response code - 0x%02x", spdm_response->header.request_response_code); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.spdm_version == SPDM_MESSAGE_VERSION_10) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_VERSION, SPDM_RESPONDER_TEST_CASE_VERSION_INVALID_REQUEST, 3, + test_result, "response version - 0x%02x", spdm_response->header.spdm_version); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.param1 == SPDM_ERROR_CODE_INVALID_REQUEST) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_VERSION, SPDM_RESPONDER_TEST_CASE_VERSION_INVALID_REQUEST, 4, + test_result, "response param1 - 0x%02x", spdm_response->header.param1); + + if (spdm_response->header.param2 == 0) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_VERSION, SPDM_RESPONDER_TEST_CASE_VERSION_INVALID_REQUEST, 5, + test_result, "response param2 - 0x%02x", spdm_response->header.param2); +} + +common_test_case_t m_spdm_test_group_version[] = { + {SPDM_RESPONDER_TEST_CASE_VERSION_SUCCESS_10, "spdm_test_case_version_success", + spdm_test_case_version_success}, + {SPDM_RESPONDER_TEST_CASE_VERSION_INVALID_REQUEST, "spdm_test_case_version_invalid_request", + spdm_test_case_version_invalid_request}, + {COMMON_TEST_ID_END, NULL, NULL}, +}; diff --git a/library/spdm_responder_conformance_test_lib/spdm_responder_test_2_capabilities.c b/library/spdm_responder_conformance_test_lib/spdm_responder_test_2_capabilities.c new file mode 100644 index 0000000..e261606 --- /dev/null +++ b/library/spdm_responder_conformance_test_lib/spdm_responder_test_2_capabilities.c @@ -0,0 +1,1136 @@ +/** + * Copyright Notice: + * Copyright 2021 DMTF. All rights reserved. + * License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/spdm-emu/blob/main/LICENSE.md + **/ + +#include "spdm_responder_test.h" + +#pragma pack(1) +typedef struct { + uint8_t support_version_bitmask; + uint8_t version_number_entry_count; + spdm_version_number_t version_number_entry[LIBSPDM_MAX_VERSION_COUNT]; +} spdm_capabilities_test_buffer_t; +#pragma pack() + +bool spdm_test_case_capabilities_setup_version (void *test_context, + spdm_version_number_t spdm_version) +{ + spdm_test_context_t *spdm_test_context; + void *spdm_context; + libspdm_return_t status; + libspdm_data_parameter_t parameter; + spdm_capabilities_test_buffer_t *test_buffer; + + spdm_test_context = test_context; + spdm_context = spdm_test_context->spdm_context; + + libspdm_zero_mem(¶meter, sizeof(parameter)); + parameter.location = LIBSPDM_DATA_LOCATION_LOCAL; + libspdm_set_data(spdm_context, LIBSPDM_DATA_SPDM_VERSION, ¶meter, + &spdm_version, sizeof(spdm_version)); + + status = libspdm_get_version (spdm_context, NULL, NULL); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + return false; + } + + test_buffer = (void *)spdm_test_context->test_scratch_buffer; + LIBSPDM_ASSERT(sizeof(spdm_test_context->test_scratch_buffer) >= + sizeof(spdm_capabilities_test_buffer_t)); + libspdm_zero_mem(test_buffer, sizeof(spdm_capabilities_test_buffer_t)); + spdm_test_context->test_scratch_buffer_size = 0; + + return true; +} + +bool spdm_test_case_capabilities_setup_version_all (void *test_context) +{ + spdm_test_context_t *spdm_test_context; + void *spdm_context; + libspdm_return_t status; + size_t index; + uint8_t version; + spdm_capabilities_test_buffer_t *test_buffer; + + spdm_test_context = test_context; + spdm_context = spdm_test_context->spdm_context; + + test_buffer = (void *)spdm_test_context->test_scratch_buffer; + LIBSPDM_ASSERT(sizeof(spdm_test_context->test_scratch_buffer) >= + sizeof(spdm_capabilities_test_buffer_t)); + libspdm_zero_mem(test_buffer, sizeof(spdm_capabilities_test_buffer_t)); + spdm_test_context->test_scratch_buffer_size = sizeof(spdm_capabilities_test_buffer_t); + + test_buffer->version_number_entry_count = LIBSPDM_MAX_VERSION_COUNT; + status = libspdm_get_version (spdm_context, &test_buffer->version_number_entry_count, + test_buffer->version_number_entry); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + return false; + } + + test_buffer->support_version_bitmask = 0; + for (index = 0; index < test_buffer->version_number_entry_count; index++) { + version = test_buffer->version_number_entry[index] >> SPDM_VERSION_NUMBER_SHIFT_BIT; + if (version == SPDM_MESSAGE_VERSION_10) { + test_buffer->support_version_bitmask |= SPDM_TEST_VERSION_MASK_V10; + } else if (version == SPDM_MESSAGE_VERSION_11) { + test_buffer->support_version_bitmask |= SPDM_TEST_VERSION_MASK_V11; + } else if (version == SPDM_MESSAGE_VERSION_12) { + test_buffer->support_version_bitmask |= SPDM_TEST_VERSION_MASK_V12; + } + } + + spdm_test_context->test_scratch_buffer_size = offsetof(spdm_capabilities_test_buffer_t, + version_number_entry) + + sizeof(spdm_version_number_t) * + test_buffer->version_number_entry_count; + + return true; +} + +bool spdm_test_case_capabilities_setup_version_10 (void *test_context) +{ + return spdm_test_case_capabilities_setup_version (test_context, + SPDM_MESSAGE_VERSION_10 << + SPDM_VERSION_NUMBER_SHIFT_BIT); +} + +bool spdm_test_case_capabilities_setup_version_11 (void *test_context) +{ + return spdm_test_case_capabilities_setup_version (test_context, + SPDM_MESSAGE_VERSION_11 << + SPDM_VERSION_NUMBER_SHIFT_BIT); +} + +bool spdm_test_case_capabilities_setup_version_12 (void *test_context) +{ + return spdm_test_case_capabilities_setup_version (test_context, + SPDM_MESSAGE_VERSION_12 << + SPDM_VERSION_NUMBER_SHIFT_BIT); +} + +void spdm_test_case_capabilities_success_10 (void *test_context) +{ + spdm_test_context_t *spdm_test_context; + void *spdm_context; + libspdm_return_t status; + spdm_get_capabilities_request_t spdm_request; + size_t spdm_request_size; + spdm_capabilities_response_t *spdm_response; + uint8_t message[LIBSPDM_MAX_MESSAGE_BUFFER_SIZE]; + size_t spdm_response_size; + common_test_result_t test_result; + uint32_t flags; + + spdm_test_context = test_context; + spdm_context = spdm_test_context->spdm_context; + LIBSPDM_ASSERT (spdm_test_context->test_scratch_buffer_size == 0); + + libspdm_zero_mem(&spdm_request, sizeof(spdm_request)); + spdm_request.header.spdm_version = SPDM_MESSAGE_VERSION_10; + spdm_request_size = sizeof(spdm_request.header); + spdm_request.header.request_response_code = SPDM_GET_CAPABILITIES; + spdm_request.header.param1 = 0; + spdm_request.header.param2 = 0; + + spdm_response = (void *)message; + spdm_response_size = sizeof(message); + libspdm_zero_mem(message, sizeof(message)); + status = libspdm_send_receive_data(spdm_context, NULL, false, + &spdm_request, spdm_request_size, + spdm_response, &spdm_response_size); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CAPABILITIES, + SPDM_RESPONDER_TEST_CASE_CAPABILITIES_SUCCESS_10, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "send/receive failure"); + return; + } + + if (spdm_response_size >= sizeof(spdm_capabilities_response_t) - + sizeof(spdm_response->data_transfer_size) - + sizeof(spdm_response->max_spdm_msg_size)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CAPABILITIES, SPDM_RESPONDER_TEST_CASE_CAPABILITIES_SUCCESS_10, 1, + test_result, "response size - %d", spdm_response_size); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.request_response_code == SPDM_CAPABILITIES) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CAPABILITIES, SPDM_RESPONDER_TEST_CASE_CAPABILITIES_SUCCESS_10, 2, + test_result, "response code - 0x%02x", spdm_response->header.request_response_code); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.spdm_version == SPDM_MESSAGE_VERSION_10) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CAPABILITIES, SPDM_RESPONDER_TEST_CASE_CAPABILITIES_SUCCESS_10, 3, + test_result, "response version - 0x%02x", spdm_response->header.spdm_version); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + flags = spdm_response->flags; + if ((flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP) != + SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CAPABILITIES, SPDM_RESPONDER_TEST_CASE_CAPABILITIES_SUCCESS_10, 4, + test_result, "response flags - 0x%08x", spdm_response->flags); +} + +void spdm_test_case_capabilities_version_mismatch (void *test_context) +{ + spdm_test_context_t *spdm_test_context; + void *spdm_context; + libspdm_return_t status; + spdm_get_capabilities_request_t spdm_request; + size_t spdm_request_size; + spdm_error_response_t *spdm_response; + uint8_t message[LIBSPDM_MAX_MESSAGE_BUFFER_SIZE]; + size_t spdm_response_size; + common_test_result_t test_result; + spdm_capabilities_test_buffer_t *test_buffer; + uint8_t mismatched_version[] = { + SPDM_MESSAGE_VERSION_10 - 1, + SPDM_MESSAGE_VERSION_12 + 1, + }; + size_t index; + + spdm_test_context = test_context; + spdm_context = spdm_test_context->spdm_context; + test_buffer = (void *)spdm_test_context->test_scratch_buffer; + LIBSPDM_ASSERT (spdm_test_context->test_scratch_buffer_size == + offsetof(spdm_capabilities_test_buffer_t, version_number_entry) + + sizeof(spdm_version_number_t) * test_buffer->version_number_entry_count); + + mismatched_version[0] = + (uint8_t)((test_buffer->version_number_entry[test_buffer->version_number_entry_count - 1] >> SPDM_VERSION_NUMBER_SHIFT_BIT) - + 1); + mismatched_version[1] = (uint8_t)((test_buffer->version_number_entry[0] >> SPDM_VERSION_NUMBER_SHIFT_BIT) + 1); + + for (index = 0; index < LIBSPDM_ARRAY_SIZE(mismatched_version); index++) { + common_test_record_test_message ("test mismatched_version - 0x%02x\n", + mismatched_version[index]); + libspdm_zero_mem(&spdm_request, sizeof(spdm_request)); + spdm_request.header.spdm_version = mismatched_version[index]; + spdm_request_size = sizeof(spdm_request.header); + spdm_request.header.request_response_code = SPDM_GET_CAPABILITIES; + spdm_request.header.param1 = 0; + spdm_request.header.param2 = 0; + + spdm_response = (void *)message; + spdm_response_size = sizeof(message); + libspdm_zero_mem(message, sizeof(message)); + status = libspdm_send_receive_data(spdm_context, NULL, false, + &spdm_request, spdm_request_size, + spdm_response, &spdm_response_size); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CAPABILITIES, + SPDM_RESPONDER_TEST_CASE_CAPABILITIES_VERSION_MISMATCH, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "send/receive failure"); + continue; + } + + if (spdm_response_size >= sizeof(spdm_error_response_t)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CAPABILITIES, + SPDM_RESPONDER_TEST_CASE_CAPABILITIES_VERSION_MISMATCH, 1, + test_result, "response size - %d", spdm_response_size); + if (test_result == COMMON_TEST_RESULT_FAIL) { + continue; + } + + if (spdm_response->header.request_response_code == SPDM_ERROR) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CAPABILITIES, + SPDM_RESPONDER_TEST_CASE_CAPABILITIES_VERSION_MISMATCH, 2, + test_result, "response code - 0x%02x", spdm_response->header.request_response_code); + if (test_result == COMMON_TEST_RESULT_FAIL) { + continue; + } + + if (spdm_response->header.spdm_version == SPDM_MESSAGE_VERSION_10) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CAPABILITIES, + SPDM_RESPONDER_TEST_CASE_CAPABILITIES_VERSION_MISMATCH, 3, + test_result, "response version - 0x%02x", spdm_response->header.spdm_version); + if (test_result == COMMON_TEST_RESULT_FAIL) { + continue; + } + + if (spdm_response->header.param1 == SPDM_ERROR_CODE_VERSION_MISMATCH) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CAPABILITIES, + SPDM_RESPONDER_TEST_CASE_CAPABILITIES_VERSION_MISMATCH, 4, + test_result, "response param1 - 0x%02x", spdm_response->header.param1); + + if (spdm_response->header.param2 == 0) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CAPABILITIES, + SPDM_RESPONDER_TEST_CASE_CAPABILITIES_VERSION_MISMATCH, 5, + test_result, "response param2 - 0x%02x", spdm_response->header.param2); + } +} + +void spdm_test_case_capabilities_success_11 (void *test_context) +{ + spdm_test_context_t *spdm_test_context; + void *spdm_context; + libspdm_return_t status; + spdm_get_capabilities_request_t spdm_request; + size_t spdm_request_size; + spdm_capabilities_response_t *spdm_response; + uint8_t message[LIBSPDM_MAX_MESSAGE_BUFFER_SIZE]; + size_t spdm_response_size; + common_test_result_t test_result; + uint32_t flags; + + spdm_test_context = test_context; + spdm_context = spdm_test_context->spdm_context; + LIBSPDM_ASSERT (spdm_test_context->test_scratch_buffer_size == 0); + + libspdm_zero_mem(&spdm_request, sizeof(spdm_request)); + spdm_request.header.spdm_version = SPDM_MESSAGE_VERSION_11; + spdm_request_size = offsetof(spdm_get_capabilities_request_t, data_transfer_size); + spdm_request.header.request_response_code = SPDM_GET_CAPABILITIES; + spdm_request.header.param1 = 0; + spdm_request.header.param2 = 0; + spdm_request.reserved = 0; + spdm_request.ct_exponent = 0; + spdm_request.reserved2 = 0; + spdm_request.flags = SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CERT_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHAL_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_ENCRYPT_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MAC_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MUT_AUTH_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_KEY_EX_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_ENCAP_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_HBEAT_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_KEY_UPD_CAP; + + spdm_response = (void *)message; + spdm_response_size = sizeof(message); + libspdm_zero_mem(message, sizeof(message)); + status = libspdm_send_receive_data(spdm_context, NULL, false, + &spdm_request, spdm_request_size, + spdm_response, &spdm_response_size); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CAPABILITIES, + SPDM_RESPONDER_TEST_CASE_CAPABILITIES_SUCCESS_11, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "send/receive failure"); + return; + } + + if (spdm_response_size >= sizeof(spdm_capabilities_response_t) - + sizeof(spdm_response->data_transfer_size) - + sizeof(spdm_response->max_spdm_msg_size)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CAPABILITIES, SPDM_RESPONDER_TEST_CASE_CAPABILITIES_SUCCESS_11, 1, + test_result, "response size - %d", spdm_response_size); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.request_response_code == SPDM_CAPABILITIES) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CAPABILITIES, SPDM_RESPONDER_TEST_CASE_CAPABILITIES_SUCCESS_11, 2, + test_result, "response code - 0x%02x", spdm_response->header.request_response_code); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.spdm_version == SPDM_MESSAGE_VERSION_11) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CAPABILITIES, SPDM_RESPONDER_TEST_CASE_CAPABILITIES_SUCCESS_11, 3, + test_result, "response version - 0x%02x", spdm_response->header.spdm_version); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + flags = spdm_response->flags; + if ((flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP) != + SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CAPABILITIES, SPDM_RESPONDER_TEST_CASE_CAPABILITIES_SUCCESS_11, 4, + test_result, "response flags - 0x%08x", spdm_response->flags); + + if ((flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_ENCRYPT_CAP) != 0) { + if (((flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_KEY_EX_CAP) != 0) || + ((flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_PSK_CAP) != 0)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CAPABILITIES, + SPDM_RESPONDER_TEST_CASE_CAPABILITIES_SUCCESS_11, 5, + test_result, "response flags - 0x%08x", spdm_response->flags); + } + + if ((flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MAC_CAP) != 0) { + if (((flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_KEY_EX_CAP) != 0) || + ((flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_PSK_CAP) != 0)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CAPABILITIES, + SPDM_RESPONDER_TEST_CASE_CAPABILITIES_SUCCESS_11, 6, + test_result, "response flags - 0x%08x", spdm_response->flags); + } + + if ((flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_KEY_EX_CAP) != 0) { + if (((flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_ENCRYPT_CAP) != 0) || + ((flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MAC_CAP) != 0)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CAPABILITIES, + SPDM_RESPONDER_TEST_CASE_CAPABILITIES_SUCCESS_11, 7, + test_result, "response flags - 0x%08x", spdm_response->flags); + } + + if ((flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_PSK_CAP) != + SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_PSK_CAP) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CAPABILITIES, SPDM_RESPONDER_TEST_CASE_CAPABILITIES_SUCCESS_11, 8, + test_result, "response flags - 0x%08x", spdm_response->flags); + + if ((flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_PSK_CAP) != 0) { + if (((flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_ENCRYPT_CAP) != 0) || + ((flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MAC_CAP) != 0)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CAPABILITIES, + SPDM_RESPONDER_TEST_CASE_CAPABILITIES_SUCCESS_11, 9, + test_result, "response flags - 0x%08x", spdm_response->flags); + } + + if ((flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MUT_AUTH_CAP) != 0) { + if ((flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_ENCAP_CAP) != 0) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CAPABILITIES, + SPDM_RESPONDER_TEST_CASE_CAPABILITIES_SUCCESS_11, 10, + test_result, "response flags - 0x%08x", spdm_response->flags); + } + + if ((flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_HANDSHAKE_IN_THE_CLEAR_CAP) != 0) { + if ((flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_KEY_EX_CAP) != 0) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CAPABILITIES, + SPDM_RESPONDER_TEST_CASE_CAPABILITIES_SUCCESS_11, 11, + test_result, "response flags - 0x%08x", spdm_response->flags); + } + + if ((flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_PUB_KEY_ID_CAP) != 0) { + if ((flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP) == 0) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CAPABILITIES, + SPDM_RESPONDER_TEST_CASE_CAPABILITIES_SUCCESS_11, 12, + test_result, "response flags - 0x%08x", spdm_response->flags); + } +} + +void spdm_test_case_capabilities_invalid_request (void *test_context) +{ + spdm_test_context_t *spdm_test_context; + void *spdm_context; + libspdm_return_t status; + spdm_get_capabilities_request_t spdm_request; + spdm_get_capabilities_request_t spdm_request_new; + size_t spdm_request_size; + spdm_error_response_t *spdm_response; + uint8_t message[LIBSPDM_MAX_MESSAGE_BUFFER_SIZE]; + size_t spdm_response_size; + common_test_result_t test_result; + spdm_capabilities_test_buffer_t *test_buffer; + uint8_t version; + size_t index; + uint32_t invalid_flags_v11[] = { + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CERT_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHAL_CAP | + /* SPDM_GET_CAPABILITIES_REQUEST_FLAGS_ENCRYPT_CAP | + * SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MAC_CAP |*/ + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MUT_AUTH_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_KEY_EX_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_ENCAP_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_HBEAT_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_KEY_UPD_CAP, + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CERT_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHAL_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_ENCRYPT_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MAC_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MUT_AUTH_CAP | + /* SPDM_GET_CAPABILITIES_REQUEST_FLAGS_KEY_EX_CAP | */ + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_ENCAP_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_HBEAT_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_KEY_UPD_CAP, + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CERT_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHAL_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_ENCRYPT_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MAC_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MUT_AUTH_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_KEY_EX_CAP | + /* SPDM_GET_CAPABILITIES_REQUEST_FLAGS_ENCAP_CAP | */ + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_HBEAT_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_KEY_UPD_CAP, + }; + uint32_t invalid_transport_size_v12[] = { + SPDM_MIN_DATA_TRANSFER_SIZE_VERSION_12 - 1, + LIBSPDM_MAX_SPDM_MSG_SIZE + 1, + }; + + spdm_test_context = test_context; + spdm_context = spdm_test_context->spdm_context; + test_buffer = (void *)spdm_test_context->test_scratch_buffer; + LIBSPDM_ASSERT (spdm_test_context->test_scratch_buffer_size == + offsetof(spdm_capabilities_test_buffer_t, version_number_entry) + + sizeof(spdm_version_number_t) * test_buffer->version_number_entry_count); + + if ((test_buffer->support_version_bitmask & SPDM_TEST_VERSION_MASK_V12) != 0) { + version = SPDM_MESSAGE_VERSION_12; + } else if ((test_buffer->support_version_bitmask & SPDM_TEST_VERSION_MASK_V11) != 0) { + version = SPDM_MESSAGE_VERSION_11; + } else { + version = SPDM_MESSAGE_VERSION_10; + } + + libspdm_zero_mem(&spdm_request, sizeof(spdm_request)); + spdm_request.header.spdm_version = version; + spdm_request.header.request_response_code = SPDM_GET_CAPABILITIES; + spdm_request.header.param1 = 0; + spdm_request.header.param2 = 0; + spdm_request.reserved = 0; + spdm_request.ct_exponent = 0; + spdm_request.reserved2 = 0; + spdm_request.flags = SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CERT_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHAL_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_ENCRYPT_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MAC_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MUT_AUTH_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_KEY_EX_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_ENCAP_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_HBEAT_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_KEY_UPD_CAP; + spdm_request.data_transfer_size = LIBSPDM_DATA_TRANSFER_SIZE; + spdm_request.max_spdm_msg_size = LIBSPDM_MAX_SPDM_MSG_SIZE; + + for (index = 0; + index < + LIBSPDM_ARRAY_SIZE(invalid_flags_v11) + LIBSPDM_ARRAY_SIZE(invalid_transport_size_v12); + index++) { + libspdm_copy_mem (&spdm_request_new, sizeof(spdm_request_new), &spdm_request, + sizeof(spdm_request)); + + if (index < LIBSPDM_ARRAY_SIZE(invalid_flags_v11)) { + if ((test_buffer->support_version_bitmask & + (SPDM_TEST_VERSION_MASK_V11 | SPDM_TEST_VERSION_MASK_V12)) != 0) { + common_test_record_test_message ("test v11 flags - 0x%08x\n", + invalid_flags_v11[index]); + if ((test_buffer->support_version_bitmask & SPDM_TEST_VERSION_MASK_V12) != 0) { + version = SPDM_MESSAGE_VERSION_12; + spdm_request_size = sizeof(spdm_request); + } else { + version = SPDM_MESSAGE_VERSION_11; + spdm_request_size = + offsetof(spdm_get_capabilities_request_t, data_transfer_size); + } + spdm_request_new.header.spdm_version = version; + spdm_request_new.flags = invalid_flags_v11[index]; + } else { + continue; + } + } else { + if ((test_buffer->support_version_bitmask & SPDM_TEST_VERSION_MASK_V12) != 0) { + common_test_record_test_message ("test v12 transfer_size - 0x%08x\n", + invalid_transport_size_v12[index - LIBSPDM_ARRAY_SIZE(invalid_flags_v11)]); + version = SPDM_MESSAGE_VERSION_12; + spdm_request_size = sizeof(spdm_request); + spdm_request_new.header.spdm_version = version; + spdm_request_new.data_transfer_size = invalid_transport_size_v12[index - LIBSPDM_ARRAY_SIZE(invalid_flags_v11)]; + } else { + continue; + } + } + + spdm_response = (void *)message; + spdm_response_size = sizeof(message); + libspdm_zero_mem(message, sizeof(message)); + status = libspdm_send_receive_data(spdm_context, NULL, false, + &spdm_request_new, spdm_request_size, + spdm_response, &spdm_response_size); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CAPABILITIES, + SPDM_RESPONDER_TEST_CASE_CAPABILITIES_INVALID_REQUEST, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "send/receive failure"); + continue; + } + + if (spdm_response_size >= sizeof(spdm_error_response_t)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CAPABILITIES, + SPDM_RESPONDER_TEST_CASE_CAPABILITIES_INVALID_REQUEST, 1, + test_result, "response size - %d", spdm_response_size); + if (test_result == COMMON_TEST_RESULT_FAIL) { + continue; + } + + if (spdm_response->header.request_response_code == SPDM_ERROR) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CAPABILITIES, + SPDM_RESPONDER_TEST_CASE_CAPABILITIES_INVALID_REQUEST, 2, + test_result, "response code - 0x%02x", spdm_response->header.request_response_code); + if (test_result == COMMON_TEST_RESULT_FAIL) { + continue; + } + + if (spdm_response->header.spdm_version == version) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CAPABILITIES, + SPDM_RESPONDER_TEST_CASE_CAPABILITIES_INVALID_REQUEST, 3, + test_result, "response version - 0x%02x", spdm_response->header.spdm_version); + if (test_result == COMMON_TEST_RESULT_FAIL) { + continue; + } + + if (spdm_response->header.param1 == SPDM_ERROR_CODE_INVALID_REQUEST) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CAPABILITIES, + SPDM_RESPONDER_TEST_CASE_CAPABILITIES_INVALID_REQUEST, 4, + test_result, "response param1 - 0x%02x", spdm_response->header.param1); + + if (spdm_response->header.param2 == 0) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CAPABILITIES, + SPDM_RESPONDER_TEST_CASE_CAPABILITIES_INVALID_REQUEST, 5, + test_result, "response param2 - 0x%02x", spdm_response->header.param2); + } +} + +void spdm_test_case_capabilities_success_12 (void *test_context) +{ + spdm_test_context_t *spdm_test_context; + void *spdm_context; + libspdm_return_t status; + spdm_get_capabilities_request_t spdm_request; + size_t spdm_request_size; + spdm_capabilities_response_t *spdm_response; + uint8_t message[LIBSPDM_MAX_MESSAGE_BUFFER_SIZE]; + size_t spdm_response_size; + common_test_result_t test_result; + uint32_t flags; + + spdm_test_context = test_context; + spdm_context = spdm_test_context->spdm_context; + LIBSPDM_ASSERT (spdm_test_context->test_scratch_buffer_size == 0); + + libspdm_zero_mem(&spdm_request, sizeof(spdm_request)); + spdm_request.header.spdm_version = SPDM_MESSAGE_VERSION_12; + spdm_request_size = sizeof(spdm_request); + spdm_request.header.request_response_code = SPDM_GET_CAPABILITIES; + spdm_request.header.param1 = 0; + spdm_request.header.param2 = 0; + spdm_request.reserved = 0; + spdm_request.ct_exponent = 0; + spdm_request.reserved2 = 0; + spdm_request.flags = SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CERT_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHAL_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_ENCRYPT_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MAC_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MUT_AUTH_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_KEY_EX_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_ENCAP_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_HBEAT_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_KEY_UPD_CAP; + spdm_request.data_transfer_size = LIBSPDM_DATA_TRANSFER_SIZE; + spdm_request.max_spdm_msg_size = LIBSPDM_MAX_SPDM_MSG_SIZE; + + spdm_response = (void *)message; + spdm_response_size = sizeof(message); + libspdm_zero_mem(message, sizeof(message)); + status = libspdm_send_receive_data(spdm_context, NULL, false, + &spdm_request, spdm_request_size, + spdm_response, &spdm_response_size); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CAPABILITIES, + SPDM_RESPONDER_TEST_CASE_CAPABILITIES_SUCCESS_12, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "send/receive failure"); + return; + } + + if (spdm_response_size >= sizeof(spdm_capabilities_response_t)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CAPABILITIES, SPDM_RESPONDER_TEST_CASE_CAPABILITIES_SUCCESS_12, 1, + test_result, "response size - %d", spdm_response_size); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.request_response_code == SPDM_CAPABILITIES) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CAPABILITIES, SPDM_RESPONDER_TEST_CASE_CAPABILITIES_SUCCESS_12, 2, + test_result, "response code - 0x%02x", spdm_response->header.request_response_code); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.spdm_version == SPDM_MESSAGE_VERSION_12) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CAPABILITIES, SPDM_RESPONDER_TEST_CASE_CAPABILITIES_SUCCESS_12, 3, + test_result, "response version - 0x%02x", spdm_response->header.spdm_version); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + flags = spdm_response->flags; + if ((flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP) != + SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CAPABILITIES, SPDM_RESPONDER_TEST_CASE_CAPABILITIES_SUCCESS_12, 4, + test_result, "response flags - 0x%08x", spdm_response->flags); + + if ((flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_ENCRYPT_CAP) != 0) { + if (((flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_KEY_EX_CAP) != 0) || + ((flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_PSK_CAP) != 0)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CAPABILITIES, + SPDM_RESPONDER_TEST_CASE_CAPABILITIES_SUCCESS_12, 5, + test_result, "response flags - 0x%08x", spdm_response->flags); + } + + if ((flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MAC_CAP) != 0) { + if (((flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_KEY_EX_CAP) != 0) || + ((flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_PSK_CAP) != 0)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CAPABILITIES, + SPDM_RESPONDER_TEST_CASE_CAPABILITIES_SUCCESS_12, 6, + test_result, "response flags - 0x%08x", spdm_response->flags); + } + + if ((flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_KEY_EX_CAP) != 0) { + if (((flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_ENCRYPT_CAP) != 0) || + ((flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MAC_CAP) != 0)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CAPABILITIES, + SPDM_RESPONDER_TEST_CASE_CAPABILITIES_SUCCESS_12, 7, + test_result, "response flags - 0x%08x", spdm_response->flags); + } + + if ((flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_PSK_CAP) != + SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_PSK_CAP) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CAPABILITIES, SPDM_RESPONDER_TEST_CASE_CAPABILITIES_SUCCESS_12, 8, + test_result, "response flags - 0x%08x", spdm_response->flags); + + if ((flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_PSK_CAP) != 0) { + if (((flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_ENCRYPT_CAP) != 0) || + ((flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MAC_CAP) != 0)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CAPABILITIES, + SPDM_RESPONDER_TEST_CASE_CAPABILITIES_SUCCESS_12, 9, + test_result, "response flags - 0x%08x", spdm_response->flags); + } + + if ((flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MUT_AUTH_CAP) != 0) { + if ((flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_ENCAP_CAP) != 0) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CAPABILITIES, + SPDM_RESPONDER_TEST_CASE_CAPABILITIES_SUCCESS_12, 10, + test_result, "response flags - 0x%08x", spdm_response->flags); + } + + if ((flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_HANDSHAKE_IN_THE_CLEAR_CAP) != 0) { + if ((flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_KEY_EX_CAP) != 0) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CAPABILITIES, + SPDM_RESPONDER_TEST_CASE_CAPABILITIES_SUCCESS_12, 11, + test_result, "response flags - 0x%08x", spdm_response->flags); + } + + if ((flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_PUB_KEY_ID_CAP) != 0) { + if ((flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP) == 0) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CAPABILITIES, + SPDM_RESPONDER_TEST_CASE_CAPABILITIES_SUCCESS_12, 12, + test_result, "response flags - 0x%08x", spdm_response->flags); + } + + if (spdm_response->data_transfer_size >= SPDM_MIN_DATA_TRANSFER_SIZE_VERSION_12) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CAPABILITIES, SPDM_RESPONDER_TEST_CASE_CAPABILITIES_SUCCESS_12, + 13, + test_result, "response data_transfer_size - 0x%08x", spdm_response->data_transfer_size); + + if (spdm_response->max_spdm_msg_size >= spdm_response->data_transfer_size) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CAPABILITIES, SPDM_RESPONDER_TEST_CASE_CAPABILITIES_SUCCESS_12, + 14, + test_result, "response max_spdm_msg_size - 0x%08x, data_transfer_size - 0x%08x", + spdm_response->max_spdm_msg_size, spdm_response->data_transfer_size); +} + +void spdm_test_case_capabilities_unexpected_non_identical (void *test_context) +{ + spdm_test_context_t *spdm_test_context; + void *spdm_context; + libspdm_return_t status; + spdm_get_capabilities_request_t spdm_request; + spdm_get_capabilities_request_t spdm_request_new; + size_t spdm_request_size; + spdm_capabilities_response_t *spdm_response; + uint8_t message[LIBSPDM_MAX_MESSAGE_BUFFER_SIZE]; + size_t spdm_response_size; + common_test_result_t test_result; + spdm_capabilities_test_buffer_t *test_buffer; + uint8_t version; + size_t index; + + spdm_test_context = test_context; + spdm_context = spdm_test_context->spdm_context; + test_buffer = (void *)spdm_test_context->test_scratch_buffer; + LIBSPDM_ASSERT (spdm_test_context->test_scratch_buffer_size == + offsetof(spdm_capabilities_test_buffer_t, version_number_entry) + + sizeof(spdm_version_number_t) * test_buffer->version_number_entry_count); + + if ((test_buffer->support_version_bitmask & SPDM_TEST_VERSION_MASK_V12) != 0) { + version = SPDM_MESSAGE_VERSION_12; + spdm_request_size = sizeof(spdm_request); + } else if ((test_buffer->support_version_bitmask & SPDM_TEST_VERSION_MASK_V11) != 0) { + version = SPDM_MESSAGE_VERSION_11; + spdm_request_size = offsetof(spdm_get_capabilities_request_t, data_transfer_size); + } else { + version = SPDM_MESSAGE_VERSION_10; + spdm_request_size = sizeof(spdm_request.header); + } + + libspdm_zero_mem(&spdm_request, sizeof(spdm_request)); + spdm_request.header.spdm_version = version; + spdm_request.header.request_response_code = SPDM_GET_CAPABILITIES; + spdm_request.header.param1 = 0; + spdm_request.header.param2 = 0; + spdm_request.reserved = 0; + spdm_request.ct_exponent = 0; + spdm_request.reserved2 = 0; + spdm_request.flags = SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CERT_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHAL_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_ENCRYPT_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MAC_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MUT_AUTH_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_KEY_EX_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_ENCAP_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_HBEAT_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_KEY_UPD_CAP; + spdm_request.data_transfer_size = LIBSPDM_DATA_TRANSFER_SIZE; + spdm_request.max_spdm_msg_size = LIBSPDM_MAX_SPDM_MSG_SIZE; + + spdm_response = (void *)message; + spdm_response_size = sizeof(message); + libspdm_zero_mem(message, sizeof(message)); + status = libspdm_send_receive_data(spdm_context, NULL, false, + &spdm_request, spdm_request_size, + spdm_response, &spdm_response_size); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CAPABILITIES, + SPDM_RESPONDER_TEST_CASE_CAPABILITIES_UNEXPECTED_REQUEST_NON_IDENTICAL, + COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "First send/receive failure"); + return; + } + if (spdm_response->header.request_response_code != SPDM_CAPABILITIES) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CAPABILITIES, + SPDM_RESPONDER_TEST_CASE_CAPABILITIES_UNEXPECTED_REQUEST_NON_IDENTICAL, + COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "First GET_CAPABILITIES failure"); + return; + } + + for (index = 0; index < 3; index++) { + libspdm_copy_mem (&spdm_request_new, sizeof(spdm_request_new), &spdm_request, + sizeof(spdm_request)); + + switch (index) { + case 0: + spdm_request_new.header.param2 = 1; + common_test_record_test_message ("test param2 - 1\n"); + break; + case 1: + if (version < SPDM_MESSAGE_VERSION_11) { + continue; + } + spdm_request_new.ct_exponent += 1; + spdm_request_new.flags &= ~SPDM_GET_CAPABILITIES_REQUEST_FLAGS_HBEAT_CAP; + common_test_record_test_message ("test ct_exponent - 1, flags - 0x%08x\n", + spdm_request_new.flags); + break; + case 2: + if (version < SPDM_MESSAGE_VERSION_12) { + continue; + } + spdm_request_new.data_transfer_size += 1; + spdm_request_new.max_spdm_msg_size += 1; + common_test_record_test_message ( + "test data_transfer_size - 0x%08x, max_spdm_msg_size - 0x%08x\n", + spdm_request_new.data_transfer_size, + spdm_request_new.max_spdm_msg_size); + break; + default: + break; + } + + spdm_response = (void *)message; + spdm_response_size = sizeof(message); + libspdm_zero_mem(message, sizeof(message)); + status = libspdm_send_receive_data(spdm_context, NULL, false, + &spdm_request, spdm_request_size, + spdm_response, &spdm_response_size); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CAPABILITIES, + SPDM_RESPONDER_TEST_CASE_CAPABILITIES_UNEXPECTED_REQUEST_NON_IDENTICAL, + COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "Second send/receive failure"); + return; + } + + if (spdm_response_size >= sizeof(spdm_error_response_t)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CAPABILITIES, + SPDM_RESPONDER_TEST_CASE_CAPABILITIES_UNEXPECTED_REQUEST_NON_IDENTICAL, 1, + test_result, "response size - %d", spdm_response_size); + if (test_result == COMMON_TEST_RESULT_FAIL) { + continue; + } + + if (spdm_response->header.request_response_code == SPDM_ERROR) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CAPABILITIES, + SPDM_RESPONDER_TEST_CASE_CAPABILITIES_UNEXPECTED_REQUEST_NON_IDENTICAL, 2, + test_result, "response code - 0x%02x", spdm_response->header.request_response_code); + if (test_result == COMMON_TEST_RESULT_FAIL) { + continue; + } + + if (spdm_response->header.spdm_version == version) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CAPABILITIES, + SPDM_RESPONDER_TEST_CASE_CAPABILITIES_UNEXPECTED_REQUEST_NON_IDENTICAL, 3, + test_result, "response version - 0x%02x", spdm_response->header.spdm_version); + if (test_result == COMMON_TEST_RESULT_FAIL) { + continue; + } + + if (spdm_response->header.param1 == SPDM_ERROR_CODE_UNEXPECTED_REQUEST) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CAPABILITIES, + SPDM_RESPONDER_TEST_CASE_CAPABILITIES_UNEXPECTED_REQUEST_NON_IDENTICAL, 4, + test_result, "response param1 - 0x%02x", spdm_response->header.param1); + + if (spdm_response->header.param2 == 0) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CAPABILITIES, + SPDM_RESPONDER_TEST_CASE_CAPABILITIES_UNEXPECTED_REQUEST_NON_IDENTICAL, 5, + test_result, "response param2 - 0x%02x", spdm_response->header.param2); + } +} + +common_test_case_t m_spdm_test_group_capabilities[] = { + {SPDM_RESPONDER_TEST_CASE_CAPABILITIES_SUCCESS_10, "spdm_test_case_capabilities_success_10", + spdm_test_case_capabilities_success_10, spdm_test_case_capabilities_setup_version_10}, + {SPDM_RESPONDER_TEST_CASE_CAPABILITIES_VERSION_MISMATCH, + "spdm_test_case_capabilities_version_mismatch", + spdm_test_case_capabilities_version_mismatch, + spdm_test_case_capabilities_setup_version_all}, + {SPDM_RESPONDER_TEST_CASE_CAPABILITIES_SUCCESS_11, "spdm_test_case_capabilities_success_11", + spdm_test_case_capabilities_success_11, spdm_test_case_capabilities_setup_version_11}, + {SPDM_RESPONDER_TEST_CASE_CAPABILITIES_INVALID_REQUEST, + "spdm_test_case_capabilities_invalid_request", spdm_test_case_capabilities_invalid_request, + spdm_test_case_capabilities_setup_version_all}, + {SPDM_RESPONDER_TEST_CASE_CAPABILITIES_SUCCESS_12, "spdm_test_case_capabilities_success_12", + spdm_test_case_capabilities_success_12, spdm_test_case_capabilities_setup_version_12}, + {SPDM_RESPONDER_TEST_CASE_CAPABILITIES_UNEXPECTED_REQUEST_NON_IDENTICAL, + "spdm_test_case_capabilities_unexpected_non_identical", + spdm_test_case_capabilities_unexpected_non_identical, + spdm_test_case_capabilities_setup_version_all}, + {COMMON_TEST_ID_END, NULL, NULL}, +}; diff --git a/library/spdm_responder_conformance_test_lib/spdm_responder_test_3_algorithms.c b/library/spdm_responder_conformance_test_lib/spdm_responder_test_3_algorithms.c new file mode 100644 index 0000000..87d6bed --- /dev/null +++ b/library/spdm_responder_conformance_test_lib/spdm_responder_test_3_algorithms.c @@ -0,0 +1,2180 @@ +/** + * Copyright Notice: + * Copyright 2021 DMTF. All rights reserved. + * License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/spdm-emu/blob/main/LICENSE.md + **/ + +#include "spdm_responder_test.h" + +#pragma pack(1) +typedef struct { + uint8_t version; + uint32_t rsp_cap_flags; + uint8_t support_version_bitmask; +} spdm_algorithms_test_buffer_t; +#pragma pack() + +#pragma pack(1) +typedef struct { + spdm_message_header_t header; + uint16_t length; + uint8_t measurement_specification; + uint8_t other_params_support; + uint32_t base_asym_algo; + uint32_t base_hash_algo; + uint8_t reserved2[12]; + uint8_t ext_asym_count; + uint8_t ext_hash_count; + uint16_t reserved3; + spdm_negotiate_algorithms_common_struct_table_t struct_table[4]; +} spdm_negotiate_algorithms_request_mine_t; + +#pragma pack() + +bool spdm_test_case_algorithms_setup_version_capabilities (void *test_context, + spdm_version_number_t spdm_version) +{ + spdm_test_context_t *spdm_test_context; + void *spdm_context; + libspdm_return_t status; + libspdm_data_parameter_t parameter; + size_t data_size; + spdm_algorithms_test_buffer_t *test_buffer; + + spdm_test_context = test_context; + spdm_context = spdm_test_context->spdm_context; + + if (spdm_version != 0) { + libspdm_zero_mem(¶meter, sizeof(parameter)); + parameter.location = LIBSPDM_DATA_LOCATION_LOCAL; + libspdm_set_data(spdm_context, LIBSPDM_DATA_SPDM_VERSION, ¶meter, + &spdm_version, sizeof(spdm_version)); + } + + status = libspdm_get_version (spdm_context, NULL, NULL); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + return false; + } + + status = libspdm_get_capabilities (spdm_context); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + return false; + } + + test_buffer = (void *)spdm_test_context->test_scratch_buffer; + LIBSPDM_ASSERT(sizeof(spdm_test_context->test_scratch_buffer) >= + sizeof(spdm_algorithms_test_buffer_t)); + libspdm_zero_mem(test_buffer, sizeof(spdm_algorithms_test_buffer_t)); + spdm_test_context->test_scratch_buffer_size = sizeof(spdm_algorithms_test_buffer_t); + + spdm_version = 0; + data_size = sizeof(spdm_version); + libspdm_zero_mem(¶meter, sizeof(parameter)); + parameter.location = LIBSPDM_DATA_LOCATION_CONNECTION; + libspdm_get_data(spdm_context, LIBSPDM_DATA_SPDM_VERSION, ¶meter, &spdm_version, + &data_size); + test_buffer->version = (spdm_version >> SPDM_VERSION_NUMBER_SHIFT_BIT); + + data_size = sizeof(test_buffer->rsp_cap_flags); + libspdm_zero_mem(¶meter, sizeof(parameter)); + parameter.location = LIBSPDM_DATA_LOCATION_CONNECTION; + libspdm_get_data(spdm_context, LIBSPDM_DATA_CAPABILITY_FLAGS, ¶meter, + &test_buffer->rsp_cap_flags, &data_size); + + test_buffer->support_version_bitmask = 0; + + spdm_test_context->test_scratch_buffer_size = sizeof(spdm_algorithms_test_buffer_t); + + return true; +} + +bool spdm_test_case_algorithms_setup_version_10 (void *test_context) +{ + return spdm_test_case_algorithms_setup_version_capabilities (test_context, + SPDM_MESSAGE_VERSION_10 << + SPDM_VERSION_NUMBER_SHIFT_BIT); +} + +bool spdm_test_case_algorithms_setup_version_11 (void *test_context) +{ + return spdm_test_case_algorithms_setup_version_capabilities (test_context, + SPDM_MESSAGE_VERSION_11 << + SPDM_VERSION_NUMBER_SHIFT_BIT); +} + +bool spdm_test_case_algorithms_setup_version_12 (void *test_context) +{ + return spdm_test_case_algorithms_setup_version_capabilities (test_context, + SPDM_MESSAGE_VERSION_12 << + SPDM_VERSION_NUMBER_SHIFT_BIT); +} + +bool spdm_test_case_algorithms_setup_version_any (void *test_context) +{ + return spdm_test_case_algorithms_setup_version_capabilities (test_context, 0); +} + +bool spdm_test_case_algorithms_setup_version_only (void *test_context) +{ + spdm_test_context_t *spdm_test_context; + void *spdm_context; + libspdm_return_t status; + libspdm_data_parameter_t parameter; + spdm_version_number_t spdm_version; + size_t data_size; + spdm_algorithms_test_buffer_t *test_buffer; + uint8_t version_number_entry_count; + spdm_version_number_t version_number_entry[LIBSPDM_MAX_VERSION_COUNT]; + + spdm_test_context = test_context; + spdm_context = spdm_test_context->spdm_context; + + test_buffer = (void *)spdm_test_context->test_scratch_buffer; + LIBSPDM_ASSERT(sizeof(spdm_test_context->test_scratch_buffer) >= + sizeof(spdm_algorithms_test_buffer_t)); + libspdm_zero_mem(test_buffer, sizeof(spdm_algorithms_test_buffer_t)); + spdm_test_context->test_scratch_buffer_size = sizeof(spdm_algorithms_test_buffer_t); + + version_number_entry_count = LIBSPDM_MAX_VERSION_COUNT; + status = libspdm_get_version (spdm_context, &version_number_entry_count, version_number_entry); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + return false; + } + + spdm_version = 0; + data_size = sizeof(spdm_version); + libspdm_zero_mem(¶meter, sizeof(parameter)); + parameter.location = LIBSPDM_DATA_LOCATION_CONNECTION; + libspdm_get_data(spdm_context, LIBSPDM_DATA_SPDM_VERSION, ¶meter, &spdm_version, + &data_size); + test_buffer->version = (spdm_version >> SPDM_VERSION_NUMBER_SHIFT_BIT); + + data_size = sizeof(test_buffer->rsp_cap_flags); + libspdm_zero_mem(¶meter, sizeof(parameter)); + parameter.location = LIBSPDM_DATA_LOCATION_CONNECTION; + libspdm_get_data(spdm_context, LIBSPDM_DATA_CAPABILITY_FLAGS, ¶meter, + &test_buffer->rsp_cap_flags, &data_size); + + return true; +} + +void spdm_test_case_algorithms_success_10 (void *test_context) +{ + spdm_test_context_t *spdm_test_context; + void *spdm_context; + libspdm_return_t status; + spdm_negotiate_algorithms_request_mine_t spdm_request; + spdm_algorithms_response_t *spdm_response; + uint8_t message[LIBSPDM_MAX_MESSAGE_BUFFER_SIZE]; + size_t spdm_response_size; + uint32_t algo; + common_test_result_t test_result; + spdm_algorithms_test_buffer_t *test_buffer; + + spdm_test_context = test_context; + spdm_context = spdm_test_context->spdm_context; + test_buffer = (void *)spdm_test_context->test_scratch_buffer; + LIBSPDM_ASSERT (spdm_test_context->test_scratch_buffer_size == + sizeof(spdm_algorithms_test_buffer_t)); + + libspdm_zero_mem(&spdm_request, sizeof(spdm_request)); + spdm_request.header.spdm_version = SPDM_MESSAGE_VERSION_10; + spdm_request.length = sizeof(spdm_request) - sizeof(spdm_request.struct_table); + spdm_request.header.param1 = 0; + spdm_request.header.request_response_code = SPDM_NEGOTIATE_ALGORITHMS; + spdm_request.header.param2 = 0; + spdm_request.measurement_specification = SPDM_MEASUREMENT_BLOCK_HEADER_SPECIFICATION_DMTF; + spdm_request.base_asym_algo = SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_2048 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_3072 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_3072 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_4096 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_4096 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P384 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P521; + spdm_request.base_hash_algo = SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_256 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_384 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_512 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA3_256 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA3_384 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA3_512; + spdm_request.ext_asym_count = 0; + spdm_request.ext_hash_count = 0; + + spdm_response = (void *)message; + spdm_response_size = sizeof(message); + libspdm_zero_mem(message, sizeof(message)); + status = libspdm_send_receive_data(spdm_context, NULL, false, + &spdm_request, spdm_request.length, + spdm_response, &spdm_response_size); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, SPDM_RESPONDER_TEST_CASE_ALGORITHMS_SUCCESS_10, + COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "send/receive failure"); + return; + } + + if (spdm_response_size >= sizeof(spdm_algorithms_response_t)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, SPDM_RESPONDER_TEST_CASE_ALGORITHMS_SUCCESS_10, 1, + test_result, "response size - %d", spdm_response_size); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.request_response_code == SPDM_ALGORITHMS) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, SPDM_RESPONDER_TEST_CASE_ALGORITHMS_SUCCESS_10, 2, + test_result, "response code - 0x%02x", spdm_response->header.request_response_code); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.spdm_version == SPDM_MESSAGE_VERSION_10) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, SPDM_RESPONDER_TEST_CASE_ALGORITHMS_SUCCESS_10, 3, + test_result, "response version - 0x%02x", spdm_response->header.spdm_version); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if ((spdm_response->length <= spdm_response_size) && + (spdm_response->length == sizeof(spdm_algorithms_response_t) + + spdm_response->ext_asym_sel_count * sizeof(spdm_extended_algorithm_t) + + spdm_response->ext_hash_sel_count * sizeof(spdm_extended_algorithm_t))) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, SPDM_RESPONDER_TEST_CASE_ALGORITHMS_SUCCESS_10, 4, + test_result, "response length - 0x%04x", spdm_response->length); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->ext_asym_sel_count == 0) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, SPDM_RESPONDER_TEST_CASE_ALGORITHMS_SUCCESS_10, 5, + test_result, "response ext_asym_sel_count - 0x%02x", spdm_response->ext_asym_sel_count); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->ext_hash_sel_count == 0) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, SPDM_RESPONDER_TEST_CASE_ALGORITHMS_SUCCESS_10, 6, + test_result, "response ext_hash_sel_count - 0x%02x", spdm_response->ext_hash_sel_count); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + algo = spdm_test_get_one_bit (spdm_response->measurement_specification_sel, + SPDM_MEASUREMENT_BLOCK_HEADER_SPECIFICATION_DMTF); + if (algo != 0xFFFFFFFF) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, SPDM_RESPONDER_TEST_CASE_ALGORITHMS_SUCCESS_10, 7, + test_result, "response measurement_specification_sel - 0x%02x", + spdm_response->measurement_specification_sel); + + algo = spdm_test_get_one_bit (spdm_response->measurement_hash_algo, + SPDM_ALGORITHMS_MEASUREMENT_HASH_ALGO_RAW_BIT_STREAM_ONLY | + SPDM_ALGORITHMS_MEASUREMENT_HASH_ALGO_TPM_ALG_SHA_256 | + SPDM_ALGORITHMS_MEASUREMENT_HASH_ALGO_TPM_ALG_SHA_384 | + SPDM_ALGORITHMS_MEASUREMENT_HASH_ALGO_TPM_ALG_SHA_512 | + SPDM_ALGORITHMS_MEASUREMENT_HASH_ALGO_TPM_ALG_SHA3_256 | + SPDM_ALGORITHMS_MEASUREMENT_HASH_ALGO_TPM_ALG_SHA3_384 | + SPDM_ALGORITHMS_MEASUREMENT_HASH_ALGO_TPM_ALG_SHA3_512); + if (((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP) != 0) && + ((algo != 0xFFFFFFFF) && (algo != 0x0))) { + test_result = COMMON_TEST_RESULT_PASS; + } else if (((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP) == + 0) && + (algo == 0x0)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, SPDM_RESPONDER_TEST_CASE_ALGORITHMS_SUCCESS_10, 8, + test_result, "response measurement_hash_algo - 0x%08x", + spdm_response->measurement_hash_algo); + + algo = spdm_test_get_one_bit (spdm_response->base_asym_sel, + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_2048 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_3072 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_3072 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_4096 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_4096 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P384 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P521); + if ((((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHAL_CAP) != 0) || + ((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP_SIG) != 0)) && + ((algo != 0xFFFFFFFF) && (algo != 0x0))) { + test_result = COMMON_TEST_RESULT_PASS; + } else if ((((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHAL_CAP) == + 0) && + ((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP_SIG) == + 0)) && + (algo == 0x0)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, SPDM_RESPONDER_TEST_CASE_ALGORITHMS_SUCCESS_10, 9, + test_result, "response base_asym_sel - 0x%08x", spdm_response->base_asym_sel); + + algo = spdm_test_get_one_bit (spdm_response->base_hash_sel, + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_256 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_384 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_512 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA3_256 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA3_384 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA3_512); + if ((((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHAL_CAP) != 0) || + ((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP_SIG) != 0)) && + ((algo != 0xFFFFFFFF) && (algo != 0x0))) { + test_result = COMMON_TEST_RESULT_PASS; + } else if ((((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHAL_CAP) == + 0) && + ((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP_SIG) == + 0)) && + (algo == 0x0)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, SPDM_RESPONDER_TEST_CASE_ALGORITHMS_SUCCESS_10, 10, + test_result, "response base_hash_sel - 0x%08x", spdm_response->base_hash_sel); +} + +void spdm_test_case_algorithms_version_mismatch (void *test_context) +{ + spdm_test_context_t *spdm_test_context; + void *spdm_context; + libspdm_return_t status; + spdm_negotiate_algorithms_request_mine_t spdm_request; + spdm_algorithms_response_t *spdm_response; + uint8_t message[LIBSPDM_MAX_MESSAGE_BUFFER_SIZE]; + size_t spdm_response_size; + common_test_result_t test_result; + spdm_algorithms_test_buffer_t *test_buffer; + uint8_t mismatched_version[] = { + SPDM_MESSAGE_VERSION_10 - 1, + SPDM_MESSAGE_VERSION_12 + 1, + }; + size_t index; + + spdm_test_context = test_context; + spdm_context = spdm_test_context->spdm_context; + test_buffer = (void *)spdm_test_context->test_scratch_buffer; + LIBSPDM_ASSERT (spdm_test_context->test_scratch_buffer_size == + sizeof(spdm_algorithms_test_buffer_t)); + + mismatched_version[0] = (uint8_t)(test_buffer->version - 1); + mismatched_version[1] = (uint8_t)(test_buffer->version + 1); + + for (index = 0; index < LIBSPDM_ARRAY_SIZE(mismatched_version); index++) { + common_test_record_test_message ("test mismatched_version - 0x%02x\n", + mismatched_version[index]); + libspdm_zero_mem(&spdm_request, sizeof(spdm_request)); + spdm_request.header.spdm_version = mismatched_version[index]; + spdm_request.length = sizeof(spdm_request) - sizeof(spdm_request.struct_table); + spdm_request.header.param1 = 0; + spdm_request.header.request_response_code = SPDM_NEGOTIATE_ALGORITHMS; + spdm_request.header.param2 = 0; + spdm_request.measurement_specification = SPDM_MEASUREMENT_BLOCK_HEADER_SPECIFICATION_DMTF; + spdm_request.base_asym_algo = SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_2048 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_3072 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_3072 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_4096 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_4096 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P384 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P521; + spdm_request.base_hash_algo = SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_256 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_384 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_512 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA3_256 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA3_384 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA3_512; + spdm_request.ext_asym_count = 0; + spdm_request.ext_hash_count = 0; + + spdm_response = (void *)message; + spdm_response_size = sizeof(message); + libspdm_zero_mem(message, sizeof(message)); + status = libspdm_send_receive_data(spdm_context, NULL, false, + &spdm_request, spdm_request.length, + spdm_response, &spdm_response_size); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, + SPDM_RESPONDER_TEST_CASE_ALGORITHMS_VERSION_MISMATCH, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "send/receive failure"); + continue; + } + + if (spdm_response_size >= sizeof(spdm_error_response_t)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, + SPDM_RESPONDER_TEST_CASE_ALGORITHMS_VERSION_MISMATCH, 1, + test_result, "response size - %d", spdm_response_size); + if (test_result == COMMON_TEST_RESULT_FAIL) { + continue; + } + + if (spdm_response->header.request_response_code == SPDM_ERROR) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, + SPDM_RESPONDER_TEST_CASE_ALGORITHMS_VERSION_MISMATCH, 2, + test_result, "response code - 0x%02x", spdm_response->header.request_response_code); + if (test_result == COMMON_TEST_RESULT_FAIL) { + continue; + } + + if (spdm_response->header.spdm_version == test_buffer->version) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, + SPDM_RESPONDER_TEST_CASE_ALGORITHMS_VERSION_MISMATCH, 3, + test_result, "response version - 0x%02x", spdm_response->header.spdm_version); + if (test_result == COMMON_TEST_RESULT_FAIL) { + continue; + } + + if (spdm_response->header.param1 == SPDM_ERROR_CODE_VERSION_MISMATCH) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, + SPDM_RESPONDER_TEST_CASE_ALGORITHMS_VERSION_MISMATCH, 4, + test_result, "response param1 - 0x%02x", spdm_response->header.param1); + + if (spdm_response->header.param2 == 0) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, + SPDM_RESPONDER_TEST_CASE_ALGORITHMS_VERSION_MISMATCH, 5, + test_result, "response param2 - 0x%02x", spdm_response->header.param2); + } +} + +void spdm_test_case_algorithms_unexpected_request (void *test_context) +{ + spdm_test_context_t *spdm_test_context; + void *spdm_context; + libspdm_return_t status; + spdm_negotiate_algorithms_request_mine_t spdm_request; + size_t spdm_request_size; + spdm_algorithms_response_t *spdm_response; + size_t spdm_response_size; + uint8_t message[LIBSPDM_MAX_MESSAGE_BUFFER_SIZE]; + common_test_result_t test_result; + spdm_algorithms_test_buffer_t *test_buffer; + uint8_t version; + + spdm_test_context = test_context; + spdm_context = spdm_test_context->spdm_context; + test_buffer = (void *)spdm_test_context->test_scratch_buffer; + LIBSPDM_ASSERT (spdm_test_context->test_scratch_buffer_size == + sizeof(spdm_algorithms_test_buffer_t)); + + /* libspdm_check_request_version_compability will set the connection_info version + * This case receives a NEGOTIATE_ALGORITHMS before GET_CAPABILITIES, the conection_info version is 0*/ + version = 0; + if (test_buffer->version >= SPDM_MESSAGE_VERSION_11) { + spdm_request_size = sizeof(spdm_request); + } else { + spdm_request_size = sizeof(spdm_request) - sizeof(spdm_request.struct_table); + } + + libspdm_zero_mem(&spdm_request, sizeof(spdm_request)); + spdm_request.header.spdm_version = version; + spdm_request.length = (uint16_t)spdm_request_size; + if (test_buffer->version >= SPDM_MESSAGE_VERSION_11) { + spdm_request.header.param1 = 4; + } else { + spdm_request.header.param1 = 0; + } + spdm_request.header.request_response_code = SPDM_NEGOTIATE_ALGORITHMS; + spdm_request.header.param2 = 0; + if (test_buffer->version >= SPDM_MESSAGE_VERSION_12) { + spdm_request.other_params_support = SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_1; + } + spdm_request.measurement_specification = SPDM_MEASUREMENT_BLOCK_HEADER_SPECIFICATION_DMTF; + spdm_request.base_asym_algo = SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_2048 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_3072 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_3072 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_4096 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_4096 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P384 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P521; + if (test_buffer->version >= SPDM_MESSAGE_VERSION_12) { + spdm_request.base_asym_algo |= SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_SM2_ECC_SM2_P256 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED25519 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED448; + } + spdm_request.base_hash_algo = SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_256 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_384 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_512 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA3_256 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA3_384 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA3_512; + if (test_buffer->version >= SPDM_MESSAGE_VERSION_12) { + spdm_request.base_hash_algo |= SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SM3_256; + } + spdm_request.ext_asym_count = 0; + spdm_request.ext_hash_count = 0; + spdm_request.struct_table[0].alg_type = SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_DHE; + spdm_request.struct_table[0].alg_count = 0x20; + spdm_request.struct_table[0].alg_supported = SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_2048 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_3072 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_4096 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_256_R1 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_384_R1 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_521_R1; + if (test_buffer->version >= SPDM_MESSAGE_VERSION_12) { + spdm_request.struct_table[0].alg_supported |= SPDM_ALGORITHMS_DHE_NAMED_GROUP_SM2_P256; + } + spdm_request.struct_table[1].alg_type = SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_AEAD; + spdm_request.struct_table[1].alg_count = 0x20; + spdm_request.struct_table[1].alg_supported = SPDM_ALGORITHMS_AEAD_CIPHER_SUITE_AES_128_GCM | + SPDM_ALGORITHMS_AEAD_CIPHER_SUITE_AES_256_GCM | + SPDM_ALGORITHMS_AEAD_CIPHER_SUITE_CHACHA20_POLY1305; + if (test_buffer->version >= SPDM_MESSAGE_VERSION_12) { + spdm_request.struct_table[1].alg_supported |= + SPDM_ALGORITHMS_AEAD_CIPHER_SUITE_AEAD_SM4_GCM; + } + spdm_request.struct_table[2].alg_type = + SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_REQ_BASE_ASYM_ALG; + spdm_request.struct_table[2].alg_count = 0x20; + spdm_request.struct_table[2].alg_supported = + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_2048 + | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_3072 + | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_3072 + | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256 + | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_4096 + | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_4096 + | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P384 + | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P521; + if (test_buffer->version >= SPDM_MESSAGE_VERSION_12) { + spdm_request.struct_table[2].alg_supported |= + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_SM2_ECC_SM2_P256 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED25519 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED448; + } + spdm_request.struct_table[3].alg_type = + SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_KEY_SCHEDULE; + spdm_request.struct_table[3].alg_count = 0x20; + spdm_request.struct_table[3].alg_supported = SPDM_ALGORITHMS_KEY_SCHEDULE_HMAC_HASH; + + spdm_response = (void *)message; + spdm_response_size = sizeof(message); + libspdm_zero_mem(message, sizeof(message)); + status = libspdm_send_receive_data(spdm_context, NULL, false, + &spdm_request, spdm_request.length, + spdm_response, &spdm_response_size); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, + SPDM_RESPONDER_TEST_CASE_ALGORITHMS_UNEXPECTED_REQUEST, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "send/receive failure"); + return; + } + + if (spdm_response_size >= sizeof(spdm_error_response_t)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, + SPDM_RESPONDER_TEST_CASE_ALGORITHMS_UNEXPECTED_REQUEST, 1, + test_result, "response size - %d", spdm_response_size); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.request_response_code == SPDM_ERROR) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, + SPDM_RESPONDER_TEST_CASE_ALGORITHMS_UNEXPECTED_REQUEST, 2, + test_result, "response code - 0x%02x", spdm_response->header.request_response_code); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.spdm_version == SPDM_MESSAGE_VERSION_10) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, + SPDM_RESPONDER_TEST_CASE_ALGORITHMS_UNEXPECTED_REQUEST, 3, + test_result, "response version - 0x%02x", spdm_response->header.spdm_version); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.param1 == SPDM_ERROR_CODE_UNEXPECTED_REQUEST) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, + SPDM_RESPONDER_TEST_CASE_ALGORITHMS_UNEXPECTED_REQUEST, 4, + test_result, "response param1 - 0x%02x", spdm_response->header.param1); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.param2 == 0) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, + SPDM_RESPONDER_TEST_CASE_ALGORITHMS_UNEXPECTED_REQUEST, 5, + test_result, "response param2 - 0x%02x", spdm_response->header.param2); +} + +void spdm_test_case_algorithms_invalid_request (void *test_context) +{ + spdm_test_context_t *spdm_test_context; + void *spdm_context; + libspdm_return_t status; + spdm_negotiate_algorithms_request_mine_t spdm_request; + spdm_negotiate_algorithms_request_mine_t spdm_request_new; + size_t spdm_request_size; + spdm_algorithms_response_t *spdm_response; + size_t spdm_response_size; + uint8_t message[LIBSPDM_MAX_MESSAGE_BUFFER_SIZE]; + common_test_result_t test_result; + spdm_algorithms_test_buffer_t *test_buffer; + size_t index; + + spdm_test_context = test_context; + spdm_context = spdm_test_context->spdm_context; + test_buffer = (void *)spdm_test_context->test_scratch_buffer; + LIBSPDM_ASSERT (spdm_test_context->test_scratch_buffer_size == + sizeof(spdm_algorithms_test_buffer_t)); + + if (test_buffer->version >= SPDM_MESSAGE_VERSION_11) { + spdm_request_size = sizeof(spdm_request); + } else { + spdm_request_size = sizeof(spdm_request) - sizeof(spdm_request.struct_table); + } + + libspdm_zero_mem(&spdm_request, sizeof(spdm_request)); + spdm_request.header.spdm_version = test_buffer->version; + spdm_request.length = (uint16_t)spdm_request_size; + if (test_buffer->version >= SPDM_MESSAGE_VERSION_11) { + spdm_request.header.param1 = 4; + } else { + spdm_request.header.param1 = 0; + } + spdm_request.header.request_response_code = SPDM_NEGOTIATE_ALGORITHMS; + spdm_request.header.param2 = 0; + if (test_buffer->version >= SPDM_MESSAGE_VERSION_12) { + spdm_request.other_params_support = SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_1; + } + spdm_request.measurement_specification = SPDM_MEASUREMENT_BLOCK_HEADER_SPECIFICATION_DMTF; + spdm_request.base_asym_algo = SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_2048 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_3072 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_3072 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_4096 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_4096 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P384 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P521; + if (test_buffer->version >= SPDM_MESSAGE_VERSION_12) { + spdm_request.base_asym_algo |= SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_SM2_ECC_SM2_P256 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED25519 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED448; + } + spdm_request.base_hash_algo = SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_256 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_384 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_512 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA3_256 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA3_384 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA3_512; + if (test_buffer->version >= SPDM_MESSAGE_VERSION_12) { + spdm_request.base_hash_algo |= SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SM3_256; + } + spdm_request.ext_asym_count = 0; + spdm_request.ext_hash_count = 0; + spdm_request.struct_table[0].alg_type = SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_DHE; + spdm_request.struct_table[0].alg_count = 0x20; + spdm_request.struct_table[0].alg_supported = SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_2048 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_3072 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_4096 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_256_R1 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_384_R1 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_521_R1; + if (test_buffer->version >= SPDM_MESSAGE_VERSION_12) { + spdm_request.struct_table[0].alg_supported |= SPDM_ALGORITHMS_DHE_NAMED_GROUP_SM2_P256; + } + spdm_request.struct_table[1].alg_type = SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_AEAD; + spdm_request.struct_table[1].alg_count = 0x20; + spdm_request.struct_table[1].alg_supported = SPDM_ALGORITHMS_AEAD_CIPHER_SUITE_AES_128_GCM | + SPDM_ALGORITHMS_AEAD_CIPHER_SUITE_AES_256_GCM | + SPDM_ALGORITHMS_AEAD_CIPHER_SUITE_CHACHA20_POLY1305; + if (test_buffer->version >= SPDM_MESSAGE_VERSION_12) { + spdm_request.struct_table[1].alg_supported |= + SPDM_ALGORITHMS_AEAD_CIPHER_SUITE_AEAD_SM4_GCM; + } + spdm_request.struct_table[2].alg_type = + SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_REQ_BASE_ASYM_ALG; + spdm_request.struct_table[2].alg_count = 0x20; + spdm_request.struct_table[2].alg_supported = + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_2048 + | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_3072 + | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_3072 + | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256 + | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_4096 + | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_4096 + | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P384 + | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P521; + if (test_buffer->version >= SPDM_MESSAGE_VERSION_12) { + spdm_request.struct_table[2].alg_supported |= + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_SM2_ECC_SM2_P256 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED25519 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED448; + } + spdm_request.struct_table[3].alg_type = + SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_KEY_SCHEDULE; + spdm_request.struct_table[3].alg_count = 0x20; + spdm_request.struct_table[3].alg_supported = SPDM_ALGORITHMS_KEY_SCHEDULE_HMAC_HASH; + + for (index = 0; index < 6; index++) { + libspdm_copy_mem (&spdm_request_new, sizeof(spdm_request_new), &spdm_request, + sizeof(spdm_request)); + switch (index) { + case 0: + spdm_request_new.length += SPDM_NEGOTIATE_ALGORITHMS_REQUEST_MAX_LENGTH_VERSION_11 + 1; + common_test_record_test_message ("test length - 0x%04x\n", spdm_request_new.length); + break; + case 1: + spdm_request_new.ext_asym_count = 21; + common_test_record_test_message ("test ext_asym_count - 0x%02x\n", + spdm_request_new.ext_asym_count); + break; + case 2: + spdm_request_new.ext_hash_count = 21; + common_test_record_test_message ("test ext_hash_count - 0x%02x\n", + spdm_request_new.ext_hash_count); + break; + case 3: + if (test_buffer->version < SPDM_MESSAGE_VERSION_11) { + continue; + } + spdm_request_new.struct_table[0].alg_count = 0x10; + common_test_record_test_message ("test alg_count - 0x%02x\n", + spdm_request_new.struct_table[0].alg_count); + break; + case 4: + if (test_buffer->version < SPDM_MESSAGE_VERSION_11) { + continue; + } + spdm_request_new.struct_table[0].alg_count = 0x30; + common_test_record_test_message ("test alg_count - 0x%02x\n", + spdm_request_new.struct_table[0].alg_count); + break; + case 5: + if (test_buffer->version < SPDM_MESSAGE_VERSION_11) { + continue; + } + spdm_request_new.struct_table[0].alg_count = 0x0F; + spdm_request_new.struct_table[1].alg_count = 0x0F; + spdm_request_new.struct_table[2].alg_count = 0x0F; + spdm_request_new.struct_table[3].alg_count = 0x0F; + common_test_record_test_message ("test multiple alg_count - 0x%02x\n", + spdm_request_new.struct_table[0].alg_count); + break; + } + + spdm_response = (void *)message; + spdm_response_size = sizeof(message); + libspdm_zero_mem(message, sizeof(message)); + status = libspdm_send_receive_data(spdm_context, NULL, false, + &spdm_request_new, spdm_request_new.length, + spdm_response, &spdm_response_size); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, + SPDM_RESPONDER_TEST_CASE_ALGORITHMS_INVALID_REQUEST, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "send/receive failure"); + continue; + } + + if (spdm_response_size >= sizeof(spdm_error_response_t)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, + SPDM_RESPONDER_TEST_CASE_ALGORITHMS_INVALID_REQUEST, 1, + test_result, "response size - %d", spdm_response_size); + if (test_result == COMMON_TEST_RESULT_FAIL) { + continue; + } + + if (spdm_response->header.request_response_code == SPDM_ERROR) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, + SPDM_RESPONDER_TEST_CASE_ALGORITHMS_INVALID_REQUEST, 2, + test_result, "response code - 0x%02x", spdm_response->header.request_response_code); + if (test_result == COMMON_TEST_RESULT_FAIL) { + continue; + } + + if (spdm_response->header.spdm_version == test_buffer->version) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, + SPDM_RESPONDER_TEST_CASE_ALGORITHMS_INVALID_REQUEST, 3, + test_result, "response version - 0x%02x", spdm_response->header.spdm_version); + if (test_result == COMMON_TEST_RESULT_FAIL) { + continue; + } + + if (spdm_response->header.param1 == SPDM_ERROR_CODE_INVALID_REQUEST) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, + SPDM_RESPONDER_TEST_CASE_ALGORITHMS_INVALID_REQUEST, 4, + test_result, "response param1 - 0x%02x", spdm_response->header.param1); + if (test_result == COMMON_TEST_RESULT_FAIL) { + continue; + } + + if (spdm_response->header.param2 == 0) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, + SPDM_RESPONDER_TEST_CASE_ALGORITHMS_INVALID_REQUEST, 5, + test_result, "response param2 - 0x%02x", spdm_response->header.param2); + } +} + +void spdm_test_case_algorithms_success_11 (void *test_context) +{ + spdm_test_context_t *spdm_test_context; + void *spdm_context; + libspdm_return_t status; + spdm_negotiate_algorithms_request_mine_t spdm_request; + spdm_algorithms_response_t *spdm_response; + uint8_t message[LIBSPDM_MAX_MESSAGE_BUFFER_SIZE]; + size_t spdm_response_size; + uint32_t algo; + common_test_result_t test_result; + spdm_algorithms_test_buffer_t *test_buffer; + spdm_negotiate_algorithms_common_struct_table_t *struct_table; + bool dhe_named_group_is_found; + bool aead_cipher_suite_is_found; + bool req_base_asym_alg_is_found; + bool key_schedule_is_found; + uint16_t dhe_named_group; + uint16_t aead_cipher_suite; + uint16_t req_base_asym_alg; + uint16_t key_schedule; + size_t index; + uint8_t ext_alg_count; + + dhe_named_group = 0; + aead_cipher_suite = 0; + req_base_asym_alg = 0; + key_schedule = 0; + + spdm_test_context = test_context; + spdm_context = spdm_test_context->spdm_context; + test_buffer = (void *)spdm_test_context->test_scratch_buffer; + LIBSPDM_ASSERT (spdm_test_context->test_scratch_buffer_size == + sizeof(spdm_algorithms_test_buffer_t)); + + libspdm_zero_mem(&spdm_request, sizeof(spdm_request)); + spdm_request.header.spdm_version = SPDM_MESSAGE_VERSION_11; + spdm_request.length = sizeof(spdm_request); + spdm_request.header.param1 = 4; + spdm_request.header.request_response_code = SPDM_NEGOTIATE_ALGORITHMS; + spdm_request.header.param2 = 0; + spdm_request.measurement_specification = SPDM_MEASUREMENT_BLOCK_HEADER_SPECIFICATION_DMTF; + spdm_request.base_asym_algo = SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_2048 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_3072 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_3072 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_4096 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_4096 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P384 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P521; + spdm_request.base_hash_algo = SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_256 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_384 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_512 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA3_256 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA3_384 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA3_512; + spdm_request.ext_asym_count = 0; + spdm_request.ext_hash_count = 0; + spdm_request.struct_table[0].alg_type = SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_DHE; + spdm_request.struct_table[0].alg_count = 0x20; + spdm_request.struct_table[0].alg_supported = SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_2048 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_3072 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_4096 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_256_R1 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_384_R1 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_521_R1; + spdm_request.struct_table[1].alg_type = SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_AEAD; + spdm_request.struct_table[1].alg_count = 0x20; + spdm_request.struct_table[1].alg_supported = SPDM_ALGORITHMS_AEAD_CIPHER_SUITE_AES_128_GCM | + SPDM_ALGORITHMS_AEAD_CIPHER_SUITE_AES_256_GCM | + SPDM_ALGORITHMS_AEAD_CIPHER_SUITE_CHACHA20_POLY1305; + spdm_request.struct_table[2].alg_type = + SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_REQ_BASE_ASYM_ALG; + spdm_request.struct_table[2].alg_count = 0x20; + spdm_request.struct_table[2].alg_supported = + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_2048 + | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_3072 + | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_3072 + | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256 + | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_4096 + | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_4096 + | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P384 + | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P521; + spdm_request.struct_table[3].alg_type = + SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_KEY_SCHEDULE; + spdm_request.struct_table[3].alg_count = 0x20; + spdm_request.struct_table[3].alg_supported = SPDM_ALGORITHMS_KEY_SCHEDULE_HMAC_HASH; + + spdm_response = (void *)message; + spdm_response_size = sizeof(message); + libspdm_zero_mem(message, sizeof(message)); + status = libspdm_send_receive_data(spdm_context, NULL, false, + &spdm_request, spdm_request.length, + spdm_response, &spdm_response_size); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, SPDM_RESPONDER_TEST_CASE_ALGORITHMS_SUCCESS_11, + COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "send/receive failure"); + return; + } + + if (spdm_response_size >= sizeof(spdm_algorithms_response_t)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, SPDM_RESPONDER_TEST_CASE_ALGORITHMS_SUCCESS_11, 1, + test_result, "response size - %d", spdm_response_size); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.request_response_code == SPDM_ALGORITHMS) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, SPDM_RESPONDER_TEST_CASE_ALGORITHMS_SUCCESS_11, 2, + test_result, "response code - 0x%02x", spdm_response->header.request_response_code); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.spdm_version == SPDM_MESSAGE_VERSION_11) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, SPDM_RESPONDER_TEST_CASE_ALGORITHMS_SUCCESS_11, 3, + test_result, "response version - 0x%02x", spdm_response->header.spdm_version); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if ((spdm_response->length <= spdm_response_size) && + (spdm_response->length == sizeof(spdm_algorithms_response_t) + + spdm_response->ext_asym_sel_count * sizeof(spdm_extended_algorithm_t) + + spdm_response->ext_hash_sel_count * sizeof(spdm_extended_algorithm_t) + + spdm_response->header.param1 * sizeof(spdm_negotiate_algorithms_common_struct_table_t))) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, SPDM_RESPONDER_TEST_CASE_ALGORITHMS_SUCCESS_11, 4, + test_result, "response length - 0x%04x", spdm_response->length); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->ext_asym_sel_count == 0) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, SPDM_RESPONDER_TEST_CASE_ALGORITHMS_SUCCESS_11, 5, + test_result, "response ext_asym_sel_count - 0x%02x", spdm_response->ext_asym_sel_count); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->ext_hash_sel_count == 0) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, SPDM_RESPONDER_TEST_CASE_ALGORITHMS_SUCCESS_11, 6, + test_result, "response ext_hash_sel_count - 0x%02x", spdm_response->ext_hash_sel_count); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + algo = spdm_test_get_one_bit (spdm_response->measurement_specification_sel, + SPDM_MEASUREMENT_BLOCK_HEADER_SPECIFICATION_DMTF); + if (algo != 0xFFFFFFFF) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, SPDM_RESPONDER_TEST_CASE_ALGORITHMS_SUCCESS_11, 7, + test_result, "response measurement_specification_sel - 0x%02x", + spdm_response->measurement_specification_sel); + + algo = spdm_test_get_one_bit (spdm_response->measurement_hash_algo, + SPDM_ALGORITHMS_MEASUREMENT_HASH_ALGO_RAW_BIT_STREAM_ONLY | + SPDM_ALGORITHMS_MEASUREMENT_HASH_ALGO_TPM_ALG_SHA_256 | + SPDM_ALGORITHMS_MEASUREMENT_HASH_ALGO_TPM_ALG_SHA_384 | + SPDM_ALGORITHMS_MEASUREMENT_HASH_ALGO_TPM_ALG_SHA_512 | + SPDM_ALGORITHMS_MEASUREMENT_HASH_ALGO_TPM_ALG_SHA3_256 | + SPDM_ALGORITHMS_MEASUREMENT_HASH_ALGO_TPM_ALG_SHA3_384 | + SPDM_ALGORITHMS_MEASUREMENT_HASH_ALGO_TPM_ALG_SHA3_512); + if (((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP) != 0) && + ((algo != 0xFFFFFFFF) && (algo != 0x0))) { + test_result = COMMON_TEST_RESULT_PASS; + } else if (((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP) == + 0) && + (algo == 0x0)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, SPDM_RESPONDER_TEST_CASE_ALGORITHMS_SUCCESS_11, 8, + test_result, "response measurement_hash_algo - 0x%08x", + spdm_response->measurement_hash_algo); + + algo = spdm_test_get_one_bit (spdm_response->base_asym_sel, + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_2048 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_3072 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_3072 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_4096 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_4096 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P384 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P521); + if ((((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHAL_CAP) != 0) || + ((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP_SIG) != 0)) && + ((algo != 0xFFFFFFFF) && (algo != 0x0))) { + test_result = COMMON_TEST_RESULT_PASS; + } else if ((((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHAL_CAP) == + 0) && + ((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP_SIG) == + 0)) && + (algo == 0x0)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, SPDM_RESPONDER_TEST_CASE_ALGORITHMS_SUCCESS_11, 9, + test_result, "response base_asym_sel - 0x%08x", spdm_response->base_asym_sel); + + algo = spdm_test_get_one_bit (spdm_response->base_hash_sel, + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_256 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_384 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_512 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA3_256 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA3_384 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA3_512); + if ((((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHAL_CAP) != 0) || + ((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP_SIG) != 0)) && + ((algo != 0xFFFFFFFF) && (algo != 0x0))) { + test_result = COMMON_TEST_RESULT_PASS; + } else if ((((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHAL_CAP) == + 0) && + ((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP_SIG) == + 0)) && + (algo == 0x0)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, SPDM_RESPONDER_TEST_CASE_ALGORITHMS_SUCCESS_11, 10, + test_result, "response base_hash_sel - 0x%08x", spdm_response->base_hash_sel); + + if (spdm_response->header.param1 <= 4) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, SPDM_RESPONDER_TEST_CASE_ALGORITHMS_SUCCESS_11, 11, + test_result, "response param1 - 0x%02x", spdm_response->header.param1); + + dhe_named_group_is_found = false; + aead_cipher_suite_is_found = false; + req_base_asym_alg_is_found = false; + key_schedule_is_found = false; + struct_table = (void *)((size_t)spdm_response + + sizeof(spdm_algorithms_response_t) + + sizeof(uint32_t) * spdm_response->ext_asym_sel_count + + sizeof(uint32_t) * spdm_response->ext_hash_sel_count); + for (index = 0; index < spdm_response->header.param1; index++) { + switch (struct_table->alg_type) { + case SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_DHE: + if (dhe_named_group_is_found) { + test_result = COMMON_TEST_RESULT_FAIL; + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, + SPDM_RESPONDER_TEST_CASE_ALGORITHMS_SUCCESS_11, 11, + test_result, "response dup dhe_named_group - 0x%02x", struct_table->alg_type); + } + dhe_named_group_is_found = true; + dhe_named_group = (uint16_t)spdm_test_get_one_bit (struct_table->alg_supported, + SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_2048 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_3072 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_4096 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_256_R1 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_384_R1 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_521_R1); + break; + case SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_AEAD: + if (aead_cipher_suite_is_found) { + test_result = COMMON_TEST_RESULT_FAIL; + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, + SPDM_RESPONDER_TEST_CASE_ALGORITHMS_SUCCESS_11, 11, + test_result, "response dup aead_cipher_suite - 0x%02x", struct_table->alg_type); + } + aead_cipher_suite_is_found = true; + aead_cipher_suite = (uint16_t)spdm_test_get_one_bit (struct_table->alg_supported, + SPDM_ALGORITHMS_AEAD_CIPHER_SUITE_AES_128_GCM | + SPDM_ALGORITHMS_AEAD_CIPHER_SUITE_AES_256_GCM | + SPDM_ALGORITHMS_AEAD_CIPHER_SUITE_CHACHA20_POLY1305); + break; + case SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_REQ_BASE_ASYM_ALG: + if (req_base_asym_alg_is_found) { + test_result = COMMON_TEST_RESULT_FAIL; + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, + SPDM_RESPONDER_TEST_CASE_ALGORITHMS_SUCCESS_11, 11, + test_result, "response dup req_base_asym_alg - 0x%02x", struct_table->alg_type); + } + req_base_asym_alg_is_found = true; + req_base_asym_alg = (uint16_t)spdm_test_get_one_bit (struct_table->alg_supported, + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_2048 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_3072 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_3072 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_4096 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_4096 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P384 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P521); + break; + case SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_KEY_SCHEDULE: + if (key_schedule_is_found) { + test_result = COMMON_TEST_RESULT_FAIL; + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, + SPDM_RESPONDER_TEST_CASE_ALGORITHMS_SUCCESS_11, 11, + test_result, "response dup key_schedule - 0x%02x", struct_table->alg_type); + } + key_schedule_is_found = true; + key_schedule = (uint16_t)spdm_test_get_one_bit (struct_table->alg_supported, + SPDM_ALGORITHMS_KEY_SCHEDULE_HMAC_HASH); + break; + default: + test_result = COMMON_TEST_RESULT_FAIL; + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, + SPDM_RESPONDER_TEST_CASE_ALGORITHMS_SUCCESS_11, 11, + test_result, "response unknown alg_type - 0x%02x", struct_table->alg_type); + break; + } + if (struct_table->alg_count == 0x20) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, SPDM_RESPONDER_TEST_CASE_ALGORITHMS_SUCCESS_11, + 12, + test_result, "response alg_count - 0x%02x", struct_table->alg_count); + ext_alg_count = struct_table->alg_count & 0xF; + struct_table = + (void *)((size_t)struct_table + + sizeof(spdm_negotiate_algorithms_common_struct_table_t) + + sizeof(uint32_t) * ext_alg_count); + } + + if (((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_KEY_EX_CAP) != 0) && + ((dhe_named_group != 0xFFFF) && (dhe_named_group != 0x0))) { + test_result = COMMON_TEST_RESULT_PASS; + } else if (((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_KEY_EX_CAP) == + 0) && + (dhe_named_group == 0x0)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, SPDM_RESPONDER_TEST_CASE_ALGORITHMS_SUCCESS_11, 13, + test_result, "response dhe_named_group - 0x%04x", dhe_named_group); + + if ((((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_KEY_EX_CAP) != 0) || + ((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_PSK_CAP) != 0)) && + ((aead_cipher_suite != 0xFFFF) && (aead_cipher_suite != 0x0))) { + test_result = COMMON_TEST_RESULT_PASS; + } else if ((((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_KEY_EX_CAP) == + 0) && + ((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_PSK_CAP) == + 0)) && + (aead_cipher_suite == 0x0)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, SPDM_RESPONDER_TEST_CASE_ALGORITHMS_SUCCESS_11, 14, + test_result, "response aead_cipher_suite - 0x%04x", aead_cipher_suite); + + if (((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MUT_AUTH_CAP) != 0) && + ((req_base_asym_alg != 0xFFFF) && (req_base_asym_alg != 0x0))) { + test_result = COMMON_TEST_RESULT_PASS; + } else if (((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MUT_AUTH_CAP) == + 0) && + (req_base_asym_alg == 0x0)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, SPDM_RESPONDER_TEST_CASE_ALGORITHMS_SUCCESS_11, 15, + test_result, "response req_base_asym_alg - 0x%04x", req_base_asym_alg); + + if ((((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_KEY_EX_CAP) != 0) || + ((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_PSK_CAP) != 0)) && + ((key_schedule != 0xFFFF) && (key_schedule != 0x0))) { + test_result = COMMON_TEST_RESULT_PASS; + } else if ((((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_KEY_EX_CAP) == + 0) && + ((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_PSK_CAP) == + 0)) && + (key_schedule == 0x0)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, SPDM_RESPONDER_TEST_CASE_ALGORITHMS_SUCCESS_11, 16, + test_result, "response key_schedule - 0x%04x", key_schedule); +} + +void spdm_test_case_algorithms_success_12 (void *test_context) +{ + spdm_test_context_t *spdm_test_context; + void *spdm_context; + libspdm_return_t status; + spdm_negotiate_algorithms_request_mine_t spdm_request; + spdm_algorithms_response_t *spdm_response; + uint8_t message[LIBSPDM_MAX_MESSAGE_BUFFER_SIZE]; + size_t spdm_response_size; + uint32_t algo; + common_test_result_t test_result; + spdm_algorithms_test_buffer_t *test_buffer; + spdm_negotiate_algorithms_common_struct_table_t *struct_table; + bool dhe_named_group_is_found; + bool aead_cipher_suite_is_found; + bool req_base_asym_alg_is_found; + bool key_schedule_is_found; + uint16_t dhe_named_group; + uint16_t aead_cipher_suite; + uint16_t req_base_asym_alg; + uint16_t key_schedule; + size_t index; + uint8_t ext_alg_count; + + dhe_named_group = 0; + aead_cipher_suite = 0; + req_base_asym_alg = 0; + key_schedule = 0; + + spdm_test_context = test_context; + spdm_context = spdm_test_context->spdm_context; + test_buffer = (void *)spdm_test_context->test_scratch_buffer; + LIBSPDM_ASSERT (spdm_test_context->test_scratch_buffer_size == + sizeof(spdm_algorithms_test_buffer_t)); + + libspdm_zero_mem(&spdm_request, sizeof(spdm_request)); + spdm_request.header.spdm_version = SPDM_MESSAGE_VERSION_12; + spdm_request.length = sizeof(spdm_request); + spdm_request.header.param1 = 4; + spdm_request.header.request_response_code = SPDM_NEGOTIATE_ALGORITHMS; + spdm_request.header.param2 = 0; + spdm_request.measurement_specification = SPDM_MEASUREMENT_BLOCK_HEADER_SPECIFICATION_DMTF; + spdm_request.other_params_support = SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_1; + spdm_request.base_asym_algo = SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_2048 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_3072 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_3072 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_4096 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_4096 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P384 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P521 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_SM2_ECC_SM2_P256 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED25519 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED448; + spdm_request.base_hash_algo = SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_256 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_384 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_512 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA3_256 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA3_384 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA3_512 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SM3_256; + spdm_request.ext_asym_count = 0; + spdm_request.ext_hash_count = 0; + spdm_request.struct_table[0].alg_type = SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_DHE; + spdm_request.struct_table[0].alg_count = 0x20; + spdm_request.struct_table[0].alg_supported = SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_2048 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_3072 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_4096 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_256_R1 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_384_R1 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_521_R1 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_SM2_P256; + spdm_request.struct_table[1].alg_type = SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_AEAD; + spdm_request.struct_table[1].alg_count = 0x20; + spdm_request.struct_table[1].alg_supported = SPDM_ALGORITHMS_AEAD_CIPHER_SUITE_AES_128_GCM | + SPDM_ALGORITHMS_AEAD_CIPHER_SUITE_AES_256_GCM | + SPDM_ALGORITHMS_AEAD_CIPHER_SUITE_CHACHA20_POLY1305 + | + SPDM_ALGORITHMS_AEAD_CIPHER_SUITE_AEAD_SM4_GCM; + spdm_request.struct_table[2].alg_type = + SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_REQ_BASE_ASYM_ALG; + spdm_request.struct_table[2].alg_count = 0x20; + spdm_request.struct_table[2].alg_supported = + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_2048 + | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_3072 + | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_3072 + | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256 + | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_4096 + | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_4096 + | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P384 + | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P521 + | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_SM2_ECC_SM2_P256 + | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED25519 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED448; + spdm_request.struct_table[3].alg_type = + SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_KEY_SCHEDULE; + spdm_request.struct_table[3].alg_count = 0x20; + spdm_request.struct_table[3].alg_supported = SPDM_ALGORITHMS_KEY_SCHEDULE_HMAC_HASH; + + spdm_response = (void *)message; + spdm_response_size = sizeof(message); + libspdm_zero_mem(message, sizeof(message)); + status = libspdm_send_receive_data(spdm_context, NULL, false, + &spdm_request, spdm_request.length, + spdm_response, &spdm_response_size); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, SPDM_RESPONDER_TEST_CASE_ALGORITHMS_SUCCESS_11, + COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "send/receive failure"); + return; + } + + if (spdm_response_size >= sizeof(spdm_algorithms_response_t)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, SPDM_RESPONDER_TEST_CASE_ALGORITHMS_SUCCESS_12, 1, + test_result, "response size - %d", spdm_response_size); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.request_response_code == SPDM_ALGORITHMS) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, SPDM_RESPONDER_TEST_CASE_ALGORITHMS_SUCCESS_12, 2, + test_result, "response code - 0x%02x", spdm_response->header.request_response_code); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.spdm_version == SPDM_MESSAGE_VERSION_12) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, SPDM_RESPONDER_TEST_CASE_ALGORITHMS_SUCCESS_12, 3, + test_result, "response version - 0x%02x", spdm_response->header.spdm_version); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if ((spdm_response->length <= spdm_response_size) && + (spdm_response->length == sizeof(spdm_algorithms_response_t) + + spdm_response->ext_asym_sel_count * sizeof(spdm_extended_algorithm_t) + + spdm_response->ext_hash_sel_count * sizeof(spdm_extended_algorithm_t) + + spdm_response->header.param1 * sizeof(spdm_negotiate_algorithms_common_struct_table_t))) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, SPDM_RESPONDER_TEST_CASE_ALGORITHMS_SUCCESS_12, 4, + test_result, "response length - 0x%04x", spdm_response->length); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->ext_asym_sel_count == 0) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, SPDM_RESPONDER_TEST_CASE_ALGORITHMS_SUCCESS_12, 5, + test_result, "response ext_asym_sel_count - 0x%02x", spdm_response->ext_asym_sel_count); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->ext_hash_sel_count == 0) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, SPDM_RESPONDER_TEST_CASE_ALGORITHMS_SUCCESS_12, 6, + test_result, "response ext_hash_sel_count - 0x%02x", spdm_response->ext_hash_sel_count); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + algo = spdm_test_get_one_bit (spdm_response->measurement_specification_sel, + SPDM_MEASUREMENT_BLOCK_HEADER_SPECIFICATION_DMTF); + if (algo != 0xFFFFFFFF) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, SPDM_RESPONDER_TEST_CASE_ALGORITHMS_SUCCESS_12, 7, + test_result, "response measurement_specification_sel - 0x%02x", + spdm_response->measurement_specification_sel); + + algo = spdm_test_get_one_bit (spdm_response->measurement_hash_algo, + SPDM_ALGORITHMS_MEASUREMENT_HASH_ALGO_RAW_BIT_STREAM_ONLY | + SPDM_ALGORITHMS_MEASUREMENT_HASH_ALGO_TPM_ALG_SHA_256 | + SPDM_ALGORITHMS_MEASUREMENT_HASH_ALGO_TPM_ALG_SHA_384 | + SPDM_ALGORITHMS_MEASUREMENT_HASH_ALGO_TPM_ALG_SHA_512 | + SPDM_ALGORITHMS_MEASUREMENT_HASH_ALGO_TPM_ALG_SHA3_256 | + SPDM_ALGORITHMS_MEASUREMENT_HASH_ALGO_TPM_ALG_SHA3_384 | + SPDM_ALGORITHMS_MEASUREMENT_HASH_ALGO_TPM_ALG_SHA3_512 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SM3_256); + if (((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP) != 0) && + ((algo != 0xFFFFFFFF) && (algo != 0x0))) { + test_result = COMMON_TEST_RESULT_PASS; + } else if (((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP) == + 0) && + (algo == 0x0)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, SPDM_RESPONDER_TEST_CASE_ALGORITHMS_SUCCESS_12, 8, + test_result, "response measurement_hash_algo - 0x%08x", + spdm_response->measurement_hash_algo); + + algo = spdm_test_get_one_bit (spdm_response->base_asym_sel, + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_2048 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_3072 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_3072 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_4096 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_4096 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P384 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P521 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_SM2_ECC_SM2_P256 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED25519 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED448); + if ((((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHAL_CAP) != 0) || + ((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP_SIG) != 0)) && + ((algo != 0xFFFFFFFF) && (algo != 0x0))) { + test_result = COMMON_TEST_RESULT_PASS; + } else if ((((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHAL_CAP) == + 0) && + ((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP_SIG) == + 0)) && + (algo == 0x0)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, SPDM_RESPONDER_TEST_CASE_ALGORITHMS_SUCCESS_12, 9, + test_result, "response base_asym_sel - 0x%08x", spdm_response->base_asym_sel); + + algo = spdm_test_get_one_bit (spdm_response->base_hash_sel, + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_256 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_384 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_512 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA3_256 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA3_384 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA3_512 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SM3_256); + if ((((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHAL_CAP) != 0) || + ((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP_SIG) != 0)) && + ((algo != 0xFFFFFFFF) && (algo != 0x0))) { + test_result = COMMON_TEST_RESULT_PASS; + } else if ((((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHAL_CAP) == + 0) && + ((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP_SIG) == + 0)) && + (algo == 0x0)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, SPDM_RESPONDER_TEST_CASE_ALGORITHMS_SUCCESS_12, 10, + test_result, "response base_hash_sel - 0x%08x", spdm_response->base_hash_sel); + + if (spdm_response->header.param1 <= 4) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, SPDM_RESPONDER_TEST_CASE_ALGORITHMS_SUCCESS_12, 11, + test_result, "response param1 - 0x%02x", spdm_response->header.param1); + + dhe_named_group_is_found = false; + aead_cipher_suite_is_found = false; + req_base_asym_alg_is_found = false; + key_schedule_is_found = false; + struct_table = (void *)((size_t)spdm_response + + sizeof(spdm_algorithms_response_t) + + sizeof(uint32_t) * spdm_response->ext_asym_sel_count + + sizeof(uint32_t) * spdm_response->ext_hash_sel_count); + for (index = 0; index < spdm_response->header.param1; index++) { + switch (struct_table->alg_type) { + case SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_DHE: + if (dhe_named_group_is_found) { + test_result = COMMON_TEST_RESULT_FAIL; + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, + SPDM_RESPONDER_TEST_CASE_ALGORITHMS_SUCCESS_12, 11, + test_result, "response dup dhe_named_group - 0x%02x", struct_table->alg_type); + } + dhe_named_group_is_found = true; + dhe_named_group = (uint16_t)spdm_test_get_one_bit (struct_table->alg_supported, + SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_2048 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_3072 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_4096 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_256_R1 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_384_R1 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_521_R1 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_SM2_P256); + break; + case SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_AEAD: + if (aead_cipher_suite_is_found) { + test_result = COMMON_TEST_RESULT_FAIL; + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, + SPDM_RESPONDER_TEST_CASE_ALGORITHMS_SUCCESS_12, 11, + test_result, "response dup aead_cipher_suite - 0x%02x", struct_table->alg_type); + } + aead_cipher_suite_is_found = true; + aead_cipher_suite = (uint16_t)spdm_test_get_one_bit (struct_table->alg_supported, + SPDM_ALGORITHMS_AEAD_CIPHER_SUITE_AES_128_GCM | + SPDM_ALGORITHMS_AEAD_CIPHER_SUITE_AES_256_GCM | + SPDM_ALGORITHMS_AEAD_CIPHER_SUITE_CHACHA20_POLY1305 | + SPDM_ALGORITHMS_AEAD_CIPHER_SUITE_AEAD_SM4_GCM); + break; + case SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_REQ_BASE_ASYM_ALG: + if (req_base_asym_alg_is_found) { + test_result = COMMON_TEST_RESULT_FAIL; + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, + SPDM_RESPONDER_TEST_CASE_ALGORITHMS_SUCCESS_12, 11, + test_result, "response dup req_base_asym_alg - 0x%02x", struct_table->alg_type); + } + req_base_asym_alg_is_found = true; + req_base_asym_alg = (uint16_t)spdm_test_get_one_bit (struct_table->alg_supported, + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_2048 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_3072 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_3072 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_4096 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_4096 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P384 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P521 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_SM2_ECC_SM2_P256 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED25519 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED448); + break; + case SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_KEY_SCHEDULE: + if (key_schedule_is_found) { + test_result = COMMON_TEST_RESULT_FAIL; + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, + SPDM_RESPONDER_TEST_CASE_ALGORITHMS_SUCCESS_12, 11, + test_result, "response dup key_schedule - 0x%02x", struct_table->alg_type); + } + key_schedule_is_found = true; + key_schedule = (uint16_t)spdm_test_get_one_bit (struct_table->alg_supported, + SPDM_ALGORITHMS_KEY_SCHEDULE_HMAC_HASH); + break; + default: + test_result = COMMON_TEST_RESULT_FAIL; + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, + SPDM_RESPONDER_TEST_CASE_ALGORITHMS_SUCCESS_12, 11, + test_result, "response unknown alg_type - 0x%02x", struct_table->alg_type); + break; + } + if (struct_table->alg_count == 0x20) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, SPDM_RESPONDER_TEST_CASE_ALGORITHMS_SUCCESS_12, + 12, + test_result, "response alg_count - 0x%02x", struct_table->alg_count); + ext_alg_count = struct_table->alg_count & 0xF; + struct_table = + (void *)((size_t)struct_table + + sizeof(spdm_negotiate_algorithms_common_struct_table_t) + + sizeof(uint32_t) * ext_alg_count); + } + + if (((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_KEY_EX_CAP) != 0) && + ((dhe_named_group != 0xFFFF) && (dhe_named_group != 0x0))) { + test_result = COMMON_TEST_RESULT_PASS; + } else if (((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_KEY_EX_CAP) == + 0) && + (dhe_named_group == 0x0)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, SPDM_RESPONDER_TEST_CASE_ALGORITHMS_SUCCESS_12, 13, + test_result, "response dhe_named_group - 0x%04x", dhe_named_group); + + if ((((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_KEY_EX_CAP) != 0) || + ((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_PSK_CAP) != 0)) && + ((aead_cipher_suite != 0xFFFF) && (aead_cipher_suite != 0x0))) { + test_result = COMMON_TEST_RESULT_PASS; + } else if ((((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_KEY_EX_CAP) == + 0) && + ((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_PSK_CAP) == + 0)) && + (aead_cipher_suite == 0x0)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, SPDM_RESPONDER_TEST_CASE_ALGORITHMS_SUCCESS_12, 14, + test_result, "response aead_cipher_suite - 0x%04x", aead_cipher_suite); + + if (((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MUT_AUTH_CAP) != 0) && + ((req_base_asym_alg != 0xFFFF) && (req_base_asym_alg != 0x0))) { + test_result = COMMON_TEST_RESULT_PASS; + } else if (((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MUT_AUTH_CAP) == + 0) && + (req_base_asym_alg == 0x0)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, SPDM_RESPONDER_TEST_CASE_ALGORITHMS_SUCCESS_12, 15, + test_result, "response req_base_asym_alg - 0x%04x", req_base_asym_alg); + + if ((((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_KEY_EX_CAP) != 0) || + ((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_PSK_CAP) != 0)) && + ((key_schedule != 0xFFFF) && (key_schedule != 0x0))) { + test_result = COMMON_TEST_RESULT_PASS; + } else if ((((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_KEY_EX_CAP) == + 0) && + ((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_PSK_CAP) == + 0)) && + (key_schedule == 0x0)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, SPDM_RESPONDER_TEST_CASE_ALGORITHMS_SUCCESS_12, 16, + test_result, "response key_schedule - 0x%04x", key_schedule); + + spdm_response->other_params_support = SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_1; + + if (((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_KEY_EX_CAP) != 0) || + ((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_PSK_CAP) != 0)) { + if (spdm_response->other_params_support == SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_1) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, SPDM_RESPONDER_TEST_CASE_ALGORITHMS_SUCCESS_12, + 17, + test_result, "response other_params_support - 0x%02x", + spdm_response->other_params_support); + } +} + +void spdm_test_case_algorithms_unexpected_non_identical (void *test_context) +{ + spdm_test_context_t *spdm_test_context; + void *spdm_context; + libspdm_return_t status; + spdm_negotiate_algorithms_request_mine_t spdm_request; + spdm_negotiate_algorithms_request_mine_t spdm_request_new; + size_t spdm_request_size; + spdm_algorithms_response_t *spdm_response; + uint8_t message[LIBSPDM_MAX_MESSAGE_BUFFER_SIZE]; + size_t spdm_response_size; + common_test_result_t test_result; + spdm_algorithms_test_buffer_t *test_buffer; + spdm_negotiate_algorithms_common_struct_table_t *struct_table; + size_t index; + uint32_t base_asym_sel; + uint32_t base_hash_sel; + uint16_t dhe_named_group; + uint16_t aead_cipher_suite; + uint16_t req_base_asym_alg; + uint8_t ext_alg_count; + + spdm_test_context = test_context; + spdm_context = spdm_test_context->spdm_context; + test_buffer = (void *)spdm_test_context->test_scratch_buffer; + LIBSPDM_ASSERT (spdm_test_context->test_scratch_buffer_size == + sizeof(spdm_algorithms_test_buffer_t)); + + if (test_buffer->version >= SPDM_MESSAGE_VERSION_11) { + spdm_request_size = sizeof(spdm_request); + } else { + spdm_request_size = sizeof(spdm_request) - sizeof(spdm_request.struct_table); + } + + libspdm_zero_mem(&spdm_request, sizeof(spdm_request)); + spdm_request.header.spdm_version = test_buffer->version; + spdm_request.length = (uint16_t)spdm_request_size; + if (test_buffer->version >= SPDM_MESSAGE_VERSION_11) { + spdm_request.header.param1 = 4; + } else { + spdm_request.header.param1 = 0; + } + spdm_request.header.request_response_code = SPDM_NEGOTIATE_ALGORITHMS; + spdm_request.header.param2 = 0; + if (test_buffer->version >= SPDM_MESSAGE_VERSION_12) { + spdm_request.other_params_support = SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_1; + } + spdm_request.measurement_specification = SPDM_MEASUREMENT_BLOCK_HEADER_SPECIFICATION_DMTF; + spdm_request.base_asym_algo = SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_2048 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_3072 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_3072 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_4096 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_4096 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P384 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P521; + if (test_buffer->version >= SPDM_MESSAGE_VERSION_12) { + spdm_request.base_asym_algo |= SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_SM2_ECC_SM2_P256 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED25519 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED448; + } + spdm_request.base_hash_algo = SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_256 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_384 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_512 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA3_256 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA3_384 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA3_512; + if (test_buffer->version >= SPDM_MESSAGE_VERSION_12) { + spdm_request.base_hash_algo |= SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SM3_256; + } + spdm_request.ext_asym_count = 0; + spdm_request.ext_hash_count = 0; + spdm_request.struct_table[0].alg_type = SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_DHE; + spdm_request.struct_table[0].alg_count = 0x20; + spdm_request.struct_table[0].alg_supported = SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_2048 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_3072 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_4096 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_256_R1 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_384_R1 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_521_R1; + if (test_buffer->version >= SPDM_MESSAGE_VERSION_12) { + spdm_request.struct_table[0].alg_supported |= SPDM_ALGORITHMS_DHE_NAMED_GROUP_SM2_P256; + } + spdm_request.struct_table[1].alg_type = SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_AEAD; + spdm_request.struct_table[1].alg_count = 0x20; + spdm_request.struct_table[1].alg_supported = SPDM_ALGORITHMS_AEAD_CIPHER_SUITE_AES_128_GCM | + SPDM_ALGORITHMS_AEAD_CIPHER_SUITE_AES_256_GCM | + SPDM_ALGORITHMS_AEAD_CIPHER_SUITE_CHACHA20_POLY1305; + if (test_buffer->version >= SPDM_MESSAGE_VERSION_12) { + spdm_request.struct_table[1].alg_supported |= + SPDM_ALGORITHMS_AEAD_CIPHER_SUITE_AEAD_SM4_GCM; + } + spdm_request.struct_table[2].alg_type = + SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_REQ_BASE_ASYM_ALG; + spdm_request.struct_table[2].alg_count = 0x20; + spdm_request.struct_table[2].alg_supported = + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_2048 + | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_3072 + | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_3072 + | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256 + | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_4096 + | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_4096 + | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P384 + | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P521; + if (test_buffer->version >= SPDM_MESSAGE_VERSION_12) { + spdm_request.struct_table[2].alg_supported |= + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_SM2_ECC_SM2_P256 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED25519 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED448; + } + spdm_request.struct_table[3].alg_type = + SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_KEY_SCHEDULE; + spdm_request.struct_table[3].alg_count = 0x20; + spdm_request.struct_table[3].alg_supported = SPDM_ALGORITHMS_KEY_SCHEDULE_HMAC_HASH; + + spdm_response = (void *)message; + spdm_response_size = sizeof(message); + libspdm_zero_mem(message, sizeof(message)); + status = libspdm_send_receive_data(spdm_context, NULL, false, + &spdm_request, spdm_request.length, + spdm_response, &spdm_response_size); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, + SPDM_RESPONDER_TEST_CASE_ALGORITHMS_UNEXPECTED_REQUEST_NON_IDENTICAL, + COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "First send/receive failure"); + return; + } + if (spdm_response->header.request_response_code != SPDM_ALGORITHMS) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, + SPDM_RESPONDER_TEST_CASE_ALGORITHMS_UNEXPECTED_REQUEST_NON_IDENTICAL, + COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "First NEGOTIATE_ALGORITHMS failure"); + return; + } + + base_asym_sel = spdm_response->base_asym_sel; + base_hash_sel = spdm_response->base_hash_sel; + + dhe_named_group = 0; + aead_cipher_suite = 0; + req_base_asym_alg = 0; + struct_table = (void *)((size_t)spdm_response + + sizeof(spdm_algorithms_response_t) + + sizeof(uint32_t) * spdm_response->ext_asym_sel_count + + sizeof(uint32_t) * spdm_response->ext_hash_sel_count); + for (index = 0; index < spdm_response->header.param1; index++) { + switch (struct_table->alg_type) { + case SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_DHE: + dhe_named_group = struct_table->alg_supported; + break; + case SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_AEAD: + aead_cipher_suite = struct_table->alg_supported; + break; + case SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_REQ_BASE_ASYM_ALG: + req_base_asym_alg = struct_table->alg_supported; + break; + case SPDM_NEGOTIATE_ALGORITHMS_STRUCT_TABLE_ALG_TYPE_KEY_SCHEDULE: + default: + break; + } + ext_alg_count = struct_table->alg_count & 0xF; + struct_table = + (void *)((size_t)struct_table + + sizeof(spdm_negotiate_algorithms_common_struct_table_t) + + sizeof(uint32_t) * ext_alg_count); + } + + for (index = 0; index < 3; index++) { + libspdm_copy_mem (&spdm_request_new, sizeof(spdm_request_new), &spdm_request, + sizeof(spdm_request)); + switch (index) { + case 0: + spdm_request_new.header.param2 = 1; + common_test_record_test_message ("test param2 - 1\n"); + break; + case 1: + spdm_request_new.base_asym_algo = base_asym_sel; + spdm_request_new.base_hash_algo = base_hash_sel; + common_test_record_test_message ( + "test base_asym_algo - 0x%08x, base_hash_algo - 0x%08x\n", base_asym_sel, + base_hash_sel); + break; + case 2: + if (test_buffer->version < SPDM_MESSAGE_VERSION_11) { + continue; + } + spdm_request_new.struct_table[0].alg_supported = dhe_named_group; + spdm_request_new.struct_table[1].alg_supported = aead_cipher_suite; + spdm_request_new.struct_table[2].alg_supported = req_base_asym_alg; + common_test_record_test_message ( + "test dhe_named_group - 0x%04x, aead_cipher_suite - 0x%04x, req_base_asym_alg - 0x%04x\n", + dhe_named_group, aead_cipher_suite, req_base_asym_alg); + break; + default: + break; + } + + spdm_response = (void *)message; + spdm_response_size = sizeof(message); + libspdm_zero_mem(message, sizeof(message)); + status = libspdm_send_receive_data(spdm_context, NULL, false, + &spdm_request_new, spdm_request_new.length, + spdm_response, &spdm_response_size); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, + SPDM_RESPONDER_TEST_CASE_ALGORITHMS_UNEXPECTED_REQUEST_NON_IDENTICAL, + COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "Second send/receive failure"); + continue; + } + + if (spdm_response_size >= sizeof(spdm_error_response_t)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, + SPDM_RESPONDER_TEST_CASE_ALGORITHMS_UNEXPECTED_REQUEST_NON_IDENTICAL, 1, + test_result, "response size - %d", spdm_response_size); + if (test_result == COMMON_TEST_RESULT_FAIL) { + continue; + } + + if (spdm_response->header.request_response_code == SPDM_ERROR) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, + SPDM_RESPONDER_TEST_CASE_ALGORITHMS_UNEXPECTED_REQUEST_NON_IDENTICAL, 2, + test_result, "response code - 0x%02x", spdm_response->header.request_response_code); + if (test_result == COMMON_TEST_RESULT_FAIL) { + continue; + } + + if (spdm_response->header.spdm_version == test_buffer->version) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, + SPDM_RESPONDER_TEST_CASE_ALGORITHMS_UNEXPECTED_REQUEST_NON_IDENTICAL, 3, + test_result, "response version - 0x%02x", spdm_response->header.spdm_version); + if (test_result == COMMON_TEST_RESULT_FAIL) { + continue; + } + + if (spdm_response->header.param1 == SPDM_ERROR_CODE_UNEXPECTED_REQUEST) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, + SPDM_RESPONDER_TEST_CASE_ALGORITHMS_UNEXPECTED_REQUEST_NON_IDENTICAL, 4, + test_result, "response param1 - 0x%02x", spdm_response->header.param1); + if (test_result == COMMON_TEST_RESULT_FAIL) { + continue; + } + + if (spdm_response->header.param2 == 0) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, + SPDM_RESPONDER_TEST_CASE_ALGORITHMS_UNEXPECTED_REQUEST_NON_IDENTICAL, 5, + test_result, "response param2 - 0x%02x", spdm_response->header.param2); + } +} + +common_test_case_t m_spdm_test_group_algorithms[] = { + {SPDM_RESPONDER_TEST_CASE_ALGORITHMS_SUCCESS_10, "spdm_test_case_algorithms_success_10", + spdm_test_case_algorithms_success_10, spdm_test_case_algorithms_setup_version_10}, + {SPDM_RESPONDER_TEST_CASE_ALGORITHMS_VERSION_MISMATCH, + "spdm_test_case_algorithms_version_mismatch", spdm_test_case_algorithms_version_mismatch, + spdm_test_case_algorithms_setup_version_any}, + {SPDM_RESPONDER_TEST_CASE_ALGORITHMS_UNEXPECTED_REQUEST, + "spdm_test_case_algorithms_unexpected_request", + spdm_test_case_algorithms_unexpected_request, spdm_test_case_algorithms_setup_version_only}, + {SPDM_RESPONDER_TEST_CASE_ALGORITHMS_INVALID_REQUEST, + "spdm_test_case_algorithms_invalid_request", spdm_test_case_algorithms_invalid_request, + spdm_test_case_algorithms_setup_version_any}, + {SPDM_RESPONDER_TEST_CASE_ALGORITHMS_SUCCESS_11, "spdm_test_case_algorithms_success_11", + spdm_test_case_algorithms_success_11, spdm_test_case_algorithms_setup_version_11}, + {SPDM_RESPONDER_TEST_CASE_ALGORITHMS_SUCCESS_12, "spdm_test_case_algorithms_success_12", + spdm_test_case_algorithms_success_12, spdm_test_case_algorithms_setup_version_12}, + {SPDM_RESPONDER_TEST_CASE_ALGORITHMS_UNEXPECTED_REQUEST_NON_IDENTICAL, + "spdm_test_case_algorithms_unexpected_non_identical", + spdm_test_case_algorithms_unexpected_non_identical, + spdm_test_case_algorithms_setup_version_any}, + {COMMON_TEST_ID_END, NULL, NULL}, +}; diff --git a/library/spdm_responder_conformance_test_lib/spdm_responder_test_4_digests.c b/library/spdm_responder_conformance_test_lib/spdm_responder_test_4_digests.c new file mode 100644 index 0000000..85a0ed5 --- /dev/null +++ b/library/spdm_responder_conformance_test_lib/spdm_responder_test_4_digests.c @@ -0,0 +1,525 @@ +/** + * Copyright Notice: + * Copyright 2021 DMTF. All rights reserved. + * License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/spdm-emu/blob/main/LICENSE.md + **/ + +#include "spdm_responder_test.h" + +#pragma pack(1) +typedef struct { + uint8_t version; + uint32_t hash_algo; + uint32_t hash_size; +} spdm_digests_test_buffer_t; +#pragma pack() + +bool spdm_test_case_digests_setup_vca (void *test_context, + spdm_version_number_t spdm_version) +{ + spdm_test_context_t *spdm_test_context; + void *spdm_context; + libspdm_return_t status; + libspdm_data_parameter_t parameter; + uint32_t rsp_cap_flags; + size_t data_size; + uint32_t data32; + uint16_t data16; + uint8_t data8; + spdm_digests_test_buffer_t *test_buffer; + + spdm_test_context = test_context; + spdm_context = spdm_test_context->spdm_context; + + if (spdm_version != 0) { + libspdm_zero_mem(¶meter, sizeof(parameter)); + parameter.location = LIBSPDM_DATA_LOCATION_LOCAL; + libspdm_set_data(spdm_context, LIBSPDM_DATA_SPDM_VERSION, ¶meter, + &spdm_version, sizeof(spdm_version)); + } + + data32 = SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CERT_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHAL_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_ENCRYPT_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MAC_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_KEY_EX_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_ENCAP_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_HBEAT_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_KEY_UPD_CAP; + libspdm_set_data(spdm_context, LIBSPDM_DATA_CAPABILITY_FLAGS, ¶meter, + &data32, sizeof(data32)); + + data8 = SPDM_MEASUREMENT_BLOCK_HEADER_SPECIFICATION_DMTF; + libspdm_set_data(spdm_context, LIBSPDM_DATA_MEASUREMENT_SPEC, ¶meter, + &data8, sizeof(data8)); + data32 = SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_2048 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_3072 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_3072 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_4096 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_4096 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P384 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P521 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_SM2_ECC_SM2_P256 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED25519 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED448; + libspdm_set_data(spdm_context, LIBSPDM_DATA_BASE_ASYM_ALGO, ¶meter, + &data32, sizeof(data32)); + data32 = SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_256 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_384 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_512 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA3_256 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA3_384 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA3_512 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SM3_256; + libspdm_set_data(spdm_context, LIBSPDM_DATA_BASE_HASH_ALGO, ¶meter, + &data32, sizeof(data32)); + data16 = SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_2048 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_3072 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_4096 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_256_R1 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_384_R1 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_521_R1 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_SM2_P256; + libspdm_set_data(spdm_context, LIBSPDM_DATA_DHE_NAME_GROUP, ¶meter, + &data16, sizeof(data16)); + data16 = SPDM_ALGORITHMS_AEAD_CIPHER_SUITE_AES_128_GCM | + SPDM_ALGORITHMS_AEAD_CIPHER_SUITE_AES_256_GCM | + SPDM_ALGORITHMS_AEAD_CIPHER_SUITE_CHACHA20_POLY1305 | + SPDM_ALGORITHMS_AEAD_CIPHER_SUITE_AEAD_SM4_GCM; + libspdm_set_data(spdm_context, LIBSPDM_DATA_AEAD_CIPHER_SUITE, ¶meter, + &data16, sizeof(data16)); + data16 = SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_2048 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_3072 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_3072 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_4096 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_4096 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P384 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P521 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_SM2_ECC_SM2_P256 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED25519 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED448; + libspdm_set_data(spdm_context, LIBSPDM_DATA_REQ_BASE_ASYM_ALG, ¶meter, + &data16, sizeof(data16)); + data16 = SPDM_ALGORITHMS_KEY_SCHEDULE_HMAC_HASH; + libspdm_set_data(spdm_context, LIBSPDM_DATA_KEY_SCHEDULE, ¶meter, &data16, + sizeof(data16)); + data8 = SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_1; + libspdm_set_data(spdm_context, LIBSPDM_DATA_OTHER_PARAMS_SUPPORT, ¶meter, + &data8, sizeof(data8)); + + status = libspdm_init_connection (spdm_context, false); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + return false; + } + + test_buffer = (void *)spdm_test_context->test_scratch_buffer; + LIBSPDM_ASSERT(sizeof(spdm_test_context->test_scratch_buffer) >= + sizeof(spdm_digests_test_buffer_t)); + libspdm_zero_mem(test_buffer, sizeof(spdm_digests_test_buffer_t)); + spdm_test_context->test_scratch_buffer_size = sizeof(spdm_digests_test_buffer_t); + + spdm_version = 0; + data_size = sizeof(spdm_version); + libspdm_zero_mem(¶meter, sizeof(parameter)); + parameter.location = LIBSPDM_DATA_LOCATION_CONNECTION; + libspdm_get_data(spdm_context, LIBSPDM_DATA_SPDM_VERSION, ¶meter, &spdm_version, + &data_size); + test_buffer->version = (spdm_version >> SPDM_VERSION_NUMBER_SHIFT_BIT); + + rsp_cap_flags = 0; + data_size = sizeof(rsp_cap_flags); + libspdm_zero_mem(¶meter, sizeof(parameter)); + parameter.location = LIBSPDM_DATA_LOCATION_CONNECTION; + libspdm_get_data(spdm_context, LIBSPDM_DATA_CAPABILITY_FLAGS, ¶meter, &rsp_cap_flags, + &data_size); + if ((rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP) == 0) { + return false; + } + + data_size = sizeof(test_buffer->hash_algo); + libspdm_get_data(spdm_context, LIBSPDM_DATA_BASE_HASH_ALGO, ¶meter, &test_buffer->hash_algo, + &data_size); + test_buffer->hash_size = libspdm_get_hash_size(test_buffer->hash_algo); + + return true; +} + +bool spdm_test_case_digests_setup_version_any (void *test_context) +{ + return spdm_test_case_digests_setup_vca (test_context, 0); +} + +bool spdm_test_case_digests_setup_version_capabilities (void *test_context) +{ + spdm_test_context_t *spdm_test_context; + void *spdm_context; + libspdm_return_t status; + libspdm_data_parameter_t parameter; + uint32_t rsp_cap_flags; + size_t data_size; + spdm_version_number_t spdm_version; + spdm_digests_test_buffer_t *test_buffer; + + spdm_test_context = test_context; + spdm_context = spdm_test_context->spdm_context; + + status = libspdm_get_version (spdm_context, NULL, NULL); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + return false; + } + + status = libspdm_get_capabilities (spdm_context); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + return false; + } + + rsp_cap_flags = 0; + data_size = sizeof(rsp_cap_flags); + libspdm_zero_mem(¶meter, sizeof(parameter)); + parameter.location = LIBSPDM_DATA_LOCATION_CONNECTION; + libspdm_get_data(spdm_context, LIBSPDM_DATA_CAPABILITY_FLAGS, ¶meter, &rsp_cap_flags, + &data_size); + if ((rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP) == 0) { + return false; + } + + test_buffer = (void *)spdm_test_context->test_scratch_buffer; + LIBSPDM_ASSERT(sizeof(spdm_test_context->test_scratch_buffer) >= + sizeof(spdm_digests_test_buffer_t)); + libspdm_zero_mem(test_buffer, sizeof(spdm_digests_test_buffer_t)); + spdm_test_context->test_scratch_buffer_size = sizeof(spdm_digests_test_buffer_t); + + spdm_version = 0; + data_size = sizeof(spdm_version); + libspdm_zero_mem(¶meter, sizeof(parameter)); + parameter.location = LIBSPDM_DATA_LOCATION_CONNECTION; + libspdm_get_data(spdm_context, LIBSPDM_DATA_SPDM_VERSION, ¶meter, &spdm_version, + &data_size); + test_buffer->version = (spdm_version >> SPDM_VERSION_NUMBER_SHIFT_BIT); + + spdm_test_context->test_scratch_buffer_size = sizeof(test_buffer->version); + + return true; +} + +void spdm_test_case_digests_success_10 (void *test_context) +{ + spdm_test_context_t *spdm_test_context; + void *spdm_context; + libspdm_return_t status; + spdm_get_digest_request_t spdm_request; + spdm_digest_response_t *spdm_response; + uint8_t message[LIBSPDM_MAX_MESSAGE_BUFFER_SIZE]; + size_t spdm_response_size; + common_test_result_t test_result; + spdm_digests_test_buffer_t *test_buffer; + uint8_t slot_count; + size_t index; + + spdm_test_context = test_context; + spdm_context = spdm_test_context->spdm_context; + test_buffer = (void *)spdm_test_context->test_scratch_buffer; + LIBSPDM_ASSERT(spdm_test_context->test_scratch_buffer_size == + sizeof(spdm_digests_test_buffer_t)); + + libspdm_zero_mem(&spdm_request, sizeof(spdm_request)); + spdm_request.header.spdm_version = test_buffer->version; + spdm_request.header.request_response_code = SPDM_GET_DIGESTS; + spdm_request.header.param1 = 0; + spdm_request.header.param2 = 0; + + spdm_response = (void *)message; + spdm_response_size = sizeof(message); + libspdm_zero_mem(message, sizeof(message)); + status = libspdm_send_receive_data(spdm_context, NULL, false, + &spdm_request, sizeof(spdm_request), + spdm_response, &spdm_response_size); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_DIGESTS, SPDM_RESPONDER_TEST_CASE_DIGESTS_SUCCESS_10, + COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "send/receive failure"); + return; + } + + if (spdm_response_size >= sizeof(spdm_digest_response_t)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_DIGESTS, SPDM_RESPONDER_TEST_CASE_DIGESTS_SUCCESS_10, 1, + test_result, "response size - %d", spdm_response_size); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.request_response_code == SPDM_DIGESTS) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_DIGESTS, SPDM_RESPONDER_TEST_CASE_DIGESTS_SUCCESS_10, 2, + test_result, "response code - 0x%02x", spdm_response->header.request_response_code); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.spdm_version == test_buffer->version) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_DIGESTS, SPDM_RESPONDER_TEST_CASE_DIGESTS_SUCCESS_10, 3, + test_result, "response version - 0x%02x", spdm_response->header.spdm_version); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if ((spdm_response->header.param2 & 0x1) != 0) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_DIGESTS, SPDM_RESPONDER_TEST_CASE_DIGESTS_SUCCESS_10, 4, + test_result, "response param2 - 0x%02x", spdm_response->header.param2); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + slot_count = 0; + for (index = 0; index < 8; index++) { + if ((spdm_response->header.param2 & (0x1 << index)) != 0) { + slot_count++; + } + } + + if (spdm_response_size >= + sizeof(spdm_digest_response_t) + slot_count * test_buffer->hash_size) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_DIGESTS, SPDM_RESPONDER_TEST_CASE_DIGESTS_SUCCESS_10, 4, + test_result, "response spdm_response_size - 0x%08x", spdm_response_size); +} + +void spdm_test_case_digests_version_mismatch (void *test_context) +{ + spdm_test_context_t *spdm_test_context; + void *spdm_context; + libspdm_return_t status; + spdm_get_digest_request_t spdm_request; + spdm_digest_response_t *spdm_response; + uint8_t message[LIBSPDM_MAX_MESSAGE_BUFFER_SIZE]; + size_t spdm_response_size; + common_test_result_t test_result; + spdm_digests_test_buffer_t *test_buffer; + uint8_t mismatched_version[] = { + SPDM_MESSAGE_VERSION_10 - 1, + SPDM_MESSAGE_VERSION_12 + 1, + }; + size_t index; + + spdm_test_context = test_context; + spdm_context = spdm_test_context->spdm_context; + test_buffer = (void *)spdm_test_context->test_scratch_buffer; + LIBSPDM_ASSERT(spdm_test_context->test_scratch_buffer_size == + sizeof(spdm_digests_test_buffer_t)); + + mismatched_version[0] = (uint8_t)(test_buffer->version - 1); + mismatched_version[1] = (uint8_t)(test_buffer->version + 1); + + for (index = 0; index < LIBSPDM_ARRAY_SIZE(mismatched_version); index++) { + common_test_record_test_message ("test mismatched_version - 0x%02x\n", + mismatched_version[index]); + libspdm_zero_mem(&spdm_request, sizeof(spdm_request)); + spdm_request.header.spdm_version = mismatched_version[index]; + spdm_request.header.request_response_code = SPDM_GET_DIGESTS; + spdm_request.header.param1 = 0; + spdm_request.header.param2 = 0; + + spdm_response = (void *)message; + spdm_response_size = sizeof(message); + libspdm_zero_mem(message, sizeof(message)); + status = libspdm_send_receive_data(spdm_context, NULL, false, + &spdm_request, sizeof(spdm_request), + spdm_response, &spdm_response_size); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_DIGESTS, + SPDM_RESPONDER_TEST_CASE_DIGESTS_VERSION_MISMATCH, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "send/receive failure"); + continue; + } + + if (spdm_response_size >= sizeof(spdm_error_response_t)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_DIGESTS, SPDM_RESPONDER_TEST_CASE_DIGESTS_VERSION_MISMATCH, 1, + test_result, "response size - %d", spdm_response_size); + if (test_result == COMMON_TEST_RESULT_FAIL) { + continue; + } + + if (spdm_response->header.request_response_code == SPDM_ERROR) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_DIGESTS, SPDM_RESPONDER_TEST_CASE_DIGESTS_VERSION_MISMATCH, 2, + test_result, "response code - 0x%02x", spdm_response->header.request_response_code); + if (test_result == COMMON_TEST_RESULT_FAIL) { + continue; + } + + if (spdm_response->header.spdm_version == test_buffer->version) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_DIGESTS, SPDM_RESPONDER_TEST_CASE_DIGESTS_VERSION_MISMATCH, 3, + test_result, "response version - 0x%02x", spdm_response->header.spdm_version); + if (test_result == COMMON_TEST_RESULT_FAIL) { + continue; + } + + if (spdm_response->header.param1 == SPDM_ERROR_CODE_VERSION_MISMATCH) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_DIGESTS, SPDM_RESPONDER_TEST_CASE_DIGESTS_VERSION_MISMATCH, 4, + test_result, "response param1 - 0x%02x", spdm_response->header.param1); + + if (spdm_response->header.param2 == 0) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_DIGESTS, SPDM_RESPONDER_TEST_CASE_DIGESTS_VERSION_MISMATCH, 5, + test_result, "response param2 - 0x%02x", spdm_response->header.param2); + } +} + +void spdm_test_case_digests_unexpected_request (void *test_context) +{ + spdm_test_context_t *spdm_test_context; + void *spdm_context; + libspdm_return_t status; + spdm_get_digest_request_t spdm_request; + spdm_digest_response_t *spdm_response; + size_t spdm_response_size; + uint8_t message[LIBSPDM_MAX_MESSAGE_BUFFER_SIZE]; + common_test_result_t test_result; + spdm_digests_test_buffer_t *test_buffer; + + spdm_test_context = test_context; + spdm_context = spdm_test_context->spdm_context; + test_buffer = (void *)spdm_test_context->test_scratch_buffer; + LIBSPDM_ASSERT(spdm_test_context->test_scratch_buffer_size == + sizeof(test_buffer->version)); + + libspdm_zero_mem(&spdm_request, sizeof(spdm_request)); + spdm_request.header.spdm_version = test_buffer->version; + spdm_request.header.request_response_code = SPDM_GET_DIGESTS; + spdm_request.header.param1 = 0; + spdm_request.header.param2 = 0; + + spdm_response = (void *)message; + spdm_response_size = sizeof(message); + libspdm_zero_mem(message, sizeof(message)); + status = libspdm_send_receive_data(spdm_context, NULL, false, + &spdm_request, sizeof(spdm_request), + spdm_response, &spdm_response_size); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_DIGESTS, SPDM_RESPONDER_TEST_CASE_DIGESTS_UNEXPECTED_REQUEST, + COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "send/receive failure"); + return; + } + + if (spdm_response_size >= sizeof(spdm_error_response_t)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_DIGESTS, SPDM_RESPONDER_TEST_CASE_DIGESTS_UNEXPECTED_REQUEST, 1, + test_result, "response size - %d", spdm_response_size); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.request_response_code == SPDM_ERROR) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_DIGESTS, SPDM_RESPONDER_TEST_CASE_DIGESTS_UNEXPECTED_REQUEST, 2, + test_result, "response code - 0x%02x", spdm_response->header.request_response_code); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.spdm_version == test_buffer->version) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_DIGESTS, SPDM_RESPONDER_TEST_CASE_DIGESTS_UNEXPECTED_REQUEST, 3, + test_result, "response version - 0x%02x", spdm_response->header.spdm_version); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.param1 == SPDM_ERROR_CODE_UNEXPECTED_REQUEST) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_DIGESTS, SPDM_RESPONDER_TEST_CASE_DIGESTS_UNEXPECTED_REQUEST, 4, + test_result, "response param1 - 0x%02x", spdm_response->header.param1); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.param2 == 0) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_DIGESTS, SPDM_RESPONDER_TEST_CASE_DIGESTS_UNEXPECTED_REQUEST, 5, + test_result, "response param2 - 0x%02x", spdm_response->header.param2); +} + +common_test_case_t m_spdm_test_group_digests[] = { + {SPDM_RESPONDER_TEST_CASE_DIGESTS_SUCCESS_10, "spdm_test_case_digests_success_10", + spdm_test_case_digests_success_10, spdm_test_case_digests_setup_version_any}, + {SPDM_RESPONDER_TEST_CASE_DIGESTS_VERSION_MISMATCH, "spdm_test_case_digests_version_mismatch", + spdm_test_case_digests_version_mismatch, spdm_test_case_digests_setup_version_any}, + {SPDM_RESPONDER_TEST_CASE_DIGESTS_UNEXPECTED_REQUEST, + "spdm_test_case_digests_unexpected_request", spdm_test_case_digests_unexpected_request, + spdm_test_case_digests_setup_version_capabilities}, + {COMMON_TEST_ID_END, NULL, NULL}, +}; diff --git a/library/spdm_responder_conformance_test_lib/spdm_responder_test_5_certificate.c b/library/spdm_responder_conformance_test_lib/spdm_responder_test_5_certificate.c new file mode 100644 index 0000000..ba1c0e8 --- /dev/null +++ b/library/spdm_responder_conformance_test_lib/spdm_responder_test_5_certificate.c @@ -0,0 +1,750 @@ +/** + * Copyright Notice: + * Copyright 2021 DMTF. All rights reserved. + * License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/spdm-emu/blob/main/LICENSE.md + **/ + +#include "spdm_responder_test.h" + +#pragma pack(1) +typedef struct { + uint8_t version; + uint32_t hash_algo; + uint32_t hash_size; + uint8_t slot_mask; + uint8_t slot_count; + uint8_t total_digest_buffer[SPDM_MAX_SLOT_COUNT * LIBSPDM_MAX_HASH_SIZE]; +} spdm_certificate_test_buffer_t; +#pragma pack() + +bool spdm_test_case_certificate_setup_vca_digest (void *test_context, + spdm_version_number_t spdm_version) +{ + spdm_test_context_t *spdm_test_context; + void *spdm_context; + libspdm_return_t status; + libspdm_data_parameter_t parameter; + uint32_t rsp_cap_flags; + size_t data_size; + uint32_t data32; + uint16_t data16; + uint8_t data8; + spdm_certificate_test_buffer_t *test_buffer; + size_t index; + + spdm_test_context = test_context; + spdm_context = spdm_test_context->spdm_context; + + if (spdm_version != 0) { + libspdm_zero_mem(¶meter, sizeof(parameter)); + parameter.location = LIBSPDM_DATA_LOCATION_LOCAL; + libspdm_set_data(spdm_context, LIBSPDM_DATA_SPDM_VERSION, ¶meter, + &spdm_version, sizeof(spdm_version)); + } + + data32 = SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CERT_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHAL_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_ENCRYPT_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MAC_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_KEY_EX_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_ENCAP_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_HBEAT_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_KEY_UPD_CAP; + libspdm_set_data(spdm_context, LIBSPDM_DATA_CAPABILITY_FLAGS, ¶meter, + &data32, sizeof(data32)); + + data8 = SPDM_MEASUREMENT_BLOCK_HEADER_SPECIFICATION_DMTF; + libspdm_set_data(spdm_context, LIBSPDM_DATA_MEASUREMENT_SPEC, ¶meter, + &data8, sizeof(data8)); + data32 = SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_2048 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_3072 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_3072 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_4096 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_4096 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P384 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P521 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_SM2_ECC_SM2_P256 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED25519 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED448; + libspdm_set_data(spdm_context, LIBSPDM_DATA_BASE_ASYM_ALGO, ¶meter, + &data32, sizeof(data32)); + data32 = SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_256 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_384 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_512 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA3_256 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA3_384 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA3_512 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SM3_256; + libspdm_set_data(spdm_context, LIBSPDM_DATA_BASE_HASH_ALGO, ¶meter, + &data32, sizeof(data32)); + data16 = SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_2048 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_3072 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_4096 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_256_R1 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_384_R1 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_521_R1 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_SM2_P256; + libspdm_set_data(spdm_context, LIBSPDM_DATA_DHE_NAME_GROUP, ¶meter, + &data16, sizeof(data16)); + data16 = SPDM_ALGORITHMS_AEAD_CIPHER_SUITE_AES_128_GCM | + SPDM_ALGORITHMS_AEAD_CIPHER_SUITE_AES_256_GCM | + SPDM_ALGORITHMS_AEAD_CIPHER_SUITE_CHACHA20_POLY1305 | + SPDM_ALGORITHMS_AEAD_CIPHER_SUITE_AEAD_SM4_GCM; + libspdm_set_data(spdm_context, LIBSPDM_DATA_AEAD_CIPHER_SUITE, ¶meter, + &data16, sizeof(data16)); + data16 = SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_2048 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_3072 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_3072 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_4096 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_4096 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P384 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P521 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_SM2_ECC_SM2_P256 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED25519 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED448; + libspdm_set_data(spdm_context, LIBSPDM_DATA_REQ_BASE_ASYM_ALG, ¶meter, + &data16, sizeof(data16)); + data16 = SPDM_ALGORITHMS_KEY_SCHEDULE_HMAC_HASH; + libspdm_set_data(spdm_context, LIBSPDM_DATA_KEY_SCHEDULE, ¶meter, &data16, + sizeof(data16)); + data8 = SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_1; + libspdm_set_data(spdm_context, LIBSPDM_DATA_OTHER_PARAMS_SUPPORT, ¶meter, + &data8, sizeof(data8)); + + status = libspdm_init_connection (spdm_context, false); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + return false; + } + + test_buffer = (void *)spdm_test_context->test_scratch_buffer; + LIBSPDM_ASSERT(sizeof(spdm_test_context->test_scratch_buffer) >= + sizeof(spdm_certificate_test_buffer_t)); + libspdm_zero_mem(test_buffer, sizeof(spdm_certificate_test_buffer_t)); + spdm_test_context->test_scratch_buffer_size = sizeof(spdm_certificate_test_buffer_t); + + spdm_version = 0; + data_size = sizeof(spdm_version); + libspdm_zero_mem(¶meter, sizeof(parameter)); + parameter.location = LIBSPDM_DATA_LOCATION_CONNECTION; + libspdm_get_data(spdm_context, LIBSPDM_DATA_SPDM_VERSION, ¶meter, &spdm_version, + &data_size); + test_buffer->version = (spdm_version >> SPDM_VERSION_NUMBER_SHIFT_BIT); + + rsp_cap_flags = 0; + data_size = sizeof(rsp_cap_flags); + libspdm_zero_mem(¶meter, sizeof(parameter)); + parameter.location = LIBSPDM_DATA_LOCATION_CONNECTION; + libspdm_get_data(spdm_context, LIBSPDM_DATA_CAPABILITY_FLAGS, ¶meter, &rsp_cap_flags, + &data_size); + if ((rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP) == 0) { + return false; + } + + data_size = sizeof(test_buffer->hash_algo); + libspdm_get_data(spdm_context, LIBSPDM_DATA_BASE_HASH_ALGO, ¶meter, &test_buffer->hash_algo, + &data_size); + test_buffer->hash_size = libspdm_get_hash_size(test_buffer->hash_algo); + + status = libspdm_get_digest (spdm_context, &test_buffer->slot_mask, + test_buffer->total_digest_buffer); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + return false; + } + + test_buffer->slot_count = 0; + for (index = 0; index < SPDM_MAX_SLOT_COUNT; index++) { + if ((test_buffer->slot_mask & (1 << index)) != 0) { + test_buffer->slot_count++; + } + } + + spdm_test_context->test_scratch_buffer_size = offsetof(spdm_certificate_test_buffer_t, + total_digest_buffer) + + test_buffer->hash_size * test_buffer->slot_count; + + return true; +} + +bool spdm_test_case_certificate_setup_version_any (void *test_context) +{ + return spdm_test_case_certificate_setup_vca_digest (test_context, 0); +} + +bool spdm_test_case_certificate_setup_version_capabilities (void *test_context) +{ + spdm_test_context_t *spdm_test_context; + void *spdm_context; + libspdm_return_t status; + libspdm_data_parameter_t parameter; + uint32_t rsp_cap_flags; + size_t data_size; + spdm_version_number_t spdm_version; + spdm_certificate_test_buffer_t *test_buffer; + + spdm_test_context = test_context; + spdm_context = spdm_test_context->spdm_context; + + status = libspdm_get_version (spdm_context, NULL, NULL); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + return false; + } + + status = libspdm_get_capabilities (spdm_context); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + return false; + } + + rsp_cap_flags = 0; + data_size = sizeof(rsp_cap_flags); + libspdm_zero_mem(¶meter, sizeof(parameter)); + parameter.location = LIBSPDM_DATA_LOCATION_CONNECTION; + libspdm_get_data(spdm_context, LIBSPDM_DATA_CAPABILITY_FLAGS, ¶meter, &rsp_cap_flags, + &data_size); + if ((rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP) == 0) { + return false; + } + + test_buffer = (void *)spdm_test_context->test_scratch_buffer; + LIBSPDM_ASSERT(sizeof(spdm_test_context->test_scratch_buffer) >= + sizeof(spdm_certificate_test_buffer_t)); + libspdm_zero_mem(test_buffer, sizeof(spdm_certificate_test_buffer_t)); + spdm_test_context->test_scratch_buffer_size = sizeof(spdm_certificate_test_buffer_t); + + spdm_version = 0; + data_size = sizeof(spdm_version); + libspdm_zero_mem(¶meter, sizeof(parameter)); + parameter.location = LIBSPDM_DATA_LOCATION_CONNECTION; + libspdm_get_data(spdm_context, LIBSPDM_DATA_SPDM_VERSION, ¶meter, &spdm_version, + &data_size); + test_buffer->version = (spdm_version >> SPDM_VERSION_NUMBER_SHIFT_BIT); + + spdm_test_context->test_scratch_buffer_size = sizeof(test_buffer->version); + + return true; +} + +void spdm_test_case_certificate_success_10 (void *test_context) +{ + spdm_test_context_t *spdm_test_context; + void *spdm_context; + libspdm_return_t status; + spdm_get_certificate_request_t spdm_request; + spdm_certificate_response_t *spdm_response; + uint8_t message[LIBSPDM_MAX_MESSAGE_BUFFER_SIZE]; + size_t spdm_response_size; + uint8_t cert_chain_buffer[LIBSPDM_MAX_CERT_CHAIN_SIZE]; + size_t cert_chain_buffer_size; + spdm_cert_chain_t *spdm_cert_chain; + uint8_t cert_chain_hash[LIBSPDM_MAX_HASH_SIZE]; + common_test_result_t test_result; + spdm_certificate_test_buffer_t *test_buffer; + uint8_t slot_id; + uint8_t hash_index; + bool result; + + spdm_test_context = test_context; + spdm_context = spdm_test_context->spdm_context; + test_buffer = (void *)spdm_test_context->test_scratch_buffer; + LIBSPDM_ASSERT(spdm_test_context->test_scratch_buffer_size == + offsetof(spdm_certificate_test_buffer_t, total_digest_buffer) + + test_buffer->hash_size * test_buffer->slot_count); + + hash_index = 0; + for (slot_id = 0; slot_id < SPDM_MAX_SLOT_COUNT; slot_id++) { + if ((test_buffer->slot_mask & (0x1 << slot_id)) == 0) { + continue; + } + common_test_record_test_message ("test slot - 0x%02x (hash index - 0x%02x)\n", slot_id, + hash_index); + + cert_chain_buffer_size = 0; + do { + common_test_record_test_message ("test offset - 0x%04x\n", cert_chain_buffer_size); + + libspdm_zero_mem(&spdm_request, sizeof(spdm_request)); + spdm_request.header.spdm_version = test_buffer->version; + spdm_request.header.request_response_code = SPDM_GET_CERTIFICATE; + spdm_request.header.param1 = slot_id; + spdm_request.header.param2 = 0; + spdm_request.offset = (uint16_t)cert_chain_buffer_size; + spdm_request.length = LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN; + + spdm_response = (void *)message; + spdm_response_size = sizeof(message); + libspdm_zero_mem(message, sizeof(message)); + status = libspdm_send_receive_data(spdm_context, NULL, false, + &spdm_request, sizeof(spdm_request), + spdm_response, &spdm_response_size); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CERTIFICATE, + SPDM_RESPONDER_TEST_CASE_CERTIFICATE_SUCCESS_10, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "send/receive failure"); + return; + } + + if (spdm_response_size >= sizeof(spdm_certificate_response_t)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CERTIFICATE, + SPDM_RESPONDER_TEST_CASE_CERTIFICATE_SUCCESS_10, 1, + test_result, "response size - %d", spdm_response_size); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.request_response_code == SPDM_CERTIFICATE) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CERTIFICATE, + SPDM_RESPONDER_TEST_CASE_CERTIFICATE_SUCCESS_10, 2, + test_result, "response code - 0x%02x", spdm_response->header.request_response_code); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.spdm_version == test_buffer->version) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CERTIFICATE, + SPDM_RESPONDER_TEST_CASE_CERTIFICATE_SUCCESS_10, 3, + test_result, "response version - 0x%02x", spdm_response->header.spdm_version); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if ((spdm_response->portion_length > 0) && + (spdm_response->portion_length <= spdm_request.length)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CERTIFICATE, + SPDM_RESPONDER_TEST_CASE_CERTIFICATE_SUCCESS_10, 4, + test_result, "response portion_length - 0x%04x", spdm_response->portion_length); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + libspdm_copy_mem (&cert_chain_buffer[cert_chain_buffer_size], + sizeof(cert_chain_buffer) - cert_chain_buffer_size, + spdm_response + 1, + spdm_response->portion_length); + cert_chain_buffer_size += spdm_response->portion_length; + } while (spdm_response->remainder_length != 0); + + spdm_cert_chain = (void *)cert_chain_buffer; + + if ((cert_chain_buffer_size > sizeof(spdm_cert_chain) + test_buffer->hash_size) && + (cert_chain_buffer_size == spdm_cert_chain->length)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CERTIFICATE, SPDM_RESPONDER_TEST_CASE_CERTIFICATE_SUCCESS_10, + 5, + test_result, "response cert chain buffer size - 0x%x, cert_chain.length - 0x%04x", + cert_chain_buffer_size, spdm_cert_chain->length); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + result = libspdm_hash_all (test_buffer->hash_algo, cert_chain_buffer, cert_chain_buffer_size, + cert_chain_hash); + if (!result) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CERTIFICATE, SPDM_RESPONDER_TEST_CASE_CERTIFICATE_SUCCESS_10, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "calc_cert_hash failure"); + return; + } + if (libspdm_const_compare_mem (cert_chain_hash, + &test_buffer->total_digest_buffer[hash_index * + test_buffer->hash_size], + test_buffer->hash_size) == 0) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CERTIFICATE, SPDM_RESPONDER_TEST_CASE_CERTIFICATE_SUCCESS_10, + 6, + test_result, "response cert chain hash"); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + hash_index++; + } +} + +void spdm_test_case_certificate_version_mismatch (void *test_context) +{ + spdm_test_context_t *spdm_test_context; + void *spdm_context; + libspdm_return_t status; + spdm_get_certificate_request_t spdm_request; + spdm_certificate_response_t *spdm_response; + uint8_t message[LIBSPDM_MAX_MESSAGE_BUFFER_SIZE]; + size_t spdm_response_size; + common_test_result_t test_result; + spdm_certificate_test_buffer_t *test_buffer; + uint8_t mismatched_version[] = { + SPDM_MESSAGE_VERSION_10 - 1, + SPDM_MESSAGE_VERSION_12 + 1, + }; + size_t index; + + spdm_test_context = test_context; + spdm_context = spdm_test_context->spdm_context; + test_buffer = (void *)spdm_test_context->test_scratch_buffer; + LIBSPDM_ASSERT(spdm_test_context->test_scratch_buffer_size == + offsetof(spdm_certificate_test_buffer_t, total_digest_buffer) + + test_buffer->hash_size * test_buffer->slot_count); + + mismatched_version[0] = (uint8_t)(test_buffer->version - 1); + mismatched_version[1] = (uint8_t)(test_buffer->version + 1); + + for (index = 0; index < LIBSPDM_ARRAY_SIZE(mismatched_version); index++) { + common_test_record_test_message ("test mismatched_version - 0x%02x\n", + mismatched_version[index]); + libspdm_zero_mem(&spdm_request, sizeof(spdm_request)); + spdm_request.header.spdm_version = mismatched_version[index]; + spdm_request.header.request_response_code = SPDM_GET_CERTIFICATE; + spdm_request.header.param1 = 0; + spdm_request.header.param2 = 0; + spdm_request.offset = 0; + spdm_request.length = LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN; + + spdm_response = (void *)message; + spdm_response_size = sizeof(message); + libspdm_zero_mem(message, sizeof(message)); + status = libspdm_send_receive_data(spdm_context, NULL, false, + &spdm_request, sizeof(spdm_request), + spdm_response, &spdm_response_size); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CERTIFICATE, + SPDM_RESPONDER_TEST_CASE_CERTIFICATE_VERSION_MISMATCH, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "send/receive failure"); + continue; + } + + if (spdm_response_size >= sizeof(spdm_error_response_t)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CERTIFICATE, + SPDM_RESPONDER_TEST_CASE_CERTIFICATE_VERSION_MISMATCH, 1, + test_result, "response size - %d", spdm_response_size); + if (test_result == COMMON_TEST_RESULT_FAIL) { + continue; + } + + if (spdm_response->header.request_response_code == SPDM_ERROR) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CERTIFICATE, + SPDM_RESPONDER_TEST_CASE_CERTIFICATE_VERSION_MISMATCH, 2, + test_result, "response code - 0x%02x", spdm_response->header.request_response_code); + if (test_result == COMMON_TEST_RESULT_FAIL) { + continue; + } + + if (spdm_response->header.spdm_version == test_buffer->version) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CERTIFICATE, + SPDM_RESPONDER_TEST_CASE_CERTIFICATE_VERSION_MISMATCH, 3, + test_result, "response version - 0x%02x", spdm_response->header.spdm_version); + if (test_result == COMMON_TEST_RESULT_FAIL) { + continue; + } + + if (spdm_response->header.param1 == SPDM_ERROR_CODE_VERSION_MISMATCH) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CERTIFICATE, + SPDM_RESPONDER_TEST_CASE_CERTIFICATE_VERSION_MISMATCH, 4, + test_result, "response param1 - 0x%02x", spdm_response->header.param1); + + if (spdm_response->header.param2 == 0) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CERTIFICATE, + SPDM_RESPONDER_TEST_CASE_CERTIFICATE_VERSION_MISMATCH, 5, + test_result, "response param2 - 0x%02x", spdm_response->header.param2); + } +} + +void spdm_test_case_certificate_unexpected_request (void *test_context) +{ + spdm_test_context_t *spdm_test_context; + void *spdm_context; + libspdm_return_t status; + spdm_get_certificate_request_t spdm_request; + spdm_certificate_response_t *spdm_response; + size_t spdm_response_size; + uint8_t message[LIBSPDM_MAX_MESSAGE_BUFFER_SIZE]; + common_test_result_t test_result; + spdm_certificate_test_buffer_t *test_buffer; + + spdm_test_context = test_context; + spdm_context = spdm_test_context->spdm_context; + test_buffer = (void *)spdm_test_context->test_scratch_buffer; + LIBSPDM_ASSERT(spdm_test_context->test_scratch_buffer_size == + sizeof(test_buffer->version)); + + libspdm_zero_mem(&spdm_request, sizeof(spdm_request)); + spdm_request.header.spdm_version = test_buffer->version; + spdm_request.header.request_response_code = SPDM_GET_CERTIFICATE; + spdm_request.header.param1 = 0; + spdm_request.header.param2 = 0; + spdm_request.offset = 0; + spdm_request.length = LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN; + + spdm_response = (void *)message; + spdm_response_size = sizeof(message); + libspdm_zero_mem(message, sizeof(message)); + status = libspdm_send_receive_data(spdm_context, NULL, false, + &spdm_request, sizeof(spdm_request), + spdm_response, &spdm_response_size); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CERTIFICATE, + SPDM_RESPONDER_TEST_CASE_CERTIFICATE_UNEXPECTED_REQUEST, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "send/receive failure"); + return; + } + + if (spdm_response_size >= sizeof(spdm_error_response_t)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CERTIFICATE, + SPDM_RESPONDER_TEST_CASE_CERTIFICATE_UNEXPECTED_REQUEST, 1, + test_result, "response size - %d", spdm_response_size); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.request_response_code == SPDM_ERROR) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CERTIFICATE, + SPDM_RESPONDER_TEST_CASE_CERTIFICATE_UNEXPECTED_REQUEST, 2, + test_result, "response code - 0x%02x", spdm_response->header.request_response_code); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.spdm_version == test_buffer->version) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CERTIFICATE, + SPDM_RESPONDER_TEST_CASE_CERTIFICATE_UNEXPECTED_REQUEST, 3, + test_result, "response version - 0x%02x", spdm_response->header.spdm_version); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.param1 == SPDM_ERROR_CODE_UNEXPECTED_REQUEST) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CERTIFICATE, + SPDM_RESPONDER_TEST_CASE_CERTIFICATE_UNEXPECTED_REQUEST, 4, + test_result, "response param1 - 0x%02x", spdm_response->header.param1); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.param2 == 0) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CERTIFICATE, + SPDM_RESPONDER_TEST_CASE_CERTIFICATE_UNEXPECTED_REQUEST, 5, + test_result, "response param2 - 0x%02x", spdm_response->header.param2); +} + +void spdm_test_case_certificate_invalid_request (void *test_context) +{ + spdm_test_context_t *spdm_test_context; + void *spdm_context; + libspdm_return_t status; + spdm_get_certificate_request_t spdm_request; + spdm_get_certificate_request_t spdm_request_new; + spdm_certificate_response_t *spdm_response; + uint8_t message[LIBSPDM_MAX_MESSAGE_BUFFER_SIZE]; + size_t spdm_response_size; + common_test_result_t test_result; + spdm_certificate_test_buffer_t *test_buffer; + size_t index; + uint8_t slot_id; + + spdm_test_context = test_context; + spdm_context = spdm_test_context->spdm_context; + test_buffer = (void *)spdm_test_context->test_scratch_buffer; + LIBSPDM_ASSERT(spdm_test_context->test_scratch_buffer_size == + offsetof(spdm_certificate_test_buffer_t, total_digest_buffer) + + test_buffer->hash_size * test_buffer->slot_count); + + libspdm_zero_mem(&spdm_request, sizeof(spdm_request)); + spdm_request.header.spdm_version = test_buffer->version; + spdm_request.header.request_response_code = SPDM_GET_CERTIFICATE; + spdm_request.header.param1 = 0; + spdm_request.header.param2 = 0; + spdm_request.offset = 0; + spdm_request.length = LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN; + + for (index = 0; index < SPDM_MAX_SLOT_COUNT * 2 + 2; index++) { + libspdm_copy_mem (&spdm_request_new, sizeof(spdm_request_new), &spdm_request, + sizeof(spdm_request)); + + if (index < SPDM_MAX_SLOT_COUNT * 2) { + slot_id = (uint8_t)index; + if ((slot_id < SPDM_MAX_SLOT_COUNT) && + ((test_buffer->slot_mask & (0x1 << slot_id)) != 0)) { + continue; + } + common_test_record_test_message ("test invalid slot - 0x%02x\n", slot_id); + spdm_request_new.header.param1 = slot_id; + } else if (index == SPDM_MAX_SLOT_COUNT * 2) { + common_test_record_test_message ("test invalid offset - 0x%04x\n", 0xFFFF); + spdm_request_new.offset = 0xFFFF; + } else { + common_test_record_test_message ("test invalid length - 0x%04x\n", 0); + spdm_request_new.length = 0; + } + + spdm_response = (void *)message; + spdm_response_size = sizeof(message); + libspdm_zero_mem(message, sizeof(message)); + status = libspdm_send_receive_data(spdm_context, NULL, false, + &spdm_request_new, sizeof(spdm_request_new), + spdm_response, &spdm_response_size); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CERTIFICATE, + SPDM_RESPONDER_TEST_CASE_CERTIFICATE_INVALID_REQUEST, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "send/receive failure"); + continue; + } + + if (spdm_response_size >= sizeof(spdm_error_response_t)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CERTIFICATE, + SPDM_RESPONDER_TEST_CASE_CERTIFICATE_INVALID_REQUEST, 1, + test_result, "response size - %d", spdm_response_size); + if (test_result == COMMON_TEST_RESULT_FAIL) { + continue; + } + + if (spdm_response->header.request_response_code == SPDM_ERROR) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CERTIFICATE, + SPDM_RESPONDER_TEST_CASE_CERTIFICATE_INVALID_REQUEST, 2, + test_result, "response code - 0x%02x", spdm_response->header.request_response_code); + if (test_result == COMMON_TEST_RESULT_FAIL) { + continue; + } + + if (spdm_response->header.spdm_version == test_buffer->version) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CERTIFICATE, + SPDM_RESPONDER_TEST_CASE_CERTIFICATE_INVALID_REQUEST, 3, + test_result, "response version - 0x%02x", spdm_response->header.spdm_version); + if (test_result == COMMON_TEST_RESULT_FAIL) { + continue; + } + + if (spdm_response->header.param1 == SPDM_ERROR_CODE_INVALID_REQUEST) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CERTIFICATE, + SPDM_RESPONDER_TEST_CASE_CERTIFICATE_INVALID_REQUEST, 4, + test_result, "response param1 - 0x%02x", spdm_response->header.param1); + + if (spdm_response->header.param2 == 0) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CERTIFICATE, + SPDM_RESPONDER_TEST_CASE_CERTIFICATE_INVALID_REQUEST, 5, + test_result, "response param2 - 0x%02x", spdm_response->header.param2); + } +} + +common_test_case_t m_spdm_test_group_certificate[] = { + {SPDM_RESPONDER_TEST_CASE_CERTIFICATE_SUCCESS_10, "spdm_test_case_certificate_success_10", + spdm_test_case_certificate_success_10, spdm_test_case_certificate_setup_version_any}, + {SPDM_RESPONDER_TEST_CASE_CERTIFICATE_VERSION_MISMATCH, + "spdm_test_case_certificate_version_mismatch", spdm_test_case_certificate_version_mismatch, + spdm_test_case_certificate_setup_version_any}, + {SPDM_RESPONDER_TEST_CASE_CERTIFICATE_UNEXPECTED_REQUEST, + "spdm_test_case_certificate_unexpected_request", + spdm_test_case_certificate_unexpected_request, + spdm_test_case_certificate_setup_version_capabilities}, + {SPDM_RESPONDER_TEST_CASE_CERTIFICATE_INVALID_REQUEST, + "spdm_test_case_certificate_invalid_request", spdm_test_case_certificate_invalid_request, + spdm_test_case_certificate_setup_version_any}, + {COMMON_TEST_ID_END, NULL, NULL}, +}; diff --git a/library/spdm_responder_conformance_test_lib/spdm_responder_test_6_challenge_auth.c b/library/spdm_responder_conformance_test_lib/spdm_responder_test_6_challenge_auth.c new file mode 100644 index 0000000..7f1ab36 --- /dev/null +++ b/library/spdm_responder_conformance_test_lib/spdm_responder_test_6_challenge_auth.c @@ -0,0 +1,1056 @@ +/** + * Copyright Notice: + * Copyright 2021 DMTF. All rights reserved. + * License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/spdm-emu/blob/main/LICENSE.md + **/ + +#include "spdm_responder_test.h" + +#define SPDM_MESSAGE_A_MASK_VCA 0x1 +#define SPDM_MESSAGE_B_MASK_GET_DIGESTS 0x2 +#define SPDM_MESSAGE_B_MASK_GET_CERTIFICATE 0x4 + +#pragma pack(1) +typedef struct { + uint8_t version; + uint32_t rsp_cap_flags; + uint32_t hash_algo; + uint32_t hash_size; + uint32_t asym_algo; + uint32_t signature_size; + uint8_t slot_mask; + uint8_t slot_count; + uint8_t total_digest_buffer[SPDM_MAX_SLOT_COUNT * LIBSPDM_MAX_HASH_SIZE]; +} spdm_challenge_auth_test_buffer_t; +#pragma pack() + +bool spdm_test_case_challenge_auth_setup_vca_digest (void *test_context, + size_t spdm_version_count, + spdm_version_number_t *spdm_version) +{ + spdm_test_context_t *spdm_test_context; + void *spdm_context; + spdm_version_number_t version; + libspdm_return_t status; + libspdm_data_parameter_t parameter; + size_t data_size; + uint32_t data32; + uint16_t data16; + uint8_t data8; + spdm_challenge_auth_test_buffer_t *test_buffer; + size_t index; + + spdm_test_context = test_context; + spdm_context = spdm_test_context->spdm_context; + + if (spdm_version_count != 0) { + libspdm_zero_mem(¶meter, sizeof(parameter)); + parameter.location = LIBSPDM_DATA_LOCATION_LOCAL; + libspdm_set_data(spdm_context, LIBSPDM_DATA_SPDM_VERSION, ¶meter, + spdm_version, sizeof(spdm_version_number_t) * spdm_version_count); + } + + data32 = SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CERT_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHAL_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_ENCRYPT_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MAC_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_KEY_EX_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_ENCAP_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_HBEAT_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_KEY_UPD_CAP; + libspdm_set_data(spdm_context, LIBSPDM_DATA_CAPABILITY_FLAGS, ¶meter, + &data32, sizeof(data32)); + + data8 = SPDM_MEASUREMENT_BLOCK_HEADER_SPECIFICATION_DMTF; + libspdm_set_data(spdm_context, LIBSPDM_DATA_MEASUREMENT_SPEC, ¶meter, + &data8, sizeof(data8)); + data32 = SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_2048 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_3072 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_3072 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_4096 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_4096 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P384 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P521 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_SM2_ECC_SM2_P256 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED25519 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED448; + libspdm_set_data(spdm_context, LIBSPDM_DATA_BASE_ASYM_ALGO, ¶meter, + &data32, sizeof(data32)); + data32 = SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_256 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_384 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_512 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA3_256 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA3_384 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA3_512 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SM3_256; + libspdm_set_data(spdm_context, LIBSPDM_DATA_BASE_HASH_ALGO, ¶meter, + &data32, sizeof(data32)); + data16 = SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_2048 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_3072 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_4096 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_256_R1 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_384_R1 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_521_R1 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_SM2_P256; + libspdm_set_data(spdm_context, LIBSPDM_DATA_DHE_NAME_GROUP, ¶meter, + &data16, sizeof(data16)); + data16 = SPDM_ALGORITHMS_AEAD_CIPHER_SUITE_AES_128_GCM | + SPDM_ALGORITHMS_AEAD_CIPHER_SUITE_AES_256_GCM | + SPDM_ALGORITHMS_AEAD_CIPHER_SUITE_CHACHA20_POLY1305 | + SPDM_ALGORITHMS_AEAD_CIPHER_SUITE_AEAD_SM4_GCM; + libspdm_set_data(spdm_context, LIBSPDM_DATA_AEAD_CIPHER_SUITE, ¶meter, + &data16, sizeof(data16)); + data16 = SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_2048 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_3072 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_3072 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_4096 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_4096 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P384 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P521 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_SM2_ECC_SM2_P256 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED25519 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED448; + libspdm_set_data(spdm_context, LIBSPDM_DATA_REQ_BASE_ASYM_ALG, ¶meter, + &data16, sizeof(data16)); + data16 = SPDM_ALGORITHMS_KEY_SCHEDULE_HMAC_HASH; + libspdm_set_data(spdm_context, LIBSPDM_DATA_KEY_SCHEDULE, ¶meter, &data16, + sizeof(data16)); + data8 = SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_1; + libspdm_set_data(spdm_context, LIBSPDM_DATA_OTHER_PARAMS_SUPPORT, ¶meter, + &data8, sizeof(data8)); + + status = libspdm_init_connection (spdm_context, false); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + return false; + } + + test_buffer = (void *)spdm_test_context->test_scratch_buffer; + LIBSPDM_ASSERT(sizeof(spdm_test_context->test_scratch_buffer) >= + sizeof(spdm_challenge_auth_test_buffer_t)); + libspdm_zero_mem(test_buffer, sizeof(spdm_challenge_auth_test_buffer_t)); + spdm_test_context->test_scratch_buffer_size = sizeof(spdm_challenge_auth_test_buffer_t); + + data_size = sizeof(version); + libspdm_zero_mem(¶meter, sizeof(parameter)); + parameter.location = LIBSPDM_DATA_LOCATION_CONNECTION; + libspdm_get_data(spdm_context, LIBSPDM_DATA_SPDM_VERSION, ¶meter, &version, &data_size); + test_buffer->version = (version >> SPDM_VERSION_NUMBER_SHIFT_BIT); + + data_size = sizeof(test_buffer->rsp_cap_flags); + libspdm_zero_mem(¶meter, sizeof(parameter)); + parameter.location = LIBSPDM_DATA_LOCATION_CONNECTION; + libspdm_get_data(spdm_context, LIBSPDM_DATA_CAPABILITY_FLAGS, ¶meter, + &test_buffer->rsp_cap_flags, &data_size); + if (((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP) == 0) || + ((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHAL_CAP) == 0)) { + return false; + } + + data_size = sizeof(test_buffer->hash_algo); + libspdm_get_data(spdm_context, LIBSPDM_DATA_BASE_HASH_ALGO, ¶meter, &test_buffer->hash_algo, + &data_size); + test_buffer->hash_size = libspdm_get_hash_size(test_buffer->hash_algo); + + data_size = sizeof(test_buffer->asym_algo); + libspdm_get_data(spdm_context, LIBSPDM_DATA_BASE_ASYM_ALGO, ¶meter, &test_buffer->asym_algo, + &data_size); + test_buffer->signature_size = libspdm_get_asym_signature_size(test_buffer->asym_algo); + + status = libspdm_get_digest (spdm_context, &test_buffer->slot_mask, + test_buffer->total_digest_buffer); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + return false; + } + + test_buffer->slot_count = 0; + for (index = 0; index < SPDM_MAX_SLOT_COUNT; index++) { + if ((test_buffer->slot_mask & (1 << index)) != 0) { + test_buffer->slot_count++; + } + } + + spdm_test_context->test_scratch_buffer_size = offsetof(spdm_challenge_auth_test_buffer_t, + total_digest_buffer) + + test_buffer->hash_size * test_buffer->slot_count; + + return true; +} + +bool spdm_test_case_challenge_auth_setup_version_any (void *test_context) +{ + return spdm_test_case_challenge_auth_setup_vca_digest (test_context, 0, NULL); +} + +bool spdm_test_case_challenge_auth_setup_version_10_11 (void *test_context) +{ + spdm_version_number_t spdm_version[] = { + SPDM_MESSAGE_VERSION_11 << SPDM_VERSION_NUMBER_SHIFT_BIT, + SPDM_MESSAGE_VERSION_10 << SPDM_VERSION_NUMBER_SHIFT_BIT + }; + return spdm_test_case_challenge_auth_setup_vca_digest (test_context, + LIBSPDM_ARRAY_SIZE( + spdm_version), spdm_version); +} + +bool spdm_test_case_challenge_auth_setup_version_12 (void *test_context) +{ + spdm_version_number_t spdm_version[] = { + SPDM_MESSAGE_VERSION_12 << SPDM_VERSION_NUMBER_SHIFT_BIT + }; + return spdm_test_case_challenge_auth_setup_vca_digest (test_context, + LIBSPDM_ARRAY_SIZE( + spdm_version), spdm_version); +} + +bool spdm_test_case_challenge_auth_setup_version_capabilities (void *test_context) +{ + spdm_test_context_t *spdm_test_context; + void *spdm_context; + libspdm_return_t status; + libspdm_data_parameter_t parameter; + size_t data_size; + spdm_version_number_t spdm_version; + spdm_challenge_auth_test_buffer_t *test_buffer; + + spdm_test_context = test_context; + spdm_context = spdm_test_context->spdm_context; + + status = libspdm_get_version (spdm_context, NULL, NULL); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + return false; + } + + status = libspdm_get_capabilities (spdm_context); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + return false; + } + + test_buffer = (void *)spdm_test_context->test_scratch_buffer; + LIBSPDM_ASSERT(sizeof(spdm_test_context->test_scratch_buffer) >= + sizeof(spdm_challenge_auth_test_buffer_t)); + libspdm_zero_mem(test_buffer, sizeof(spdm_challenge_auth_test_buffer_t)); + spdm_test_context->test_scratch_buffer_size = sizeof(spdm_challenge_auth_test_buffer_t); + + data_size = sizeof(test_buffer->rsp_cap_flags); + libspdm_zero_mem(¶meter, sizeof(parameter)); + parameter.location = LIBSPDM_DATA_LOCATION_CONNECTION; + libspdm_get_data(spdm_context, LIBSPDM_DATA_CAPABILITY_FLAGS, ¶meter, + &test_buffer->rsp_cap_flags, &data_size); + if (((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP) == 0) || + ((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHAL_CAP) == 0)) { + return false; + } + + spdm_version = 0; + data_size = sizeof(spdm_version); + libspdm_zero_mem(¶meter, sizeof(parameter)); + parameter.location = LIBSPDM_DATA_LOCATION_CONNECTION; + libspdm_get_data(spdm_context, LIBSPDM_DATA_SPDM_VERSION, ¶meter, &spdm_version, + &data_size); + test_buffer->version = (spdm_version >> SPDM_VERSION_NUMBER_SHIFT_BIT); + + spdm_test_context->test_scratch_buffer_size = sizeof(test_buffer->version); + + return true; +} + +void spdm_test_case_challenge_auth_success_10_12 (void *test_context, uint8_t version, + uint8_t message_mask) +{ + spdm_test_context_t *spdm_test_context; + void *spdm_context; + libspdm_return_t status; + spdm_challenge_request_t spdm_request; + spdm_challenge_auth_response_t *spdm_response; + uint8_t message[LIBSPDM_MAX_MESSAGE_BUFFER_SIZE]; + size_t spdm_response_size; + uint8_t cert_chain_buffer[LIBSPDM_MAX_CERT_CHAIN_SIZE]; + size_t cert_chain_buffer_size; + common_test_result_t test_result; + spdm_challenge_auth_test_buffer_t *test_buffer; + uint8_t slot_id; + uint8_t hash_index; + uint8_t meas_hash_type_index; + uint32_t meas_hash_size; + uint8_t *cert_chain_hash_ptr; + uint16_t *opaque_length_ptr; + uint8_t *signature_ptr; + bool result; + uint8_t measurement_hash_type[] = { + SPDM_CHALLENGE_REQUEST_NO_MEASUREMENT_SUMMARY_HASH, + SPDM_CHALLENGE_REQUEST_TCB_COMPONENT_MEASUREMENT_HASH, + SPDM_CHALLENGE_REQUEST_ALL_MEASUREMENTS_HASH, + }; + common_test_case_id case_id; + + spdm_test_context = test_context; + spdm_context = spdm_test_context->spdm_context; + test_buffer = (void *)spdm_test_context->test_scratch_buffer; + LIBSPDM_ASSERT(spdm_test_context->test_scratch_buffer_size == + offsetof(spdm_challenge_auth_test_buffer_t, total_digest_buffer) + + test_buffer->hash_size * test_buffer->slot_count); + + switch (version) { + case SPDM_MESSAGE_VERSION_10: + LIBSPDM_ASSERT ((test_buffer->version == SPDM_MESSAGE_VERSION_10) || + (test_buffer->version == SPDM_MESSAGE_VERSION_11)); + switch (message_mask) { + case SPDM_MESSAGE_A_MASK_VCA | SPDM_MESSAGE_B_MASK_GET_DIGESTS | + SPDM_MESSAGE_B_MASK_GET_CERTIFICATE: + case_id = SPDM_RESPONDER_TEST_CASE_CHALLENGE_AUTH_SUCCESS_10_A1B1C1; + break; + case SPDM_MESSAGE_A_MASK_VCA: + case_id = SPDM_RESPONDER_TEST_CASE_CHALLENGE_AUTH_SUCCESS_10_A1B2C1; + break; + case SPDM_MESSAGE_A_MASK_VCA | SPDM_MESSAGE_B_MASK_GET_DIGESTS: + case_id = SPDM_RESPONDER_TEST_CASE_CHALLENGE_AUTH_SUCCESS_10_A1B3C1; + break; + default: + LIBSPDM_ASSERT(false); + return; + } + break; + case SPDM_MESSAGE_VERSION_12: + LIBSPDM_ASSERT (test_buffer->version == SPDM_MESSAGE_VERSION_12); + switch (message_mask) { + case SPDM_MESSAGE_A_MASK_VCA | SPDM_MESSAGE_B_MASK_GET_DIGESTS | + SPDM_MESSAGE_B_MASK_GET_CERTIFICATE: + case_id = SPDM_RESPONDER_TEST_CASE_CHALLENGE_AUTH_SUCCESS_12_A1B1C1; + break; + case SPDM_MESSAGE_A_MASK_VCA: + case_id = SPDM_RESPONDER_TEST_CASE_CHALLENGE_AUTH_SUCCESS_12_A1B2C1; + break; + case SPDM_MESSAGE_A_MASK_VCA | SPDM_MESSAGE_B_MASK_GET_DIGESTS: + case_id = SPDM_RESPONDER_TEST_CASE_CHALLENGE_AUTH_SUCCESS_12_A1B3C1; + break; + case SPDM_MESSAGE_A_MASK_VCA | SPDM_MESSAGE_B_MASK_GET_CERTIFICATE: + case_id = SPDM_RESPONDER_TEST_CASE_CHALLENGE_AUTH_SUCCESS_12_A1B4C1; + break; + case SPDM_MESSAGE_B_MASK_GET_DIGESTS | SPDM_MESSAGE_B_MASK_GET_CERTIFICATE: + case_id = SPDM_RESPONDER_TEST_CASE_CHALLENGE_AUTH_SUCCESS_12_A2B1C1; + break; + case 0: + case_id = SPDM_RESPONDER_TEST_CASE_CHALLENGE_AUTH_SUCCESS_12_A2B2C1; + break; + case SPDM_MESSAGE_B_MASK_GET_DIGESTS: + case_id = SPDM_RESPONDER_TEST_CASE_CHALLENGE_AUTH_SUCCESS_12_A2B3C1; + break; + case SPDM_MESSAGE_B_MASK_GET_CERTIFICATE: + case_id = SPDM_RESPONDER_TEST_CASE_CHALLENGE_AUTH_SUCCESS_12_A2B4C1; + break; + default: + LIBSPDM_ASSERT(false); + return; + } + break; + default: + LIBSPDM_ASSERT(false); + return; + } + + hash_index = 0; + for (slot_id = 0; slot_id < SPDM_MAX_SLOT_COUNT; slot_id++) { + if ((test_buffer->slot_mask & (0x1 << slot_id)) == 0) { + continue; + } + common_test_record_test_message ("test slot - 0x%02x (hash index - 0x%02x)\n", slot_id, + hash_index); + + for (meas_hash_type_index = 0; + meas_hash_type_index < LIBSPDM_ARRAY_SIZE(measurement_hash_type); + meas_hash_type_index++) { + if ((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP) == 0) { + if (measurement_hash_type[meas_hash_type_index] != + SPDM_CHALLENGE_REQUEST_NO_MEASUREMENT_SUMMARY_HASH) { + continue; + } + } + common_test_record_test_message ("test meas hash type - 0x%02x\n", + measurement_hash_type[meas_hash_type_index]); + + status = libspdm_init_connection (spdm_context, false); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CHALLENGE_AUTH, case_id, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "init_connection failure"); + continue; + } + + if ((message_mask & SPDM_MESSAGE_A_MASK_VCA) == 0) { + status = + libspdm_challenge (spdm_context, slot_id, + measurement_hash_type[meas_hash_type_index], NULL, NULL); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CHALLENGE_AUTH, case_id, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "first challenge failure"); + continue; + } + } + + if ((message_mask & SPDM_MESSAGE_B_MASK_GET_DIGESTS) != 0) { + status = libspdm_get_digest (spdm_context, NULL, NULL); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CHALLENGE_AUTH, case_id, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "get_digest failure"); + continue; + } + } + + if ((message_mask & SPDM_MESSAGE_B_MASK_GET_CERTIFICATE) != 0) { + cert_chain_buffer_size = sizeof(cert_chain_buffer); + status = libspdm_get_certificate (spdm_context, slot_id, &cert_chain_buffer_size, + cert_chain_buffer); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CHALLENGE_AUTH, case_id, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "get_certificate failure"); + continue; + } + } + + libspdm_zero_mem(&spdm_request, sizeof(spdm_request)); + spdm_request.header.spdm_version = test_buffer->version; + spdm_request.header.request_response_code = SPDM_CHALLENGE; + spdm_request.header.param1 = slot_id; + spdm_request.header.param2 = measurement_hash_type[meas_hash_type_index]; + /* ignore spdm_request.nonce */ + + spdm_response = (void *)message; + spdm_response_size = sizeof(message); + libspdm_zero_mem(message, sizeof(message)); + status = libspdm_send_receive_data(spdm_context, NULL, false, + &spdm_request, sizeof(spdm_request), + spdm_response, &spdm_response_size); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CHALLENGE_AUTH, case_id, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "send/receive failure"); + return; + } + + if (measurement_hash_type[meas_hash_type_index] == + SPDM_CHALLENGE_REQUEST_NO_MEASUREMENT_SUMMARY_HASH) { + meas_hash_size = 0; + } else { + meas_hash_size = test_buffer->hash_size; + } + opaque_length_ptr = + (void *)((size_t)spdm_response + sizeof(spdm_challenge_auth_response_t) + + test_buffer->hash_size + SPDM_NONCE_SIZE + + meas_hash_size); + if (spdm_response_size < sizeof(spdm_challenge_auth_response_t) + + test_buffer->hash_size + SPDM_NONCE_SIZE + + meas_hash_size + sizeof(uint16_t) + + test_buffer->signature_size) { + test_result = COMMON_TEST_RESULT_FAIL; + } else { + if (spdm_response_size < sizeof(spdm_challenge_auth_response_t) + + test_buffer->hash_size + SPDM_NONCE_SIZE + + meas_hash_size + sizeof(uint16_t) + + *opaque_length_ptr + test_buffer->signature_size) { + test_result = COMMON_TEST_RESULT_FAIL; + } else { + test_result = COMMON_TEST_RESULT_PASS; + } + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CHALLENGE_AUTH, case_id, 1, + test_result, "response size - %d", spdm_response_size); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + cert_chain_hash_ptr = + (void *)((size_t)spdm_response + sizeof(spdm_challenge_auth_response_t)); + signature_ptr = + (void *)((size_t)spdm_response + sizeof(spdm_challenge_auth_response_t) + + test_buffer->hash_size + SPDM_NONCE_SIZE + + meas_hash_size + sizeof(uint16_t) + + *opaque_length_ptr); + + if (spdm_response->header.request_response_code == SPDM_CHALLENGE_AUTH) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CHALLENGE_AUTH, case_id, 2, + test_result, "response code - 0x%02x", spdm_response->header.request_response_code); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.spdm_version == test_buffer->version) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CHALLENGE_AUTH, case_id, 3, + test_result, "response version - 0x%02x", spdm_response->header.spdm_version); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if ((spdm_response->header.param1 & + SPDM_CHALLENGE_AUTH_RESPONSE_ATTRIBUTE_SLOT_ID_MASK) == slot_id) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CHALLENGE_AUTH, case_id, 4, + test_result, "response param1 - 0x%02x", spdm_response->header.param1); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if ((spdm_response->header.param2 & (1 << slot_id)) != 0) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CHALLENGE_AUTH, case_id, 5, + test_result, "response param2 - 0x%02x", spdm_response->header.param2); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (libspdm_const_compare_mem (cert_chain_hash_ptr, + &test_buffer->total_digest_buffer[hash_index * + test_buffer->hash_size], + test_buffer->hash_size) == 0) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CHALLENGE_AUTH, case_id, 6, + test_result, "response cert chain hash"); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + status = libspdm_append_message_c(spdm_context, &spdm_request, + sizeof(spdm_request)); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CHALLENGE_AUTH, case_id, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "append_message_c failure"); + return; + } + status = libspdm_append_message_c(spdm_context, spdm_response, + (size_t)signature_ptr - (size_t)spdm_response); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CHALLENGE_AUTH, case_id, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "append_message_c failure"); + return; + } + result = libspdm_verify_challenge_auth_signature( + spdm_context, true, signature_ptr, test_buffer->signature_size); + if (result) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CHALLENGE_AUTH, case_id, 7, + test_result, "response signature"); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + } + + hash_index++; + } +} + +void spdm_test_case_challenge_auth_success_10_a1b1c1 (void *test_context) +{ + spdm_test_case_challenge_auth_success_10_12 (test_context, + SPDM_MESSAGE_VERSION_10, + SPDM_MESSAGE_A_MASK_VCA | + SPDM_MESSAGE_B_MASK_GET_DIGESTS | + SPDM_MESSAGE_B_MASK_GET_CERTIFICATE); +} + +void spdm_test_case_challenge_auth_success_10_a1b2c1 (void *test_context) +{ + spdm_test_case_challenge_auth_success_10_12 (test_context, + SPDM_MESSAGE_VERSION_10, + SPDM_MESSAGE_A_MASK_VCA); +} + +void spdm_test_case_challenge_auth_success_10_a1b3c1 (void *test_context) +{ + spdm_test_case_challenge_auth_success_10_12 (test_context, + SPDM_MESSAGE_VERSION_10, + SPDM_MESSAGE_A_MASK_VCA | + SPDM_MESSAGE_B_MASK_GET_DIGESTS); +} + +void spdm_test_case_challenge_auth_success_12_a1b1c1 (void *test_context) +{ + spdm_test_case_challenge_auth_success_10_12 (test_context, + SPDM_MESSAGE_VERSION_12, + SPDM_MESSAGE_A_MASK_VCA | + SPDM_MESSAGE_B_MASK_GET_DIGESTS | + SPDM_MESSAGE_B_MASK_GET_CERTIFICATE); +} + +void spdm_test_case_challenge_auth_success_12_a1b2c1 (void *test_context) +{ + spdm_test_case_challenge_auth_success_10_12 (test_context, + SPDM_MESSAGE_VERSION_12, + SPDM_MESSAGE_A_MASK_VCA); +} + +void spdm_test_case_challenge_auth_success_12_a1b3c1 (void *test_context) +{ + spdm_test_case_challenge_auth_success_10_12 (test_context, + SPDM_MESSAGE_VERSION_12, + SPDM_MESSAGE_A_MASK_VCA | + SPDM_MESSAGE_B_MASK_GET_DIGESTS); +} + +void spdm_test_case_challenge_auth_success_12_a1b4c1 (void *test_context) +{ + spdm_test_case_challenge_auth_success_10_12 (test_context, + SPDM_MESSAGE_VERSION_12, + SPDM_MESSAGE_A_MASK_VCA | + SPDM_MESSAGE_B_MASK_GET_CERTIFICATE); +} + +void spdm_test_case_challenge_auth_success_12_a2b1c1 (void *test_context) +{ + spdm_test_case_challenge_auth_success_10_12 (test_context, + SPDM_MESSAGE_VERSION_12, + SPDM_MESSAGE_B_MASK_GET_DIGESTS | + SPDM_MESSAGE_B_MASK_GET_CERTIFICATE); +} + +void spdm_test_case_challenge_auth_success_12_a2b2c1 (void *test_context) +{ + spdm_test_case_challenge_auth_success_10_12 (test_context, + SPDM_MESSAGE_VERSION_12, 0); +} + +void spdm_test_case_challenge_auth_success_12_a2b3c1 (void *test_context) +{ + spdm_test_case_challenge_auth_success_10_12 (test_context, + SPDM_MESSAGE_VERSION_12, + SPDM_MESSAGE_B_MASK_GET_DIGESTS); +} + +void spdm_test_case_challenge_auth_success_12_a2b4c1 (void *test_context) +{ + spdm_test_case_challenge_auth_success_10_12 (test_context, + SPDM_MESSAGE_VERSION_12, + SPDM_MESSAGE_B_MASK_GET_CERTIFICATE); +} + +void spdm_test_case_challenge_auth_version_mismatch (void *test_context) +{ + spdm_test_context_t *spdm_test_context; + void *spdm_context; + libspdm_return_t status; + spdm_challenge_request_t spdm_request; + spdm_challenge_auth_response_t *spdm_response; + uint8_t message[LIBSPDM_MAX_MESSAGE_BUFFER_SIZE]; + size_t spdm_response_size; + common_test_result_t test_result; + spdm_challenge_auth_test_buffer_t *test_buffer; + uint8_t mismatched_version[] = { + SPDM_MESSAGE_VERSION_10 - 1, + SPDM_MESSAGE_VERSION_12 + 1, + }; + size_t index; + + spdm_test_context = test_context; + spdm_context = spdm_test_context->spdm_context; + test_buffer = (void *)spdm_test_context->test_scratch_buffer; + LIBSPDM_ASSERT(spdm_test_context->test_scratch_buffer_size == + offsetof(spdm_challenge_auth_test_buffer_t, total_digest_buffer) + + test_buffer->hash_size * test_buffer->slot_count); + + mismatched_version[0] = (uint8_t)(test_buffer->version - 1); + mismatched_version[1] = (uint8_t)(test_buffer->version + 1); + + for (index = 0; index < LIBSPDM_ARRAY_SIZE(mismatched_version); index++) { + common_test_record_test_message ("test mismatched_version - 0x%02x\n", + mismatched_version[index]); + libspdm_zero_mem(&spdm_request, sizeof(spdm_request)); + spdm_request.header.spdm_version = mismatched_version[index]; + spdm_request.header.request_response_code = SPDM_CHALLENGE; + spdm_request.header.param1 = 0; + spdm_request.header.param2 = SPDM_CHALLENGE_REQUEST_NO_MEASUREMENT_SUMMARY_HASH; + + spdm_response = (void *)message; + spdm_response_size = sizeof(message); + libspdm_zero_mem(message, sizeof(message)); + status = libspdm_send_receive_data(spdm_context, NULL, false, + &spdm_request, sizeof(spdm_request), + spdm_response, &spdm_response_size); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CHALLENGE_AUTH, + SPDM_RESPONDER_TEST_CASE_CHALLENGE_AUTH_VERSION_MISMATCH, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "send/receive failure"); + continue; + } + + if (spdm_response_size >= sizeof(spdm_error_response_t)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CHALLENGE_AUTH, + SPDM_RESPONDER_TEST_CASE_CHALLENGE_AUTH_VERSION_MISMATCH, 1, + test_result, "response size - %d", spdm_response_size); + if (test_result == COMMON_TEST_RESULT_FAIL) { + continue; + } + + if (spdm_response->header.request_response_code == SPDM_ERROR) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CHALLENGE_AUTH, + SPDM_RESPONDER_TEST_CASE_CHALLENGE_AUTH_VERSION_MISMATCH, 2, + test_result, "response code - 0x%02x", spdm_response->header.request_response_code); + if (test_result == COMMON_TEST_RESULT_FAIL) { + continue; + } + + if (spdm_response->header.spdm_version == test_buffer->version) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CHALLENGE_AUTH, + SPDM_RESPONDER_TEST_CASE_CHALLENGE_AUTH_VERSION_MISMATCH, 3, + test_result, "response version - 0x%02x", spdm_response->header.spdm_version); + if (test_result == COMMON_TEST_RESULT_FAIL) { + continue; + } + + if (spdm_response->header.param1 == SPDM_ERROR_CODE_VERSION_MISMATCH) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CHALLENGE_AUTH, + SPDM_RESPONDER_TEST_CASE_CHALLENGE_AUTH_VERSION_MISMATCH, 4, + test_result, "response param1 - 0x%02x", spdm_response->header.param1); + + if (spdm_response->header.param2 == 0) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CHALLENGE_AUTH, + SPDM_RESPONDER_TEST_CASE_CHALLENGE_AUTH_VERSION_MISMATCH, 5, + test_result, "response param2 - 0x%02x", spdm_response->header.param2); + } +} + +void spdm_test_case_challenge_auth_unexpected_request (void *test_context) +{ + spdm_test_context_t *spdm_test_context; + void *spdm_context; + libspdm_return_t status; + spdm_challenge_request_t spdm_request; + spdm_challenge_auth_response_t *spdm_response; + size_t spdm_response_size; + uint8_t message[LIBSPDM_MAX_MESSAGE_BUFFER_SIZE]; + common_test_result_t test_result; + spdm_challenge_auth_test_buffer_t *test_buffer; + + spdm_test_context = test_context; + spdm_context = spdm_test_context->spdm_context; + test_buffer = (void *)spdm_test_context->test_scratch_buffer; + LIBSPDM_ASSERT(spdm_test_context->test_scratch_buffer_size == + sizeof(test_buffer->version)); + + libspdm_zero_mem(&spdm_request, sizeof(spdm_request)); + spdm_request.header.spdm_version = test_buffer->version; + spdm_request.header.request_response_code = SPDM_CHALLENGE; + spdm_request.header.param1 = 0; + spdm_request.header.param2 = SPDM_CHALLENGE_REQUEST_NO_MEASUREMENT_SUMMARY_HASH; + + spdm_response = (void *)message; + spdm_response_size = sizeof(message); + libspdm_zero_mem(message, sizeof(message)); + status = libspdm_send_receive_data(spdm_context, NULL, false, + &spdm_request, sizeof(spdm_request), + spdm_response, &spdm_response_size); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CHALLENGE_AUTH, + SPDM_RESPONDER_TEST_CASE_CHALLENGE_AUTH_UNEXPECTED_REQUEST, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "send/receive failure"); + return; + } + + if (spdm_response_size >= sizeof(spdm_error_response_t)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CHALLENGE_AUTH, + SPDM_RESPONDER_TEST_CASE_CHALLENGE_AUTH_UNEXPECTED_REQUEST, 1, + test_result, "response size - %d", spdm_response_size); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.request_response_code == SPDM_ERROR) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CHALLENGE_AUTH, + SPDM_RESPONDER_TEST_CASE_CHALLENGE_AUTH_UNEXPECTED_REQUEST, 2, + test_result, "response code - 0x%02x", spdm_response->header.request_response_code); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.spdm_version == test_buffer->version) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CHALLENGE_AUTH, + SPDM_RESPONDER_TEST_CASE_CHALLENGE_AUTH_UNEXPECTED_REQUEST, 3, + test_result, "response version - 0x%02x", spdm_response->header.spdm_version); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.param1 == SPDM_ERROR_CODE_UNEXPECTED_REQUEST) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CHALLENGE_AUTH, + SPDM_RESPONDER_TEST_CASE_CHALLENGE_AUTH_UNEXPECTED_REQUEST, 4, + test_result, "response param1 - 0x%02x", spdm_response->header.param1); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.param2 == 0) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CHALLENGE_AUTH, + SPDM_RESPONDER_TEST_CASE_CHALLENGE_AUTH_UNEXPECTED_REQUEST, 5, + test_result, "response param2 - 0x%02x", spdm_response->header.param2); +} + +void spdm_test_case_challenge_auth_invalid_request (void *test_context) +{ + spdm_test_context_t *spdm_test_context; + void *spdm_context; + libspdm_return_t status; + spdm_challenge_request_t spdm_request; + spdm_challenge_request_t spdm_request_new; + spdm_challenge_auth_response_t *spdm_response; + uint8_t message[LIBSPDM_MAX_MESSAGE_BUFFER_SIZE]; + size_t spdm_response_size; + common_test_result_t test_result; + spdm_challenge_auth_test_buffer_t *test_buffer; + size_t index; + uint8_t slot_id; + + spdm_test_context = test_context; + spdm_context = spdm_test_context->spdm_context; + test_buffer = (void *)spdm_test_context->test_scratch_buffer; + LIBSPDM_ASSERT(spdm_test_context->test_scratch_buffer_size == + offsetof(spdm_challenge_auth_test_buffer_t, total_digest_buffer) + + test_buffer->hash_size * test_buffer->slot_count); + + libspdm_zero_mem(&spdm_request, sizeof(spdm_request)); + spdm_request.header.spdm_version = test_buffer->version; + spdm_request.header.request_response_code = SPDM_CHALLENGE; + spdm_request.header.param1 = 0; + spdm_request.header.param2 = SPDM_CHALLENGE_REQUEST_NO_MEASUREMENT_SUMMARY_HASH; + + for (index = 0; index < SPDM_MAX_SLOT_COUNT * 2 + 2; index++) { + libspdm_copy_mem (&spdm_request_new, sizeof(spdm_request_new), &spdm_request, + sizeof(spdm_request)); + + if (index < SPDM_MAX_SLOT_COUNT * 2) { + slot_id = (uint8_t)index; + if ((slot_id < SPDM_MAX_SLOT_COUNT) && + ((test_buffer->slot_mask & (0x1 << slot_id)) != 0)) { + continue; + } + common_test_record_test_message ("test invalid slot - 0x%02x\n", slot_id); + spdm_request_new.header.param1 = slot_id; + } else if (index == SPDM_MAX_SLOT_COUNT * 2) { + common_test_record_test_message ("test invalid meas_hash_type - 0x%02x\n", + SPDM_CHALLENGE_REQUEST_TCB_COMPONENT_MEASUREMENT_HASH + + 1); + spdm_request_new.header.param2 = SPDM_CHALLENGE_REQUEST_TCB_COMPONENT_MEASUREMENT_HASH + + 1; + } else { + common_test_record_test_message ("test invalid meas_hash_type - 0x%02x\n", + SPDM_CHALLENGE_REQUEST_ALL_MEASUREMENTS_HASH - 1); + spdm_request_new.header.param2 = SPDM_CHALLENGE_REQUEST_ALL_MEASUREMENTS_HASH - 1; + } + + spdm_response = (void *)message; + spdm_response_size = sizeof(message); + libspdm_zero_mem(message, sizeof(message)); + status = libspdm_send_receive_data(spdm_context, NULL, false, + &spdm_request_new, sizeof(spdm_request_new), + spdm_response, &spdm_response_size); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CHALLENGE_AUTH, + SPDM_RESPONDER_TEST_CASE_CHALLENGE_AUTH_INVALID_REQUEST, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "send/receive failure"); + continue; + } + + if (spdm_response_size >= sizeof(spdm_error_response_t)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CHALLENGE_AUTH, + SPDM_RESPONDER_TEST_CASE_CHALLENGE_AUTH_INVALID_REQUEST, 1, + test_result, "response size - %d", spdm_response_size); + if (test_result == COMMON_TEST_RESULT_FAIL) { + continue; + } + + if (spdm_response->header.request_response_code == SPDM_ERROR) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CHALLENGE_AUTH, + SPDM_RESPONDER_TEST_CASE_CHALLENGE_AUTH_INVALID_REQUEST, 2, + test_result, "response code - 0x%02x", spdm_response->header.request_response_code); + if (test_result == COMMON_TEST_RESULT_FAIL) { + continue; + } + + if (spdm_response->header.spdm_version == test_buffer->version) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CHALLENGE_AUTH, + SPDM_RESPONDER_TEST_CASE_CHALLENGE_AUTH_INVALID_REQUEST, 3, + test_result, "response version - 0x%02x", spdm_response->header.spdm_version); + if (test_result == COMMON_TEST_RESULT_FAIL) { + continue; + } + + if (spdm_response->header.param1 == SPDM_ERROR_CODE_INVALID_REQUEST) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CHALLENGE_AUTH, + SPDM_RESPONDER_TEST_CASE_CHALLENGE_AUTH_INVALID_REQUEST, 4, + test_result, "response param1 - 0x%02x", spdm_response->header.param1); + + if (spdm_response->header.param2 == 0) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_CHALLENGE_AUTH, + SPDM_RESPONDER_TEST_CASE_CHALLENGE_AUTH_INVALID_REQUEST, 5, + test_result, "response param2 - 0x%02x", spdm_response->header.param2); + } +} + +common_test_case_t m_spdm_test_group_challenge_auth[] = { + {SPDM_RESPONDER_TEST_CASE_CHALLENGE_AUTH_SUCCESS_10_A1B1C1, + "spdm_test_case_challenge_auth_success_10_a1b1c1", + spdm_test_case_challenge_auth_success_10_a1b1c1, + spdm_test_case_challenge_auth_setup_version_10_11}, + {SPDM_RESPONDER_TEST_CASE_CHALLENGE_AUTH_SUCCESS_10_A1B2C1, + "spdm_test_case_challenge_auth_success_10_a1b2c1", + spdm_test_case_challenge_auth_success_10_a1b2c1, + spdm_test_case_challenge_auth_setup_version_10_11}, + {SPDM_RESPONDER_TEST_CASE_CHALLENGE_AUTH_SUCCESS_10_A1B3C1, + "spdm_test_case_challenge_auth_success_10_a1b3c1", + spdm_test_case_challenge_auth_success_10_a1b3c1, + spdm_test_case_challenge_auth_setup_version_10_11}, + {SPDM_RESPONDER_TEST_CASE_CHALLENGE_AUTH_VERSION_MISMATCH, + "spdm_test_case_challenge_auth_version_mismatch", + spdm_test_case_challenge_auth_version_mismatch, + spdm_test_case_challenge_auth_setup_version_any}, + {SPDM_RESPONDER_TEST_CASE_CHALLENGE_AUTH_UNEXPECTED_REQUEST, + "spdm_test_case_challenge_auth_unexpected_request", + spdm_test_case_challenge_auth_unexpected_request, + spdm_test_case_challenge_auth_setup_version_capabilities}, + {SPDM_RESPONDER_TEST_CASE_CHALLENGE_AUTH_INVALID_REQUEST, + "spdm_test_case_challenge_auth_invalid_request", + spdm_test_case_challenge_auth_invalid_request, + spdm_test_case_challenge_auth_setup_version_any}, + {SPDM_RESPONDER_TEST_CASE_CHALLENGE_AUTH_SUCCESS_12_A1B1C1, + "spdm_test_case_challenge_auth_success_12_a1b1c1", + spdm_test_case_challenge_auth_success_12_a1b1c1, + spdm_test_case_challenge_auth_setup_version_12}, + {SPDM_RESPONDER_TEST_CASE_CHALLENGE_AUTH_SUCCESS_12_A1B2C1, + "spdm_test_case_challenge_auth_success_12_a1b2c1", + spdm_test_case_challenge_auth_success_12_a1b2c1, + spdm_test_case_challenge_auth_setup_version_12}, + {SPDM_RESPONDER_TEST_CASE_CHALLENGE_AUTH_SUCCESS_12_A1B3C1, + "spdm_test_case_challenge_auth_success_12_a1b3c1", + spdm_test_case_challenge_auth_success_12_a1b3c1, + spdm_test_case_challenge_auth_setup_version_12}, + {SPDM_RESPONDER_TEST_CASE_CHALLENGE_AUTH_SUCCESS_12_A1B4C1, + "spdm_test_case_challenge_auth_success_12_a1b4c1", + spdm_test_case_challenge_auth_success_12_a1b4c1, + spdm_test_case_challenge_auth_setup_version_12}, + {SPDM_RESPONDER_TEST_CASE_CHALLENGE_AUTH_SUCCESS_12_A2B1C1, + "spdm_test_case_challenge_auth_success_12_a2b1c1", + spdm_test_case_challenge_auth_success_12_a2b1c1, + spdm_test_case_challenge_auth_setup_version_12}, + {SPDM_RESPONDER_TEST_CASE_CHALLENGE_AUTH_SUCCESS_12_A2B2C1, + "spdm_test_case_challenge_auth_success_12_a2b2c1", + spdm_test_case_challenge_auth_success_12_a2b2c1, + spdm_test_case_challenge_auth_setup_version_12}, + {SPDM_RESPONDER_TEST_CASE_CHALLENGE_AUTH_SUCCESS_12_A2B3C1, + "spdm_test_case_challenge_auth_success_12_a2b3c1", + spdm_test_case_challenge_auth_success_12_a2b3c1, + spdm_test_case_challenge_auth_setup_version_12}, + {SPDM_RESPONDER_TEST_CASE_CHALLENGE_AUTH_SUCCESS_12_A2B4C1, + "spdm_test_case_challenge_auth_success_12_a2b4c1", + spdm_test_case_challenge_auth_success_12_a2b4c1, + spdm_test_case_challenge_auth_setup_version_12}, + {COMMON_TEST_ID_END, NULL, NULL}, +}; diff --git a/library/spdm_responder_conformance_test_lib/spdm_responder_test_7_measurements.c b/library/spdm_responder_conformance_test_lib/spdm_responder_test_7_measurements.c new file mode 100644 index 0000000..5c9156c --- /dev/null +++ b/library/spdm_responder_conformance_test_lib/spdm_responder_test_7_measurements.c @@ -0,0 +1,1816 @@ +/** + * Copyright Notice: + * Copyright 2021 DMTF. All rights reserved. + * License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/spdm-emu/blob/main/LICENSE.md + **/ + +#include "spdm_responder_test.h" + +#pragma pack(1) +typedef struct { + uint8_t version; + uint32_t rsp_cap_flags; + uint32_t hash_algo; + uint32_t hash_size; + uint32_t asym_algo; + uint32_t signature_size; + uint8_t slot_mask; + uint8_t slot_count; + uint8_t reserved; + uint32_t session_id; + uint8_t measurement_summary_hash[LIBSPDM_MAX_HASH_SIZE]; +} spdm_measurements_test_buffer_t; +#pragma pack() + +bool spdm_test_case_measurements_setup_vca_challenge_session (void *test_context, bool need_session, + size_t spdm_version_count, + spdm_version_number_t *spdm_version) +{ + spdm_test_context_t *spdm_test_context; + void *spdm_context; + spdm_version_number_t version; + libspdm_return_t status; + libspdm_data_parameter_t parameter; + size_t data_size; + uint32_t data32; + uint16_t data16; + uint8_t data8; + spdm_measurements_test_buffer_t *test_buffer; + size_t index; + + spdm_test_context = test_context; + spdm_context = spdm_test_context->spdm_context; + + if (spdm_version_count != 0) { + libspdm_zero_mem(¶meter, sizeof(parameter)); + parameter.location = LIBSPDM_DATA_LOCATION_LOCAL; + libspdm_set_data(spdm_context, LIBSPDM_DATA_SPDM_VERSION, ¶meter, + spdm_version, sizeof(spdm_version_number_t) * spdm_version_count); + } + + data32 = SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CERT_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHAL_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_ENCRYPT_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MAC_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_KEY_EX_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_ENCAP_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_HBEAT_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_KEY_UPD_CAP; + libspdm_set_data(spdm_context, LIBSPDM_DATA_CAPABILITY_FLAGS, ¶meter, + &data32, sizeof(data32)); + + data8 = SPDM_MEASUREMENT_BLOCK_HEADER_SPECIFICATION_DMTF; + libspdm_set_data(spdm_context, LIBSPDM_DATA_MEASUREMENT_SPEC, ¶meter, + &data8, sizeof(data8)); + data32 = SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_2048 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_3072 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_3072 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_4096 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_4096 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P384 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P521 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_SM2_ECC_SM2_P256 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED25519 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED448; + libspdm_set_data(spdm_context, LIBSPDM_DATA_BASE_ASYM_ALGO, ¶meter, + &data32, sizeof(data32)); + data32 = SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_256 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_384 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_512 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA3_256 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA3_384 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA3_512 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SM3_256; + libspdm_set_data(spdm_context, LIBSPDM_DATA_BASE_HASH_ALGO, ¶meter, + &data32, sizeof(data32)); + data16 = SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_2048 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_3072 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_4096 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_256_R1 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_384_R1 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_521_R1 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_SM2_P256; + libspdm_set_data(spdm_context, LIBSPDM_DATA_DHE_NAME_GROUP, ¶meter, + &data16, sizeof(data16)); + data16 = SPDM_ALGORITHMS_AEAD_CIPHER_SUITE_AES_128_GCM | + SPDM_ALGORITHMS_AEAD_CIPHER_SUITE_AES_256_GCM | + SPDM_ALGORITHMS_AEAD_CIPHER_SUITE_CHACHA20_POLY1305 | + SPDM_ALGORITHMS_AEAD_CIPHER_SUITE_AEAD_SM4_GCM; + libspdm_set_data(spdm_context, LIBSPDM_DATA_AEAD_CIPHER_SUITE, ¶meter, + &data16, sizeof(data16)); + data16 = SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_2048 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_3072 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_3072 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_4096 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_4096 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P384 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P521 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_SM2_ECC_SM2_P256 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED25519 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED448; + libspdm_set_data(spdm_context, LIBSPDM_DATA_REQ_BASE_ASYM_ALG, ¶meter, + &data16, sizeof(data16)); + data16 = SPDM_ALGORITHMS_KEY_SCHEDULE_HMAC_HASH; + libspdm_set_data(spdm_context, LIBSPDM_DATA_KEY_SCHEDULE, ¶meter, &data16, + sizeof(data16)); + data8 = SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_1; + libspdm_set_data(spdm_context, LIBSPDM_DATA_OTHER_PARAMS_SUPPORT, ¶meter, + &data8, sizeof(data8)); + + status = libspdm_init_connection (spdm_context, false); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + return false; + } + + test_buffer = (void *)spdm_test_context->test_scratch_buffer; + LIBSPDM_ASSERT(sizeof(spdm_test_context->test_scratch_buffer) >= + sizeof(spdm_measurements_test_buffer_t)); + libspdm_zero_mem(test_buffer, sizeof(spdm_measurements_test_buffer_t)); + spdm_test_context->test_scratch_buffer_size = sizeof(spdm_measurements_test_buffer_t); + + data_size = sizeof(version); + libspdm_zero_mem(¶meter, sizeof(parameter)); + parameter.location = LIBSPDM_DATA_LOCATION_CONNECTION; + libspdm_get_data(spdm_context, LIBSPDM_DATA_SPDM_VERSION, ¶meter, &version, &data_size); + test_buffer->version = (version >> SPDM_VERSION_NUMBER_SHIFT_BIT); + + data_size = sizeof(test_buffer->rsp_cap_flags); + libspdm_zero_mem(¶meter, sizeof(parameter)); + parameter.location = LIBSPDM_DATA_LOCATION_CONNECTION; + libspdm_get_data(spdm_context, LIBSPDM_DATA_CAPABILITY_FLAGS, ¶meter, + &test_buffer->rsp_cap_flags, &data_size); + if (((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP) == 0) || + (((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP_SIG) != 0) && + ((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP) == 0))) { + return false; + } + + data_size = sizeof(test_buffer->hash_algo); + libspdm_get_data(spdm_context, LIBSPDM_DATA_BASE_HASH_ALGO, ¶meter, &test_buffer->hash_algo, + &data_size); + test_buffer->hash_size = libspdm_get_hash_size(test_buffer->hash_algo); + + data_size = sizeof(test_buffer->asym_algo); + libspdm_get_data(spdm_context, LIBSPDM_DATA_BASE_ASYM_ALGO, ¶meter, &test_buffer->asym_algo, + &data_size); + test_buffer->signature_size = libspdm_get_asym_signature_size(test_buffer->asym_algo); + + status = libspdm_get_digest (spdm_context, &test_buffer->slot_mask, NULL); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + return false; + } + + test_buffer->slot_count = 0; + for (index = 0; index < SPDM_MAX_SLOT_COUNT; index++) { + if ((test_buffer->slot_mask & (1 << index)) != 0) { + test_buffer->slot_count++; + } + } + + status = libspdm_get_certificate (spdm_context, 0, NULL, NULL); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + return false; + } + + status = libspdm_challenge (spdm_context, 0, SPDM_CHALLENGE_REQUEST_ALL_MEASUREMENTS_HASH, + &test_buffer->measurement_summary_hash, NULL); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + return false; + } + + if (need_session) { + if ((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_KEY_EX_CAP) == 0) { + return false; + } + + status = libspdm_start_session (spdm_context, false, + SPDM_KEY_EXCHANGE_REQUEST_ALL_MEASUREMENTS_HASH, + 0, 0, &test_buffer->session_id, NULL, + &test_buffer->measurement_summary_hash); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + return false; + } + } + + spdm_test_context->test_scratch_buffer_size = offsetof(spdm_measurements_test_buffer_t, + measurement_summary_hash) + + test_buffer->hash_size; + + return true; +} + +bool spdm_test_case_measurements_setup_version_10 (void *test_context) +{ + spdm_version_number_t spdm_version[] = { + SPDM_MESSAGE_VERSION_10 << SPDM_VERSION_NUMBER_SHIFT_BIT + }; + return spdm_test_case_measurements_setup_vca_challenge_session (test_context, false, + LIBSPDM_ARRAY_SIZE( + spdm_version), + spdm_version); +} + +bool spdm_test_case_measurements_setup_version_11 (void *test_context) +{ + spdm_version_number_t spdm_version[] = { + SPDM_MESSAGE_VERSION_11 << SPDM_VERSION_NUMBER_SHIFT_BIT + }; + return spdm_test_case_measurements_setup_vca_challenge_session (test_context, false, + LIBSPDM_ARRAY_SIZE( + spdm_version), + spdm_version); +} + +bool spdm_test_case_measurements_setup_version_12 (void *test_context) +{ + spdm_version_number_t spdm_version[] = { + SPDM_MESSAGE_VERSION_12 << SPDM_VERSION_NUMBER_SHIFT_BIT + }; + return spdm_test_case_measurements_setup_vca_challenge_session (test_context, false, + LIBSPDM_ARRAY_SIZE( + spdm_version), + spdm_version); +} + +bool spdm_test_case_measurements_setup_version_11_session (void *test_context) +{ + spdm_version_number_t spdm_version[] = { + SPDM_MESSAGE_VERSION_11 << SPDM_VERSION_NUMBER_SHIFT_BIT + }; + return spdm_test_case_measurements_setup_vca_challenge_session (test_context, true, + LIBSPDM_ARRAY_SIZE( + spdm_version), + spdm_version); +} + +bool spdm_test_case_measurements_setup_version_12_session (void *test_context) +{ + spdm_version_number_t spdm_version[] = { + SPDM_MESSAGE_VERSION_12 << SPDM_VERSION_NUMBER_SHIFT_BIT + }; + return spdm_test_case_measurements_setup_vca_challenge_session (test_context, true, + LIBSPDM_ARRAY_SIZE( + spdm_version), + spdm_version); +} + +bool spdm_test_case_measurements_setup_version_any (void *test_context) +{ + return spdm_test_case_measurements_setup_vca_challenge_session (test_context, false, 0, NULL); +} + +bool spdm_test_case_measurements_setup_version_any_session_cap (void *test_context) +{ + spdm_version_number_t spdm_version[] = { + SPDM_MESSAGE_VERSION_12 << SPDM_VERSION_NUMBER_SHIFT_BIT, + SPDM_MESSAGE_VERSION_11 << SPDM_VERSION_NUMBER_SHIFT_BIT + }; + bool result; + spdm_test_context_t *spdm_test_context; + spdm_measurements_test_buffer_t *test_buffer; + + spdm_test_context = test_context; + test_buffer = (void *)spdm_test_context->test_scratch_buffer; + + result = spdm_test_case_measurements_setup_vca_challenge_session (test_context, false, + LIBSPDM_ARRAY_SIZE( + spdm_version), + spdm_version); + if (!result) { + return false; + } + if ((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_KEY_EX_CAP) == 0) { + return false; + } + return true; +} + +bool spdm_test_case_measurements_setup_version_capabilities (void *test_context) +{ + spdm_test_context_t *spdm_test_context; + void *spdm_context; + libspdm_return_t status; + libspdm_data_parameter_t parameter; + size_t data_size; + spdm_version_number_t spdm_version; + spdm_measurements_test_buffer_t *test_buffer; + + spdm_test_context = test_context; + spdm_context = spdm_test_context->spdm_context; + + status = libspdm_get_version (spdm_context, NULL, NULL); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + return false; + } + + status = libspdm_get_capabilities (spdm_context); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + return false; + } + + test_buffer = (void *)spdm_test_context->test_scratch_buffer; + LIBSPDM_ASSERT(sizeof(spdm_test_context->test_scratch_buffer) >= + sizeof(spdm_measurements_test_buffer_t)); + libspdm_zero_mem(test_buffer, sizeof(spdm_measurements_test_buffer_t)); + spdm_test_context->test_scratch_buffer_size = sizeof(spdm_measurements_test_buffer_t); + + data_size = sizeof(test_buffer->rsp_cap_flags); + libspdm_zero_mem(¶meter, sizeof(parameter)); + parameter.location = LIBSPDM_DATA_LOCATION_CONNECTION; + libspdm_get_data(spdm_context, LIBSPDM_DATA_CAPABILITY_FLAGS, ¶meter, + &test_buffer->rsp_cap_flags, &data_size); + if (((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP) == 0) || + (((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP_SIG) != 0) && + ((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP) == 0))) { + return false; + } + + spdm_version = 0; + data_size = sizeof(spdm_version); + libspdm_zero_mem(¶meter, sizeof(parameter)); + parameter.location = LIBSPDM_DATA_LOCATION_CONNECTION; + libspdm_get_data(spdm_context, LIBSPDM_DATA_SPDM_VERSION, ¶meter, &spdm_version, + &data_size); + test_buffer->version = (spdm_version >> SPDM_VERSION_NUMBER_SHIFT_BIT); + + spdm_test_context->test_scratch_buffer_size = sizeof(test_buffer->version); + + return true; +} + +bool spdm_test_measurement_parse_record (uint8_t number_of_blocks_in, + uint32_t measurement_record_length_in, + uint8_t *measurement_record, + uint8_t *number_of_blocks_out, + uint32_t *measurement_record_length_out) +{ + size_t index; + uint16_t measurement_size; + uint8_t *measurement_record_end; + + measurement_record_end = measurement_record + measurement_record_length_in; + *number_of_blocks_out = 0; + *measurement_record_length_out = 0; + for (index = 0; index < number_of_blocks_in; index++) { + if ((size_t)measurement_record + sizeof(spdm_measurement_block_common_header_t) > + (size_t)measurement_record_end) { + return false; + } + measurement_size = + ((spdm_measurement_block_common_header_t *)measurement_record)->measurement_size; + if ((size_t)measurement_record + sizeof(spdm_measurement_block_common_header_t) + + measurement_size > + (size_t)measurement_record_end) { + return false; + } + *number_of_blocks_out += 1; + *measurement_record_length_out += sizeof(spdm_measurement_block_common_header_t) + + measurement_size; + + measurement_record = + (void *)((size_t)measurement_record + sizeof(spdm_measurement_block_common_header_t) + + measurement_size); + } + + LIBSPDM_ASSERT (*measurement_record_length_out <= measurement_record_length_in); + if (*measurement_record_length_out < measurement_record_length_in) { + return false; + } + + return true; +} + +void spdm_test_measurement_set_index_mask (uint8_t *measurement_index_mask, + uint8_t measurement_index) +{ + uint8_t index; + uint8_t offset; + + index = measurement_index / 8; + offset = measurement_index & 0x7; + + measurement_index_mask[index] |= (1 << offset); +} + +bool spdm_test_measurement_has_valid_index (uint8_t *measurement_index_mask, + uint8_t measurement_index) +{ + uint8_t index; + uint8_t offset; + + index = measurement_index / 8; + offset = measurement_index & 0x7; + + return (measurement_index_mask[index] & (1 << offset)) != 0; +} + +bool spdm_test_measurement_calc_summary_hash (uint8_t spdm_version, + uint32_t hash_algo, + uint8_t number_of_blocks_in, + uint32_t measurement_record_length_in, + uint8_t *measurement_record, + uint8_t *measurement_summary_hash, + uint8_t *measurement_index_mask) +{ + uint8_t measurement_data[LIBSPDM_MAX_MESSAGE_BUFFER_SIZE]; + uint32_t measurment_data_size; + size_t index; + uint16_t measurement_size; + uint8_t *measurement_record_end; + bool result; + + libspdm_zero_mem (measurement_index_mask, 256 / 8); + + measurement_record_end = measurement_record + measurement_record_length_in; + + LIBSPDM_ASSERT (measurement_record_length_in <= LIBSPDM_MAX_MESSAGE_BUFFER_SIZE); + + measurment_data_size = 0; + for (index = 0; index < number_of_blocks_in; index++) { + LIBSPDM_ASSERT ((size_t)measurement_record + sizeof(spdm_measurement_block_common_header_t) < + (size_t)measurement_record_end); + measurement_size = + ((spdm_measurement_block_common_header_t *)measurement_record)->measurement_size; + LIBSPDM_ASSERT ((size_t)measurement_record + sizeof(spdm_measurement_block_common_header_t) + measurement_size <= + (size_t)measurement_record_end); + + spdm_test_measurement_set_index_mask ( + measurement_index_mask, + ((spdm_measurement_block_common_header_t *)measurement_record)->index); + + LIBSPDM_ASSERT (measurment_data_size < LIBSPDM_MAX_MESSAGE_BUFFER_SIZE); + if (spdm_version < SPDM_MESSAGE_VERSION_12) { + libspdm_copy_mem (&measurement_data[measurment_data_size], + LIBSPDM_MAX_MESSAGE_BUFFER_SIZE - measurment_data_size, + measurement_record + sizeof(spdm_measurement_block_common_header_t), + measurement_size); + measurment_data_size += measurement_size; + } else { + libspdm_copy_mem (&measurement_data[measurment_data_size], + LIBSPDM_MAX_MESSAGE_BUFFER_SIZE - measurment_data_size, + measurement_record, + sizeof(spdm_measurement_block_common_header_t) + measurement_size); + measurment_data_size += sizeof(spdm_measurement_block_common_header_t) + + measurement_size; + } + + measurement_record = + (void *)((size_t)measurement_record + sizeof(spdm_measurement_block_common_header_t) + + measurement_size); + } + result = libspdm_hash_all(hash_algo, measurement_data, + measurment_data_size, measurement_summary_hash); + + return result; +} + +bool spdm_test_measurement_get_measure_record_by_index ( + uint8_t number_of_blocks, + uint8_t *measurement_record_in, + uint32_t measurement_record_length_in, + uint8_t measurement_index, + uint8_t **measurement_record_out, + uint32_t *measurement_record_length_out) +{ + size_t index; + uint16_t measurement_size; + uint8_t *measurement_record_end; + + *measurement_record_out = NULL; + *measurement_record_length_out = 0; + + measurement_record_end = measurement_record_in + measurement_record_length_in; + + LIBSPDM_ASSERT (measurement_record_length_in <= LIBSPDM_MAX_MESSAGE_BUFFER_SIZE); + + for (index = 0; index < number_of_blocks; index++) { + LIBSPDM_ASSERT ((size_t)measurement_record_in + + sizeof(spdm_measurement_block_common_header_t) < + (size_t)measurement_record_end); + measurement_size = + ((spdm_measurement_block_common_header_t *)measurement_record_in)->measurement_size; + LIBSPDM_ASSERT ((size_t)measurement_record_in + + sizeof(spdm_measurement_block_common_header_t) + measurement_size <= + (size_t)measurement_record_end); + + if (measurement_index == + ((spdm_measurement_block_common_header_t *)measurement_record_in)->index) { + if (*measurement_record_out != NULL) { + /* duplication */ + return false; + } + *measurement_record_out = measurement_record_in; + *measurement_record_length_out = sizeof(spdm_measurement_block_common_header_t) + + measurement_size; + } + + measurement_record_in = + (void *)((size_t)measurement_record_in + + sizeof(spdm_measurement_block_common_header_t) + + measurement_size); + } + + if (*measurement_record_out == NULL) { + /* not found */ + return false; + } + return true; +} + +void spdm_test_case_measurements_success_10_11_12 (void *test_context, uint8_t version, + bool need_session) +{ + spdm_test_context_t *spdm_test_context; + void *spdm_context; + libspdm_return_t status; + spdm_get_measurements_request_t spdm_request; + size_t spdm_request_size; + spdm_measurements_response_t *spdm_response; + uint8_t message[LIBSPDM_MAX_MESSAGE_BUFFER_SIZE]; + size_t spdm_response_size; + common_test_result_t test_result; + spdm_measurements_test_buffer_t *test_buffer; + uint32_t measurement_record_length; + uint16_t *opaque_length_ptr; + uint32_t signature_size; + uint8_t *signature_ptr; + uint8_t slot_id; + bool result; + uint8_t number_of_blocks_out; + uint32_t measurement_record_length_out; + uint8_t measurement_summary_hash[LIBSPDM_MAX_HASH_SIZE]; + uint8_t measurement_record[LIBSPDM_MAX_MEASUREMENT_RECORD_SIZE]; + uint32_t measurement_record_size; + uint8_t measurement_block_count; + uint8_t measurement_index_mask[256 / 8]; + uint8_t meas_index; + uint8_t meas_count; + uint8_t *measurement_record_out; + common_test_case_id case_id; + uint32_t *session_id; + + spdm_test_context = test_context; + spdm_context = spdm_test_context->spdm_context; + test_buffer = (void *)spdm_test_context->test_scratch_buffer; + LIBSPDM_ASSERT(spdm_test_context->test_scratch_buffer_size == + offsetof(spdm_measurements_test_buffer_t, measurement_summary_hash) + + test_buffer->hash_size); + + LIBSPDM_ASSERT (test_buffer->version == version); + + session_id = NULL; + switch (version) { + case SPDM_MESSAGE_VERSION_10: + case_id = SPDM_RESPONDER_TEST_CASE_MEASUREMENTS_SUCCESS_10; + break; + case SPDM_MESSAGE_VERSION_11: + if (need_session) { + session_id = &test_buffer->session_id; + case_id = SPDM_RESPONDER_TEST_CASE_MEASUREMENTS_SUCCESS_11_IN_DHE_SESSION; + } else { + case_id = SPDM_RESPONDER_TEST_CASE_MEASUREMENTS_SUCCESS_11; + } + break; + case SPDM_MESSAGE_VERSION_12: + if (need_session) { + session_id = &test_buffer->session_id; + case_id = SPDM_RESPONDER_TEST_CASE_MEASUREMENTS_SUCCESS_12_IN_DHE_SESSION; + } else { + case_id = SPDM_RESPONDER_TEST_CASE_MEASUREMENTS_SUCCESS_12; + } + break; + default: + LIBSPDM_ASSERT(false); + return; + } + + if (session_id != NULL) { + common_test_record_test_message ("test session_id - 0x%08x\n", *session_id); + } + if (version == SPDM_MESSAGE_VERSION_10) { + test_buffer->slot_mask = 0x1; + } + for (slot_id = 0; slot_id < SPDM_MAX_SLOT_COUNT; slot_id++) { + if ((test_buffer->slot_mask & (0x1 << slot_id)) == 0) { + continue; + } + if (version > SPDM_MESSAGE_VERSION_10) { + common_test_record_test_message ("test slot - 0x%02x\n", slot_id); + } + + /* get number */ + common_test_record_test_message ("test number\n"); + libspdm_zero_mem(&spdm_request, sizeof(spdm_request)); + spdm_request.header.spdm_version = test_buffer->version; + spdm_request.header.request_response_code = SPDM_GET_MEASUREMENTS; + if ((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP_SIG) != 0) { + spdm_request.header.param1 = + SPDM_GET_MEASUREMENTS_REQUEST_ATTRIBUTES_GENERATE_SIGNATURE; + } else { + spdm_request.header.param1 = 0; + } + spdm_request.header.param2 = + SPDM_GET_MEASUREMENTS_REQUEST_MEASUREMENT_OPERATION_TOTAL_NUMBER_OF_MEASUREMENTS; + /* ignore spdm_request.nonce */ + spdm_request.slot_id_param = slot_id; + if (version == SPDM_MESSAGE_VERSION_10) { + spdm_request_size = offsetof(spdm_get_measurements_request_t, slot_id_param); + } else { + spdm_request_size = sizeof(spdm_get_measurements_request_t); + } + + spdm_response = (void *)message; + spdm_response_size = sizeof(message); + libspdm_zero_mem(message, sizeof(message)); + status = libspdm_send_receive_data(spdm_context, session_id, false, + &spdm_request, spdm_request_size, + spdm_response, &spdm_response_size); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_MEASUREMENTS, case_id, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "send/receive failure"); + return; + } + + if ((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP_SIG) != 0) { + signature_size = test_buffer->signature_size; + } else { + signature_size = 0; + } + if (spdm_response_size < sizeof(spdm_measurements_response_t) + + SPDM_NONCE_SIZE + sizeof(uint16_t) + + signature_size) { + test_result = COMMON_TEST_RESULT_FAIL; + } else { + measurement_record_length = libspdm_read_uint24 ( + spdm_response->measurement_record_length); + if (spdm_response_size < sizeof(spdm_measurements_response_t) + + measurement_record_length + SPDM_NONCE_SIZE + + sizeof(uint16_t) + signature_size) { + test_result = COMMON_TEST_RESULT_FAIL; + } else { + opaque_length_ptr = + (void *)((size_t)spdm_response + sizeof(spdm_measurements_response_t) + + measurement_record_length + SPDM_NONCE_SIZE); + if (spdm_response_size < sizeof(spdm_measurements_response_t) + + measurement_record_length + SPDM_NONCE_SIZE + + sizeof(uint16_t) + *opaque_length_ptr + + signature_size) { + test_result = COMMON_TEST_RESULT_FAIL; + } else { + test_result = COMMON_TEST_RESULT_PASS; + } + } + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_MEASUREMENTS, case_id, 1, + test_result, "response size - %d", spdm_response_size); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + signature_ptr = (void *)((size_t)spdm_response + sizeof(spdm_measurements_response_t) + + measurement_record_length + SPDM_NONCE_SIZE + + sizeof(uint16_t) + *opaque_length_ptr); + + if (spdm_response->header.request_response_code == SPDM_MEASUREMENTS) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_MEASUREMENTS, case_id, 2, + test_result, "response code - 0x%02x", spdm_response->header.request_response_code); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.spdm_version == test_buffer->version) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_MEASUREMENTS, case_id, 3, + test_result, "response version - 0x%02x", spdm_response->header.spdm_version); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.param1 > 0) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_MEASUREMENTS, case_id, 4, + test_result, "response param1 - 0x%02x", spdm_response->header.param1); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->number_of_blocks == 0) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_MEASUREMENTS, case_id, 5, + test_result, "response number_of_blocks - 0x%02x", spdm_response->number_of_blocks); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (measurement_record_length == 0) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_MEASUREMENTS, case_id, 6, + test_result, "response measurement_record_length - 0x%06x", measurement_record_length); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if ((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP_SIG) != 0) { + + status = libspdm_append_message_m(spdm_context, NULL, + &spdm_request, spdm_request_size); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_MEASUREMENTS, case_id, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "append_message_m failure"); + return; + } + status = libspdm_append_message_m(spdm_context, NULL, + spdm_response, + (size_t)signature_ptr - (size_t)spdm_response); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_MEASUREMENTS, case_id, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "append_message_m failure"); + return; + } + + if (version >= SPDM_MESSAGE_VERSION_10) { + if ((spdm_response->header.param2 & SPDM_MEASUREMENTS_RESPONSE_SLOT_ID_MASK) == + slot_id) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_MEASUREMENTS, case_id, 7, + test_result, "response param2 (slot_id) - 0x%02x", + spdm_response->header.param2 & SPDM_MEASUREMENTS_RESPONSE_SLOT_ID_MASK); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + } + if (version >= SPDM_MESSAGE_VERSION_12) { + if (((spdm_response->header.param2 & + SPDM_MEASUREMENTS_RESPONSE_CONTENT_CHANGE_MASK) == + SPDM_MEASUREMENTS_RESPONSE_CONTENT_CHANGE_NO_DETECTION) || + ((spdm_response->header.param2 & + SPDM_MEASUREMENTS_RESPONSE_CONTENT_CHANGE_MASK) == + SPDM_MEASUREMENTS_RESPONSE_CONTENT_NO_CHANGE_DETECTED) ) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_MEASUREMENTS, case_id, 7, + test_result, "response param2 (content changed) - 0x%02x", + spdm_response->header.param2 & SPDM_MEASUREMENTS_RESPONSE_CONTENT_CHANGE_MASK); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + } + + result = libspdm_verify_measurement_signature( + spdm_context, NULL, signature_ptr, signature_size); + if (result) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_MEASUREMENTS, case_id, 7, + test_result, "response signature"); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + libspdm_reset_message_m (spdm_context, NULL); + } + + + /* get all */ + common_test_record_test_message ("test all\n"); + libspdm_zero_mem(&spdm_request, sizeof(spdm_request)); + spdm_request.header.spdm_version = test_buffer->version; + spdm_request.header.request_response_code = SPDM_GET_MEASUREMENTS; + if ((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP_SIG) != 0) { + spdm_request.header.param1 = + SPDM_GET_MEASUREMENTS_REQUEST_ATTRIBUTES_GENERATE_SIGNATURE; + } else { + spdm_request.header.param1 = 0; + } + spdm_request.header.param2 = + SPDM_GET_MEASUREMENTS_REQUEST_MEASUREMENT_OPERATION_ALL_MEASUREMENTS; + /* ignore spdm_request.nonce */ + spdm_request.slot_id_param = slot_id; + if (version == SPDM_MESSAGE_VERSION_10) { + spdm_request_size = offsetof(spdm_get_measurements_request_t, slot_id_param); + } else { + spdm_request_size = sizeof(spdm_get_measurements_request_t); + } + + spdm_response = (void *)message; + spdm_response_size = sizeof(message); + libspdm_zero_mem(message, sizeof(message)); + status = libspdm_send_receive_data(spdm_context, session_id, false, + &spdm_request, spdm_request_size, + spdm_response, &spdm_response_size); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_MEASUREMENTS, case_id, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "send/receive failure"); + return; + } + + if ((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP_SIG) != 0) { + signature_size = test_buffer->signature_size; + } else { + signature_size = 0; + } + if (spdm_response_size < sizeof(spdm_measurements_response_t) + + SPDM_NONCE_SIZE + sizeof(uint16_t) + + signature_size) { + test_result = COMMON_TEST_RESULT_FAIL; + } else { + measurement_record_length = libspdm_read_uint24 ( + spdm_response->measurement_record_length); + if (spdm_response_size < sizeof(spdm_measurements_response_t) + + measurement_record_length + SPDM_NONCE_SIZE + + sizeof(uint16_t) + signature_size) { + test_result = COMMON_TEST_RESULT_FAIL; + } else { + opaque_length_ptr = + (void *)((size_t)spdm_response + sizeof(spdm_measurements_response_t) + + measurement_record_length + SPDM_NONCE_SIZE); + if (spdm_response_size < sizeof(spdm_measurements_response_t) + + measurement_record_length + SPDM_NONCE_SIZE + + sizeof(uint16_t) + *opaque_length_ptr + + signature_size) { + test_result = COMMON_TEST_RESULT_FAIL; + } else { + test_result = COMMON_TEST_RESULT_PASS; + } + } + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_MEASUREMENTS, case_id, 8, + test_result, "response size - %d", spdm_response_size); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + signature_ptr = (void *)((size_t)spdm_response + sizeof(spdm_measurements_response_t) + + measurement_record_length + SPDM_NONCE_SIZE + + sizeof(uint16_t) + *opaque_length_ptr); + + if (spdm_response->header.request_response_code == SPDM_MEASUREMENTS) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_MEASUREMENTS, case_id, 9, + test_result, "response code - 0x%02x", spdm_response->header.request_response_code); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.spdm_version == test_buffer->version) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_MEASUREMENTS, case_id, 10, + test_result, "response version - 0x%02x", spdm_response->header.spdm_version); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + spdm_test_measurement_parse_record (spdm_response->number_of_blocks, + measurement_record_length, + (void *)(spdm_response + 1), + &number_of_blocks_out, + &measurement_record_length_out); + if ((spdm_response->number_of_blocks > 0) && + (spdm_response->number_of_blocks == number_of_blocks_out)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_MEASUREMENTS, case_id, 11, + test_result, "response number_of_blocks - 0x%02x, get - 0x%02x", + spdm_response->number_of_blocks, number_of_blocks_out); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if ((measurement_record_length > 0) && + (measurement_record_length == measurement_record_length_out)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_MEASUREMENTS, case_id, 12, + test_result, "response measurement_record_length - 0x%06x, get - 0x%06x", + measurement_record_length, measurement_record_length_out); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + libspdm_copy_mem (measurement_record, sizeof(measurement_record), + (void *)(spdm_response + 1), measurement_record_length); + measurement_record_size = measurement_record_length; + measurement_block_count = spdm_response->number_of_blocks; + + result = spdm_test_measurement_calc_summary_hash (test_buffer->version, + test_buffer->hash_algo, + spdm_response->number_of_blocks, + measurement_record_length, + (void *)(spdm_response + 1), + measurement_summary_hash, + measurement_index_mask); + if (!result) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_MEASUREMENTS, case_id, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "calc_summary_hash failure"); + return; + } + if (libspdm_const_compare_mem (measurement_summary_hash, + test_buffer->measurement_summary_hash, + test_buffer->hash_size) == 0) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_MEASUREMENTS, case_id, 13, + test_result, "response measurement summary hash"); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if ((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP_SIG) != 0) { + + status = libspdm_append_message_m(spdm_context, NULL, + &spdm_request, spdm_request_size); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_MEASUREMENTS, case_id, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "append_message_m failure"); + return; + } + status = libspdm_append_message_m(spdm_context, NULL, + spdm_response, + (size_t)signature_ptr - (size_t)spdm_response); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_MEASUREMENTS, case_id, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "append_message_m failure"); + return; + } + + if (version >= SPDM_MESSAGE_VERSION_10) { + if ((spdm_response->header.param2 & SPDM_MEASUREMENTS_RESPONSE_SLOT_ID_MASK) == + slot_id) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_MEASUREMENTS, case_id, 14, + test_result, "response param2 (slot_id) - 0x%02x", + spdm_response->header.param2 & SPDM_MEASUREMENTS_RESPONSE_SLOT_ID_MASK); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + } + if (version >= SPDM_MESSAGE_VERSION_12) { + if (((spdm_response->header.param2 & + SPDM_MEASUREMENTS_RESPONSE_CONTENT_CHANGE_MASK) == + SPDM_MEASUREMENTS_RESPONSE_CONTENT_CHANGE_NO_DETECTION) || + ((spdm_response->header.param2 & + SPDM_MEASUREMENTS_RESPONSE_CONTENT_CHANGE_MASK) == + SPDM_MEASUREMENTS_RESPONSE_CONTENT_NO_CHANGE_DETECTED) ) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_MEASUREMENTS, case_id, 14, + test_result, "response param2 (content changed) - 0x%02x", + spdm_response->header.param2 & SPDM_MEASUREMENTS_RESPONSE_CONTENT_CHANGE_MASK); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + } + + result = libspdm_verify_measurement_signature( + spdm_context, NULL, signature_ptr, signature_size); + if (result) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_MEASUREMENTS, case_id, 14, + test_result, "response signature"); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + libspdm_reset_message_m (spdm_context, NULL); + } + + /* get one-by-one */ + common_test_record_test_message ("test one by one\n"); + libspdm_zero_mem(&spdm_request, sizeof(spdm_request)); + spdm_request.header.spdm_version = test_buffer->version; + spdm_request.header.request_response_code = SPDM_GET_MEASUREMENTS; + spdm_request.header.param1 = 0; + spdm_request.header.param2 = 0; + /* ignore spdm_request.nonce */ + spdm_request.slot_id_param = slot_id; + spdm_request_size = offsetof(spdm_get_measurements_request_t, nonce); + + meas_count = 0; + for (meas_index = 1; meas_index <= 0xFE; meas_index++) { + if (!spdm_test_measurement_has_valid_index (measurement_index_mask, meas_index)) { + continue; + } + meas_count++; + common_test_record_test_message ("test meas_index - 0x%02x, count - 0x%02x\n", + meas_index, meas_count); + if (((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP_SIG) != + 0) && + (meas_count == measurement_block_count)) { + spdm_request.header.param1 = + SPDM_GET_MEASUREMENTS_REQUEST_ATTRIBUTES_GENERATE_SIGNATURE; + if (version == SPDM_MESSAGE_VERSION_10) { + spdm_request_size = offsetof(spdm_get_measurements_request_t, slot_id_param); + } else { + spdm_request_size = sizeof(spdm_get_measurements_request_t); + } + } + + spdm_request.header.param2 = meas_index; + + spdm_response = (void *)message; + spdm_response_size = sizeof(message); + libspdm_zero_mem(message, sizeof(message)); + status = libspdm_send_receive_data(spdm_context, session_id, false, + &spdm_request, spdm_request_size, + spdm_response, &spdm_response_size); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_MEASUREMENTS, case_id, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "send/receive failure"); + return; + } + + if (((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP_SIG) != + 0) && + (meas_count == measurement_block_count)) { + signature_size = test_buffer->signature_size; + } else { + signature_size = 0; + } + if (spdm_response_size < sizeof(spdm_measurements_response_t) + + SPDM_NONCE_SIZE + sizeof(uint16_t) + + signature_size) { + test_result = COMMON_TEST_RESULT_FAIL; + } else { + measurement_record_length = libspdm_read_uint24 ( + spdm_response->measurement_record_length); + if (spdm_response_size < sizeof(spdm_measurements_response_t) + + measurement_record_length + SPDM_NONCE_SIZE + + sizeof(uint16_t) + signature_size) { + test_result = COMMON_TEST_RESULT_FAIL; + } else { + opaque_length_ptr = + (void *)((size_t)spdm_response + sizeof(spdm_measurements_response_t) + + measurement_record_length + SPDM_NONCE_SIZE); + if (spdm_response_size < sizeof(spdm_measurements_response_t) + + measurement_record_length + SPDM_NONCE_SIZE + + sizeof(uint16_t) + *opaque_length_ptr + + signature_size) { + test_result = COMMON_TEST_RESULT_FAIL; + } else { + test_result = COMMON_TEST_RESULT_PASS; + } + } + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_MEASUREMENTS, case_id, 15, + test_result, "response size - %d", spdm_response_size); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + signature_ptr = (void *)((size_t)spdm_response + sizeof(spdm_measurements_response_t) + + measurement_record_length + SPDM_NONCE_SIZE + + sizeof(uint16_t) + *opaque_length_ptr); + + if (spdm_response->header.request_response_code == SPDM_MEASUREMENTS) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_MEASUREMENTS, case_id, 16, + test_result, "response code - 0x%02x", spdm_response->header.request_response_code); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.spdm_version == test_buffer->version) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_MEASUREMENTS, case_id, 17, + test_result, "response version - 0x%02x", spdm_response->header.spdm_version); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->number_of_blocks == 1) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_MEASUREMENTS, case_id, 18, + test_result, "response number_of_blocks - 0x%02x", spdm_response->number_of_blocks); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + result = spdm_test_measurement_get_measure_record_by_index ( + measurement_block_count, measurement_record, measurement_record_size, + meas_index, &measurement_record_out, &measurement_record_length_out); + if (result && + (measurement_record_length > 0) && + (measurement_record_length == measurement_record_length_out)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_MEASUREMENTS, case_id, 19, + test_result, "response measurement_record_length - 0x%06x, get - 0x%06x (dup - %x)", + measurement_record_length, measurement_record_length_out, !result); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (libspdm_const_compare_mem ((void *)(spdm_response + 1), + measurement_record_out, + measurement_record_length_out) == 0) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_MEASUREMENTS, case_id, 20, + test_result, "response measurement record"); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + status = libspdm_append_message_m(spdm_context, NULL, + &spdm_request, spdm_request_size); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_MEASUREMENTS, case_id, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "append_message_m failure"); + return; + } + status = libspdm_append_message_m(spdm_context, NULL, + spdm_response, + (size_t)signature_ptr - (size_t)spdm_response); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_MEASUREMENTS, case_id, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "append_message_m failure"); + return; + } + + if (((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP_SIG) != + 0) && + (meas_count == measurement_block_count)) { + + if (version >= SPDM_MESSAGE_VERSION_10) { + if ((spdm_response->header.param2 & SPDM_MEASUREMENTS_RESPONSE_SLOT_ID_MASK) == + slot_id) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_MEASUREMENTS, case_id, 21, + test_result, "response param2 (slot_id) - 0x%02x", + spdm_response->header.param2 & SPDM_MEASUREMENTS_RESPONSE_SLOT_ID_MASK); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + } + if (version >= SPDM_MESSAGE_VERSION_12) { + if (((spdm_response->header.param2 & + SPDM_MEASUREMENTS_RESPONSE_CONTENT_CHANGE_MASK) == + SPDM_MEASUREMENTS_RESPONSE_CONTENT_CHANGE_NO_DETECTION) || + ((spdm_response->header.param2 & + SPDM_MEASUREMENTS_RESPONSE_CONTENT_CHANGE_MASK) == + SPDM_MEASUREMENTS_RESPONSE_CONTENT_NO_CHANGE_DETECTED) ) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_MEASUREMENTS, case_id, 21, + test_result, "response param2 (content changed) - 0x%02x", + spdm_response->header.param2 & + SPDM_MEASUREMENTS_RESPONSE_CONTENT_CHANGE_MASK); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + } + + result = libspdm_verify_measurement_signature( + spdm_context, NULL, signature_ptr, signature_size); + if (result) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_MEASUREMENTS, case_id, 21, + test_result, "response signature"); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + libspdm_reset_message_m (spdm_context, NULL); + } + } + } +} + +void spdm_test_case_measurements_success_10 (void *test_context) +{ + spdm_test_case_measurements_success_10_11_12 (test_context, + SPDM_MESSAGE_VERSION_10, false); +} + +void spdm_test_case_measurements_success_11 (void *test_context) +{ + spdm_test_case_measurements_success_10_11_12 (test_context, + SPDM_MESSAGE_VERSION_11, false); +} + +void spdm_test_case_measurements_success_12 (void *test_context) +{ + spdm_test_case_measurements_success_10_11_12 (test_context, + SPDM_MESSAGE_VERSION_12, false); +} + +void spdm_test_case_measurements_success_11_session (void *test_context) +{ + spdm_test_case_measurements_success_10_11_12 (test_context, + SPDM_MESSAGE_VERSION_11, true); +} + +void spdm_test_case_measurements_success_12_session (void *test_context) +{ + spdm_test_case_measurements_success_10_11_12 (test_context, + SPDM_MESSAGE_VERSION_12, true); +} + +void spdm_test_case_measurements_version_mismatch (void *test_context) +{ + spdm_test_context_t *spdm_test_context; + void *spdm_context; + libspdm_return_t status; + spdm_get_measurements_request_t spdm_request; + size_t spdm_request_size; + spdm_measurements_response_t *spdm_response; + uint8_t message[LIBSPDM_MAX_MESSAGE_BUFFER_SIZE]; + size_t spdm_response_size; + common_test_result_t test_result; + spdm_measurements_test_buffer_t *test_buffer; + uint8_t mismatched_version[] = { + SPDM_MESSAGE_VERSION_10 - 1, + SPDM_MESSAGE_VERSION_12 + 1, + }; + size_t index; + + spdm_test_context = test_context; + spdm_context = spdm_test_context->spdm_context; + test_buffer = (void *)spdm_test_context->test_scratch_buffer; + LIBSPDM_ASSERT(spdm_test_context->test_scratch_buffer_size == + offsetof(spdm_measurements_test_buffer_t, measurement_summary_hash) + + test_buffer->hash_size); + + mismatched_version[0] = (uint8_t)(test_buffer->version - 1); + mismatched_version[1] = (uint8_t)(test_buffer->version + 1); + + for (index = 0; index < LIBSPDM_ARRAY_SIZE(mismatched_version); index++) { + common_test_record_test_message ("test mismatched_version - 0x%02x\n", + mismatched_version[index]); + libspdm_zero_mem(&spdm_request, sizeof(spdm_request)); + spdm_request.header.spdm_version = mismatched_version[index]; + spdm_request.header.request_response_code = SPDM_GET_MEASUREMENTS; + spdm_request.header.param1 = 0; + spdm_request.header.param2 = + SPDM_GET_MEASUREMENTS_REQUEST_MEASUREMENT_OPERATION_TOTAL_NUMBER_OF_MEASUREMENTS; + spdm_request.slot_id_param = 0; + if (test_buffer->version == SPDM_MESSAGE_VERSION_10) { + spdm_request_size = offsetof(spdm_get_measurements_request_t, slot_id_param); + } else { + spdm_request_size = sizeof(spdm_get_measurements_request_t); + } + + spdm_response = (void *)message; + spdm_response_size = sizeof(message); + libspdm_zero_mem(message, sizeof(message)); + status = libspdm_send_receive_data(spdm_context, NULL, false, + &spdm_request, spdm_request_size, + spdm_response, &spdm_response_size); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_MEASUREMENTS, + SPDM_RESPONDER_TEST_CASE_MEASUREMENTS_VERSION_MISMATCH, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "send/receive failure"); + continue; + } + + if (spdm_response_size >= sizeof(spdm_error_response_t)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_MEASUREMENTS, + SPDM_RESPONDER_TEST_CASE_MEASUREMENTS_VERSION_MISMATCH, 1, + test_result, "response size - %d", spdm_response_size); + if (test_result == COMMON_TEST_RESULT_FAIL) { + continue; + } + + if (spdm_response->header.request_response_code == SPDM_ERROR) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_MEASUREMENTS, + SPDM_RESPONDER_TEST_CASE_MEASUREMENTS_VERSION_MISMATCH, 2, + test_result, "response code - 0x%02x", spdm_response->header.request_response_code); + if (test_result == COMMON_TEST_RESULT_FAIL) { + continue; + } + + if (spdm_response->header.spdm_version == test_buffer->version) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_MEASUREMENTS, + SPDM_RESPONDER_TEST_CASE_MEASUREMENTS_VERSION_MISMATCH, 3, + test_result, "response version - 0x%02x", spdm_response->header.spdm_version); + if (test_result == COMMON_TEST_RESULT_FAIL) { + continue; + } + + if (spdm_response->header.param1 == SPDM_ERROR_CODE_VERSION_MISMATCH) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_MEASUREMENTS, + SPDM_RESPONDER_TEST_CASE_MEASUREMENTS_VERSION_MISMATCH, 4, + test_result, "response param1 - 0x%02x", spdm_response->header.param1); + + if (spdm_response->header.param2 == 0) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_MEASUREMENTS, + SPDM_RESPONDER_TEST_CASE_MEASUREMENTS_VERSION_MISMATCH, 5, + test_result, "response param2 - 0x%02x", spdm_response->header.param2); + } +} + +void spdm_test_case_measurements_unexpected_request (void *test_context) +{ + spdm_test_context_t *spdm_test_context; + void *spdm_context; + libspdm_return_t status; + spdm_get_measurements_request_t spdm_request; + size_t spdm_request_size; + spdm_measurements_response_t *spdm_response; + size_t spdm_response_size; + uint8_t message[LIBSPDM_MAX_MESSAGE_BUFFER_SIZE]; + common_test_result_t test_result; + spdm_measurements_test_buffer_t *test_buffer; + + spdm_test_context = test_context; + spdm_context = spdm_test_context->spdm_context; + test_buffer = (void *)spdm_test_context->test_scratch_buffer; + LIBSPDM_ASSERT(spdm_test_context->test_scratch_buffer_size == + sizeof(test_buffer->version)); + + libspdm_zero_mem(&spdm_request, sizeof(spdm_request)); + spdm_request.header.spdm_version = test_buffer->version; + spdm_request.header.request_response_code = SPDM_GET_MEASUREMENTS; + spdm_request.header.param1 = 0; + spdm_request.header.param2 = + SPDM_GET_MEASUREMENTS_REQUEST_MEASUREMENT_OPERATION_TOTAL_NUMBER_OF_MEASUREMENTS; + spdm_request.slot_id_param = 0; + if (test_buffer->version == SPDM_MESSAGE_VERSION_10) { + spdm_request_size = offsetof(spdm_get_measurements_request_t, slot_id_param); + } else { + spdm_request_size = sizeof(spdm_get_measurements_request_t); + } + + spdm_response = (void *)message; + spdm_response_size = sizeof(message); + libspdm_zero_mem(message, sizeof(message)); + status = libspdm_send_receive_data(spdm_context, NULL, false, + &spdm_request, spdm_request_size, + spdm_response, &spdm_response_size); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_MEASUREMENTS, + SPDM_RESPONDER_TEST_CASE_MEASUREMENTS_UNEXPECTED_REQUEST, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "send/receive failure"); + return; + } + + if (spdm_response_size >= sizeof(spdm_error_response_t)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_MEASUREMENTS, + SPDM_RESPONDER_TEST_CASE_MEASUREMENTS_UNEXPECTED_REQUEST, 1, + test_result, "response size - %d", spdm_response_size); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.request_response_code == SPDM_ERROR) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_MEASUREMENTS, + SPDM_RESPONDER_TEST_CASE_MEASUREMENTS_UNEXPECTED_REQUEST, 2, + test_result, "response code - 0x%02x", spdm_response->header.request_response_code); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.spdm_version == test_buffer->version) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_MEASUREMENTS, + SPDM_RESPONDER_TEST_CASE_MEASUREMENTS_UNEXPECTED_REQUEST, 3, + test_result, "response version - 0x%02x", spdm_response->header.spdm_version); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.param1 == SPDM_ERROR_CODE_UNEXPECTED_REQUEST) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_MEASUREMENTS, + SPDM_RESPONDER_TEST_CASE_MEASUREMENTS_UNEXPECTED_REQUEST, 4, + test_result, "response param1 - 0x%02x", spdm_response->header.param1); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.param2 == 0) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_MEASUREMENTS, + SPDM_RESPONDER_TEST_CASE_MEASUREMENTS_UNEXPECTED_REQUEST, 5, + test_result, "response param2 - 0x%02x", spdm_response->header.param2); +} + +void spdm_test_case_measurements_invalid_request (void *test_context) +{ + spdm_test_context_t *spdm_test_context; + void *spdm_context; + libspdm_return_t status; + spdm_get_measurements_request_t spdm_request; + spdm_get_measurements_request_t spdm_request_new; + size_t spdm_request_size; + spdm_measurements_response_t *spdm_response; + uint8_t message[LIBSPDM_MAX_MESSAGE_BUFFER_SIZE]; + size_t spdm_response_size; + common_test_result_t test_result; + spdm_measurements_test_buffer_t *test_buffer; + size_t index; + uint8_t slot_id; + + spdm_test_context = test_context; + spdm_context = spdm_test_context->spdm_context; + test_buffer = (void *)spdm_test_context->test_scratch_buffer; + LIBSPDM_ASSERT(spdm_test_context->test_scratch_buffer_size == + offsetof(spdm_measurements_test_buffer_t, measurement_summary_hash) + + test_buffer->hash_size); + + libspdm_zero_mem(&spdm_request, sizeof(spdm_request)); + spdm_request.header.spdm_version = test_buffer->version; + spdm_request.header.request_response_code = SPDM_GET_MEASUREMENTS; + spdm_request.header.param1 = 0; + spdm_request.header.param2 = + SPDM_GET_MEASUREMENTS_REQUEST_MEASUREMENT_OPERATION_TOTAL_NUMBER_OF_MEASUREMENTS; + spdm_request.slot_id_param = 0; + if (test_buffer->version == SPDM_MESSAGE_VERSION_10) { + spdm_request_size = offsetof(spdm_get_measurements_request_t, slot_id_param); + } else { + spdm_request_size = sizeof(spdm_get_measurements_request_t); + } + + for (index = 0; index < SPDM_MAX_SLOT_COUNT * 2; index++) { + libspdm_copy_mem (&spdm_request_new, sizeof(spdm_request_new), &spdm_request, + sizeof(spdm_request)); + + slot_id = (uint8_t)index; + if ((slot_id < SPDM_MAX_SLOT_COUNT) && + ((test_buffer->slot_mask & (0x1 << slot_id)) != 0)) { + continue; + } + common_test_record_test_message ("test invalid slot - 0x%02x\n", slot_id); + spdm_request_new.slot_id_param = slot_id; + + spdm_response = (void *)message; + spdm_response_size = sizeof(message); + libspdm_zero_mem(message, sizeof(message)); + status = libspdm_send_receive_data(spdm_context, NULL, false, + &spdm_request_new, spdm_request_size, + spdm_response, &spdm_response_size); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_MEASUREMENTS, + SPDM_RESPONDER_TEST_CASE_MEASUREMENTS_INVALID_REQUEST, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "send/receive failure"); + continue; + } + + if (spdm_response_size >= sizeof(spdm_error_response_t)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_MEASUREMENTS, + SPDM_RESPONDER_TEST_CASE_MEASUREMENTS_INVALID_REQUEST, 1, + test_result, "response size - %d", spdm_response_size); + if (test_result == COMMON_TEST_RESULT_FAIL) { + continue; + } + + if (spdm_response->header.request_response_code == SPDM_ERROR) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_MEASUREMENTS, + SPDM_RESPONDER_TEST_CASE_MEASUREMENTS_INVALID_REQUEST, 2, + test_result, "response code - 0x%02x", spdm_response->header.request_response_code); + if (test_result == COMMON_TEST_RESULT_FAIL) { + continue; + } + + if (spdm_response->header.spdm_version == test_buffer->version) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_MEASUREMENTS, + SPDM_RESPONDER_TEST_CASE_MEASUREMENTS_INVALID_REQUEST, 3, + test_result, "response version - 0x%02x", spdm_response->header.spdm_version); + if (test_result == COMMON_TEST_RESULT_FAIL) { + continue; + } + + if (spdm_response->header.param1 == SPDM_ERROR_CODE_INVALID_REQUEST) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_MEASUREMENTS, + SPDM_RESPONDER_TEST_CASE_MEASUREMENTS_INVALID_REQUEST, 4, + test_result, "response param1 - 0x%02x", spdm_response->header.param1); + + if (spdm_response->header.param2 == 0) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_MEASUREMENTS, + SPDM_RESPONDER_TEST_CASE_MEASUREMENTS_INVALID_REQUEST, 5, + test_result, "response param2 - 0x%02x", spdm_response->header.param2); + } +} + +void spdm_test_case_measurements_unexpected_request_in_session (void *test_context) +{ + spdm_test_context_t *spdm_test_context; + void *spdm_context; + libspdm_return_t status; + spdm_get_measurements_request_t spdm_request; + size_t spdm_request_size; + spdm_measurements_response_t *spdm_response; + size_t spdm_response_size; + uint8_t message[LIBSPDM_MAX_MESSAGE_BUFFER_SIZE]; + common_test_result_t test_result; + spdm_measurements_test_buffer_t *test_buffer; + uint8_t req_slot_id_param; + + spdm_test_context = test_context; + spdm_context = spdm_test_context->spdm_context; + test_buffer = (void *)spdm_test_context->test_scratch_buffer; + LIBSPDM_ASSERT(spdm_test_context->test_scratch_buffer_size == + sizeof(test_buffer->version)); + + status = libspdm_send_receive_key_exchange (spdm_context, + SPDM_KEY_EXCHANGE_REQUEST_NO_MEASUREMENT_SUMMARY_HASH, + 0, 0, &test_buffer->session_id, NULL, &req_slot_id_param, + &test_buffer->measurement_summary_hash); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_MEASUREMENTS, + SPDM_RESPONDER_TEST_CASE_MEASUREMENTS_UNEXPECTED_REQUEST_IN_DHE_SESSION_HS, + COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "key_exchange failure"); + return; + } + + libspdm_zero_mem(&spdm_request, sizeof(spdm_request)); + spdm_request.header.spdm_version = test_buffer->version; + spdm_request.header.request_response_code = SPDM_GET_MEASUREMENTS; + spdm_request.header.param1 = 0; + spdm_request.header.param2 = + SPDM_GET_MEASUREMENTS_REQUEST_MEASUREMENT_OPERATION_TOTAL_NUMBER_OF_MEASUREMENTS; + spdm_request.slot_id_param = 0; + if (test_buffer->version == SPDM_MESSAGE_VERSION_10) { + spdm_request_size = offsetof(spdm_get_measurements_request_t, slot_id_param); + } else { + spdm_request_size = sizeof(spdm_get_measurements_request_t); + } + + spdm_response = (void *)message; + spdm_response_size = sizeof(message); + libspdm_zero_mem(message, sizeof(message)); + status = libspdm_send_receive_data(spdm_context, &test_buffer->session_id, false, + &spdm_request, spdm_request_size, + spdm_response, &spdm_response_size); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_MEASUREMENTS, + SPDM_RESPONDER_TEST_CASE_MEASUREMENTS_UNEXPECTED_REQUEST_IN_DHE_SESSION_HS, + COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "send/receive failure"); + return; + } + + if (spdm_response_size >= sizeof(spdm_error_response_t)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_MEASUREMENTS, + SPDM_RESPONDER_TEST_CASE_MEASUREMENTS_UNEXPECTED_REQUEST_IN_DHE_SESSION_HS, 1, + test_result, "response size - %d", spdm_response_size); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.request_response_code == SPDM_ERROR) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_MEASUREMENTS, + SPDM_RESPONDER_TEST_CASE_MEASUREMENTS_UNEXPECTED_REQUEST_IN_DHE_SESSION_HS, 2, + test_result, "response code - 0x%02x", spdm_response->header.request_response_code); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.spdm_version == test_buffer->version) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_MEASUREMENTS, + SPDM_RESPONDER_TEST_CASE_MEASUREMENTS_UNEXPECTED_REQUEST_IN_DHE_SESSION_HS, 3, + test_result, "response version - 0x%02x", spdm_response->header.spdm_version); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.param1 == SPDM_ERROR_CODE_UNEXPECTED_REQUEST) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_MEASUREMENTS, + SPDM_RESPONDER_TEST_CASE_MEASUREMENTS_UNEXPECTED_REQUEST_IN_DHE_SESSION_HS, 4, + test_result, "response param1 - 0x%02x", spdm_response->header.param1); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.param2 == 0) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_MEASUREMENTS, + SPDM_RESPONDER_TEST_CASE_MEASUREMENTS_UNEXPECTED_REQUEST_IN_DHE_SESSION_HS, 5, + test_result, "response param2 - 0x%02x", spdm_response->header.param2); +} + +common_test_case_t m_spdm_test_group_measurements[] = { + {SPDM_RESPONDER_TEST_CASE_MEASUREMENTS_SUCCESS_10, "spdm_test_case_measurements_success_10", + spdm_test_case_measurements_success_10, spdm_test_case_measurements_setup_version_10}, + {SPDM_RESPONDER_TEST_CASE_MEASUREMENTS_VERSION_MISMATCH, + "spdm_test_case_measurements_version_mismatch", + spdm_test_case_measurements_version_mismatch, + spdm_test_case_measurements_setup_version_any}, + {SPDM_RESPONDER_TEST_CASE_MEASUREMENTS_UNEXPECTED_REQUEST, + "spdm_test_case_measurements_unexpected_request", + spdm_test_case_measurements_unexpected_request, + spdm_test_case_measurements_setup_version_capabilities}, + {SPDM_RESPONDER_TEST_CASE_MEASUREMENTS_INVALID_REQUEST, + "spdm_test_case_measurements_invalid_request", spdm_test_case_measurements_invalid_request, + spdm_test_case_measurements_setup_version_any}, + {SPDM_RESPONDER_TEST_CASE_MEASUREMENTS_SUCCESS_11, "spdm_test_case_measurements_success_11", + spdm_test_case_measurements_success_11, spdm_test_case_measurements_setup_version_11}, + {SPDM_RESPONDER_TEST_CASE_MEASUREMENTS_SUCCESS_11_IN_DHE_SESSION, + "spdm_test_case_measurements_success_11_session", + spdm_test_case_measurements_success_11_session, + spdm_test_case_measurements_setup_version_11_session}, + {SPDM_RESPONDER_TEST_CASE_MEASUREMENTS_UNEXPECTED_REQUEST_IN_DHE_SESSION_HS, + "spdm_test_case_measurements_unexpected_request_in_session", + spdm_test_case_measurements_unexpected_request_in_session, + spdm_test_case_measurements_setup_version_any_session_cap}, + {SPDM_RESPONDER_TEST_CASE_MEASUREMENTS_SUCCESS_12, "spdm_test_case_measurements_success_12", + spdm_test_case_measurements_success_12, spdm_test_case_measurements_setup_version_12}, + {SPDM_RESPONDER_TEST_CASE_MEASUREMENTS_SUCCESS_12_IN_DHE_SESSION, + "spdm_test_case_measurements_success_12_session", + spdm_test_case_measurements_success_12_session, + spdm_test_case_measurements_setup_version_12_session}, + {COMMON_TEST_ID_END, NULL, NULL}, +}; diff --git a/library/spdm_responder_conformance_test_lib/spdm_responder_test_8_key_exchange_rsp.c b/library/spdm_responder_conformance_test_lib/spdm_responder_test_8_key_exchange_rsp.c new file mode 100644 index 0000000..d1356b8 --- /dev/null +++ b/library/spdm_responder_conformance_test_lib/spdm_responder_test_8_key_exchange_rsp.c @@ -0,0 +1,1382 @@ +/** + * Copyright Notice: + * Copyright 2021 DMTF. All rights reserved. + * License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/spdm-emu/blob/main/LICENSE.md + **/ + +#include "spdm_responder_test.h" + +#pragma pack(1) +typedef struct { + uint8_t version; + uint32_t rsp_cap_flags; + uint32_t hash_algo; + uint32_t hash_size; + uint32_t asym_algo; + uint32_t signature_size; + uint16_t dhe_named_group; + uint32_t dhe_key_size; + uint8_t slot_mask; + uint8_t slot_count; + uint8_t total_digest_buffer[SPDM_MAX_SLOT_COUNT * LIBSPDM_MAX_HASH_SIZE]; +} spdm_key_exchange_rsp_test_buffer_t; +#pragma pack() + +#pragma pack(1) +typedef struct { + spdm_message_header_t header; + uint16_t req_session_id; + uint8_t session_policy; + uint8_t reserved; + uint8_t random_data[32]; + uint8_t exchange_data[LIBSPDM_MAX_DHE_KEY_SIZE]; + uint16_t opaque_length; + uint8_t opaque_data[SPDM_MAX_OPAQUE_DATA_SIZE]; +} spdm_key_exchange_request_mine_t; + +#pragma pack() + +bool spdm_test_case_key_exchange_rsp_setup_vca_digest (void *test_context, + size_t spdm_version_count, + spdm_version_number_t *spdm_version, + bool hs_clear) +{ + spdm_test_context_t *spdm_test_context; + void *spdm_context; + spdm_version_number_t version; + libspdm_return_t status; + libspdm_data_parameter_t parameter; + size_t data_size; + uint32_t data32; + uint16_t data16; + uint8_t data8; + spdm_key_exchange_rsp_test_buffer_t *test_buffer; + size_t index; + uint8_t cert_chain_buffer[LIBSPDM_MAX_CERT_CHAIN_SIZE]; + size_t cert_chain_buffer_size; + + spdm_test_context = test_context; + spdm_context = spdm_test_context->spdm_context; + + if (spdm_version_count != 0) { + libspdm_zero_mem(¶meter, sizeof(parameter)); + parameter.location = LIBSPDM_DATA_LOCATION_LOCAL; + libspdm_set_data(spdm_context, LIBSPDM_DATA_SPDM_VERSION, ¶meter, + spdm_version, sizeof(spdm_version_number_t) * spdm_version_count); + } + + data32 = SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CERT_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHAL_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_ENCRYPT_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MAC_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_KEY_EX_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_ENCAP_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_HBEAT_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_KEY_UPD_CAP; + if (hs_clear) { + data32 |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_HANDSHAKE_IN_THE_CLEAR_CAP; + } + libspdm_set_data(spdm_context, LIBSPDM_DATA_CAPABILITY_FLAGS, ¶meter, + &data32, sizeof(data32)); + + data8 = SPDM_MEASUREMENT_BLOCK_HEADER_SPECIFICATION_DMTF; + libspdm_set_data(spdm_context, LIBSPDM_DATA_MEASUREMENT_SPEC, ¶meter, + &data8, sizeof(data8)); + data32 = SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_2048 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_3072 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_3072 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_4096 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_4096 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P384 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P521 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_SM2_ECC_SM2_P256 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED25519 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED448; + libspdm_set_data(spdm_context, LIBSPDM_DATA_BASE_ASYM_ALGO, ¶meter, + &data32, sizeof(data32)); + data32 = SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_256 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_384 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_512 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA3_256 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA3_384 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA3_512 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SM3_256; + libspdm_set_data(spdm_context, LIBSPDM_DATA_BASE_HASH_ALGO, ¶meter, + &data32, sizeof(data32)); + data16 = SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_2048 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_3072 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_4096 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_256_R1 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_384_R1 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_521_R1 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_SM2_P256; + libspdm_set_data(spdm_context, LIBSPDM_DATA_DHE_NAME_GROUP, ¶meter, + &data16, sizeof(data16)); + data16 = SPDM_ALGORITHMS_AEAD_CIPHER_SUITE_AES_128_GCM | + SPDM_ALGORITHMS_AEAD_CIPHER_SUITE_AES_256_GCM | + SPDM_ALGORITHMS_AEAD_CIPHER_SUITE_CHACHA20_POLY1305 | + SPDM_ALGORITHMS_AEAD_CIPHER_SUITE_AEAD_SM4_GCM; + libspdm_set_data(spdm_context, LIBSPDM_DATA_AEAD_CIPHER_SUITE, ¶meter, + &data16, sizeof(data16)); + data16 = SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_2048 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_3072 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_3072 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_4096 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_4096 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P384 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P521 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_SM2_ECC_SM2_P256 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED25519 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED448; + libspdm_set_data(spdm_context, LIBSPDM_DATA_REQ_BASE_ASYM_ALG, ¶meter, + &data16, sizeof(data16)); + data16 = SPDM_ALGORITHMS_KEY_SCHEDULE_HMAC_HASH; + libspdm_set_data(spdm_context, LIBSPDM_DATA_KEY_SCHEDULE, ¶meter, &data16, + sizeof(data16)); + data8 = SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_1; + libspdm_set_data(spdm_context, LIBSPDM_DATA_OTHER_PARAMS_SUPPORT, ¶meter, + &data8, sizeof(data8)); + + status = libspdm_init_connection (spdm_context, false); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + return false; + } + + test_buffer = (void *)spdm_test_context->test_scratch_buffer; + LIBSPDM_ASSERT(sizeof(spdm_test_context->test_scratch_buffer) >= + sizeof(spdm_key_exchange_rsp_test_buffer_t)); + libspdm_zero_mem(test_buffer, sizeof(spdm_key_exchange_rsp_test_buffer_t)); + spdm_test_context->test_scratch_buffer_size = sizeof(spdm_key_exchange_rsp_test_buffer_t); + + data_size = sizeof(version); + libspdm_zero_mem(¶meter, sizeof(parameter)); + parameter.location = LIBSPDM_DATA_LOCATION_CONNECTION; + libspdm_get_data(spdm_context, LIBSPDM_DATA_SPDM_VERSION, ¶meter, &version, &data_size); + test_buffer->version = (version >> SPDM_VERSION_NUMBER_SHIFT_BIT); + + data_size = sizeof(test_buffer->rsp_cap_flags); + libspdm_zero_mem(¶meter, sizeof(parameter)); + parameter.location = LIBSPDM_DATA_LOCATION_CONNECTION; + libspdm_get_data(spdm_context, LIBSPDM_DATA_CAPABILITY_FLAGS, ¶meter, + &test_buffer->rsp_cap_flags, &data_size); + if (((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP) == 0) || + ((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_KEY_EX_CAP) == 0)) { + return false; + } + + if (hs_clear) { + if ((test_buffer->rsp_cap_flags & + SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_HANDSHAKE_IN_THE_CLEAR_CAP) == 0) { + return false; + } + } + + data_size = sizeof(test_buffer->hash_algo); + libspdm_get_data(spdm_context, LIBSPDM_DATA_BASE_HASH_ALGO, ¶meter, &test_buffer->hash_algo, + &data_size); + test_buffer->hash_size = libspdm_get_hash_size(test_buffer->hash_algo); + + data_size = sizeof(test_buffer->asym_algo); + libspdm_get_data(spdm_context, LIBSPDM_DATA_BASE_ASYM_ALGO, ¶meter, &test_buffer->asym_algo, + &data_size); + test_buffer->signature_size = libspdm_get_asym_signature_size(test_buffer->asym_algo); + + data_size = sizeof(test_buffer->dhe_named_group); + libspdm_get_data(spdm_context, LIBSPDM_DATA_DHE_NAME_GROUP, ¶meter, + &test_buffer->dhe_named_group, &data_size); + test_buffer->dhe_key_size = libspdm_get_dhe_pub_key_size(test_buffer->dhe_named_group); + + status = libspdm_get_digest (spdm_context, &test_buffer->slot_mask, + test_buffer->total_digest_buffer); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + return false; + } + + cert_chain_buffer_size = sizeof(cert_chain_buffer); + status = libspdm_get_certificate (spdm_context, 0, &cert_chain_buffer_size, cert_chain_buffer); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + return false; + } + + test_buffer->slot_count = 0; + for (index = 0; index < SPDM_MAX_SLOT_COUNT; index++) { + if ((test_buffer->slot_mask & (1 << index)) != 0) { + test_buffer->slot_count++; + } + } + + spdm_test_context->test_scratch_buffer_size = offsetof(spdm_key_exchange_rsp_test_buffer_t, + total_digest_buffer) + + test_buffer->hash_size * test_buffer->slot_count; + + return true; +} + +bool spdm_test_case_key_exchange_rsp_setup_version_any (void *test_context) +{ + return spdm_test_case_key_exchange_rsp_setup_vca_digest (test_context, 0, NULL, false); +} + +bool spdm_test_case_key_exchange_rsp_setup_version_11 (void *test_context) +{ + spdm_version_number_t spdm_version[] = { + SPDM_MESSAGE_VERSION_11 << SPDM_VERSION_NUMBER_SHIFT_BIT + }; + return spdm_test_case_key_exchange_rsp_setup_vca_digest (test_context, + LIBSPDM_ARRAY_SIZE( + spdm_version), spdm_version, + false); +} + +bool spdm_test_case_key_exchange_rsp_setup_version_11_hs_clear (void *test_context) +{ + spdm_version_number_t spdm_version[] = { + SPDM_MESSAGE_VERSION_11 << SPDM_VERSION_NUMBER_SHIFT_BIT + }; + return spdm_test_case_key_exchange_rsp_setup_vca_digest (test_context, + LIBSPDM_ARRAY_SIZE( + spdm_version), spdm_version, true); +} + +bool spdm_test_case_key_exchange_rsp_setup_version_12 (void *test_context) +{ + spdm_version_number_t spdm_version[] = { + SPDM_MESSAGE_VERSION_12 << SPDM_VERSION_NUMBER_SHIFT_BIT + }; + return spdm_test_case_key_exchange_rsp_setup_vca_digest (test_context, + LIBSPDM_ARRAY_SIZE( + spdm_version), spdm_version, + false); +} + +bool spdm_test_case_key_exchange_rsp_setup_version_12_hs_clear (void *test_context) +{ + spdm_version_number_t spdm_version[] = { + SPDM_MESSAGE_VERSION_12 << SPDM_VERSION_NUMBER_SHIFT_BIT + }; + return spdm_test_case_key_exchange_rsp_setup_vca_digest (test_context, + LIBSPDM_ARRAY_SIZE( + spdm_version), spdm_version, true); +} + +bool spdm_test_case_key_exchange_rsp_setup_version_capabilities (void *test_context) +{ + spdm_test_context_t *spdm_test_context; + void *spdm_context; + libspdm_return_t status; + libspdm_data_parameter_t parameter; + size_t data_size; + spdm_version_number_t spdm_version; + spdm_key_exchange_rsp_test_buffer_t *test_buffer; + + spdm_test_context = test_context; + spdm_context = spdm_test_context->spdm_context; + + status = libspdm_get_version (spdm_context, NULL, NULL); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + return false; + } + + status = libspdm_get_capabilities (spdm_context); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + return false; + } + + test_buffer = (void *)spdm_test_context->test_scratch_buffer; + LIBSPDM_ASSERT(sizeof(spdm_test_context->test_scratch_buffer) >= + sizeof(spdm_key_exchange_rsp_test_buffer_t)); + libspdm_zero_mem(test_buffer, sizeof(spdm_key_exchange_rsp_test_buffer_t)); + spdm_test_context->test_scratch_buffer_size = sizeof(spdm_key_exchange_rsp_test_buffer_t); + + data_size = sizeof(test_buffer->rsp_cap_flags); + libspdm_zero_mem(¶meter, sizeof(parameter)); + parameter.location = LIBSPDM_DATA_LOCATION_CONNECTION; + libspdm_get_data(spdm_context, LIBSPDM_DATA_CAPABILITY_FLAGS, ¶meter, + &test_buffer->rsp_cap_flags, &data_size); + if (((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP) == 0) || + ((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_KEY_EX_CAP) == 0)) { + return false; + } + + spdm_version = 0; + data_size = sizeof(spdm_version); + libspdm_zero_mem(¶meter, sizeof(parameter)); + parameter.location = LIBSPDM_DATA_LOCATION_CONNECTION; + libspdm_get_data(spdm_context, LIBSPDM_DATA_SPDM_VERSION, ¶meter, &spdm_version, + &data_size); + test_buffer->version = (spdm_version >> SPDM_VERSION_NUMBER_SHIFT_BIT); + + spdm_test_context->test_scratch_buffer_size = sizeof(test_buffer->version); + + return true; +} + +void spdm_test_case_key_exchange_rsp_success_11_12 (void *test_context, uint8_t version, + bool hs_clear) +{ + spdm_test_context_t *spdm_test_context; + void *spdm_context; + libspdm_return_t status; + spdm_key_exchange_request_mine_t spdm_request; + size_t spdm_request_size; + spdm_key_exchange_response_t *spdm_response; + uint8_t message[LIBSPDM_MAX_MESSAGE_BUFFER_SIZE]; + size_t spdm_response_size; + uint8_t cert_chain_buffer[LIBSPDM_MAX_CERT_CHAIN_SIZE]; + size_t cert_chain_buffer_size; + common_test_result_t test_result; + spdm_key_exchange_rsp_test_buffer_t *test_buffer; + uint8_t slot_id; + size_t dhe_key_size; + uint8_t meas_hash_type_index; + uint32_t meas_hash_size; + uint32_t verify_data_size; + uint8_t *ptr; + void *dhe_context; + uint16_t req_session_id; + uint16_t rsp_session_id; + uint32_t session_id; + void *session_info; + void *secured_message_context; + size_t opaque_key_exchange_req_size; + uint16_t *opaque_length_ptr; + uint8_t *exchange_data_ptr; + uint8_t *signature_ptr; + uint8_t *verify_data_ptr; + uint8_t th1_hash_data[LIBSPDM_MAX_HASH_SIZE]; + bool result; + uint8_t measurement_hash_type[] = { + SPDM_KEY_EXCHANGE_REQUEST_NO_MEASUREMENT_SUMMARY_HASH, + SPDM_KEY_EXCHANGE_REQUEST_TCB_COMPONENT_MEASUREMENT_HASH, + SPDM_KEY_EXCHANGE_REQUEST_ALL_MEASUREMENTS_HASH, + }; + common_test_case_id case_id; + + spdm_test_context = test_context; + spdm_context = spdm_test_context->spdm_context; + test_buffer = (void *)spdm_test_context->test_scratch_buffer; + LIBSPDM_ASSERT(spdm_test_context->test_scratch_buffer_size == + offsetof(spdm_key_exchange_rsp_test_buffer_t, total_digest_buffer) + + test_buffer->hash_size * test_buffer->slot_count); + + switch (version) { + case SPDM_MESSAGE_VERSION_11: + LIBSPDM_ASSERT (test_buffer->version == SPDM_MESSAGE_VERSION_11); + if (hs_clear) { + case_id = SPDM_RESPONDER_TEST_CASE_KEY_EXCHANGE_RSP_SUCCESS_11_HS_CLEAR; + } else { + case_id = SPDM_RESPONDER_TEST_CASE_KEY_EXCHANGE_RSP_SUCCESS_11; + } + break; + case SPDM_MESSAGE_VERSION_12: + LIBSPDM_ASSERT (test_buffer->version == SPDM_MESSAGE_VERSION_12); + if (hs_clear) { + case_id = SPDM_RESPONDER_TEST_CASE_KEY_EXCHANGE_RSP_SUCCESS_12_HS_CLEAR; + } else { + case_id = SPDM_RESPONDER_TEST_CASE_KEY_EXCHANGE_RSP_SUCCESS_12; + } + break; + default: + LIBSPDM_ASSERT(false); + return; + } + + for (slot_id = 0; slot_id < SPDM_MAX_SLOT_COUNT; slot_id++) { + if ((test_buffer->slot_mask & (0x1 << slot_id)) == 0) { + continue; + } + common_test_record_test_message ("test slot - 0x%02x\n", slot_id); + + for (meas_hash_type_index = 0; + meas_hash_type_index < LIBSPDM_ARRAY_SIZE(measurement_hash_type); + meas_hash_type_index++) { + if ((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP) == 0) { + if (measurement_hash_type[meas_hash_type_index] != + SPDM_KEY_EXCHANGE_REQUEST_NO_MEASUREMENT_SUMMARY_HASH) { + continue; + } + } + common_test_record_test_message ("test meas hash type - 0x%02x\n", + measurement_hash_type[meas_hash_type_index]); + + status = libspdm_init_connection (spdm_context, false); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_EXCHANGE_RSP, case_id, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "init_connection failure"); + continue; + } + + cert_chain_buffer_size = sizeof(cert_chain_buffer); + status = libspdm_get_certificate (spdm_context, slot_id, &cert_chain_buffer_size, + cert_chain_buffer); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_EXCHANGE_RSP, case_id, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "get_certificate failure"); + continue; + } + + libspdm_zero_mem(&spdm_request, sizeof(spdm_request)); + spdm_request.header.spdm_version = test_buffer->version; + spdm_request.header.request_response_code = SPDM_KEY_EXCHANGE; + spdm_request.header.param1 = measurement_hash_type[meas_hash_type_index]; + spdm_request.header.param2 = slot_id; + /* ignore spdm_request.random_data */ + req_session_id = libspdm_allocate_req_session_id(spdm_context); + spdm_request.req_session_id = req_session_id; + spdm_request.session_policy = 0; + + dhe_context = libspdm_secured_message_dhe_new( + test_buffer->version, + test_buffer->dhe_named_group, true); + if (dhe_context == NULL) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_EXCHANGE_RSP, case_id, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "dhe_new failure"); + return; + } + dhe_key_size = test_buffer->dhe_key_size; + ptr = spdm_request.exchange_data; + result = libspdm_secured_message_dhe_generate_key( + test_buffer->dhe_named_group, + dhe_context, ptr, &dhe_key_size); + if (!result) { + libspdm_secured_message_dhe_free( + test_buffer->dhe_named_group, dhe_context); + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_EXCHANGE_RSP, case_id, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "dhe_generate_key failure"); + return; + } + ptr += dhe_key_size; + + 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); + status = libspdm_build_opaque_data_supported_version_data( + spdm_context, &opaque_key_exchange_req_size, ptr); + LIBSPDM_ASSERT(status == LIBSPDM_STATUS_SUCCESS); + ptr += opaque_key_exchange_req_size; + + spdm_request_size = (size_t)ptr - (size_t)&spdm_request; + + spdm_response = (void *)message; + spdm_response_size = sizeof(message); + libspdm_zero_mem(message, sizeof(message)); + status = libspdm_send_receive_data(spdm_context, NULL, false, + &spdm_request, spdm_request_size, + spdm_response, &spdm_response_size); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + libspdm_secured_message_dhe_free( + test_buffer->dhe_named_group, dhe_context); + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_EXCHANGE_RSP, case_id, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "send/receive failure"); + return; + } + + if (measurement_hash_type[meas_hash_type_index] == + SPDM_KEY_EXCHANGE_REQUEST_NO_MEASUREMENT_SUMMARY_HASH) { + meas_hash_size = 0; + } else { + meas_hash_size = test_buffer->hash_size; + } + if (hs_clear) { + verify_data_size = 0; + } else { + verify_data_size = test_buffer->hash_size; + } + opaque_length_ptr = + (void *)((size_t)spdm_response + sizeof(spdm_key_exchange_response_t) + + test_buffer->dhe_key_size + meas_hash_size); + if (spdm_response_size < sizeof(spdm_key_exchange_response_t) + + test_buffer->dhe_key_size + meas_hash_size + sizeof(uint16_t) + + test_buffer->signature_size + verify_data_size) { + test_result = COMMON_TEST_RESULT_FAIL; + } else { + if (spdm_response_size < sizeof(spdm_key_exchange_response_t) + + test_buffer->dhe_key_size + meas_hash_size + sizeof(uint16_t) + + *opaque_length_ptr + test_buffer->signature_size + verify_data_size) { + test_result = COMMON_TEST_RESULT_FAIL; + } else { + test_result = COMMON_TEST_RESULT_PASS; + } + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_EXCHANGE_RSP, case_id, 1, + test_result, "response size - %d", spdm_response_size); + if (test_result == COMMON_TEST_RESULT_FAIL) { + libspdm_secured_message_dhe_free( + test_buffer->dhe_named_group, dhe_context); + return; + } + exchange_data_ptr = + (void *)((size_t)spdm_response + sizeof(spdm_key_exchange_response_t)); + signature_ptr = (void *)((size_t)spdm_response + sizeof(spdm_key_exchange_response_t) + + test_buffer->dhe_key_size + meas_hash_size + sizeof(uint16_t) + + *opaque_length_ptr); + verify_data_ptr = (void *)(signature_ptr + test_buffer->signature_size); + if (spdm_response->header.request_response_code == SPDM_KEY_EXCHANGE_RSP) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_EXCHANGE_RSP, case_id, 2, + test_result, "response code - 0x%02x", spdm_response->header.request_response_code); + if (test_result == COMMON_TEST_RESULT_FAIL) { + libspdm_secured_message_dhe_free( + test_buffer->dhe_named_group, dhe_context); + return; + } + + if (spdm_response->header.spdm_version == test_buffer->version) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_EXCHANGE_RSP, case_id, 3, + test_result, "response version - 0x%02x", spdm_response->header.spdm_version); + if (test_result == COMMON_TEST_RESULT_FAIL) { + libspdm_secured_message_dhe_free( + test_buffer->dhe_named_group, dhe_context); + return; + } + + if (spdm_response->mut_auth_requested == 0) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_EXCHANGE_RSP, case_id, 4, + test_result, "response mut_auth_requested - 0x%02x", + spdm_response->mut_auth_requested); + if (test_result == COMMON_TEST_RESULT_FAIL) { + libspdm_secured_message_dhe_free( + test_buffer->dhe_named_group, dhe_context); + return; + } + + if (spdm_response->req_slot_id_param == 0) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_EXCHANGE_RSP, case_id, 4, + test_result, "response req_slot_id_param - 0x%02x", + spdm_response->req_slot_id_param); + if (test_result == COMMON_TEST_RESULT_FAIL) { + libspdm_secured_message_dhe_free( + test_buffer->dhe_named_group, dhe_context); + return; + } + + rsp_session_id = spdm_response->rsp_session_id; + session_id = (req_session_id << 16) | rsp_session_id; + common_test_record_test_message ("test session_id - 0x%08x\n", session_id); + session_info = libspdm_assign_session_id(spdm_context, session_id, false); + if (session_info == NULL) { + libspdm_secured_message_dhe_free( + test_buffer->dhe_named_group, dhe_context); + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_EXCHANGE_RSP, case_id, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "assign_session_id failure"); + return; + } + secured_message_context = libspdm_get_secured_message_context_via_session_info( + session_info); + LIBSPDM_ASSERT (secured_message_context != NULL); + + status = libspdm_append_message_k(spdm_context, session_info, true, &spdm_request, + spdm_request_size); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + libspdm_free_session_id(spdm_context, session_id); + libspdm_secured_message_dhe_free( + test_buffer->dhe_named_group, dhe_context); + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_EXCHANGE_RSP, case_id, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "append_message_k failure"); + return; + } + status = libspdm_append_message_k(spdm_context, session_info, true, spdm_response, + (size_t)signature_ptr - (size_t)spdm_response); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + libspdm_free_session_id(spdm_context, session_id); + libspdm_secured_message_dhe_free( + test_buffer->dhe_named_group, dhe_context); + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_EXCHANGE_RSP, case_id, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "append_message_k failure"); + return; + } + result = libspdm_verify_key_exchange_rsp_signature( + spdm_context, session_info, signature_ptr, test_buffer->signature_size); + if (result) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_EXCHANGE_RSP, case_id, 5, + test_result, "response signature"); + if (test_result == COMMON_TEST_RESULT_FAIL) { + libspdm_free_session_id(spdm_context, session_id); + libspdm_secured_message_dhe_free( + test_buffer->dhe_named_group, dhe_context); + return; + } + status = libspdm_append_message_k(spdm_context, session_info, true, signature_ptr, + test_buffer->signature_size); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + libspdm_free_session_id(spdm_context, session_id); + libspdm_secured_message_dhe_free( + test_buffer->dhe_named_group, dhe_context); + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_EXCHANGE_RSP, case_id, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "append_message_k failure"); + return; + } + + result = libspdm_secured_message_dhe_compute_key( + test_buffer->dhe_named_group, + dhe_context, exchange_data_ptr, test_buffer->dhe_key_size, + secured_message_context); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + libspdm_free_session_id(spdm_context, session_id); + libspdm_secured_message_dhe_free( + test_buffer->dhe_named_group, dhe_context); + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_EXCHANGE_RSP, case_id, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "dhe_compute_key failure"); + return; + } + + libspdm_secured_message_dhe_free( + test_buffer->dhe_named_group, dhe_context); + + result = libspdm_calculate_th1_hash(spdm_context, session_info, true, + th1_hash_data); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + libspdm_free_session_id(spdm_context, session_id); + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_EXCHANGE_RSP, case_id, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "calculate_th1_hash failure"); + return; + } + + result = libspdm_generate_session_handshake_key( + secured_message_context, th1_hash_data); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + libspdm_free_session_id(spdm_context, session_id); + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_EXCHANGE_RSP, case_id, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "generate_session_handshake_key failure"); + return; + } + + if (!hs_clear) { + result = libspdm_verify_key_exchange_rsp_hmac( + spdm_context, session_info, verify_data_ptr, test_buffer->hash_size); + if (result) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_EXCHANGE_RSP, case_id, 6, + test_result, "response verify_data"); + if (test_result == COMMON_TEST_RESULT_FAIL) { + libspdm_free_session_id(spdm_context, session_id); + return; + } + status = libspdm_append_message_k(spdm_context, session_info, true, verify_data_ptr, + test_buffer->hash_size); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + libspdm_free_session_id(spdm_context, session_id); + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_EXCHANGE_RSP, case_id, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "append_message_k failure"); + return; + } + } + libspdm_reset_message_k (spdm_context, session_info); + libspdm_free_session_id(spdm_context, session_id); + } + } +} + +void spdm_test_case_key_exchange_rsp_success_11 (void *test_context) +{ + spdm_test_case_key_exchange_rsp_success_11_12 (test_context, + SPDM_MESSAGE_VERSION_11, false); +} + +void spdm_test_case_key_exchange_rsp_success_11_hs_clear (void *test_context) +{ + spdm_test_case_key_exchange_rsp_success_11_12 (test_context, + SPDM_MESSAGE_VERSION_11, true); +} + +void spdm_test_case_key_exchange_rsp_success_12 (void *test_context) +{ + spdm_test_case_key_exchange_rsp_success_11_12 (test_context, + SPDM_MESSAGE_VERSION_12, false); +} + +void spdm_test_case_key_exchange_rsp_success_12_hs_clear (void *test_context) +{ + spdm_test_case_key_exchange_rsp_success_11_12 (test_context, + SPDM_MESSAGE_VERSION_12, true); +} + +void spdm_test_case_key_exchange_rsp_version_mismatch (void *test_context) +{ + spdm_test_context_t *spdm_test_context; + void *spdm_context; + libspdm_return_t status; + spdm_key_exchange_request_mine_t spdm_request; + size_t spdm_request_size; + spdm_key_exchange_response_t *spdm_response; + uint8_t message[LIBSPDM_MAX_MESSAGE_BUFFER_SIZE]; + size_t spdm_response_size; + uint8_t *ptr; + size_t dhe_key_size; + size_t opaque_key_exchange_req_size; + void *dhe_context; + uint16_t req_session_id; + bool result; + common_test_result_t test_result; + spdm_key_exchange_rsp_test_buffer_t *test_buffer; + uint8_t mismatched_version[] = { + SPDM_MESSAGE_VERSION_10 - 1, + SPDM_MESSAGE_VERSION_12 + 1, + }; + size_t index; + + spdm_test_context = test_context; + spdm_context = spdm_test_context->spdm_context; + test_buffer = (void *)spdm_test_context->test_scratch_buffer; + LIBSPDM_ASSERT(spdm_test_context->test_scratch_buffer_size == + offsetof(spdm_key_exchange_rsp_test_buffer_t, total_digest_buffer) + + test_buffer->hash_size * test_buffer->slot_count); + + mismatched_version[0] = (uint8_t)(test_buffer->version - 1); + mismatched_version[1] = (uint8_t)(test_buffer->version + 1); + + for (index = 0; index < LIBSPDM_ARRAY_SIZE(mismatched_version); index++) { + common_test_record_test_message ("test mismatched_version - 0x%02x\n", + mismatched_version[index]); + + libspdm_zero_mem(&spdm_request, sizeof(spdm_request)); + spdm_request.header.spdm_version = mismatched_version[index]; + spdm_request.header.request_response_code = SPDM_KEY_EXCHANGE; + spdm_request.header.param1 = SPDM_KEY_EXCHANGE_REQUEST_NO_MEASUREMENT_SUMMARY_HASH; + spdm_request.header.param2 = 0; + /* ignore spdm_request.random_data */ + req_session_id = libspdm_allocate_req_session_id(spdm_context); + spdm_request.req_session_id = req_session_id; + spdm_request.session_policy = 0; + + dhe_context = libspdm_secured_message_dhe_new( + test_buffer->version, + test_buffer->dhe_named_group, true); + if (dhe_context == NULL) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_EXCHANGE_RSP, + SPDM_RESPONDER_TEST_CASE_KEY_EXCHANGE_RSP_VERSION_MISMATCH, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "dhe_new failure"); + return; + } + dhe_key_size = test_buffer->dhe_key_size; + ptr = spdm_request.exchange_data; + result = libspdm_secured_message_dhe_generate_key( + test_buffer->dhe_named_group, + dhe_context, ptr, &dhe_key_size); + if (!result) { + libspdm_secured_message_dhe_free( + test_buffer->dhe_named_group, dhe_context); + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_EXCHANGE_RSP, + SPDM_RESPONDER_TEST_CASE_KEY_EXCHANGE_RSP_VERSION_MISMATCH, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "dhe_generate_key failure"); + return; + } + ptr += dhe_key_size; + + 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); + status = libspdm_build_opaque_data_supported_version_data( + spdm_context, &opaque_key_exchange_req_size, ptr); + LIBSPDM_ASSERT(status == LIBSPDM_STATUS_SUCCESS); + ptr += opaque_key_exchange_req_size; + + spdm_request_size = (size_t)ptr - (size_t)&spdm_request; + + spdm_response = (void *)message; + spdm_response_size = sizeof(message); + libspdm_zero_mem(message, sizeof(message)); + status = libspdm_send_receive_data(spdm_context, NULL, false, + &spdm_request, spdm_request_size, + spdm_response, &spdm_response_size); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_EXCHANGE_RSP, + SPDM_RESPONDER_TEST_CASE_KEY_EXCHANGE_RSP_VERSION_MISMATCH, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "send/receive failure"); + continue; + } + + if (spdm_response_size >= sizeof(spdm_error_response_t)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_EXCHANGE_RSP, + SPDM_RESPONDER_TEST_CASE_KEY_EXCHANGE_RSP_VERSION_MISMATCH, 1, + test_result, "response size - %d", spdm_response_size); + if (test_result == COMMON_TEST_RESULT_FAIL) { + continue; + } + + if (spdm_response->header.request_response_code == SPDM_ERROR) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_EXCHANGE_RSP, + SPDM_RESPONDER_TEST_CASE_KEY_EXCHANGE_RSP_VERSION_MISMATCH, 2, + test_result, "response code - 0x%02x", spdm_response->header.request_response_code); + if (test_result == COMMON_TEST_RESULT_FAIL) { + continue; + } + + if (spdm_response->header.spdm_version == test_buffer->version) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_EXCHANGE_RSP, + SPDM_RESPONDER_TEST_CASE_KEY_EXCHANGE_RSP_VERSION_MISMATCH, 3, + test_result, "response version - 0x%02x", spdm_response->header.spdm_version); + if (test_result == COMMON_TEST_RESULT_FAIL) { + continue; + } + + if (spdm_response->header.param1 == SPDM_ERROR_CODE_VERSION_MISMATCH) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_EXCHANGE_RSP, + SPDM_RESPONDER_TEST_CASE_KEY_EXCHANGE_RSP_VERSION_MISMATCH, 4, + test_result, "response param1 - 0x%02x", spdm_response->header.param1); + + if (spdm_response->header.param2 == 0) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_EXCHANGE_RSP, + SPDM_RESPONDER_TEST_CASE_KEY_EXCHANGE_RSP_VERSION_MISMATCH, 5, + test_result, "response param2 - 0x%02x", spdm_response->header.param2); + } +} + +void spdm_test_case_key_exchange_rsp_unexpected_request (void *test_context) +{ + spdm_test_context_t *spdm_test_context; + void *spdm_context; + libspdm_return_t status; + spdm_key_exchange_request_mine_t spdm_request; + size_t spdm_request_size; + spdm_key_exchange_response_t *spdm_response; + size_t spdm_response_size; + uint8_t message[LIBSPDM_MAX_MESSAGE_BUFFER_SIZE]; + uint8_t *ptr; + common_test_result_t test_result; + spdm_key_exchange_rsp_test_buffer_t *test_buffer; + + spdm_test_context = test_context; + spdm_context = spdm_test_context->spdm_context; + test_buffer = (void *)spdm_test_context->test_scratch_buffer; + LIBSPDM_ASSERT(spdm_test_context->test_scratch_buffer_size == + sizeof(test_buffer->version)); + + libspdm_zero_mem(&spdm_request, sizeof(spdm_request)); + spdm_request.header.spdm_version = test_buffer->version; + spdm_request.header.request_response_code = SPDM_KEY_EXCHANGE; + spdm_request.header.param1 = SPDM_KEY_EXCHANGE_REQUEST_NO_MEASUREMENT_SUMMARY_HASH; + spdm_request.header.param2 = 0; + spdm_request.req_session_id = 0; + spdm_request.session_policy = 0; + ptr = spdm_request.exchange_data; + ptr += test_buffer->dhe_key_size; + *(uint16_t *)ptr = 0; + ptr += sizeof(uint16_t); + spdm_request_size = (size_t)ptr - (size_t)&spdm_request; + + spdm_response = (void *)message; + spdm_response_size = sizeof(message); + libspdm_zero_mem(message, sizeof(message)); + status = libspdm_send_receive_data(spdm_context, NULL, false, + &spdm_request, spdm_request_size, + spdm_response, &spdm_response_size); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_EXCHANGE_RSP, + SPDM_RESPONDER_TEST_CASE_KEY_EXCHANGE_RSP_UNEXPECTED_REQUEST, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "send/receive failure"); + return; + } + + if (spdm_response_size >= sizeof(spdm_error_response_t)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_EXCHANGE_RSP, + SPDM_RESPONDER_TEST_CASE_KEY_EXCHANGE_RSP_UNEXPECTED_REQUEST, 1, + test_result, "response size - %d", spdm_response_size); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.request_response_code == SPDM_ERROR) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_EXCHANGE_RSP, + SPDM_RESPONDER_TEST_CASE_KEY_EXCHANGE_RSP_UNEXPECTED_REQUEST, 2, + test_result, "response code - 0x%02x", spdm_response->header.request_response_code); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.spdm_version == test_buffer->version) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_EXCHANGE_RSP, + SPDM_RESPONDER_TEST_CASE_KEY_EXCHANGE_RSP_UNEXPECTED_REQUEST, 3, + test_result, "response version - 0x%02x", spdm_response->header.spdm_version); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.param1 == SPDM_ERROR_CODE_UNEXPECTED_REQUEST) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_EXCHANGE_RSP, + SPDM_RESPONDER_TEST_CASE_KEY_EXCHANGE_RSP_UNEXPECTED_REQUEST, 4, + test_result, "response param1 - 0x%02x", spdm_response->header.param1); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.param2 == 0) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_EXCHANGE_RSP, + SPDM_RESPONDER_TEST_CASE_KEY_EXCHANGE_RSP_UNEXPECTED_REQUEST, 5, + test_result, "response param2 - 0x%02x", spdm_response->header.param2); +} + +void spdm_test_case_key_exchange_rsp_unexpected_request_in_session (void *test_context) +{ + spdm_test_context_t *spdm_test_context; + void *spdm_context; + libspdm_return_t status; + spdm_key_exchange_request_mine_t spdm_request; + size_t spdm_request_size; + spdm_key_exchange_response_t *spdm_response; + size_t spdm_response_size; + uint8_t message[LIBSPDM_MAX_MESSAGE_BUFFER_SIZE]; + uint8_t *ptr; + size_t dhe_key_size; + size_t opaque_key_exchange_req_size; + void *dhe_context; + uint16_t req_session_id; + bool result; + common_test_result_t test_result; + spdm_key_exchange_rsp_test_buffer_t *test_buffer; + uint32_t session_id; + + spdm_test_context = test_context; + spdm_context = spdm_test_context->spdm_context; + test_buffer = (void *)spdm_test_context->test_scratch_buffer; + LIBSPDM_ASSERT(spdm_test_context->test_scratch_buffer_size == + sizeof(test_buffer->version)); + + status = libspdm_start_session (spdm_context, false, + SPDM_KEY_EXCHANGE_REQUEST_NO_MEASUREMENT_SUMMARY_HASH, + 0, 0, &session_id, NULL, NULL); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_EXCHANGE_RSP, + SPDM_RESPONDER_TEST_CASE_KEY_EXCHANGE_RSP_UNEXPECTED_REQUEST_IN_SESSION, + COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "start_session failure"); + return; + } + + libspdm_zero_mem(&spdm_request, sizeof(spdm_request)); + spdm_request.header.spdm_version = test_buffer->version; + spdm_request.header.request_response_code = SPDM_KEY_EXCHANGE; + spdm_request.header.param1 = SPDM_KEY_EXCHANGE_REQUEST_NO_MEASUREMENT_SUMMARY_HASH; + spdm_request.header.param2 = 0; + req_session_id = libspdm_allocate_req_session_id(spdm_context); + spdm_request.req_session_id = req_session_id; + spdm_request.session_policy = 0; + + dhe_context = libspdm_secured_message_dhe_new( + test_buffer->version, + test_buffer->dhe_named_group, true); + if (dhe_context == NULL) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_EXCHANGE_RSP, + SPDM_RESPONDER_TEST_CASE_KEY_EXCHANGE_RSP_UNEXPECTED_REQUEST_IN_SESSION, + COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "dhe_new failure"); + return; + } + dhe_key_size = test_buffer->dhe_key_size; + ptr = spdm_request.exchange_data; + result = libspdm_secured_message_dhe_generate_key( + test_buffer->dhe_named_group, + dhe_context, ptr, &dhe_key_size); + if (!result) { + libspdm_secured_message_dhe_free( + test_buffer->dhe_named_group, dhe_context); + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_EXCHANGE_RSP, + SPDM_RESPONDER_TEST_CASE_KEY_EXCHANGE_RSP_UNEXPECTED_REQUEST_IN_SESSION, + COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "dhe_generate_key failure"); + return; + } + ptr += dhe_key_size; + + 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); + status = libspdm_build_opaque_data_supported_version_data( + spdm_context, &opaque_key_exchange_req_size, ptr); + LIBSPDM_ASSERT(status == LIBSPDM_STATUS_SUCCESS); + ptr += opaque_key_exchange_req_size; + + spdm_request_size = (size_t)ptr - (size_t)&spdm_request; + + spdm_response = (void *)message; + spdm_response_size = sizeof(message); + libspdm_zero_mem(message, sizeof(message)); + status = libspdm_send_receive_data(spdm_context, &session_id, false, + &spdm_request, spdm_request_size, + spdm_response, &spdm_response_size); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_EXCHANGE_RSP, + SPDM_RESPONDER_TEST_CASE_KEY_EXCHANGE_RSP_UNEXPECTED_REQUEST_IN_SESSION, + COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "send/receive failure"); + return; + } + + if (spdm_response_size >= sizeof(spdm_error_response_t)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_EXCHANGE_RSP, + SPDM_RESPONDER_TEST_CASE_KEY_EXCHANGE_RSP_UNEXPECTED_REQUEST_IN_SESSION, 1, + test_result, "response size - %d", spdm_response_size); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.request_response_code == SPDM_ERROR) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_EXCHANGE_RSP, + SPDM_RESPONDER_TEST_CASE_KEY_EXCHANGE_RSP_UNEXPECTED_REQUEST_IN_SESSION, 2, + test_result, "response code - 0x%02x", spdm_response->header.request_response_code); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.spdm_version == test_buffer->version) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_EXCHANGE_RSP, + SPDM_RESPONDER_TEST_CASE_KEY_EXCHANGE_RSP_UNEXPECTED_REQUEST_IN_SESSION, 3, + test_result, "response version - 0x%02x", spdm_response->header.spdm_version); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.param1 == SPDM_ERROR_CODE_UNEXPECTED_REQUEST) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_EXCHANGE_RSP, + SPDM_RESPONDER_TEST_CASE_KEY_EXCHANGE_RSP_UNEXPECTED_REQUEST_IN_SESSION, 4, + test_result, "response param1 - 0x%02x", spdm_response->header.param1); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.param2 == 0) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_EXCHANGE_RSP, + SPDM_RESPONDER_TEST_CASE_KEY_EXCHANGE_RSP_UNEXPECTED_REQUEST_IN_SESSION, 5, + test_result, "response param2 - 0x%02x", spdm_response->header.param2); +} + +void spdm_test_case_key_exchange_rsp_invalid_request (void *test_context) +{ + spdm_test_context_t *spdm_test_context; + void *spdm_context; + libspdm_return_t status; + spdm_key_exchange_request_mine_t spdm_request; + spdm_key_exchange_request_mine_t spdm_request_new; + size_t spdm_request_size; + spdm_key_exchange_response_t *spdm_response; + uint8_t message[LIBSPDM_MAX_MESSAGE_BUFFER_SIZE]; + size_t spdm_response_size; + uint8_t *ptr; + size_t dhe_key_size; + size_t opaque_key_exchange_req_size; + void *dhe_context; + uint16_t req_session_id; + bool result; + common_test_result_t test_result; + spdm_key_exchange_rsp_test_buffer_t *test_buffer; + size_t index; + uint8_t slot_id; + + spdm_test_context = test_context; + spdm_context = spdm_test_context->spdm_context; + test_buffer = (void *)spdm_test_context->test_scratch_buffer; + LIBSPDM_ASSERT(spdm_test_context->test_scratch_buffer_size == + offsetof(spdm_key_exchange_rsp_test_buffer_t, total_digest_buffer) + + test_buffer->hash_size * test_buffer->slot_count); + + libspdm_zero_mem(&spdm_request, sizeof(spdm_request)); + spdm_request.header.spdm_version = test_buffer->version; + spdm_request.header.request_response_code = SPDM_KEY_EXCHANGE; + spdm_request.header.param1 = SPDM_KEY_EXCHANGE_REQUEST_NO_MEASUREMENT_SUMMARY_HASH; + spdm_request.header.param2 = 0; + /* ignore spdm_request.random_data */ + req_session_id = libspdm_allocate_req_session_id(spdm_context); + spdm_request.req_session_id = req_session_id; + spdm_request.session_policy = 0; + + dhe_context = libspdm_secured_message_dhe_new( + test_buffer->version, + test_buffer->dhe_named_group, true); + if (dhe_context == NULL) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_EXCHANGE_RSP, + SPDM_RESPONDER_TEST_CASE_KEY_EXCHANGE_RSP_INVALID_REQUEST, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "dhe_new failure"); + return; + } + dhe_key_size = test_buffer->dhe_key_size; + ptr = spdm_request.exchange_data; + result = libspdm_secured_message_dhe_generate_key( + test_buffer->dhe_named_group, + dhe_context, ptr, &dhe_key_size); + if (!result) { + libspdm_secured_message_dhe_free( + test_buffer->dhe_named_group, dhe_context); + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_EXCHANGE_RSP, + SPDM_RESPONDER_TEST_CASE_KEY_EXCHANGE_RSP_INVALID_REQUEST, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "dhe_generate_key failure"); + return; + } + ptr += dhe_key_size; + + 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); + status = libspdm_build_opaque_data_supported_version_data( + spdm_context, &opaque_key_exchange_req_size, ptr); + LIBSPDM_ASSERT(status == LIBSPDM_STATUS_SUCCESS); + ptr += opaque_key_exchange_req_size; + + spdm_request_size = (size_t)ptr - (size_t)&spdm_request; + + for (index = 0; index < SPDM_MAX_SLOT_COUNT * 2 + 2; index++) { + libspdm_copy_mem (&spdm_request_new, sizeof(spdm_request_new), &spdm_request, + spdm_request_size); + + if (index < SPDM_MAX_SLOT_COUNT * 2) { + slot_id = (uint8_t)index; + if ((slot_id < SPDM_MAX_SLOT_COUNT) && + ((test_buffer->slot_mask & (0x1 << slot_id)) != 0)) { + continue; + } + common_test_record_test_message ("test invalid slot - 0x%02x\n", slot_id); + spdm_request_new.header.param2 = slot_id; + } else if (index == SPDM_MAX_SLOT_COUNT * 2) { + common_test_record_test_message ("test invalid meas_hash_type - 0x%02x\n", + SPDM_KEY_EXCHANGE_REQUEST_TCB_COMPONENT_MEASUREMENT_HASH + + 1); + spdm_request_new.header.param1 = + SPDM_KEY_EXCHANGE_REQUEST_TCB_COMPONENT_MEASUREMENT_HASH + 1; + } else { + common_test_record_test_message ("test invalid meas_hash_type - 0x%02x\n", + SPDM_KEY_EXCHANGE_REQUEST_ALL_MEASUREMENTS_HASH - 1); + spdm_request_new.header.param1 = SPDM_KEY_EXCHANGE_REQUEST_ALL_MEASUREMENTS_HASH - 1; + } + + spdm_response = (void *)message; + spdm_response_size = sizeof(message); + libspdm_zero_mem(message, sizeof(message)); + status = libspdm_send_receive_data(spdm_context, NULL, false, + &spdm_request_new, spdm_request_size, + spdm_response, &spdm_response_size); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_EXCHANGE_RSP, + SPDM_RESPONDER_TEST_CASE_KEY_EXCHANGE_RSP_INVALID_REQUEST, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "send/receive failure"); + continue; + } + + if (spdm_response_size >= sizeof(spdm_error_response_t)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_EXCHANGE_RSP, + SPDM_RESPONDER_TEST_CASE_KEY_EXCHANGE_RSP_INVALID_REQUEST, 1, + test_result, "response size - %d", spdm_response_size); + if (test_result == COMMON_TEST_RESULT_FAIL) { + continue; + } + + if (spdm_response->header.request_response_code == SPDM_ERROR) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_EXCHANGE_RSP, + SPDM_RESPONDER_TEST_CASE_KEY_EXCHANGE_RSP_INVALID_REQUEST, 2, + test_result, "response code - 0x%02x", spdm_response->header.request_response_code); + if (test_result == COMMON_TEST_RESULT_FAIL) { + continue; + } + + if (spdm_response->header.spdm_version == test_buffer->version) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_EXCHANGE_RSP, + SPDM_RESPONDER_TEST_CASE_KEY_EXCHANGE_RSP_INVALID_REQUEST, 3, + test_result, "response version - 0x%02x", spdm_response->header.spdm_version); + if (test_result == COMMON_TEST_RESULT_FAIL) { + continue; + } + + if (spdm_response->header.param1 == SPDM_ERROR_CODE_INVALID_REQUEST) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_EXCHANGE_RSP, + SPDM_RESPONDER_TEST_CASE_KEY_EXCHANGE_RSP_INVALID_REQUEST, 4, + test_result, "response param1 - 0x%02x", spdm_response->header.param1); + + if (spdm_response->header.param2 == 0) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_KEY_EXCHANGE_RSP, + SPDM_RESPONDER_TEST_CASE_KEY_EXCHANGE_RSP_INVALID_REQUEST, 5, + test_result, "response param2 - 0x%02x", spdm_response->header.param2); + } +} + +common_test_case_t m_spdm_test_group_key_exchange_rsp[] = { + {SPDM_RESPONDER_TEST_CASE_KEY_EXCHANGE_RSP_SUCCESS_11, + "spdm_test_case_key_exchange_rsp_success_11", spdm_test_case_key_exchange_rsp_success_11, + spdm_test_case_key_exchange_rsp_setup_version_11}, + {SPDM_RESPONDER_TEST_CASE_KEY_EXCHANGE_RSP_SUCCESS_11_HS_CLEAR, + "spdm_test_case_key_exchange_rsp_success_11_hs_clear", + spdm_test_case_key_exchange_rsp_success_11_hs_clear, + spdm_test_case_key_exchange_rsp_setup_version_11_hs_clear}, + {SPDM_RESPONDER_TEST_CASE_KEY_EXCHANGE_RSP_VERSION_MISMATCH, + "spdm_test_case_key_exchange_rsp_version_mismatch", + spdm_test_case_key_exchange_rsp_version_mismatch, + spdm_test_case_key_exchange_rsp_setup_version_any}, + {SPDM_RESPONDER_TEST_CASE_KEY_EXCHANGE_RSP_UNEXPECTED_REQUEST, + "spdm_test_case_key_exchange_rsp_unexpected_request", + spdm_test_case_key_exchange_rsp_unexpected_request, + spdm_test_case_key_exchange_rsp_setup_version_capabilities}, + {SPDM_RESPONDER_TEST_CASE_KEY_EXCHANGE_RSP_UNEXPECTED_REQUEST_IN_SESSION, + "spdm_test_case_key_exchange_rsp_unexpected_request_in_session", + spdm_test_case_key_exchange_rsp_unexpected_request_in_session, + spdm_test_case_key_exchange_rsp_setup_version_any}, + {SPDM_RESPONDER_TEST_CASE_KEY_EXCHANGE_RSP_INVALID_REQUEST, + "spdm_test_case_key_exchange_rsp_invalid_request", + spdm_test_case_key_exchange_rsp_invalid_request, + spdm_test_case_key_exchange_rsp_setup_version_any}, + {SPDM_RESPONDER_TEST_CASE_KEY_EXCHANGE_RSP_SUCCESS_12, + "spdm_test_case_key_exchange_rsp_success_12", spdm_test_case_key_exchange_rsp_success_12, + spdm_test_case_key_exchange_rsp_setup_version_12}, + {SPDM_RESPONDER_TEST_CASE_KEY_EXCHANGE_RSP_SUCCESS_12_HS_CLEAR, + "spdm_test_case_key_exchange_rsp_success_12_hs_clear", + spdm_test_case_key_exchange_rsp_success_12_hs_clear, + spdm_test_case_key_exchange_rsp_setup_version_12_hs_clear}, + {COMMON_TEST_ID_END, NULL, NULL}, +}; diff --git a/library/spdm_responder_conformance_test_lib/spdm_responder_test_9_finish_rsp.c b/library/spdm_responder_conformance_test_lib/spdm_responder_test_9_finish_rsp.c new file mode 100644 index 0000000..b993c15 --- /dev/null +++ b/library/spdm_responder_conformance_test_lib/spdm_responder_test_9_finish_rsp.c @@ -0,0 +1,1498 @@ +/** + * Copyright Notice: + * Copyright 2021 DMTF. All rights reserved. + * License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/spdm-emu/blob/main/LICENSE.md + **/ + +#include "spdm_responder_test.h" + +#pragma pack(1) +typedef struct { + uint8_t version; + uint32_t rsp_cap_flags; + uint32_t hash_algo; + uint32_t hash_size; + uint8_t slot_mask; + uint8_t slot_count; + uint8_t total_digest_buffer[SPDM_MAX_SLOT_COUNT * LIBSPDM_MAX_HASH_SIZE]; +} spdm_finish_rsp_test_buffer_t; +#pragma pack() + +#pragma pack(1) +typedef struct { + spdm_message_header_t header; + uint8_t verify_data[LIBSPDM_MAX_HASH_SIZE]; +} spdm_finish_request_mine_t; + +#pragma pack() + +bool spdm_test_case_finish_rsp_setup_vca_digest (void *test_context, + size_t spdm_version_count, + spdm_version_number_t *spdm_version, bool hs_clear) +{ + spdm_test_context_t *spdm_test_context; + void *spdm_context; + spdm_version_number_t version; + libspdm_return_t status; + libspdm_data_parameter_t parameter; + size_t data_size; + uint32_t data32; + uint16_t data16; + uint8_t data8; + spdm_finish_rsp_test_buffer_t *test_buffer; + size_t index; + uint8_t cert_chain_buffer[LIBSPDM_MAX_CERT_CHAIN_SIZE]; + size_t cert_chain_buffer_size; + + spdm_test_context = test_context; + spdm_context = spdm_test_context->spdm_context; + + if (spdm_version_count != 0) { + libspdm_zero_mem(¶meter, sizeof(parameter)); + parameter.location = LIBSPDM_DATA_LOCATION_LOCAL; + libspdm_set_data(spdm_context, LIBSPDM_DATA_SPDM_VERSION, ¶meter, + spdm_version, sizeof(spdm_version_number_t) * spdm_version_count); + } + + data32 = SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CERT_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHAL_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_ENCRYPT_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MAC_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_KEY_EX_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_ENCAP_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_HBEAT_CAP | + SPDM_GET_CAPABILITIES_REQUEST_FLAGS_KEY_UPD_CAP; + if (hs_clear) { + data32 |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_HANDSHAKE_IN_THE_CLEAR_CAP; + } + libspdm_set_data(spdm_context, LIBSPDM_DATA_CAPABILITY_FLAGS, ¶meter, + &data32, sizeof(data32)); + + data8 = SPDM_MEASUREMENT_BLOCK_HEADER_SPECIFICATION_DMTF; + libspdm_set_data(spdm_context, LIBSPDM_DATA_MEASUREMENT_SPEC, ¶meter, + &data8, sizeof(data8)); + data32 = SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_2048 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_3072 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_3072 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_4096 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_4096 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P384 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P521 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_SM2_ECC_SM2_P256 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED25519 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED448; + libspdm_set_data(spdm_context, LIBSPDM_DATA_BASE_ASYM_ALGO, ¶meter, + &data32, sizeof(data32)); + data32 = SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_256 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_384 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_512 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA3_256 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA3_384 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA3_512 | + SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SM3_256; + libspdm_set_data(spdm_context, LIBSPDM_DATA_BASE_HASH_ALGO, ¶meter, + &data32, sizeof(data32)); + data16 = SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_2048 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_3072 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_FFDHE_4096 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_256_R1 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_384_R1 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_521_R1 | + SPDM_ALGORITHMS_DHE_NAMED_GROUP_SM2_P256; + libspdm_set_data(spdm_context, LIBSPDM_DATA_DHE_NAME_GROUP, ¶meter, + &data16, sizeof(data16)); + data16 = SPDM_ALGORITHMS_AEAD_CIPHER_SUITE_AES_128_GCM | + SPDM_ALGORITHMS_AEAD_CIPHER_SUITE_AES_256_GCM | + SPDM_ALGORITHMS_AEAD_CIPHER_SUITE_CHACHA20_POLY1305 | + SPDM_ALGORITHMS_AEAD_CIPHER_SUITE_AEAD_SM4_GCM; + libspdm_set_data(spdm_context, LIBSPDM_DATA_AEAD_CIPHER_SUITE, ¶meter, + &data16, sizeof(data16)); + data16 = SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_2048 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_3072 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_3072 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_4096 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSAPSS_4096 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P384 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P521 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_SM2_ECC_SM2_P256 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED25519 | + SPDM_ALGORITHMS_BASE_ASYM_ALGO_EDDSA_ED448; + libspdm_set_data(spdm_context, LIBSPDM_DATA_REQ_BASE_ASYM_ALG, ¶meter, + &data16, sizeof(data16)); + data16 = SPDM_ALGORITHMS_KEY_SCHEDULE_HMAC_HASH; + libspdm_set_data(spdm_context, LIBSPDM_DATA_KEY_SCHEDULE, ¶meter, &data16, + sizeof(data16)); + data8 = SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_1; + libspdm_set_data(spdm_context, LIBSPDM_DATA_OTHER_PARAMS_SUPPORT, ¶meter, + &data8, sizeof(data8)); + + status = libspdm_init_connection (spdm_context, false); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + return false; + } + + test_buffer = (void *)spdm_test_context->test_scratch_buffer; + LIBSPDM_ASSERT(sizeof(spdm_test_context->test_scratch_buffer) >= + sizeof(spdm_finish_rsp_test_buffer_t)); + libspdm_zero_mem(test_buffer, sizeof(spdm_finish_rsp_test_buffer_t)); + spdm_test_context->test_scratch_buffer_size = sizeof(spdm_finish_rsp_test_buffer_t); + + data_size = sizeof(version); + libspdm_zero_mem(¶meter, sizeof(parameter)); + parameter.location = LIBSPDM_DATA_LOCATION_CONNECTION; + libspdm_get_data(spdm_context, LIBSPDM_DATA_SPDM_VERSION, ¶meter, &version, &data_size); + test_buffer->version = (version >> SPDM_VERSION_NUMBER_SHIFT_BIT); + + data_size = sizeof(test_buffer->rsp_cap_flags); + libspdm_zero_mem(¶meter, sizeof(parameter)); + parameter.location = LIBSPDM_DATA_LOCATION_CONNECTION; + libspdm_get_data(spdm_context, LIBSPDM_DATA_CAPABILITY_FLAGS, ¶meter, + &test_buffer->rsp_cap_flags, &data_size); + if (((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP) == 0) || + ((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_KEY_EX_CAP) == 0)) { + return false; + } + + if (hs_clear) { + if ((test_buffer->rsp_cap_flags & + SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_HANDSHAKE_IN_THE_CLEAR_CAP) == 0) { + return false; + } + } + + data_size = sizeof(test_buffer->hash_algo); + libspdm_get_data(spdm_context, LIBSPDM_DATA_BASE_HASH_ALGO, ¶meter, &test_buffer->hash_algo, + &data_size); + test_buffer->hash_size = libspdm_get_hash_size(test_buffer->hash_algo); + + status = libspdm_get_digest (spdm_context, &test_buffer->slot_mask, + test_buffer->total_digest_buffer); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + return false; + } + + cert_chain_buffer_size = sizeof(cert_chain_buffer); + status = libspdm_get_certificate (spdm_context, 0, &cert_chain_buffer_size, cert_chain_buffer); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + return false; + } + + test_buffer->slot_count = 0; + for (index = 0; index < SPDM_MAX_SLOT_COUNT; index++) { + if ((test_buffer->slot_mask & (1 << index)) != 0) { + test_buffer->slot_count++; + } + } + + spdm_test_context->test_scratch_buffer_size = offsetof(spdm_finish_rsp_test_buffer_t, + total_digest_buffer) + + test_buffer->hash_size * test_buffer->slot_count; + + return true; +} + +bool spdm_test_case_finish_rsp_setup_version_any (void *test_context) +{ + return spdm_test_case_finish_rsp_setup_vca_digest (test_context, 0, NULL, false); +} + +bool spdm_test_case_finish_rsp_setup_version_any_hs_clear (void *test_context) +{ + return spdm_test_case_finish_rsp_setup_vca_digest (test_context, 0, NULL, true); +} + +bool spdm_test_case_finish_rsp_setup_version_11 (void *test_context) +{ + spdm_version_number_t spdm_version[] = { + SPDM_MESSAGE_VERSION_11 << SPDM_VERSION_NUMBER_SHIFT_BIT + }; + return spdm_test_case_finish_rsp_setup_vca_digest (test_context, + LIBSPDM_ARRAY_SIZE( + spdm_version), spdm_version, false); +} + +bool spdm_test_case_finish_rsp_setup_version_11_hs_clear (void *test_context) +{ + spdm_version_number_t spdm_version[] = { + SPDM_MESSAGE_VERSION_11 << SPDM_VERSION_NUMBER_SHIFT_BIT + }; + return spdm_test_case_finish_rsp_setup_vca_digest (test_context, + LIBSPDM_ARRAY_SIZE( + spdm_version), spdm_version, true); +} + +bool spdm_test_case_finish_rsp_setup_version_12 (void *test_context) +{ + spdm_version_number_t spdm_version[] = { + SPDM_MESSAGE_VERSION_12 << SPDM_VERSION_NUMBER_SHIFT_BIT + }; + return spdm_test_case_finish_rsp_setup_vca_digest (test_context, + LIBSPDM_ARRAY_SIZE( + spdm_version), spdm_version, false); +} + +bool spdm_test_case_finish_rsp_setup_version_12_hs_clear (void *test_context) +{ + spdm_version_number_t spdm_version[] = { + SPDM_MESSAGE_VERSION_12 << SPDM_VERSION_NUMBER_SHIFT_BIT + }; + return spdm_test_case_finish_rsp_setup_vca_digest (test_context, + LIBSPDM_ARRAY_SIZE( + spdm_version), spdm_version, true); +} + +bool spdm_test_case_finish_rsp_setup_version_capabilities (void *test_context) +{ + spdm_test_context_t *spdm_test_context; + void *spdm_context; + libspdm_return_t status; + libspdm_data_parameter_t parameter; + size_t data_size; + spdm_version_number_t spdm_version; + spdm_finish_rsp_test_buffer_t *test_buffer; + + spdm_test_context = test_context; + spdm_context = spdm_test_context->spdm_context; + + status = libspdm_get_version (spdm_context, NULL, NULL); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + return false; + } + + status = libspdm_get_capabilities (spdm_context); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + return false; + } + + test_buffer = (void *)spdm_test_context->test_scratch_buffer; + LIBSPDM_ASSERT(sizeof(spdm_test_context->test_scratch_buffer) >= + sizeof(spdm_finish_rsp_test_buffer_t)); + libspdm_zero_mem(test_buffer, sizeof(spdm_finish_rsp_test_buffer_t)); + spdm_test_context->test_scratch_buffer_size = sizeof(spdm_finish_rsp_test_buffer_t); + + data_size = sizeof(test_buffer->rsp_cap_flags); + libspdm_zero_mem(¶meter, sizeof(parameter)); + parameter.location = LIBSPDM_DATA_LOCATION_CONNECTION; + libspdm_get_data(spdm_context, LIBSPDM_DATA_CAPABILITY_FLAGS, ¶meter, + &test_buffer->rsp_cap_flags, &data_size); + if (((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP) == 0) || + ((test_buffer->rsp_cap_flags & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_KEY_EX_CAP) == 0)) { + return false; + } + + spdm_version = 0; + data_size = sizeof(spdm_version); + libspdm_zero_mem(¶meter, sizeof(parameter)); + parameter.location = LIBSPDM_DATA_LOCATION_CONNECTION; + libspdm_get_data(spdm_context, LIBSPDM_DATA_SPDM_VERSION, ¶meter, &spdm_version, + &data_size); + test_buffer->version = (spdm_version >> SPDM_VERSION_NUMBER_SHIFT_BIT); + + spdm_test_context->test_scratch_buffer_size = sizeof(test_buffer->version); + + return true; +} + +void spdm_test_case_finish_rsp_success_11_12 (void *test_context, uint8_t version, bool hs_clear) +{ + spdm_test_context_t *spdm_test_context; + void *spdm_context; + libspdm_return_t status; + spdm_finish_request_mine_t spdm_request; + size_t spdm_request_size; + spdm_finish_response_t *spdm_response; + uint8_t message[LIBSPDM_MAX_MESSAGE_BUFFER_SIZE]; + size_t spdm_response_size; + uint8_t cert_chain_buffer[LIBSPDM_MAX_CERT_CHAIN_SIZE]; + size_t cert_chain_buffer_size; + common_test_result_t test_result; + spdm_finish_rsp_test_buffer_t *test_buffer; + uint8_t slot_id; + uint32_t session_id; + uint8_t req_slot_id_param; + uint32_t verify_data_size; + uint8_t *ptr; + void *session_info; + uint8_t *verify_data_ptr; + uint8_t th2_hash_data[LIBSPDM_MAX_HASH_SIZE]; + bool result; + common_test_case_id case_id; + + spdm_test_context = test_context; + spdm_context = spdm_test_context->spdm_context; + test_buffer = (void *)spdm_test_context->test_scratch_buffer; + LIBSPDM_ASSERT(spdm_test_context->test_scratch_buffer_size == + offsetof(spdm_finish_rsp_test_buffer_t, total_digest_buffer) + + test_buffer->hash_size * test_buffer->slot_count); + + switch (version) { + case SPDM_MESSAGE_VERSION_11: + LIBSPDM_ASSERT (test_buffer->version == SPDM_MESSAGE_VERSION_11); + if (hs_clear) { + case_id = SPDM_RESPONDER_TEST_CASE_FINISH_RSP_SUCCESS_11_HS_CLEAR; + } else { + case_id = SPDM_RESPONDER_TEST_CASE_FINISH_RSP_SUCCESS_11; + } + break; + case SPDM_MESSAGE_VERSION_12: + LIBSPDM_ASSERT (test_buffer->version == SPDM_MESSAGE_VERSION_12); + if (hs_clear) { + case_id = SPDM_RESPONDER_TEST_CASE_FINISH_RSP_SUCCESS_12_HS_CLEAR; + } else { + case_id = SPDM_RESPONDER_TEST_CASE_FINISH_RSP_SUCCESS_12; + } + break; + default: + LIBSPDM_ASSERT(false); + return; + } + + for (slot_id = 0; slot_id < SPDM_MAX_SLOT_COUNT; slot_id++) { + if ((test_buffer->slot_mask & (0x1 << slot_id)) == 0) { + continue; + } + common_test_record_test_message ("test slot - 0x%02x\n", slot_id); + + status = libspdm_init_connection (spdm_context, false); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_FINISH_RSP, case_id, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "init_connection failure"); + continue; + } + + cert_chain_buffer_size = sizeof(cert_chain_buffer); + status = libspdm_get_certificate (spdm_context, slot_id, &cert_chain_buffer_size, + cert_chain_buffer); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_FINISH_RSP, case_id, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "get_certificate failure"); + continue; + } + + status = libspdm_send_receive_key_exchange (spdm_context, + SPDM_KEY_EXCHANGE_REQUEST_NO_MEASUREMENT_SUMMARY_HASH, + slot_id, 0, &session_id, NULL, &req_slot_id_param, + NULL); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_FINISH_RSP, case_id, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "key_exchange failure"); + continue; + } + + session_info = + libspdm_get_session_info_via_session_id(spdm_context, session_id); + LIBSPDM_ASSERT (session_info != NULL); + + libspdm_zero_mem(&spdm_request, sizeof(spdm_request)); + spdm_request.header.spdm_version = test_buffer->version; + spdm_request.header.request_response_code = SPDM_FINISH; + spdm_request.header.param1 = 0; + spdm_request.header.param2 = 0; + + status = libspdm_append_message_f(spdm_context, session_info, true, + (uint8_t *)&spdm_request, + sizeof(spdm_finish_request_t)); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_FINISH_RSP, case_id, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "append_message_f failure"); + continue; + } + ptr = spdm_request.verify_data; + result = libspdm_generate_finish_req_hmac(spdm_context, session_info, ptr); + if (!result) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_FINISH_RSP, case_id, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "generate_finish_req_hmac failure"); + continue; + } + status = libspdm_append_message_f(spdm_context, session_info, true, ptr, + test_buffer->hash_size); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_FINISH_RSP, case_id, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "append_message_f failure"); + continue; + } + + spdm_request_size = sizeof(spdm_finish_request_t) + test_buffer->hash_size; + + spdm_response = (void *)message; + spdm_response_size = sizeof(message); + libspdm_zero_mem(message, sizeof(message)); + if (hs_clear) { + status = libspdm_send_receive_data(spdm_context, NULL, false, + &spdm_request, spdm_request_size, + spdm_response, &spdm_response_size); + } else { + status = libspdm_send_receive_data(spdm_context, session_info, false, + &spdm_request, spdm_request_size, + spdm_response, &spdm_response_size); + } + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_FINISH_RSP, case_id, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "send/receive failure"); + return; + } + + if (hs_clear) { + verify_data_size = test_buffer->hash_size; + } else { + verify_data_size = 0; + } + if (spdm_response_size < sizeof(spdm_finish_response_t) + verify_data_size) { + test_result = COMMON_TEST_RESULT_FAIL; + } else { + test_result = COMMON_TEST_RESULT_PASS; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_FINISH_RSP, case_id, 1, + test_result, "response size - %d", spdm_response_size); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + verify_data_ptr = (void *)((size_t)spdm_response + sizeof(spdm_finish_response_t)); + if (spdm_response->header.request_response_code == SPDM_FINISH_RSP) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_FINISH_RSP, case_id, 2, + test_result, "response code - 0x%02x", spdm_response->header.request_response_code); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.spdm_version == test_buffer->version) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_FINISH_RSP, case_id, 3, + test_result, "response version - 0x%02x", spdm_response->header.spdm_version); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + status = libspdm_append_message_f(spdm_context, session_info, true, spdm_response, + sizeof(spdm_finish_response_t)); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_FINISH_RSP, case_id, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "append_message_k failure"); + return; + } + + if (hs_clear) { + result = libspdm_verify_finish_rsp_hmac( + spdm_context, session_info, verify_data_ptr, test_buffer->hash_size); + if (result) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_FINISH_RSP, case_id, 4, + test_result, "response verify_data"); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + status = libspdm_append_message_f(spdm_context, session_info, true, verify_data_ptr, + test_buffer->hash_size); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_FINISH_RSP, case_id, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "append_message_f failure"); + return; + } + } + + result = libspdm_calculate_th2_hash(spdm_context, session_info, true, + th2_hash_data); + if (!result) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_FINISH_RSP, case_id, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "calculate_th2_hash failure"); + return; + } + } +} + +void spdm_test_case_finish_rsp_success_11 (void *test_context) +{ + spdm_test_case_finish_rsp_success_11_12 (test_context, + SPDM_MESSAGE_VERSION_11, false); +} + +void spdm_test_case_finish_rsp_success_11_hs_clear (void *test_context) +{ + spdm_test_case_finish_rsp_success_11_12 (test_context, + SPDM_MESSAGE_VERSION_11, true); +} + +void spdm_test_case_finish_rsp_success_12 (void *test_context) +{ + spdm_test_case_finish_rsp_success_11_12 (test_context, + SPDM_MESSAGE_VERSION_12, false); +} + +void spdm_test_case_finish_rsp_success_12_hs_clear (void *test_context) +{ + spdm_test_case_finish_rsp_success_11_12 (test_context, + SPDM_MESSAGE_VERSION_12, true); +} + +void spdm_test_case_finish_rsp_version_mismatch (void *test_context) +{ + spdm_test_context_t *spdm_test_context; + void *spdm_context; + libspdm_return_t status; + spdm_finish_request_mine_t spdm_request; + size_t spdm_request_size; + spdm_finish_response_t *spdm_response; + uint8_t message[LIBSPDM_MAX_MESSAGE_BUFFER_SIZE]; + size_t spdm_response_size; + uint32_t session_id; + uint8_t req_slot_id_param; + uint8_t *ptr; + void *session_info; + bool result; + common_test_result_t test_result; + spdm_finish_rsp_test_buffer_t *test_buffer; + uint8_t mismatched_version[] = { + SPDM_MESSAGE_VERSION_10 - 1, + SPDM_MESSAGE_VERSION_12 + 1, + }; + size_t index; + + spdm_test_context = test_context; + spdm_context = spdm_test_context->spdm_context; + test_buffer = (void *)spdm_test_context->test_scratch_buffer; + LIBSPDM_ASSERT(spdm_test_context->test_scratch_buffer_size == + offsetof(spdm_finish_rsp_test_buffer_t, total_digest_buffer) + + test_buffer->hash_size * test_buffer->slot_count); + + mismatched_version[0] = (uint8_t)(test_buffer->version - 1); + mismatched_version[1] = (uint8_t)(test_buffer->version + 1); + + status = libspdm_send_receive_key_exchange (spdm_context, + SPDM_KEY_EXCHANGE_REQUEST_NO_MEASUREMENT_SUMMARY_HASH, + 0, 0, &session_id, NULL, &req_slot_id_param, NULL); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_FINISH_RSP, + SPDM_RESPONDER_TEST_CASE_FINISH_RSP_VERSION_MISMATCH, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "key_exchange failure"); + return; + } + + for (index = 0; index < LIBSPDM_ARRAY_SIZE(mismatched_version); index++) { + common_test_record_test_message ("test mismatched_version - 0x%02x\n", + mismatched_version[index]); + + libspdm_zero_mem(&spdm_request, sizeof(spdm_request)); + spdm_request.header.spdm_version = mismatched_version[index]; + spdm_request.header.request_response_code = SPDM_FINISH; + spdm_request.header.param1 = 0; + spdm_request.header.param2 = 0; + + session_info = + libspdm_get_session_info_via_session_id(spdm_context, session_id); + LIBSPDM_ASSERT (session_info != NULL); + + status = libspdm_append_message_f(spdm_context, session_info, true, + (uint8_t *)&spdm_request, + sizeof(spdm_finish_request_t)); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_FINISH_RSP, + SPDM_RESPONDER_TEST_CASE_FINISH_RSP_VERSION_MISMATCH, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "append_message_f failure"); + continue; + } + ptr = spdm_request.verify_data; + result = libspdm_generate_finish_req_hmac(spdm_context, session_info, ptr); + if (!result) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_FINISH_RSP, + SPDM_RESPONDER_TEST_CASE_FINISH_RSP_VERSION_MISMATCH, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "generate_finish_req_hmac failure"); + continue; + } + status = libspdm_append_message_f(spdm_context, session_info, true, ptr, + test_buffer->hash_size); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_FINISH_RSP, + SPDM_RESPONDER_TEST_CASE_FINISH_RSP_VERSION_MISMATCH, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "append_message_f failure"); + continue; + } + + spdm_request_size = sizeof(spdm_finish_request_t) + test_buffer->hash_size; + + spdm_response = (void *)message; + spdm_response_size = sizeof(message); + libspdm_zero_mem(message, sizeof(message)); + status = libspdm_send_receive_data(spdm_context, session_info, false, + &spdm_request, spdm_request_size, + spdm_response, &spdm_response_size); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_FINISH_RSP, + SPDM_RESPONDER_TEST_CASE_FINISH_RSP_VERSION_MISMATCH, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "send/receive failure"); + continue; + } + + if (spdm_response_size >= sizeof(spdm_error_response_t)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_FINISH_RSP, + SPDM_RESPONDER_TEST_CASE_FINISH_RSP_VERSION_MISMATCH, 1, + test_result, "response size - %d", spdm_response_size); + if (test_result == COMMON_TEST_RESULT_FAIL) { + continue; + } + + if (spdm_response->header.request_response_code == SPDM_ERROR) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_FINISH_RSP, + SPDM_RESPONDER_TEST_CASE_FINISH_RSP_VERSION_MISMATCH, 2, + test_result, "response code - 0x%02x", spdm_response->header.request_response_code); + if (test_result == COMMON_TEST_RESULT_FAIL) { + continue; + } + + if (spdm_response->header.spdm_version == test_buffer->version) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_FINISH_RSP, + SPDM_RESPONDER_TEST_CASE_FINISH_RSP_VERSION_MISMATCH, 3, + test_result, "response version - 0x%02x", spdm_response->header.spdm_version); + if (test_result == COMMON_TEST_RESULT_FAIL) { + continue; + } + + if (spdm_response->header.param1 == SPDM_ERROR_CODE_VERSION_MISMATCH) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_FINISH_RSP, + SPDM_RESPONDER_TEST_CASE_FINISH_RSP_VERSION_MISMATCH, 4, + test_result, "response param1 - 0x%02x", spdm_response->header.param1); + + if (spdm_response->header.param2 == 0) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_FINISH_RSP, + SPDM_RESPONDER_TEST_CASE_FINISH_RSP_VERSION_MISMATCH, 5, + test_result, "response param2 - 0x%02x", spdm_response->header.param2); + } +} + +void spdm_test_case_finish_rsp_unexpected_request (void *test_context) +{ + spdm_test_context_t *spdm_test_context; + void *spdm_context; + libspdm_return_t status; + spdm_finish_request_mine_t spdm_request; + size_t spdm_request_size; + spdm_finish_response_t *spdm_response; + size_t spdm_response_size; + uint8_t message[LIBSPDM_MAX_MESSAGE_BUFFER_SIZE]; + common_test_result_t test_result; + spdm_finish_rsp_test_buffer_t *test_buffer; + + spdm_test_context = test_context; + spdm_context = spdm_test_context->spdm_context; + test_buffer = (void *)spdm_test_context->test_scratch_buffer; + LIBSPDM_ASSERT(spdm_test_context->test_scratch_buffer_size == + sizeof(test_buffer->version)); + + libspdm_zero_mem(&spdm_request, sizeof(spdm_request)); + spdm_request.header.spdm_version = test_buffer->version; + spdm_request.header.request_response_code = SPDM_FINISH; + spdm_request.header.param1 = 0; + spdm_request.header.param2 = 0; + + spdm_request_size = sizeof(spdm_finish_request_t) + test_buffer->hash_size; + + spdm_response = (void *)message; + spdm_response_size = sizeof(message); + libspdm_zero_mem(message, sizeof(message)); + status = libspdm_send_receive_data(spdm_context, NULL, false, + &spdm_request, spdm_request_size, + spdm_response, &spdm_response_size); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_FINISH_RSP, + SPDM_RESPONDER_TEST_CASE_FINISH_RSP_UNEXPECTED_REQUEST, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "send/receive failure"); + return; + } + + if (spdm_response_size >= sizeof(spdm_error_response_t)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_FINISH_RSP, + SPDM_RESPONDER_TEST_CASE_FINISH_RSP_UNEXPECTED_REQUEST, 1, + test_result, "response size - %d", spdm_response_size); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.request_response_code == SPDM_ERROR) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_FINISH_RSP, + SPDM_RESPONDER_TEST_CASE_FINISH_RSP_UNEXPECTED_REQUEST, 2, + test_result, "response code - 0x%02x", spdm_response->header.request_response_code); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.spdm_version == test_buffer->version) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_FINISH_RSP, + SPDM_RESPONDER_TEST_CASE_FINISH_RSP_UNEXPECTED_REQUEST, 3, + test_result, "response version - 0x%02x", spdm_response->header.spdm_version); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.param1 == SPDM_ERROR_CODE_UNEXPECTED_REQUEST) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_FINISH_RSP, + SPDM_RESPONDER_TEST_CASE_FINISH_RSP_UNEXPECTED_REQUEST, 4, + test_result, "response param1 - 0x%02x", spdm_response->header.param1); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.param2 == 0) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_FINISH_RSP, + SPDM_RESPONDER_TEST_CASE_FINISH_RSP_UNEXPECTED_REQUEST, 5, + test_result, "response param2 - 0x%02x", spdm_response->header.param2); +} + +void spdm_test_case_finish_rsp_unexpected_request_in_session (void *test_context) +{ + spdm_test_context_t *spdm_test_context; + void *spdm_context; + libspdm_return_t status; + spdm_finish_request_mine_t spdm_request; + size_t spdm_request_size; + spdm_finish_response_t *spdm_response; + size_t spdm_response_size; + uint8_t message[LIBSPDM_MAX_MESSAGE_BUFFER_SIZE]; + uint32_t session_id; + uint8_t *ptr; + void *session_info; + bool result; + common_test_result_t test_result; + spdm_finish_rsp_test_buffer_t *test_buffer; + + spdm_test_context = test_context; + spdm_context = spdm_test_context->spdm_context; + test_buffer = (void *)spdm_test_context->test_scratch_buffer; + LIBSPDM_ASSERT(spdm_test_context->test_scratch_buffer_size == + sizeof(test_buffer->version)); + + status = libspdm_start_session (spdm_context, false, + SPDM_KEY_EXCHANGE_REQUEST_NO_MEASUREMENT_SUMMARY_HASH, + 0, 0, &session_id, NULL, NULL); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_FINISH_RSP, + SPDM_RESPONDER_TEST_CASE_FINISH_RSP_UNEXPECTED_REQUEST_IN_SESSION, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "start_session failure"); + return; + } + + libspdm_zero_mem(&spdm_request, sizeof(spdm_request)); + spdm_request.header.spdm_version = test_buffer->version; + spdm_request.header.request_response_code = SPDM_FINISH; + spdm_request.header.param1 = 0; + spdm_request.header.param2 = 0; + + session_info = + libspdm_get_session_info_via_session_id(spdm_context, session_id); + LIBSPDM_ASSERT (session_info != NULL); + + status = libspdm_append_message_f(spdm_context, session_info, true, (uint8_t *)&spdm_request, + sizeof(spdm_finish_request_t)); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_FINISH_RSP, + SPDM_RESPONDER_TEST_CASE_FINISH_RSP_UNEXPECTED_REQUEST_IN_SESSION, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "append_message_f failure"); + return; + } + ptr = spdm_request.verify_data; + result = libspdm_generate_finish_req_hmac(spdm_context, session_info, ptr); + if (!result) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_FINISH_RSP, + SPDM_RESPONDER_TEST_CASE_FINISH_RSP_UNEXPECTED_REQUEST_IN_SESSION, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "generate_finish_req_hmac failure"); + return; + } + status = libspdm_append_message_f(spdm_context, session_info, true, ptr, + test_buffer->hash_size); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_FINISH_RSP, + SPDM_RESPONDER_TEST_CASE_FINISH_RSP_UNEXPECTED_REQUEST_IN_SESSION, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "append_message_f failure"); + return; + } + + spdm_request_size = sizeof(spdm_finish_request_t) + test_buffer->hash_size; + + spdm_response = (void *)message; + spdm_response_size = sizeof(message); + libspdm_zero_mem(message, sizeof(message)); + status = libspdm_send_receive_data(spdm_context, &session_id, false, + &spdm_request, spdm_request_size, + spdm_response, &spdm_response_size); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_FINISH_RSP, + SPDM_RESPONDER_TEST_CASE_FINISH_RSP_UNEXPECTED_REQUEST_IN_SESSION, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "send/receive failure"); + return; + } + + if (spdm_response_size >= sizeof(spdm_error_response_t)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_FINISH_RSP, + SPDM_RESPONDER_TEST_CASE_FINISH_RSP_UNEXPECTED_REQUEST_IN_SESSION, 1, + test_result, "response size - %d", spdm_response_size); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.request_response_code == SPDM_ERROR) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_FINISH_RSP, + SPDM_RESPONDER_TEST_CASE_FINISH_RSP_UNEXPECTED_REQUEST_IN_SESSION, 2, + test_result, "response code - 0x%02x", spdm_response->header.request_response_code); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.spdm_version == test_buffer->version) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_FINISH_RSP, + SPDM_RESPONDER_TEST_CASE_FINISH_RSP_UNEXPECTED_REQUEST_IN_SESSION, 3, + test_result, "response version - 0x%02x", spdm_response->header.spdm_version); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.param1 == SPDM_ERROR_CODE_UNEXPECTED_REQUEST) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_FINISH_RSP, + SPDM_RESPONDER_TEST_CASE_FINISH_RSP_UNEXPECTED_REQUEST_IN_SESSION, 4, + test_result, "response param1 - 0x%02x", spdm_response->header.param1); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.param2 == 0) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_FINISH_RSP, + SPDM_RESPONDER_TEST_CASE_FINISH_RSP_UNEXPECTED_REQUEST_IN_SESSION, 5, + test_result, "response param2 - 0x%02x", spdm_response->header.param2); +} + +void spdm_test_case_finish_rsp_invalid_request (void *test_context) +{ + spdm_test_context_t *spdm_test_context; + void *spdm_context; + libspdm_return_t status; + spdm_finish_request_mine_t spdm_request; + spdm_finish_request_mine_t spdm_request_new; + size_t spdm_request_size; + spdm_finish_response_t *spdm_response; + uint8_t message[LIBSPDM_MAX_MESSAGE_BUFFER_SIZE]; + size_t spdm_response_size; + uint32_t session_id; + uint8_t req_slot_id_param; + uint8_t *ptr; + void *session_info; + bool result; + common_test_result_t test_result; + spdm_finish_rsp_test_buffer_t *test_buffer; + size_t index; + uint8_t slot_id; + + spdm_test_context = test_context; + spdm_context = spdm_test_context->spdm_context; + test_buffer = (void *)spdm_test_context->test_scratch_buffer; + LIBSPDM_ASSERT(spdm_test_context->test_scratch_buffer_size == + offsetof(spdm_finish_rsp_test_buffer_t, total_digest_buffer) + + test_buffer->hash_size * test_buffer->slot_count); + + status = libspdm_send_receive_key_exchange (spdm_context, + SPDM_KEY_EXCHANGE_REQUEST_NO_MEASUREMENT_SUMMARY_HASH, + 0, 0, &session_id, NULL, &req_slot_id_param, NULL); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_FINISH_RSP, + SPDM_RESPONDER_TEST_CASE_FINISH_RSP_INVALID_REQUEST, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "key_exchange failure"); + return; + } + + session_info = + libspdm_get_session_info_via_session_id(spdm_context, session_id); + LIBSPDM_ASSERT (session_info != NULL); + + libspdm_zero_mem(&spdm_request, sizeof(spdm_request)); + spdm_request.header.spdm_version = test_buffer->version; + spdm_request.header.request_response_code = SPDM_FINISH; + spdm_request.header.param1 = 0; + spdm_request.header.param2 = 0; + + status = libspdm_append_message_f(spdm_context, session_info, true, (uint8_t *)&spdm_request, + sizeof(spdm_finish_request_t)); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_FINISH_RSP, + SPDM_RESPONDER_TEST_CASE_FINISH_RSP_INVALID_REQUEST, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "append_message_f failure"); + return; + } + ptr = spdm_request.verify_data; + result = libspdm_generate_finish_req_hmac(spdm_context, session_info, ptr); + if (!result) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_FINISH_RSP, + SPDM_RESPONDER_TEST_CASE_FINISH_RSP_INVALID_REQUEST, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "generate_finish_req_hmac failure"); + return; + } + status = libspdm_append_message_f(spdm_context, session_info, true, ptr, + test_buffer->hash_size); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_FINISH_RSP, + SPDM_RESPONDER_TEST_CASE_FINISH_RSP_INVALID_REQUEST, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "append_message_f failure"); + return; + } + + spdm_request_size = sizeof(spdm_finish_request_t) + test_buffer->hash_size; + + for (index = 0; index < SPDM_MAX_SLOT_COUNT * 2 + 1; index++) { + libspdm_copy_mem (&spdm_request_new, sizeof(spdm_request_new), &spdm_request, + spdm_request_size); + + if (index < SPDM_MAX_SLOT_COUNT * 2) { + slot_id = (uint8_t)index; + if (slot_id == 0) { + continue; + } + common_test_record_test_message ("test invalid slot - 0x%02x\n", slot_id); + spdm_request_new.header.param2 = slot_id; + } else { + common_test_record_test_message ("test invalid size - 0x%x\n", spdm_request_size); + spdm_request_size = sizeof(spdm_finish_request_t); + } + + spdm_response = (void *)message; + spdm_response_size = sizeof(message); + libspdm_zero_mem(message, sizeof(message)); + status = libspdm_send_receive_data(spdm_context, session_info, false, + &spdm_request_new, spdm_request_size, + spdm_response, &spdm_response_size); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_FINISH_RSP, + SPDM_RESPONDER_TEST_CASE_FINISH_RSP_INVALID_REQUEST, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "send/receive failure"); + continue; + } + + if (spdm_response_size >= sizeof(spdm_error_response_t)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_FINISH_RSP, + SPDM_RESPONDER_TEST_CASE_FINISH_RSP_INVALID_REQUEST, 1, + test_result, "response size - %d", spdm_response_size); + if (test_result == COMMON_TEST_RESULT_FAIL) { + continue; + } + + if (spdm_response->header.request_response_code == SPDM_ERROR) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_FINISH_RSP, + SPDM_RESPONDER_TEST_CASE_FINISH_RSP_INVALID_REQUEST, 2, + test_result, "response code - 0x%02x", spdm_response->header.request_response_code); + if (test_result == COMMON_TEST_RESULT_FAIL) { + continue; + } + + if (spdm_response->header.spdm_version == test_buffer->version) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_FINISH_RSP, + SPDM_RESPONDER_TEST_CASE_FINISH_RSP_INVALID_REQUEST, 3, + test_result, "response version - 0x%02x", spdm_response->header.spdm_version); + if (test_result == COMMON_TEST_RESULT_FAIL) { + continue; + } + + if (spdm_response->header.param1 == SPDM_ERROR_CODE_INVALID_REQUEST) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_FINISH_RSP, + SPDM_RESPONDER_TEST_CASE_FINISH_RSP_INVALID_REQUEST, 4, + test_result, "response param1 - 0x%02x", spdm_response->header.param1); + + if (spdm_response->header.param2 == 0) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_FINISH_RSP, + SPDM_RESPONDER_TEST_CASE_FINISH_RSP_INVALID_REQUEST, 5, + test_result, "response param2 - 0x%02x", spdm_response->header.param2); + } +} + +void spdm_test_case_finish_rsp_decrypt_error_invalid_verify_data_common (void *test_context, + bool hs_clear) +{ + spdm_test_context_t *spdm_test_context; + void *spdm_context; + libspdm_return_t status; + spdm_finish_request_mine_t spdm_request; + size_t spdm_request_size; + spdm_finish_response_t *spdm_response; + uint8_t message[LIBSPDM_MAX_MESSAGE_BUFFER_SIZE]; + size_t spdm_response_size; + uint32_t session_id; + uint8_t req_slot_id_param; + uint8_t *ptr; + void *session_info; + bool result; + common_test_result_t test_result; + spdm_finish_rsp_test_buffer_t *test_buffer; + common_test_case_id case_id; + size_t index; + + spdm_test_context = test_context; + spdm_context = spdm_test_context->spdm_context; + test_buffer = (void *)spdm_test_context->test_scratch_buffer; + LIBSPDM_ASSERT(spdm_test_context->test_scratch_buffer_size == + offsetof(spdm_finish_rsp_test_buffer_t, total_digest_buffer) + + test_buffer->hash_size * test_buffer->slot_count); + + if (hs_clear) { + case_id = SPDM_RESPONDER_TEST_CASE_FINISH_RSP_DECRYPT_ERROR_INVALID_VERIFY_DATA_HS_CLEAR; + } else { + case_id = SPDM_RESPONDER_TEST_CASE_FINISH_RSP_DECRYPT_ERROR_INVALID_VERIFY_DATA; + } + + status = libspdm_send_receive_key_exchange (spdm_context, + SPDM_KEY_EXCHANGE_REQUEST_NO_MEASUREMENT_SUMMARY_HASH, + 0, 0, &session_id, NULL, &req_slot_id_param, NULL); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_FINISH_RSP, case_id, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "key_exchange failure"); + return; + } + + session_info = + libspdm_get_session_info_via_session_id(spdm_context, session_id); + LIBSPDM_ASSERT (session_info != NULL); + + libspdm_zero_mem(&spdm_request, sizeof(spdm_request)); + spdm_request.header.spdm_version = test_buffer->version; + spdm_request.header.request_response_code = SPDM_FINISH; + spdm_request.header.param1 = 0; + spdm_request.header.param2 = 0; + + status = libspdm_append_message_f(spdm_context, session_info, true, (uint8_t *)&spdm_request, + sizeof(spdm_finish_request_t)); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_FINISH_RSP, case_id, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "append_message_f failure"); + return; + } + ptr = spdm_request.verify_data; + result = libspdm_generate_finish_req_hmac(spdm_context, session_info, ptr); + if (!result) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_FINISH_RSP, case_id, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "generate_finish_req_hmac failure"); + return; + } + for (index = 0; index < test_buffer->hash_size; index++) { + ptr[index] = ptr[index] ^ 0xFF; + } + status = libspdm_append_message_f(spdm_context, session_info, true, ptr, + test_buffer->hash_size); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_FINISH_RSP, case_id, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "append_message_f failure"); + return; + } + + spdm_request_size = sizeof(spdm_finish_request_t) + test_buffer->hash_size; + + spdm_response = (void *)message; + spdm_response_size = sizeof(message); + libspdm_zero_mem(message, sizeof(message)); + if (hs_clear) { + status = libspdm_send_receive_data(spdm_context, NULL, false, + &spdm_request, spdm_request_size, + spdm_response, &spdm_response_size); + } else { + status = libspdm_send_receive_data(spdm_context, session_info, false, + &spdm_request, spdm_request_size, + spdm_response, &spdm_response_size); + } + if (LIBSPDM_STATUS_IS_ERROR(status) && (status != LIBSPDM_STATUS_SESSION_MSG_ERROR)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_FINISH_RSP, case_id, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "send/receive failure"); + return; + } + + if (status == LIBSPDM_STATUS_SESSION_MSG_ERROR) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_FINISH_RSP, case_id, 1, + COMMON_TEST_RESULT_PASS, "response size"); + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_FINISH_RSP, case_id, 2, + COMMON_TEST_RESULT_PASS, "response code"); + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_FINISH_RSP, case_id, 3, + COMMON_TEST_RESULT_PASS, "response version"); + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_FINISH_RSP, case_id, 4, + COMMON_TEST_RESULT_PASS, "response param1"); + return; + } + + if (spdm_response_size >= sizeof(spdm_error_response_t)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_FINISH_RSP, case_id, 1, + test_result, "response size - %d", spdm_response_size); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.request_response_code == SPDM_ERROR) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_FINISH_RSP, case_id, 2, + test_result, "response code - 0x%02x", spdm_response->header.request_response_code); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.spdm_version == test_buffer->version) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_FINISH_RSP, case_id, 3, + test_result, "response version - 0x%02x", spdm_response->header.spdm_version); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.param1 == SPDM_ERROR_CODE_DECRYPT_ERROR) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_FINISH_RSP, case_id, 4, + test_result, "response param1 - 0x%02x", spdm_response->header.param1); +} + +void spdm_test_case_finish_rsp_decrypt_error_invalid_verify_data (void *test_context) +{ + spdm_test_case_finish_rsp_decrypt_error_invalid_verify_data_common (test_context, false); +} + +void spdm_test_case_finish_rsp_decrypt_error_invalid_verify_data_hs_clear (void *test_context) +{ + spdm_test_case_finish_rsp_decrypt_error_invalid_verify_data_common (test_context, true); +} + +void spdm_test_case_finish_rsp_session_required (void *test_context) +{ + spdm_test_context_t *spdm_test_context; + void *spdm_context; + libspdm_return_t status; + spdm_finish_request_mine_t spdm_request; + size_t spdm_request_size; + spdm_finish_response_t *spdm_response; + uint8_t message[LIBSPDM_MAX_MESSAGE_BUFFER_SIZE]; + size_t spdm_response_size; + uint32_t session_id; + uint8_t req_slot_id_param; + uint8_t *ptr; + void *session_info; + bool result; + common_test_result_t test_result; + spdm_finish_rsp_test_buffer_t *test_buffer; + + spdm_test_context = test_context; + spdm_context = spdm_test_context->spdm_context; + test_buffer = (void *)spdm_test_context->test_scratch_buffer; + LIBSPDM_ASSERT(spdm_test_context->test_scratch_buffer_size == + offsetof(spdm_finish_rsp_test_buffer_t, total_digest_buffer) + + test_buffer->hash_size * test_buffer->slot_count); + + status = libspdm_send_receive_key_exchange (spdm_context, + SPDM_KEY_EXCHANGE_REQUEST_NO_MEASUREMENT_SUMMARY_HASH, + 0, 0, &session_id, NULL, &req_slot_id_param, NULL); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_FINISH_RSP, + SPDM_RESPONDER_TEST_CASE_FINISH_RSP_SESSION_REQUIRED, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "key_exchange failure"); + return; + } + + session_info = + libspdm_get_session_info_via_session_id(spdm_context, session_id); + LIBSPDM_ASSERT (session_info != NULL); + + libspdm_zero_mem(&spdm_request, sizeof(spdm_request)); + spdm_request.header.spdm_version = test_buffer->version; + spdm_request.header.request_response_code = SPDM_FINISH; + spdm_request.header.param1 = 0; + spdm_request.header.param2 = 0; + + status = libspdm_append_message_f(spdm_context, session_info, true, (uint8_t *)&spdm_request, + sizeof(spdm_finish_request_t)); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_FINISH_RSP, + SPDM_RESPONDER_TEST_CASE_FINISH_RSP_SESSION_REQUIRED, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "append_message_f failure"); + return; + } + ptr = spdm_request.verify_data; + result = libspdm_generate_finish_req_hmac(spdm_context, session_info, ptr); + if (!result) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_FINISH_RSP, + SPDM_RESPONDER_TEST_CASE_FINISH_RSP_SESSION_REQUIRED, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "generate_finish_req_hmac failure"); + return; + } + status = libspdm_append_message_f(spdm_context, session_info, true, ptr, + test_buffer->hash_size); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_FINISH_RSP, + SPDM_RESPONDER_TEST_CASE_FINISH_RSP_SESSION_REQUIRED, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "append_message_f failure"); + return; + } + + spdm_request_size = sizeof(spdm_finish_request_t) + test_buffer->hash_size; + + spdm_response = (void *)message; + spdm_response_size = sizeof(message); + libspdm_zero_mem(message, sizeof(message)); + status = libspdm_send_receive_data(spdm_context, NULL, false, + &spdm_request, spdm_request_size, + spdm_response, &spdm_response_size); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_FINISH_RSP, + SPDM_RESPONDER_TEST_CASE_FINISH_RSP_SESSION_REQUIRED, COMMON_TEST_ID_END, + COMMON_TEST_RESULT_NOT_TESTED, "send/receive failure"); + return; + } + + if (spdm_response_size >= sizeof(spdm_error_response_t)) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_FINISH_RSP, SPDM_RESPONDER_TEST_CASE_FINISH_RSP_SESSION_REQUIRED, + 1, + test_result, "response size - %d", spdm_response_size); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.request_response_code == SPDM_ERROR) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_FINISH_RSP, SPDM_RESPONDER_TEST_CASE_FINISH_RSP_SESSION_REQUIRED, + 2, + test_result, "response code - 0x%02x", spdm_response->header.request_response_code); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.spdm_version == test_buffer->version) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_FINISH_RSP, SPDM_RESPONDER_TEST_CASE_FINISH_RSP_SESSION_REQUIRED, + 3, + test_result, "response version - 0x%02x", spdm_response->header.spdm_version); + if (test_result == COMMON_TEST_RESULT_FAIL) { + return; + } + + if (spdm_response->header.param1 == SPDM_ERROR_CODE_SESSION_REQUIRED) { + test_result = COMMON_TEST_RESULT_PASS; + } else { + test_result = COMMON_TEST_RESULT_FAIL; + } + common_test_record_test_assertion ( + SPDM_RESPONDER_TEST_GROUP_FINISH_RSP, SPDM_RESPONDER_TEST_CASE_FINISH_RSP_SESSION_REQUIRED, + 4, + test_result, "response param1 - 0x%02x", spdm_response->header.param1); +} + +common_test_case_t m_spdm_test_group_finish_rsp[] = { + {SPDM_RESPONDER_TEST_CASE_FINISH_RSP_SUCCESS_11, "spdm_test_case_finish_rsp_success_11", + spdm_test_case_finish_rsp_success_11, spdm_test_case_finish_rsp_setup_version_11}, + {SPDM_RESPONDER_TEST_CASE_FINISH_RSP_SUCCESS_11_HS_CLEAR, + "spdm_test_case_finish_rsp_success_11_hs_clear", + spdm_test_case_finish_rsp_success_11_hs_clear, + spdm_test_case_finish_rsp_setup_version_11_hs_clear}, + {SPDM_RESPONDER_TEST_CASE_FINISH_RSP_VERSION_MISMATCH, + "spdm_test_case_finish_rsp_version_mismatch", spdm_test_case_finish_rsp_version_mismatch, + spdm_test_case_finish_rsp_setup_version_any}, + {SPDM_RESPONDER_TEST_CASE_FINISH_RSP_UNEXPECTED_REQUEST, + "spdm_test_case_finish_rsp_unexpected_request", + spdm_test_case_finish_rsp_unexpected_request, + spdm_test_case_finish_rsp_setup_version_capabilities}, + {SPDM_RESPONDER_TEST_CASE_FINISH_RSP_UNEXPECTED_REQUEST_IN_SESSION, + "spdm_test_case_finish_rsp_unexpected_request_in_session", + spdm_test_case_finish_rsp_unexpected_request_in_session, + spdm_test_case_finish_rsp_setup_version_any}, + {SPDM_RESPONDER_TEST_CASE_FINISH_RSP_INVALID_REQUEST, + "spdm_test_case_finish_rsp_invalid_request", spdm_test_case_finish_rsp_invalid_request, + spdm_test_case_finish_rsp_setup_version_any}, + {SPDM_RESPONDER_TEST_CASE_FINISH_RSP_DECRYPT_ERROR_INVALID_VERIFY_DATA, + "spdm_test_case_finish_rsp_decrypt_error_invalid_verify_data", + spdm_test_case_finish_rsp_decrypt_error_invalid_verify_data, + spdm_test_case_finish_rsp_setup_version_any}, + {SPDM_RESPONDER_TEST_CASE_FINISH_RSP_DECRYPT_ERROR_INVALID_VERIFY_DATA_HS_CLEAR, + "spdm_test_case_finish_rsp_decrypt_error_invalid_verify_data_hs_clear", + spdm_test_case_finish_rsp_decrypt_error_invalid_verify_data_hs_clear, + spdm_test_case_finish_rsp_setup_version_any_hs_clear}, + {SPDM_RESPONDER_TEST_CASE_FINISH_RSP_SUCCESS_12, "spdm_test_case_finish_rsp_success_12", + spdm_test_case_finish_rsp_success_12, spdm_test_case_finish_rsp_setup_version_12}, + {SPDM_RESPONDER_TEST_CASE_FINISH_RSP_SUCCESS_12_HS_CLEAR, + "spdm_test_case_finish_rsp_success_12_hs_clear", + spdm_test_case_finish_rsp_success_12_hs_clear, + spdm_test_case_finish_rsp_setup_version_12_hs_clear}, + {SPDM_RESPONDER_TEST_CASE_FINISH_RSP_SESSION_REQUIRED, + "spdm_test_case_finish_rsp_session_required", spdm_test_case_finish_rsp_session_required, + spdm_test_case_finish_rsp_setup_version_12}, + {COMMON_TEST_ID_END, NULL, NULL}, +}; diff --git a/library/spdm_responder_conformance_test_lib/spdm_responder_test_support.c b/library/spdm_responder_conformance_test_lib/spdm_responder_test_support.c new file mode 100644 index 0000000..909645b --- /dev/null +++ b/library/spdm_responder_conformance_test_lib/spdm_responder_test_support.c @@ -0,0 +1,36 @@ +/** + * Copyright Notice: + * Copyright 2021 DMTF. All rights reserved. + * License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/spdm-emu/blob/main/LICENSE.md + **/ + +#include "spdm_responder_test.h" + +/* + * return one bit in the data according to the mask + * + * @retval 0 if (data & mask) is 0. + * @retval 0xFFFFFFFF if (data & mask) includes more than one bit. + * @return (data & mask) if (data & mask) includes one bit. + */ +uint32_t spdm_test_get_one_bit (uint32_t data, uint32_t mask) +{ + uint32_t final; + uint8_t index; + + data = data & mask; + + final = 0; + for (index = 0; index < 32; index++) { + if ((data & (1 << index)) != 0) { + if (final == 0) { + /* first bit, record it to final */ + final = (1 << index); + } else { + /* more than one bit */ + return 0xFFFFFFFF; + } + } + } + return final; +} diff --git a/spdm_emu/spdm_device_validator_sample/CMakeLists.txt b/spdm_emu/spdm_device_validator_sample/CMakeLists.txt deleted file mode 100644 index cf6cfb2..0000000 --- a/spdm_emu/spdm_device_validator_sample/CMakeLists.txt +++ /dev/null @@ -1,72 +0,0 @@ -cmake_minimum_required(VERSION 2.6) - -INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/spdm_emu/spdm_responder_test_client - ${PROJECT_SOURCE_DIR}/spdm_emu/spdm_emu_common - ${PROJECT_SOURCE_DIR}/include - ${LIBSPDM_DIR}/os_stub/spdm_device_secret_lib_sample - ${LIBSPDM_DIR}/include - ${LIBSPDM_DIR}/include/hal/${ARCH} - ${LIBSPDM_DIR}/os_stub/include - ${SPDM_RESPONDER_VALIDATOR_DIR}/include - ${COMMON_TEST_FRAMEWORK_DIR}/include -) - -SET(src_spdm_device_validator_sample - spdm_device_validator_sample.c - spdm_device_validator_config.c - spdm_device_validator_spdm.c - spdm_device_validator_pci_doe.c - ${PROJECT_SOURCE_DIR}/spdm_emu/spdm_emu_common/spdm_emu.c - ${PROJECT_SOURCE_DIR}/spdm_emu/spdm_emu_common/command.c - ${PROJECT_SOURCE_DIR}/spdm_emu/spdm_emu_common/key.c - ${PROJECT_SOURCE_DIR}/spdm_emu/spdm_emu_common/nv_storage.c - ${PROJECT_SOURCE_DIR}/spdm_emu/spdm_emu_common/pcap.c - ${PROJECT_SOURCE_DIR}/spdm_emu/spdm_emu_common/support.c -) - -SET(spdm_device_validator_sample_LIBRARY - memlib - debuglib_null - spdm_requester_lib - spdm_common_lib - ${CRYPTO_LIB_PATHS} - rnglib - cryptlib_${CRYPTO} - malloclib - spdm_crypt_lib - spdm_secured_message_lib - spdm_transport_mctp_lib - spdm_transport_pcidoe_lib - spdm_transport_none_lib - spdm_device_secret_lib_sample - mctp_requester_lib - pci_doe_requester_lib - platform_lib - spdm_responder_conformance_test_lib - common_test_utility_lib -) - -if((TOOLCHAIN STREQUAL "KLEE") OR (TOOLCHAIN STREQUAL "CBMC")) - ADD_EXECUTABLE(spdm_device_validator_sample - ${src_spdm_responder_test_client} - $ - $ - $ - $ - $ - $ - $ - $ - $ - $ - $ - $ - $ - $ - $ - $ - ) -else() - ADD_EXECUTABLE(spdm_device_validator_sample ${src_spdm_device_validator_sample}) - TARGET_LINK_LIBRARIES(spdm_device_validator_sample ${spdm_device_validator_sample_LIBRARY}) -endif() diff --git a/spdm_emu/spdm_device_validator_sample/spdm_device_validator_config.c b/spdm_emu/spdm_device_validator_sample/spdm_device_validator_config.c deleted file mode 100644 index ece0559..0000000 --- a/spdm_emu/spdm_device_validator_sample/spdm_device_validator_config.c +++ /dev/null @@ -1,155 +0,0 @@ -/** - * Copyright Notice: - * Copyright 2021-2022 DMTF. All rights reserved. - * License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/spdm-emu/blob/main/LICENSE.md - **/ - -#include "spdm_device_validator_sample.h" - -common_test_case_config_t m_spdm_test_group_version_configs[] = { - {SPDM_RESPONDER_TEST_CASE_VERSION_SUCCESS_10, COMMON_TEST_ACTION_RUN}, - {SPDM_RESPONDER_TEST_CASE_VERSION_INVALID_REQUEST, COMMON_TEST_ACTION_RUN}, - {COMMON_TEST_ID_END, COMMON_TEST_ACTION_SKIP}, -}; - -common_test_case_config_t m_spdm_test_group_capabilities_configs[] = { - {SPDM_RESPONDER_TEST_CASE_CAPABILITIES_SUCCESS_10, COMMON_TEST_ACTION_RUN}, - {SPDM_RESPONDER_TEST_CASE_CAPABILITIES_VERSION_MISMATCH, COMMON_TEST_ACTION_RUN}, - {SPDM_RESPONDER_TEST_CASE_CAPABILITIES_SUCCESS_11, COMMON_TEST_ACTION_RUN}, - {SPDM_RESPONDER_TEST_CASE_CAPABILITIES_INVALID_REQUEST, COMMON_TEST_ACTION_RUN}, - {SPDM_RESPONDER_TEST_CASE_CAPABILITIES_SUCCESS_12, COMMON_TEST_ACTION_RUN}, - {SPDM_RESPONDER_TEST_CASE_CAPABILITIES_UNEXPECTED_REQUEST_NON_IDENTICAL, COMMON_TEST_ACTION_RUN}, - {COMMON_TEST_ID_END, COMMON_TEST_ACTION_SKIP}, -}; - -common_test_case_config_t m_spdm_test_group_algorithms_configs[] = { - {SPDM_RESPONDER_TEST_CASE_ALGORITHMS_SUCCESS_10, COMMON_TEST_ACTION_RUN}, - {SPDM_RESPONDER_TEST_CASE_ALGORITHMS_VERSION_MISMATCH, COMMON_TEST_ACTION_RUN}, - {SPDM_RESPONDER_TEST_CASE_ALGORITHMS_UNEXPECTED_REQUEST, COMMON_TEST_ACTION_RUN}, - {SPDM_RESPONDER_TEST_CASE_ALGORITHMS_INVALID_REQUEST, COMMON_TEST_ACTION_RUN}, - {SPDM_RESPONDER_TEST_CASE_ALGORITHMS_SUCCESS_11, COMMON_TEST_ACTION_RUN}, - {SPDM_RESPONDER_TEST_CASE_ALGORITHMS_SUCCESS_12, COMMON_TEST_ACTION_RUN}, - {SPDM_RESPONDER_TEST_CASE_ALGORITHMS_UNEXPECTED_REQUEST_NON_IDENTICAL, COMMON_TEST_ACTION_RUN}, - {COMMON_TEST_ID_END, COMMON_TEST_ACTION_SKIP}, -}; - -common_test_case_config_t m_spdm_test_group_digests_configs[] = { - {SPDM_RESPONDER_TEST_CASE_DIGESTS_SUCCESS_10, COMMON_TEST_ACTION_RUN}, - {SPDM_RESPONDER_TEST_CASE_DIGESTS_VERSION_MISMATCH, COMMON_TEST_ACTION_RUN}, - {SPDM_RESPONDER_TEST_CASE_DIGESTS_UNEXPECTED_REQUEST, COMMON_TEST_ACTION_RUN}, - {COMMON_TEST_ID_END, COMMON_TEST_ACTION_SKIP}, -}; - -common_test_case_config_t m_spdm_test_group_certificate_configs[] = { - {SPDM_RESPONDER_TEST_CASE_CERTIFICATE_SUCCESS_10, COMMON_TEST_ACTION_RUN}, - {SPDM_RESPONDER_TEST_CASE_CERTIFICATE_VERSION_MISMATCH, COMMON_TEST_ACTION_RUN}, - {SPDM_RESPONDER_TEST_CASE_CERTIFICATE_UNEXPECTED_REQUEST, COMMON_TEST_ACTION_RUN}, - {SPDM_RESPONDER_TEST_CASE_CERTIFICATE_INVALID_REQUEST, COMMON_TEST_ACTION_RUN}, - {SPDM_RESPONDER_TEST_CASE_CERTIFICATE_SPDM_X509_CERTIFICATE, COMMON_TEST_ACTION_RUN}, - {COMMON_TEST_ID_END, COMMON_TEST_ACTION_SKIP}, -}; - -common_test_case_config_t m_spdm_test_group_challenge_auth_configs[] = { - {SPDM_RESPONDER_TEST_CASE_CHALLENGE_AUTH_SUCCESS_10_A1B1C1, COMMON_TEST_ACTION_RUN}, - {SPDM_RESPONDER_TEST_CASE_CHALLENGE_AUTH_SUCCESS_10_A1B2C1, COMMON_TEST_ACTION_RUN}, - {SPDM_RESPONDER_TEST_CASE_CHALLENGE_AUTH_SUCCESS_10_A1B3C1, COMMON_TEST_ACTION_RUN}, - {SPDM_RESPONDER_TEST_CASE_CHALLENGE_AUTH_VERSION_MISMATCH, COMMON_TEST_ACTION_RUN}, - {SPDM_RESPONDER_TEST_CASE_CHALLENGE_AUTH_UNEXPECTED_REQUEST, COMMON_TEST_ACTION_RUN}, - {SPDM_RESPONDER_TEST_CASE_CHALLENGE_AUTH_INVALID_REQUEST, COMMON_TEST_ACTION_RUN}, - {SPDM_RESPONDER_TEST_CASE_CHALLENGE_AUTH_SUCCESS_12_A1B1C1, COMMON_TEST_ACTION_RUN}, - {SPDM_RESPONDER_TEST_CASE_CHALLENGE_AUTH_SUCCESS_12_A1B2C1, COMMON_TEST_ACTION_RUN}, - {SPDM_RESPONDER_TEST_CASE_CHALLENGE_AUTH_SUCCESS_12_A1B3C1, COMMON_TEST_ACTION_RUN}, - {SPDM_RESPONDER_TEST_CASE_CHALLENGE_AUTH_SUCCESS_12_A1B4C1, COMMON_TEST_ACTION_RUN}, - {SPDM_RESPONDER_TEST_CASE_CHALLENGE_AUTH_SUCCESS_12_A2B1C1, COMMON_TEST_ACTION_RUN}, - {SPDM_RESPONDER_TEST_CASE_CHALLENGE_AUTH_SUCCESS_12_A2B2C1, COMMON_TEST_ACTION_RUN}, - {SPDM_RESPONDER_TEST_CASE_CHALLENGE_AUTH_SUCCESS_12_A2B3C1, COMMON_TEST_ACTION_RUN}, - {SPDM_RESPONDER_TEST_CASE_CHALLENGE_AUTH_SUCCESS_12_A2B4C1, COMMON_TEST_ACTION_RUN}, - {COMMON_TEST_ID_END, COMMON_TEST_ACTION_SKIP}, -}; - -common_test_case_config_t m_spdm_test_group_measurements_configs[] = { - {SPDM_RESPONDER_TEST_CASE_MEASUREMENTS_SUCCESS_10, COMMON_TEST_ACTION_RUN}, - {SPDM_RESPONDER_TEST_CASE_MEASUREMENTS_VERSION_MISMATCH, COMMON_TEST_ACTION_RUN}, - {SPDM_RESPONDER_TEST_CASE_MEASUREMENTS_UNEXPECTED_REQUEST, COMMON_TEST_ACTION_RUN}, - {SPDM_RESPONDER_TEST_CASE_MEASUREMENTS_INVALID_REQUEST, COMMON_TEST_ACTION_RUN}, - {SPDM_RESPONDER_TEST_CASE_MEASUREMENTS_SPDM_MEASUREMENT_BLOCK, COMMON_TEST_ACTION_RUN}, - {SPDM_RESPONDER_TEST_CASE_MEASUREMENTS_SUCCESS_11, COMMON_TEST_ACTION_RUN}, - {SPDM_RESPONDER_TEST_CASE_MEASUREMENTS_SUCCESS_11_IN_DHE_SESSION, COMMON_TEST_ACTION_RUN}, - {SPDM_RESPONDER_TEST_CASE_MEASUREMENTS_UNEXPECTED_REQUEST_IN_DHE_SESSION_HS, COMMON_TEST_ACTION_RUN}, - {SPDM_RESPONDER_TEST_CASE_MEASUREMENTS_SUCCESS_12, COMMON_TEST_ACTION_RUN}, - {SPDM_RESPONDER_TEST_CASE_MEASUREMENTS_SUCCESS_12_IN_DHE_SESSION, COMMON_TEST_ACTION_RUN}, - {COMMON_TEST_ID_END, COMMON_TEST_ACTION_SKIP}, -}; - -common_test_case_config_t m_spdm_test_group_key_exchange_rsp_configs[] = { - {SPDM_RESPONDER_TEST_CASE_KEY_EXCHANGE_RSP_SUCCESS_11, COMMON_TEST_ACTION_RUN}, - {SPDM_RESPONDER_TEST_CASE_KEY_EXCHANGE_RSP_SUCCESS_11_HS_CLEAR, COMMON_TEST_ACTION_RUN}, - {SPDM_RESPONDER_TEST_CASE_KEY_EXCHANGE_RSP_VERSION_MISMATCH, COMMON_TEST_ACTION_RUN}, - {SPDM_RESPONDER_TEST_CASE_KEY_EXCHANGE_RSP_UNEXPECTED_REQUEST, COMMON_TEST_ACTION_RUN}, - {SPDM_RESPONDER_TEST_CASE_KEY_EXCHANGE_RSP_UNEXPECTED_REQUEST_IN_SESSION, COMMON_TEST_ACTION_RUN}, - {SPDM_RESPONDER_TEST_CASE_KEY_EXCHANGE_RSP_INVALID_REQUEST, COMMON_TEST_ACTION_RUN}, - {SPDM_RESPONDER_TEST_CASE_KEY_EXCHANGE_RSP_SUCCESS_12, COMMON_TEST_ACTION_RUN}, - {SPDM_RESPONDER_TEST_CASE_KEY_EXCHANGE_RSP_SUCCESS_12_HS_CLEAR, COMMON_TEST_ACTION_RUN}, - {COMMON_TEST_ID_END, COMMON_TEST_ACTION_SKIP}, -}; - -common_test_case_config_t m_spdm_test_group_finish_rsp_configs[] = { - {SPDM_RESPONDER_TEST_CASE_FINISH_RSP_SUCCESS_11, COMMON_TEST_ACTION_RUN}, - {SPDM_RESPONDER_TEST_CASE_FINISH_RSP_SUCCESS_11_HS_CLEAR, COMMON_TEST_ACTION_RUN}, - {SPDM_RESPONDER_TEST_CASE_FINISH_RSP_VERSION_MISMATCH, COMMON_TEST_ACTION_RUN}, - {SPDM_RESPONDER_TEST_CASE_FINISH_RSP_UNEXPECTED_REQUEST, COMMON_TEST_ACTION_RUN}, - {SPDM_RESPONDER_TEST_CASE_FINISH_RSP_UNEXPECTED_REQUEST_IN_SESSION, COMMON_TEST_ACTION_RUN}, - {SPDM_RESPONDER_TEST_CASE_FINISH_RSP_INVALID_REQUEST, COMMON_TEST_ACTION_RUN}, - {SPDM_RESPONDER_TEST_CASE_FINISH_RSP_DECRYPT_ERROR_INVALID_VERIFY_DATA, COMMON_TEST_ACTION_RUN}, - {SPDM_RESPONDER_TEST_CASE_FINISH_RSP_DECRYPT_ERROR_INVALID_VERIFY_DATA_HS_CLEAR, COMMON_TEST_ACTION_RUN}, - {SPDM_RESPONDER_TEST_CASE_FINISH_RSP_SUCCESS_12, COMMON_TEST_ACTION_RUN}, - {SPDM_RESPONDER_TEST_CASE_FINISH_RSP_SUCCESS_12_HS_CLEAR, COMMON_TEST_ACTION_RUN}, - {SPDM_RESPONDER_TEST_CASE_FINISH_RSP_SESSION_REQUIRED, COMMON_TEST_ACTION_RUN}, - {COMMON_TEST_ID_END, COMMON_TEST_ACTION_SKIP}, -}; - -common_test_case_config_t m_spdm_test_group_heartbeat_ack_configs[] = { - {SPDM_RESPONDER_TEST_CASE_HEARTBEAT_ACK_SUCCESS_11_IN_DHE_SESSION, COMMON_TEST_ACTION_RUN}, - {SPDM_RESPONDER_TEST_CASE_HEARTBEAT_ACK_VERSION_MISMATCH_IN_DHE_SESSION, COMMON_TEST_ACTION_RUN}, - {SPDM_RESPONDER_TEST_CASE_HEARTBEAT_ACK_UNEXPECTED_REQUEST_IN_DHE_SESSION_HS, COMMON_TEST_ACTION_RUN}, - {SPDM_RESPONDER_TEST_CASE_HEARTBEAT_ACK_SESSION_REQUIRED, COMMON_TEST_ACTION_RUN}, - {COMMON_TEST_ID_END, COMMON_TEST_ACTION_SKIP}, -}; - -common_test_case_config_t m_spdm_test_group_key_update_ack_configs[] = { - {SPDM_RESPONDER_TEST_CASE_KEY_UPDATE_ACK_SUCCESS_11_IN_DHE_SESSION, COMMON_TEST_ACTION_RUN}, - {SPDM_RESPONDER_TEST_CASE_KEY_UPDATE_ACK_VERSION_MISMATCH_IN_DHE_SESSION, COMMON_TEST_ACTION_RUN}, - {SPDM_RESPONDER_TEST_CASE_KEY_UPDATE_ACK_INVALID_REQUEST_IN_DHE_SESSION, COMMON_TEST_ACTION_RUN}, - {SPDM_RESPONDER_TEST_CASE_KEY_UPDATE_ACK_UNEXPECTED_REQUEST_IN_DHE_SESSION_HS, COMMON_TEST_ACTION_RUN}, - {SPDM_RESPONDER_TEST_CASE_KEY_UPDATE_ACK_SESSION_REQUIRED, COMMON_TEST_ACTION_RUN}, - {COMMON_TEST_ID_END, COMMON_TEST_ACTION_SKIP}, -}; - -common_test_case_config_t m_spdm_test_group_end_session_ack_configs[] = { - {SPDM_RESPONDER_TEST_CASE_END_SESSION_ACK_SUCCESS_11_IN_DHE_SESSION, COMMON_TEST_ACTION_RUN}, - {SPDM_RESPONDER_TEST_CASE_END_SESSION_ACK_VERSION_MISMATCH_IN_DHE_SESSION, COMMON_TEST_ACTION_RUN}, - {SPDM_RESPONDER_TEST_CASE_END_SESSION_ACK_UNEXPECTED_REQUEST_IN_DHE_SESSION_HS, COMMON_TEST_ACTION_RUN}, - {SPDM_RESPONDER_TEST_CASE_END_SESSION_ACK_SESSION_REQUIRED, COMMON_TEST_ACTION_RUN}, - {COMMON_TEST_ID_END, COMMON_TEST_ACTION_SKIP}, -}; - -common_test_group_config_t m_spdm_test_group_configs[] = { - {SPDM_RESPONDER_TEST_GROUP_VERSION, COMMON_TEST_ACTION_RUN, m_spdm_test_group_version_configs}, - {SPDM_RESPONDER_TEST_GROUP_CAPABILITIES, COMMON_TEST_ACTION_RUN, m_spdm_test_group_capabilities_configs}, - {SPDM_RESPONDER_TEST_GROUP_ALGORITHMS, COMMON_TEST_ACTION_RUN, m_spdm_test_group_algorithms_configs}, - {SPDM_RESPONDER_TEST_GROUP_DIGESTS, COMMON_TEST_ACTION_RUN, m_spdm_test_group_digests_configs}, - {SPDM_RESPONDER_TEST_GROUP_CERTIFICATE, COMMON_TEST_ACTION_RUN, m_spdm_test_group_certificate_configs}, - {SPDM_RESPONDER_TEST_GROUP_CHALLENGE_AUTH, COMMON_TEST_ACTION_RUN, m_spdm_test_group_challenge_auth_configs}, - {SPDM_RESPONDER_TEST_GROUP_MEASUREMENTS, COMMON_TEST_ACTION_RUN, m_spdm_test_group_measurements_configs}, - {SPDM_RESPONDER_TEST_GROUP_KEY_EXCHANGE_RSP, COMMON_TEST_ACTION_RUN, m_spdm_test_group_key_exchange_rsp_configs}, - {SPDM_RESPONDER_TEST_GROUP_FINISH_RSP, COMMON_TEST_ACTION_RUN, m_spdm_test_group_finish_rsp_configs}, - {SPDM_RESPONDER_TEST_GROUP_HEARTBEAT_ACK, COMMON_TEST_ACTION_RUN, m_spdm_test_group_heartbeat_ack_configs}, - {SPDM_RESPONDER_TEST_GROUP_KEY_UPDATE_ACK, COMMON_TEST_ACTION_RUN, m_spdm_test_group_key_update_ack_configs}, - {SPDM_RESPONDER_TEST_GROUP_END_SESSION_ACK, COMMON_TEST_ACTION_RUN, m_spdm_test_group_end_session_ack_configs}, - {COMMON_TEST_ID_END, COMMON_TEST_ACTION_SKIP, NULL}, -}; - -common_test_suite_config_t m_spdm_responder_validator_config = { - "spdm_responder_validator default config", - m_spdm_test_group_configs -}; diff --git a/spdm_emu/spdm_device_validator_sample/spdm_device_validator_pci_doe.c b/spdm_emu/spdm_device_validator_sample/spdm_device_validator_pci_doe.c deleted file mode 100644 index 7f2a131..0000000 --- a/spdm_emu/spdm_device_validator_sample/spdm_device_validator_pci_doe.c +++ /dev/null @@ -1,33 +0,0 @@ -/** - * Copyright Notice: - * Copyright 2021-2022 DMTF. All rights reserved. - * License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/spdm-emu/blob/main/LICENSE.md - **/ - -#include "spdm_device_validator_sample.h" - -void *m_pci_doe_context; - -libspdm_return_t pci_doe_init_request() -{ - pci_doe_data_object_protocol_t data_object_protocol[6]; - size_t data_object_protocol_size; - libspdm_return_t status; - uint32_t index; - - data_object_protocol_size = sizeof(data_object_protocol); - status = - pci_doe_discovery (m_pci_doe_context, data_object_protocol, &data_object_protocol_size); - if (LIBSPDM_STATUS_IS_ERROR(status)) { - return status; - } - - for (index = 0; index < data_object_protocol_size/sizeof(pci_doe_data_object_protocol_t); - index++) { - printf("DOE(0x%x) VendorId-0x%04x, DataObjectType-0x%02x\n", - index, data_object_protocol[index].vendor_id, - data_object_protocol[index].data_object_type); - } - - return LIBSPDM_STATUS_SUCCESS; -} diff --git a/spdm_emu/spdm_device_validator_sample/spdm_device_validator_sample.c b/spdm_emu/spdm_device_validator_sample/spdm_device_validator_sample.c deleted file mode 100644 index a3e6ef0..0000000 --- a/spdm_emu/spdm_device_validator_sample/spdm_device_validator_sample.c +++ /dev/null @@ -1,161 +0,0 @@ -/** - * Copyright Notice: - * Copyright 2021-2022 DMTF. All rights reserved. - * License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/spdm-emu/blob/main/LICENSE.md - **/ - -#include "spdm_device_validator_sample.h" - -#define IP_ADDRESS "127.0.0.1" - -#ifdef _MSC_VER -struct in_addr m_ip_address = { { { 127, 0, 0, 1 } } }; -#else -struct in_addr m_ip_address = { 0x0100007F }; -#endif -uint8_t m_receive_buffer[LIBSPDM_MAX_MESSAGE_BUFFER_SIZE]; - -extern SOCKET m_socket; - -extern void *m_spdm_context; -extern void *m_scratch_buffer; - -void *spdm_client_init(void); - -libspdm_return_t pci_doe_init_request(void); - -bool communicate_platform_data(SOCKET socket, uint32_t command, - const uint8_t *send_buffer, size_t bytes_to_send, - uint32_t *response, - size_t *bytes_to_receive, - uint8_t *receive_buffer); - - -bool init_client(SOCKET *sock, uint16_t port) -{ - SOCKET client_socket; - struct sockaddr_in server_addr; - int32_t ret_val; - - client_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - if (client_socket == INVALID_SOCKET) { - printf("Create socket Failed - %x\n", -#ifdef _MSC_VER - WSAGetLastError() -#else - errno -#endif - ); - return false; - } - - server_addr.sin_family = AF_INET; - libspdm_copy_mem(&server_addr.sin_addr.s_addr, sizeof(struct in_addr), &m_ip_address, - sizeof(struct in_addr)); - server_addr.sin_port = htons(port); - libspdm_zero_mem(server_addr.sin_zero, sizeof(server_addr.sin_zero)); - - ret_val = connect(client_socket, (struct sockaddr *)&server_addr, - sizeof(server_addr)); - if (ret_val == SOCKET_ERROR) { - printf("Connect Error - %x\n", -#ifdef _MSC_VER - WSAGetLastError() -#else - errno -#endif - ); - closesocket(client_socket); - return false; - } - - printf("connect success!\n"); - - *sock = client_socket; - return true; -} - -bool platform_client_routine(uint16_t port_number) -{ - SOCKET platform_socket; - bool result; - uint32_t response; - size_t response_size; - libspdm_return_t status; - -#ifdef _MSC_VER - WSADATA ws; - if (WSAStartup(MAKEWORD(2, 2), &ws) != 0) { - printf("Init Windows socket Failed - %x\n", WSAGetLastError()); - return false; - } -#endif - result = init_client(&platform_socket, port_number); - if (!result) { -#ifdef _MSC_VER - WSACleanup(); -#endif - return false; - } - - m_socket = platform_socket; - - if (m_use_transport_layer != SOCKET_TRANSPORT_TYPE_NONE) { - response_size = sizeof(m_receive_buffer); - result = communicate_platform_data( - platform_socket, - SOCKET_SPDM_COMMAND_TEST, - (uint8_t *)"Client Hello!", - sizeof("Client Hello!"), &response, - &response_size, m_receive_buffer); - if (!result) { - goto done; - } - } - - if (m_use_transport_layer == SOCKET_TRANSPORT_TYPE_PCI_DOE) { - status = pci_doe_init_request (); - if (LIBSPDM_STATUS_IS_ERROR(status)) { - printf("pci_doe_init_request - %x\n", (uint32_t)status); - goto done; - } - } - - /* Do test - begin*/ - - m_spdm_context = spdm_client_init (); - spdm_responder_conformance_test (m_spdm_context, &m_spdm_responder_validator_config); - if (m_spdm_context != NULL) { - free(m_spdm_context); - } - - /* Do test - end*/ - -done: - response_size = 0; - result = communicate_platform_data( - platform_socket, SOCKET_SPDM_COMMAND_SHUTDOWN - m_exe_mode, - NULL, 0, &response, &response_size, NULL); - - closesocket(platform_socket); - -#ifdef _MSC_VER - WSACleanup(); -#endif - - return true; -} - -int main(int argc, char *argv[]) -{ - printf("%s version 0.1\n", "spdm_device_validator_sample"); - srand((unsigned int)time(NULL)); - - process_args("spdm_device_validator_sample", argc, argv); - - platform_client_routine(DEFAULT_SPDM_PLATFORM_PORT); - printf("Client stopped\n"); - - close_pcap_packet_file(); - return 0; -} diff --git a/spdm_emu/spdm_device_validator_sample/spdm_device_validator_sample.h b/spdm_emu/spdm_device_validator_sample/spdm_device_validator_sample.h deleted file mode 100644 index 862f0f2..0000000 --- a/spdm_emu/spdm_device_validator_sample/spdm_device_validator_sample.h +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Copyright Notice: - * Copyright 2021-2022 DMTF. All rights reserved. - * License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/spdm-emu/blob/main/LICENSE.md - **/ - -#ifndef __SPDM_DEVICE_VALIDATOR_SAMPLE_H__ -#define __SPDM_DEVICE_VALIDATOR_SAMPLE_H__ - -#include "hal/base.h" -#include "hal/library/memlib.h" -#include "library/spdm_requester_lib.h" -#include "library/spdm_transport_none_lib.h" -#include "library/spdm_transport_mctp_lib.h" -#include "library/spdm_transport_pcidoe_lib.h" -#include "library/mctp_requester_lib.h" -#include "library/pci_doe_requester_lib.h" -#include "library/spdm_responder_conformance_test_lib.h" - -#include "os_include.h" -#include "stdio.h" -#include "spdm_emu.h" - -extern common_test_suite_config_t m_spdm_responder_validator_config; - -#endif diff --git a/spdm_emu/spdm_device_validator_sample/spdm_device_validator_spdm.c b/spdm_emu/spdm_device_validator_sample/spdm_device_validator_spdm.c deleted file mode 100644 index db0b0e6..0000000 --- a/spdm_emu/spdm_device_validator_sample/spdm_device_validator_spdm.c +++ /dev/null @@ -1,171 +0,0 @@ -/** - * Copyright Notice: - * Copyright 2021-2022 DMTF. All rights reserved. - * License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/spdm-emu/blob/main/LICENSE.md - **/ - -#include "spdm_device_validator_sample.h" - -void *m_spdm_context; -void *m_scratch_buffer; -SOCKET m_socket; - -bool communicate_platform_data(SOCKET socket, uint32_t command, - const uint8_t *send_buffer, size_t bytes_to_send, - uint32_t *response, - size_t *bytes_to_receive, - uint8_t *receive_buffer) -{ - bool result; - - result = - send_platform_data(socket, command, send_buffer, bytes_to_send); - if (!result) { - printf("send_platform_data Error - %x\n", -#ifdef _MSC_VER - WSAGetLastError() -#else - errno -#endif - ); - return result; - } - - result = receive_platform_data(socket, response, receive_buffer, - bytes_to_receive); - if (!result) { - printf("receive_platform_data Error - %x\n", -#ifdef _MSC_VER - WSAGetLastError() -#else - errno -#endif - ); - return result; - } - return result; -} - -libspdm_return_t spdm_device_send_message(void *spdm_context, - size_t request_size, const void *request, - uint64_t timeout) -{ - bool result; - - result = send_platform_data(m_socket, SOCKET_SPDM_COMMAND_NORMAL, - request, (uint32_t)request_size); - if (!result) { - printf("send_platform_data Error - %x\n", -#ifdef _MSC_VER - WSAGetLastError() -#else - errno -#endif - ); - return LIBSPDM_STATUS_SEND_FAIL; - } - return LIBSPDM_STATUS_SUCCESS; -} - -libspdm_return_t spdm_device_receive_message(void *spdm_context, - size_t *response_size, - void **response, - uint64_t timeout) -{ - bool result; - uint32_t command; - - result = receive_platform_data(m_socket, &command, *response, - response_size); - if (!result) { - printf("receive_platform_data Error - %x\n", -#ifdef _MSC_VER - WSAGetLastError() -#else - errno -#endif - ); - return LIBSPDM_STATUS_RECEIVE_FAIL; - } - return LIBSPDM_STATUS_SUCCESS; -} - -/** - * Send and receive an DOE message - * - * @param request the PCI DOE request message, start from pci_doe_data_object_header_t. - * @param request_size size in bytes of request. - * @param response the PCI DOE response message, start from pci_doe_data_object_header_t. - * @param response_size size in bytes of response. - * - * @retval LIBSPDM_STATUS_SUCCESS The request is sent and response is received. - * @return ERROR The response is not received correctly. - **/ -libspdm_return_t pci_doe_send_receive_data(const void *pci_doe_context, - size_t request_size, const void *request, - size_t *response_size, void *response) -{ - bool result; - uint32_t response_code; - - result = communicate_platform_data( - m_socket, SOCKET_SPDM_COMMAND_NORMAL, - request, request_size, - &response_code, response_size, - response); - if (!result) { - return LIBSPDM_STATUS_RECEIVE_FAIL; - } - return LIBSPDM_STATUS_SUCCESS; -} - -void *spdm_client_init(void) -{ - void *spdm_context; - size_t scratch_buffer_size; - - printf("context_size - 0x%x\n", (uint32_t)libspdm_get_context_size()); - - m_spdm_context = (void *)malloc(libspdm_get_context_size()); - if (m_spdm_context == NULL) { - return NULL; - } - spdm_context = m_spdm_context; - libspdm_init_context(spdm_context); - scratch_buffer_size = libspdm_get_sizeof_required_scratch_buffer(m_spdm_context); - m_scratch_buffer = (void *)malloc(scratch_buffer_size); - if (m_scratch_buffer == NULL) { - free(m_spdm_context); - m_spdm_context = NULL; - return NULL; - } - - libspdm_register_device_io_func(spdm_context, spdm_device_send_message, - spdm_device_receive_message); - if (m_use_transport_layer == SOCKET_TRANSPORT_TYPE_MCTP) { - libspdm_register_transport_layer_func( - spdm_context, libspdm_transport_mctp_encode_message, - libspdm_transport_mctp_decode_message, - libspdm_transport_mctp_get_header_size); - } else if (m_use_transport_layer == SOCKET_TRANSPORT_TYPE_PCI_DOE) { - libspdm_register_transport_layer_func( - spdm_context, libspdm_transport_pci_doe_encode_message, - libspdm_transport_pci_doe_decode_message, - libspdm_transport_pci_doe_get_header_size); - } else if (m_use_transport_layer == SOCKET_TRANSPORT_TYPE_NONE) { - libspdm_register_transport_layer_func( - spdm_context, spdm_transport_none_encode_message, - spdm_transport_none_decode_message, - spdm_transport_none_get_header_size); - } else { - return NULL; - } - libspdm_register_device_buffer_func(spdm_context, - spdm_device_acquire_sender_buffer, - spdm_device_release_sender_buffer, - spdm_device_acquire_receiver_buffer, - spdm_device_release_receiver_buffer); - libspdm_set_scratch_buffer (spdm_context, m_scratch_buffer, scratch_buffer_size); - - return m_spdm_context; -} From 51cddc33ca56b3d0a47d910801a2121f30d81ccb Mon Sep 17 00:00:00 2001 From: Wenxing Hou Date: Tue, 27 Sep 2022 17:22:59 +0800 Subject: [PATCH 2/2] Delete CI check for SPDM-Responder-Validator Fix the issue: #148 Signed-off-by: Wenxing Hou --- .github/workflows/build_CI.yml | 22 ++-------------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/.github/workflows/build_CI.yml b/.github/workflows/build_CI.yml index b4a3d2c..8cb1593 100644 --- a/.github/workflows/build_CI.yml +++ b/.github/workflows/build_CI.yml @@ -80,11 +80,7 @@ jobs: echo "requester.log size is `stat -c%s "$filename"`" exit 1 fi - - name: Responder_validator_Test - run: | - cd build/bin - ./spdm_responder_emu & - ./spdm_device_validator_sample + - name: Test_RECORD_TRANSCRIPT_DATA_consistent # open LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT flag # mkdir build1 folder, gen spdm_requester_emu.exe and spdm_responder_emu.exe @@ -224,11 +220,7 @@ jobs: echo "requester.log size is `stat -c%s "$filename"`" exit 1 fi - - name: Responder_validator_Test - run: | - cd build/bin - ./spdm_responder_emu & - ./spdm_device_validator_sample + - name: Test_RECORD_TRANSCRIPT_DATA_consistent # open LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT flag # mkdir build1 folder, gen spdm_requester_emu.exe and spdm_responder_emu.exe @@ -335,11 +327,6 @@ jobs: cd build/bin ./spdm_responder_emu & ./spdm_requester_emu - - name: Responder_validator_Test - run: | - cd build/bin - ./spdm_responder_emu & - ./spdm_device_validator_sample VS2019_openssl_build: runs-on: windows-latest @@ -367,8 +354,3 @@ jobs: cd build/bin ./spdm_responder_emu & ./spdm_requester_emu - - name: Responder_validator_Test - run: | - cd build/bin - ./spdm_responder_emu & - ./spdm_device_validator_sample \ No newline at end of file