Skip to content

Commit

Permalink
libspdm_doe_pcidoe: Add DOE discovery decode helpers
Browse files Browse the repository at this point in the history
Add helper functions for decoding the DOE discovery protocol. All DOE
requesters and responders must implement this protocol.

There isn't a straight forwrad way to integrate this into libspdm so
let's instead implement helper functions that can be used directly by
the custom send and receive functions.

Signed-off-by: Alistair Francis <[email protected]>
  • Loading branch information
alistair23 authored and jyao1 committed Dec 21, 2023
1 parent 4b47cae commit 53dc703
Show file tree
Hide file tree
Showing 3 changed files with 203 additions and 0 deletions.
45 changes: 45 additions & 0 deletions include/library/spdm_transport_pcidoe_lib.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,51 @@ libspdm_return_t libspdm_transport_pci_doe_decode_message(
size_t transport_message_size, void *transport_message,
size_t *message_size, void **message);

/**
* Decode a DOE discovery request message.
*
* @param transport_message_size Size in bytes of the transport message data buffer.
* @param transport_message A pointer to a source buffer to store the transport message.
* @param index A pointer to a destination to store the index.
*
* @retval LIBSPDM_STATUS_SUCCESS The message is encoded successfully.
* @retval LIBSPDM_STATUS_INVALID_PARAMETER The message is NULL or the message_size is zero.
**/
libspdm_return_t libspdm_pci_doe_decode_discovery_request(size_t transport_message_size,
const void *transport_message,
uint8_t *index);
/**
* Decode a DOE discovery response message.
*
* @param transport_message_size Size in bytes of the transport message data buffer.
* @param transport_message A pointer to a source buffer to store the transport message.
* @param vendor_id A pointer to a destination to store the vendor_id.
* @param protocol A pointer to a destination to store the protocol.
* @param next_index A pointer to a destination to store the next_index.
*
* @retval LIBSPDM_STATUS_SUCCESS The message is encoded successfully.
* @retval LIBSPDM_STATUS_INVALID_PARAMETER The message is NULL or the message_size is zero.
**/
libspdm_return_t libspdm_pci_doe_decode_discovery_response(size_t transport_message_size,
void *transport_message,
uint16_t *vendor_id,
uint8_t *protocol,
uint8_t *next_index);

/**
* Return the maximum transport layer message header size.
* Transport Message Header Size + sizeof(spdm_secured_message_cipher_header_t))
*
* For MCTP, Transport Message Header Size = sizeof(mctp_message_header_t)
* For PCI_DOE, Transport Message Header Size = sizeof(pci_doe_data_object_header_t)
*
* @param spdm_context A pointer to the SPDM context.
*
* @return size of maximum transport layer message header size
**/
uint32_t libspdm_transport_pci_doe_get_header_size(
void *spdm_context);

/**
* Get sequence number in an SPDM secure message.
*
Expand Down
129 changes: 129 additions & 0 deletions library/spdm_transport_pcidoe_lib/libspdm_doe_pcidoe.c
Original file line number Diff line number Diff line change
Expand Up @@ -204,3 +204,132 @@ libspdm_return_t libspdm_pci_doe_decode_message(uint32_t **session_id,
*message = (uint8_t *)transport_message + sizeof(pci_doe_data_object_header_t);
return LIBSPDM_STATUS_SUCCESS;
}

libspdm_return_t libspdm_pci_doe_decode_discovery_request(size_t transport_message_size,
const void *transport_message,
uint8_t *index)
{
const pci_doe_data_object_header_t *pci_doe_header;
uint32_t length;
const uint8_t *message;

LIBSPDM_ASSERT(transport_message_size > sizeof(pci_doe_data_object_header_t));
if (transport_message_size <= sizeof(pci_doe_data_object_header_t)) {
return LIBSPDM_STATUS_INVALID_MSG_SIZE;
}

pci_doe_header = transport_message;
if (pci_doe_header->vendor_id != PCI_DOE_VENDOR_ID_PCISIG) {
return LIBSPDM_STATUS_INVALID_MSG_FIELD;
}

switch (pci_doe_header->data_object_type) {
case PCI_DOE_DATA_OBJECT_TYPE_DOE_DISCOVERY:
/*
* Check to see if we received a DOE discovery message.
* DOE discovery is not part of the SPDM spec, instead it's part
* of the PCIe DOE spec. DOE discovery is mandatory for all
* implementations.
*/
message = (const uint8_t *)transport_message + sizeof(pci_doe_data_object_header_t);
if (index != NULL) {
*index = *message;
}
break;
default:
return LIBSPDM_STATUS_UNSUPPORTED_CAP;
}

