From 444b5fb244dfd4379e41b2065bb70848478bc697 Mon Sep 17 00:00:00 2001 From: Jiewen Yao Date: Thu, 19 Dec 2024 00:18:56 +0800 Subject: [PATCH 1/3] add SVH header to spdm header Signed-off-by: Jiewen Yao --- include/industry_standard/spdm.h | 59 ++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/include/industry_standard/spdm.h b/include/industry_standard/spdm.h index 15964cbfa95..302a63bc279 100644 --- a/include/industry_standard/spdm.h +++ b/include/industry_standard/spdm.h @@ -478,6 +478,65 @@ typedef struct { #define SPDM_REGISTRY_ID_IANA_CBOR 0xa #define SPDM_REGISTRY_ID_MAX 0xa +typedef struct { + uint8_t id; + uint8_t vendor_id_len; + /* uint8_t vendor_id[vendor_id_len]; */ +} spdm_svh_header_t; + +typedef struct { + spdm_svh_header_t header; /* SPDM_REGISTRY_ID_DMTF */ +} spdm_svh_dmtf_header_t; + +typedef struct { + spdm_svh_header_t header; /* SPDM_REGISTRY_ID_TCG */ + uint16_t vendor_id; +} spdm_svh_tcg_header_t; + +typedef struct { + spdm_svh_header_t header; /* SPDM_REGISTRY_ID_USB */ + uint16_t vendor_id; +} spdm_svh_usb_header_t; + +typedef struct { + spdm_svh_header_t header; /* SPDM_REGISTRY_ID_PCISIG */ + uint16_t vendor_id; +} spdm_svh_pcisig_header_t; + +typedef struct { + spdm_svh_header_t header; /* SPDM_REGISTRY_ID_IANA */ + uint32_t vendor_id; +} spdm_svh_iana_header_t; + +typedef struct { + spdm_svh_header_t header; /* SPDM_REGISTRY_ID_HDBASET */ + uint32_t vendor_id; +} spdm_svh_hdbaset_header_t; + +typedef struct { + spdm_svh_header_t header; /* SPDM_REGISTRY_ID_MIPI */ + uint16_t vendor_id; +} spdm_svh_mipi_header_t; + +typedef struct { + spdm_svh_header_t header; /* SPDM_REGISTRY_ID_CXL */ + uint16_t vendor_id; +} spdm_svh_cxl_header_t; + +typedef struct { + spdm_svh_header_t header; /* SPDM_REGISTRY_ID_JEDEC */ + uint16_t vendor_id; +} spdm_svh_jedec_header_t; + +typedef struct { + spdm_svh_header_t header; /* SPDM_REGISTRY_ID_VESA */ +} spdm_svh_vesa_header_t; + +typedef struct { + spdm_svh_header_t header; /* SPDM_REGISTRY_ID_IANA_CBOR */ + /* uint8_t vendor_id[vendor_id_len]; */ +} spdm_svh_iana_cbor_header_t; + /* SPDM GET_DIGESTS request */ typedef struct { spdm_message_header_t header; From 75ba2c8c3e23ad82b9f81ce4a33dee719b67fcf5 Mon Sep 17 00:00:00 2001 From: Jiewen Yao Date: Thu, 19 Dec 2024 00:21:36 +0800 Subject: [PATCH 2/3] Fix libspdm_get_element_from_opaque_data() to allow non-zero vendor_id Signed-off-by: Jiewen Yao --- .../spdm_common_lib/libspdm_com_opaque_data.c | 60 ++++++++++++------- 1 file changed, 39 insertions(+), 21 deletions(-) diff --git a/library/spdm_common_lib/libspdm_com_opaque_data.c b/library/spdm_common_lib/libspdm_com_opaque_data.c index 8bc19c4e3cf..0375293cc5c 100644 --- a/library/spdm_common_lib/libspdm_com_opaque_data.c +++ b/library/spdm_common_lib/libspdm_com_opaque_data.c @@ -119,10 +119,13 @@ bool libspdm_get_element_from_opaque_data(libspdm_context_t *spdm_context, *general_opaque_data_table_header; const spdm_general_opaque_data_table_header_t *spdm_general_opaque_data_table_header; - const secured_message_opaque_element_table_header_t + const opaque_element_table_header_t *opaque_element_table_header; + uint16_t opaque_element_data_len; + const secured_message_opaque_element_table_header_t + *secured_message_element_table_header; const secured_message_opaque_element_header_t - * secured_message_element_header; + *secured_message_element_header; bool result; uint8_t element_num; @@ -177,19 +180,30 @@ bool libspdm_get_element_from_opaque_data(libspdm_context_t *spdm_context, for (element_index = 0; element_index < element_num; element_index++) { /*ensure the opaque_element_table_header is valid*/ - if (total_element_len + sizeof(secured_message_opaque_element_table_header_t) > + if (total_element_len + sizeof(opaque_element_table_header_t) > data_element_size) { return false; } /*check element header id*/ - if ((opaque_element_table_header->id > SPDM_REGISTRY_ID_MAX) || - (opaque_element_table_header->vendor_len != 0)) { + if ((opaque_element_table_header->id > SPDM_REGISTRY_ID_MAX)) { + return false; + } + + if (total_element_len + sizeof(opaque_element_table_header_t) + + opaque_element_table_header->vendor_len + 2 > + data_element_size) { return false; } - current_element_len = sizeof(secured_message_opaque_element_table_header_t) + - opaque_element_table_header->opaque_element_data_len; + opaque_element_data_len = libspdm_read_uint16( + (const uint8_t *)opaque_element_table_header + + sizeof(opaque_element_table_header_t) + + opaque_element_table_header->vendor_len); + + current_element_len = sizeof(opaque_element_table_header_t) + + opaque_element_table_header->vendor_len + + 2 + opaque_element_data_len; /* Add Padding*/ current_element_len = (current_element_len + 3) & ~3; @@ -200,25 +214,29 @@ bool libspdm_get_element_from_opaque_data(libspdm_context_t *spdm_context, } if (opaque_element_table_header->id == element_id) { - secured_message_element_header = (const void *)(opaque_element_table_header + 1); - if ((const uint8_t *)secured_message_element_header + - sizeof(secured_message_opaque_element_header_t) > - (const uint8_t *)data_in + data_in_size) { - return false; - } + secured_message_element_table_header = (const void *)opaque_element_table_header; + if (secured_message_element_table_header->vendor_len == 0) { + secured_message_element_header = + (const void *)(secured_message_element_table_header + 1); + if ((const uint8_t *)secured_message_element_header + + sizeof(secured_message_opaque_element_header_t) > + (const uint8_t *)data_in + data_in_size) { + return false; + } - if ((secured_message_element_header->sm_data_id == sm_data_id) && - (secured_message_element_header->sm_data_version == - SECURED_MESSAGE_OPAQUE_ELEMENT_SMDATA_DATA_VERSION)) { - /*get element by element id*/ - *get_element_ptr = opaque_element_table_header; - *get_element_len = current_element_len; - result = true; + if ((secured_message_element_header->sm_data_id == sm_data_id) && + (secured_message_element_header->sm_data_version == + SECURED_MESSAGE_OPAQUE_ELEMENT_SMDATA_DATA_VERSION)) { + /*get element by element id*/ + *get_element_ptr = opaque_element_table_header; + *get_element_len = current_element_len; + result = true; + } } } /*move to next element*/ - opaque_element_table_header = (const secured_message_opaque_element_table_header_t *) + opaque_element_table_header = (const opaque_element_table_header_t *) ((const uint8_t *)opaque_element_table_header + current_element_len); } From ced48e0afa94a5df6679529d9231b4d4ad1871fd Mon Sep 17 00:00:00 2001 From: Jiewen Yao Date: Thu, 19 Dec 2024 00:23:03 +0800 Subject: [PATCH 3/3] Add unit test to cover non-zero vendor_id for opaque data. Signed-off-by: Jiewen Yao --- unit_test/test_spdm_common/context_data.c | 153 ++++++++++++++++++++++ 1 file changed, 153 insertions(+) diff --git a/unit_test/test_spdm_common/context_data.c b/unit_test/test_spdm_common/context_data.c index 377db93f2ed..efc44d5dd90 100644 --- a/unit_test/test_spdm_common/context_data.c +++ b/unit_test/test_spdm_common/context_data.c @@ -1542,6 +1542,156 @@ static void libspdm_test_max_session_count_case21(void **state) } } +#pragma pack(1) + +typedef struct { + spdm_general_opaque_data_table_header_t opaque_header; + spdm_svh_iana_cbor_header_t cbor_header; + uint8_t cbor_vendor_id[10]; + uint16_t cbor_opaque_len; + uint8_t cbor_opaque[10]; + /* uint8_t cbor_align[]; */ + spdm_svh_vesa_header_t vesa_header; + uint16_t vesa_opaque_len; + uint8_t vesa_opaque[9]; + uint8_t vesa_align[3]; + spdm_svh_jedec_header_t jedec_header; + uint16_t jedec_opaque_len; + uint8_t jedec_opaque[8]; + uint8_t jedec_align[2]; + spdm_svh_cxl_header_t cxl_header; + uint16_t cxl_opaque_len; + uint8_t cxl_opaque[7]; + uint8_t cxl_align[3]; + spdm_svh_mipi_header_t mipi_header; + uint16_t mipi_opaque_len; + uint8_t mipi_opaque[6]; + /* uint8_t mipi_align[0]; */ + spdm_svh_hdbaset_header_t hdbaset_header; + uint16_t hdbaset_opaque_len; + uint8_t hdbaset_opaque[5]; + uint8_t hdbaset_align[3]; + spdm_svh_iana_header_t iana_header; + uint16_t iana_opaque_len; + uint8_t iana_opaque[4]; + /* uint8_t iana_align[0]; */ + spdm_svh_pcisig_header_t pcisig_header; + uint16_t pcisig_opaque_len; + uint8_t pcisig_opaque[3]; + uint8_t pcisig_align[3]; + spdm_svh_usb_header_t usb_header; + uint16_t usb_opaque_len; + uint8_t usb_opaque[2]; + /* uint8_t usb_align[0]; */ + spdm_svh_tcg_header_t tcg_header; + uint16_t tcg_opaque_len; + uint8_t tcg_opaque[1]; + uint8_t tcg_align[1]; + spdm_svh_dmtf_header_t dmtf_sm_ver_sel_header; + uint16_t dmtf_sm_ver_sel_opaque_len; + secured_message_opaque_element_version_selection_t dmtf_sm_ver_sel_opaque; + /* uint8_t dmtf_sm_ver_sel_align[0]; */ + spdm_svh_dmtf_header_t dmtf_sm_sup_ver_header; + uint16_t dmtf_sm_sup_ver_opaque_len; + secured_message_opaque_element_supported_version_t dmtf_sm_sup_ver_opaque; + spdm_version_number_t dmtf_sm_sup_ver_versions_list[3]; + uint8_t dmtf_sm_sup_ver_align[3]; +} test_spdm12_opaque_data_table_t; + +#pragma pack() + +static void libspdm_test_process_opaque_data_case22(void **state) +{ + libspdm_return_t status; + libspdm_test_context_t *spdm_test_context; + libspdm_context_t *spdm_context; + const void *get_element_ptr; + size_t get_element_len; + size_t opaque_data_size; + uint8_t *opaque_data_ptr; + test_spdm12_opaque_data_table_t opaque_data; + + spdm_test_context = *state; + spdm_context = spdm_test_context->spdm_context; + spdm_test_context->case_id = 0x16; + + spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 << + SPDM_VERSION_NUMBER_SHIFT_BIT; + + spdm_context->local_context.secured_message_version.spdm_version_count = 1; + + libspdm_set_mem ((uint8_t *)&opaque_data, sizeof(opaque_data), 0xFF); + opaque_data.opaque_header.total_elements = SPDM_REGISTRY_ID_MAX + 2; + opaque_data.cbor_header.header.id = SPDM_REGISTRY_ID_IANA_CBOR; + opaque_data.cbor_header.header.vendor_id_len = sizeof(opaque_data.cbor_vendor_id); + opaque_data.cbor_opaque_len = sizeof(opaque_data.cbor_opaque); + opaque_data.vesa_header.header.id = SPDM_REGISTRY_ID_VESA; + opaque_data.vesa_header.header.vendor_id_len = 0; + opaque_data.vesa_opaque_len = sizeof(opaque_data.vesa_opaque); + opaque_data.jedec_header.header.id = SPDM_REGISTRY_ID_JEDEC; + opaque_data.jedec_header.header.vendor_id_len = sizeof(opaque_data.jedec_header.vendor_id); + opaque_data.jedec_opaque_len = sizeof(opaque_data.jedec_opaque); + opaque_data.cxl_header.header.id = SPDM_REGISTRY_ID_CXL; + opaque_data.cxl_header.header.vendor_id_len = sizeof(opaque_data.cxl_header.vendor_id); + opaque_data.cxl_opaque_len = sizeof(opaque_data.cxl_opaque); + opaque_data.mipi_header.header.id = SPDM_REGISTRY_ID_MIPI; + opaque_data.mipi_header.header.vendor_id_len = sizeof(opaque_data.mipi_header.vendor_id); + opaque_data.mipi_opaque_len = sizeof(opaque_data.mipi_opaque); + opaque_data.hdbaset_header.header.id = SPDM_REGISTRY_ID_HDBASET; + opaque_data.hdbaset_header.header.vendor_id_len = sizeof(opaque_data.hdbaset_header.vendor_id); + opaque_data.hdbaset_opaque_len = sizeof(opaque_data.hdbaset_opaque); + opaque_data.iana_header.header.id = SPDM_REGISTRY_ID_IANA; + opaque_data.iana_header.header.vendor_id_len = sizeof(opaque_data.iana_header.vendor_id); + opaque_data.iana_opaque_len = sizeof(opaque_data.iana_opaque); + opaque_data.pcisig_header.header.id = SPDM_REGISTRY_ID_PCISIG; + opaque_data.pcisig_header.header.vendor_id_len = sizeof(opaque_data.pcisig_header.vendor_id); + opaque_data.pcisig_opaque_len = sizeof(opaque_data.pcisig_opaque); + opaque_data.usb_header.header.id = SPDM_REGISTRY_ID_USB; + opaque_data.usb_header.header.vendor_id_len = sizeof(opaque_data.usb_header.vendor_id); + opaque_data.usb_opaque_len = sizeof(opaque_data.usb_opaque); + opaque_data.tcg_header.header.id = SPDM_REGISTRY_ID_TCG; + opaque_data.tcg_header.header.vendor_id_len = sizeof(opaque_data.tcg_header.vendor_id); + opaque_data.tcg_opaque_len = sizeof(opaque_data.tcg_opaque); + opaque_data.dmtf_sm_ver_sel_header.header.id = SPDM_REGISTRY_ID_DMTF; + opaque_data.dmtf_sm_ver_sel_header.header.vendor_id_len = 0; + opaque_data.dmtf_sm_ver_sel_opaque_len = sizeof(opaque_data.dmtf_sm_ver_sel_opaque); + opaque_data.dmtf_sm_ver_sel_opaque.sm_data_version = + SECURED_MESSAGE_OPAQUE_ELEMENT_SMDATA_DATA_VERSION; + opaque_data.dmtf_sm_ver_sel_opaque.sm_data_id = + SECURED_MESSAGE_OPAQUE_ELEMENT_SMDATA_ID_VERSION_SELECTION; + opaque_data.dmtf_sm_ver_sel_opaque.selected_version = SECURED_SPDM_VERSION_12 << 8; + opaque_data.dmtf_sm_sup_ver_header.header.id = SPDM_REGISTRY_ID_DMTF; + opaque_data.dmtf_sm_sup_ver_header.header.vendor_id_len = 0; + opaque_data.dmtf_sm_sup_ver_opaque_len = sizeof(opaque_data.dmtf_sm_sup_ver_opaque) + + sizeof(opaque_data.dmtf_sm_sup_ver_versions_list); + opaque_data.dmtf_sm_sup_ver_opaque.sm_data_version = + SECURED_MESSAGE_OPAQUE_ELEMENT_SMDATA_DATA_VERSION; + opaque_data.dmtf_sm_sup_ver_opaque.sm_data_id = + SECURED_MESSAGE_OPAQUE_ELEMENT_SMDATA_ID_SUPPORTED_VERSION; + opaque_data.dmtf_sm_sup_ver_opaque.version_count = + LIBSPDM_ARRAY_SIZE(opaque_data.dmtf_sm_sup_ver_versions_list); + opaque_data.dmtf_sm_sup_ver_versions_list[0] = SECURED_SPDM_VERSION_10 << 8; + opaque_data.dmtf_sm_sup_ver_versions_list[1] = SECURED_SPDM_VERSION_11 << 8; + opaque_data.dmtf_sm_sup_ver_versions_list[2] = SECURED_SPDM_VERSION_12 << 8; + + opaque_data_ptr = (uint8_t *)&opaque_data; + opaque_data_size = sizeof(opaque_data); + status = libspdm_get_element_from_opaque_data(spdm_context, + opaque_data_size, opaque_data_ptr, + SPDM_REGISTRY_ID_DMTF, + SECURED_MESSAGE_OPAQUE_ELEMENT_SMDATA_ID_VERSION_SELECTION, + &get_element_ptr, &get_element_len + ); + assert_int_equal (status, true); + status = libspdm_get_element_from_opaque_data(spdm_context, + opaque_data_size, opaque_data_ptr, + SPDM_REGISTRY_ID_DMTF, + SECURED_MESSAGE_OPAQUE_ELEMENT_SMDATA_ID_SUPPORTED_VERSION, + &get_element_ptr, &get_element_len + ); + assert_int_equal (status, true); +} + static libspdm_test_context_t m_libspdm_common_context_data_test_context = { LIBSPDM_TEST_CONTEXT_VERSION, true, @@ -1590,6 +1740,9 @@ int libspdm_common_context_data_test_main(void) /* Test the max DHE/PSK session count */ cmocka_unit_test(libspdm_test_max_session_count_case21), + + /* Successful response V1.2 for multi element */ + cmocka_unit_test(libspdm_test_process_opaque_data_case22), }; libspdm_setup_test_context(&m_libspdm_common_context_data_test_context);