From a37375163973d0db68c5e8fb13f808da7c3b0360 Mon Sep 17 00:00:00 2001 From: Aaron Li Date: Tue, 3 Mar 2026 16:59:14 +0800 Subject: [PATCH] add AODS opaque data parsing Signed-off-by: Aaron Li --- .../industry_standard/spdm_authorization.h | 54 +++++++++++++++ include/internal/libspdm_common_lib.h | 20 ++++++ .../spdm_common_lib/libspdm_com_opaque_data.c | 67 +++++++++++++++++++ unit_test/test_spdm_common/context_data.c | 60 ++++++++++++++++- 4 files changed, 199 insertions(+), 2 deletions(-) create mode 100644 include/industry_standard/spdm_authorization.h diff --git a/include/industry_standard/spdm_authorization.h b/include/industry_standard/spdm_authorization.h new file mode 100644 index 00000000000..e076c28ad80 --- /dev/null +++ b/include/industry_standard/spdm_authorization.h @@ -0,0 +1,54 @@ +/** + * Copyright Notice: + * Copyright 2026 DMTF. All rights reserved. + * License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/libspdm/blob/main/LICENSE.md + **/ + +/** @file + * Definitions of DSP0289 SPDM Authorization Specification + **/ + +#ifndef SPDM_AUTHORIZATION_H +#define SPDM_AUTHORIZATION_H + +#pragma pack(1) + +#define SPDM_SPEC_ID_0289 289 + +#define SPDM_AUTHORIZATION_DATA_STRUCTURE_ID_INVOKE_SEAP 0x0 +#define SPDM_AUTHORIZATION_DATA_STRUCTURE_ID_SEAP_SUCCESS 0x1 +#define SPDM_AUTHORIZATION_DATA_STRUCTURE_ID_AUTH_HELLO 0x2 +#define SPDM_AUTHORIZATION_DATA_STRUCTURE_ID_MAX 0x2 + +typedef struct { + uint8_t id; /* SPDM_REGISTRY_ID_DMTF_DSP */ + uint8_t vendor_len; + uint16_t dmtf_spec_id; /* SPDM_SPEC_ID_0289 */ + uint16_t opaque_element_data_len; + /* uint8_t aods_id; + * uint8_t aods_body[]; */ +} aods_general_opaque_data_table_header_t; + +typedef struct { + uint8_t aods_id; +} aods_general_opaque_element_header_t; + +typedef struct { + uint8_t aods_id; + uint8_t presence_extension; + uint16_t credetial_id; +} aods_general_opaque_element_invoke_seap_t; + +typedef struct { + uint8_t aods_id; + uint8_t presence_extension; +} aods_general_opaque_element_seap_success_t; + +typedef struct { + uint8_t aods_id; + uint8_t presence_extension; +} aods_general_opaque_element_auth_hello_t; + +#pragma pack() + +#endif /* SPDM_AUTHORIZATION_H */ diff --git a/include/internal/libspdm_common_lib.h b/include/internal/libspdm_common_lib.h index cb116703ba1..a6082a4d0d8 100644 --- a/include/internal/libspdm_common_lib.h +++ b/include/internal/libspdm_common_lib.h @@ -11,6 +11,7 @@ #include "library/spdm_secured_message_lib.h" #include "library/spdm_return_status.h" #include "library/spdm_crypt_lib.h" +#include "industry_standard/spdm_authorization.h" #include "hal/library/debuglib.h" #include "hal/library/memlib.h" #include "hal/library/requester/reqasymsignlib.h" @@ -1200,6 +1201,25 @@ bool libspdm_get_sm_data_element_from_opaque_data (libspdm_context_t *spdm_conte uint8_t sm_data_id, const void **get_element_ptr, size_t *get_element_len); +/** + * Get AODS element from multi element opaque data by AODS id + * + * @param[in] spdm_context A pointer to the SPDM context. + * @param[in] data_in_size Size of multi element opaque data. + * @param[in] data_in A pointer to the multi element opaque data. + * @param[in] aods_id ID for the AODS data type. + * @param[out] get_element_ptr Pointer to store found element. + * @param[out] get_element_len Pointer to length of found element. + * + * @retval true Get element successfully + * @retval false Get element failed + **/ +bool libspdm_get_aods_element_from_opaque_data (libspdm_context_t *spdm_context, + size_t data_in_size, const void *data_in, + uint8_t aods_id, + const void **get_element_ptr, size_t *get_element_len); + + /** * Process opaque data version selection. * diff --git a/library/spdm_common_lib/libspdm_com_opaque_data.c b/library/spdm_common_lib/libspdm_com_opaque_data.c index 8e56485ba7e..346b9c86b1b 100644 --- a/library/spdm_common_lib/libspdm_com_opaque_data.c +++ b/library/spdm_common_lib/libspdm_com_opaque_data.c @@ -254,6 +254,73 @@ bool libspdm_get_sm_data_element_from_opaque_data (libspdm_context_t *spdm_conte return false; } +bool libspdm_get_aods_element_from_opaque_data (libspdm_context_t *spdm_context, + size_t data_in_size, const void *data_in, + uint8_t aods_id, + const void **get_element_ptr, size_t *get_element_len) +{ + const opaque_element_table_header_t *opaque_element_table_header; + size_t opaque_element_len; + const aods_general_opaque_data_table_header_t *aods_element_table_header; + const aods_general_opaque_element_header_t *aods_element_header; + bool result; + uint8_t element_index; + uint8_t element_num; + uint8_t total_matched_element_cnt; + + /*check parameter in*/ + if ((data_in_size == 0) || (data_in == NULL)) { + return false; + } + + if (libspdm_get_connection_version (spdm_context) < SPDM_MESSAGE_VERSION_14) { + return false; + } + + if (aods_id > SPDM_AUTHORIZATION_DATA_STRUCTURE_ID_MAX) { + return false; + } + + /*get the total matched element count*/ + result = libspdm_get_element_from_opaque_data_with_element_id( + spdm_context, data_in_size, data_in, + SPDM_REGISTRY_ID_DMTF_DSP, 0, &total_matched_element_cnt, + (const void **) &opaque_element_table_header, &opaque_element_len); + if (!result) { + return false; + } + element_num = total_matched_element_cnt; + for (element_index = 0; element_index < element_num; element_index++) { + /*get element by element id*/ + result = libspdm_get_element_from_opaque_data_with_element_id( + spdm_context, data_in_size, data_in, + SPDM_REGISTRY_ID_DMTF_DSP, element_index, &total_matched_element_cnt, + (const void **) &opaque_element_table_header, &opaque_element_len); + if (!result) { + return false; + } + + aods_element_table_header = (const void *)opaque_element_table_header; + if (aods_element_table_header->vendor_len == 2 && + aods_element_table_header->dmtf_spec_id == SPDM_SPEC_ID_0289) { + aods_element_header = (const void *)(aods_element_table_header + 1); + if ((const uint8_t *)aods_element_header + + sizeof(aods_general_opaque_element_header_t) > + (const uint8_t *)data_in + data_in_size) { + return false; + } + + if (aods_element_header->aods_id == aods_id) { + *get_element_ptr = opaque_element_table_header; + *get_element_len = opaque_element_len; + return true; + } + } + } + + return false; +} + bool libspdm_process_general_opaque_data_check(libspdm_context_t *spdm_context, size_t data_in_size, const void *data_in) diff --git a/unit_test/test_spdm_common/context_data.c b/unit_test/test_spdm_common/context_data.c index 5a86f03f289..f4c84c86ae9 100644 --- a/unit_test/test_spdm_common/context_data.c +++ b/unit_test/test_spdm_common/context_data.c @@ -1612,6 +1612,16 @@ typedef struct { 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]; + spdm_svh_dmtf_dsp_header_t dmtf_dsp_aods_invoke_seap_header; + uint16_t dmtf_dsp_aods_invoke_seap_opaque_len; + aods_general_opaque_element_invoke_seap_t dmtf_dsp_aods_invoke_seap_opaque; + uint8_t dmtf_dsp_aods_invoke_seap_opaque_align[2]; + spdm_svh_dmtf_dsp_header_t dmtf_dsp_aods_seap_success_header; + uint16_t dmtf_dsp_aods_seap_success_opaque_len; + aods_general_opaque_element_seap_success_t dmtf_dsp_aods_seap_success_opaque; + spdm_svh_dmtf_dsp_header_t dmtf_dsp_aods_auth_hello_header; + uint16_t dmtf_dsp_aods_auth_hello_opaque_len; + aods_general_opaque_element_auth_hello_t dmtf_dsp_aods_auth_hello_opaque; } test_spdm12_opaque_data_table_t; #pragma pack() @@ -1631,13 +1641,13 @@ static void libspdm_test_process_opaque_data_case22(void **state) spdm_context = spdm_test_context->spdm_context; spdm_test_context->case_id = 0x16; - spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 << + spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_14 << SPDM_VERSION_NUMBER_SHIFT_BIT; spdm_context->local_context.secured_message_version.secured_message_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.opaque_header.total_elements = SPDM_REGISTRY_ID_MAX + 5; 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); @@ -1692,6 +1702,34 @@ static void libspdm_test_process_opaque_data_case22(void **state) 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.dmtf_dsp_aods_invoke_seap_header.header.id = SPDM_REGISTRY_ID_DMTF_DSP; + opaque_data.dmtf_dsp_aods_invoke_seap_header.header.vendor_id_len = + sizeof(opaque_data.dmtf_dsp_aods_invoke_seap_header.vendor_id); + opaque_data.dmtf_dsp_aods_invoke_seap_header.vendor_id = SPDM_SPEC_ID_0289; + opaque_data.dmtf_dsp_aods_invoke_seap_opaque_len = + sizeof(opaque_data.dmtf_dsp_aods_invoke_seap_opaque); + opaque_data.dmtf_dsp_aods_invoke_seap_opaque.aods_id = + SPDM_AUTHORIZATION_DATA_STRUCTURE_ID_INVOKE_SEAP; + opaque_data.dmtf_dsp_aods_invoke_seap_opaque.presence_extension = 0; + opaque_data.dmtf_dsp_aods_invoke_seap_opaque.credetial_id = 1; + opaque_data.dmtf_dsp_aods_seap_success_header.header.id = SPDM_REGISTRY_ID_DMTF_DSP; + opaque_data.dmtf_dsp_aods_seap_success_header.header.vendor_id_len = + sizeof(opaque_data.dmtf_dsp_aods_seap_success_header.vendor_id); + opaque_data.dmtf_dsp_aods_seap_success_header.vendor_id = SPDM_SPEC_ID_0289; + opaque_data.dmtf_dsp_aods_seap_success_opaque_len = + sizeof(opaque_data.dmtf_dsp_aods_seap_success_opaque); + opaque_data.dmtf_dsp_aods_seap_success_opaque.aods_id = + SPDM_AUTHORIZATION_DATA_STRUCTURE_ID_SEAP_SUCCESS; + opaque_data.dmtf_dsp_aods_seap_success_opaque.presence_extension = 0; + opaque_data.dmtf_dsp_aods_auth_hello_header.header.id = SPDM_REGISTRY_ID_DMTF_DSP; + opaque_data.dmtf_dsp_aods_auth_hello_header.header.vendor_id_len = + sizeof(opaque_data.dmtf_dsp_aods_auth_hello_header.vendor_id); + opaque_data.dmtf_dsp_aods_auth_hello_header.vendor_id = SPDM_SPEC_ID_0289; + opaque_data.dmtf_dsp_aods_auth_hello_opaque_len = + sizeof(opaque_data.dmtf_dsp_aods_auth_hello_opaque); + opaque_data.dmtf_dsp_aods_auth_hello_opaque.aods_id = + SPDM_AUTHORIZATION_DATA_STRUCTURE_ID_AUTH_HELLO; + opaque_data.dmtf_dsp_aods_auth_hello_opaque.presence_extension = 0; opaque_data_ptr = (uint8_t *)&opaque_data; opaque_data_size = sizeof(opaque_data); @@ -1707,6 +1745,24 @@ static void libspdm_test_process_opaque_data_case22(void **state) &get_element_ptr, &get_element_len ); assert_int_equal (status, true); + status = libspdm_get_aods_element_from_opaque_data(spdm_context, + opaque_data_size, opaque_data_ptr, + SPDM_AUTHORIZATION_DATA_STRUCTURE_ID_INVOKE_SEAP, + &get_element_ptr, &get_element_len + ); + assert_int_equal (status, true); + status = libspdm_get_aods_element_from_opaque_data(spdm_context, + opaque_data_size, opaque_data_ptr, + SPDM_AUTHORIZATION_DATA_STRUCTURE_ID_SEAP_SUCCESS, + &get_element_ptr, &get_element_len + ); + assert_int_equal (status, true); + status = libspdm_get_aods_element_from_opaque_data(spdm_context, + opaque_data_size, opaque_data_ptr, + SPDM_AUTHORIZATION_DATA_STRUCTURE_ID_AUTH_HELLO, + &get_element_ptr, &get_element_len + ); + assert_int_equal (status, true); } static libspdm_test_context_t m_libspdm_common_context_data_test_context = {