if (pci_doe_header->reserved != 0) {
return LIBSPDM_STATUS_INVALID_MSG_FIELD;
}
if (pci_doe_header->length >= PCI_DOE_MAX_SIZE_IN_DW) {
return LIBSPDM_STATUS_INVALID_MSG_SIZE;
} else if (pci_doe_header->length == 0) {
length = PCI_DOE_MAX_SIZE_IN_BYTE;
} else {
length = pci_doe_header->length * sizeof(uint32_t);
}
if (length != transport_message_size) {
return LIBSPDM_STATUS_INVALID_MSG_SIZE;
}

return LIBSPDM_STATUS_SUCCESS;
}

libspdm_return_t libspdm_pci_doe_decode_discovery_response(size_t transport_message_size,
void *transport_message,
uint16_t *vendor_id,
uint8_t *protocol,
uint8_t *next_index)
{
const pci_doe_data_object_header_t *pci_doe_header;
uint32_t length;
uint8_t *message;

LIBSPDM_ASSERT(transport_message_size > sizeof(pci_doe_data_object_header_t));
if (transport_message_size <= sizeof(pci_doe_data_object_header_t)) {
return LIBSPDM_STATUS_INVALID_MSG_SIZE;
}

pci_doe_header = transport_message;
if (pci_doe_header->vendor_id != PCI_DOE_VENDOR_ID_PCISIG) {
return LIBSPDM_STATUS_INVALID_MSG_FIELD;
}

switch (pci_doe_header->data_object_type) {
case PCI_DOE_DATA_OBJECT_TYPE_DOE_DISCOVERY:
/*
* Check to see if we received a DOE discovery message.
* DOE discovery is not part of the SPDM spec, instead it's part
* of the PCIe DOE spec. DOE discovery is mandatory for all
* implementations.
*/
message = (uint8_t *)transport_message + sizeof(pci_doe_data_object_header_t);
if (vendor_id != NULL) {
*vendor_id = *message;
}
if (protocol != NULL) {
*protocol = *(message + sizeof(uint16_t));
}
if (next_index != NULL) {
*next_index = *(message + sizeof(uint16_t) + sizeof(uint8_t));
}
break;
default:
return LIBSPDM_STATUS_UNSUPPORTED_CAP;
}

if (pci_doe_header->reserved != 0) {
return LIBSPDM_STATUS_INVALID_MSG_FIELD;
}
if (pci_doe_header->length >= PCI_DOE_MAX_SIZE_IN_DW) {
return LIBSPDM_STATUS_INVALID_MSG_SIZE;
} else if (pci_doe_header->length == 0) {
length = PCI_DOE_MAX_SIZE_IN_BYTE;
} else {
length = pci_doe_header->length * sizeof(uint32_t);
}
if (length != transport_message_size) {
return LIBSPDM_STATUS_INVALID_MSG_SIZE;
}

return LIBSPDM_STATUS_SUCCESS;
}

/**
* Return the maximum transport layer message header size.
* Transport Message Header Size + sizeof(spdm_secured_message_cipher_header_t))
*
* For MCTP, Transport Message Header Size = sizeof(mctp_message_header_t)
* For PCI_DOE, Transport Message Header Size = sizeof(pci_doe_data_object_header_t)
*
* @param spdm_context A pointer to the SPDM context.
*
* @return size of maximum transport layer message header size
**/
uint32_t libspdm_transport_pci_doe_get_header_size(
void *spdm_context)
{
return sizeof(pci_doe_data_object_header_t) + sizeof(spdm_secured_message_cipher_header_t);
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,33 @@ libspdm_test_context_t m_libspdm_transport_pci_doe_test_context = {
false,
};

void libspdm_test_transport_pci_doe_decode_discovery(void **State)
{
libspdm_test_context_t *spdm_test_context;
bool is_requester;

spdm_test_context = *State;
is_requester = spdm_test_context->is_requester;

if (is_requester) {
uint8_t index = 0;

libspdm_pci_doe_decode_discovery_request(spdm_test_context->test_buffer_size,
spdm_test_context->test_buffer,
&index);
} else {
uint16_t vendor_id = 0;
uint8_t protocol = 0;
uint8_t next_index = 0;

libspdm_pci_doe_decode_discovery_response(spdm_test_context->test_buffer_size,
spdm_test_context->test_buffer,
&vendor_id,
&protocol,
&next_index);
}
}

void libspdm_run_test_harness(void *test_buffer, size_t test_buffer_size)
{
void *State;
Expand All @@ -55,5 +82,7 @@ void libspdm_run_test_harness(void *test_buffer, size_t test_buffer_size)

libspdm_test_transport_pci_doe_decode_message(&State);

libspdm_test_transport_pci_doe_decode_discovery(&State);

libspdm_unit_test_group_teardown(&State);
}

0 comments on commit 53dc703

Please sign in to comment.