Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow non-zero vendor_id for libspdm_get_element_from_opaque_data() #2935

Merged
merged 3 commits into from
Dec 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 59 additions & 0 deletions include/industry_standard/spdm.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
60 changes: 39 additions & 21 deletions library/spdm_common_lib/libspdm_com_opaque_data.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;

Expand All @@ -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);
}
Expand Down
153 changes: 153 additions & 0 deletions unit_test/test_spdm_common/context_data.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does libspdm_get_element_from_opaque_data only get the first element_id? What if opaque data contains multiple opaque elements with the same element_id?

Copy link
Member Author

@jyao1 jyao1 Dec 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

libspdm_get_element_from_opaque_data() will get (element_id, and sm_data_id) pair. Although the name is generic, but it has assumption that element_id is DMTF, because sm_data_id is only under DMTF.

To me, this function is mess, I would not define in this way, if I can redo the work.

I plan to define two functions:

  • libspdm_get_element_from_opaque_data_with_element_id (element_id, element_index) - that is to get element with ID and index to support multiple elements.
  • libspdm_get_sm_data_element_from_opaque_data (sm_data_id) - that is to get SM_DATA only, with assumption that element_id is DMTF.

The first function can be used for SPDM 1.4 with DMTF-DSP, and support DSP0289 Authorization AODS.

  • libspdm_get_aods_element_from_opaque_data (aods_id) - that is to get AODS with assumption that element_id is DMTF-DSP.

I will file a new issue for the new function.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will file a new issue for the new function.

That will be in a separate pull request?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, separate PR definitely.
Most likely, I will submit after I finish DSP0289 Auth POC. Then we can know how to handle different element ID.

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,
Expand Down Expand Up @@ -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);
Expand Down
Loading