From 159ecd11d70f09c16fe0278821c80513dc99b4bd Mon Sep 17 00:00:00 2001 From: Alistair Francis Date: Thu, 9 Feb 2023 16:58:10 +1000 Subject: [PATCH] libspdm_doe_pcidoe: Add DOE discovery encode helpers Add helper functions for encoding 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 --- include/library/spdm_transport_pcidoe_lib.h | 15 +++++++ .../libspdm_doe_pcidoe.c | 44 +++++++++++++++++++ .../spdm_transport_pci_doe_encode_message.c | 28 ++++++++++++ 3 files changed, 87 insertions(+) diff --git a/include/library/spdm_transport_pcidoe_lib.h b/include/library/spdm_transport_pcidoe_lib.h index 649c2c5b5fe..852e7f06935 100644 --- a/include/library/spdm_transport_pcidoe_lib.h +++ b/include/library/spdm_transport_pcidoe_lib.h @@ -64,6 +64,21 @@ libspdm_return_t libspdm_transport_pci_doe_encode_message( bool is_requester, size_t message_size, void *message, size_t *transport_message_size, void **transport_message); +/** + * Encode a DOE discovery message. + * + * @param message_size Size in bytes of the message data buffer. + * @param message A pointer to a source buffer to store the message. + * @param transport_message_size Size in bytes of the transport message data buffer. + * @param transport_message A pointer to a destination buffer to store the transport message. + * + * @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_encode_discovery(size_t message_size, void *message, + size_t *transport_message_size, + void **transport_message); + /** * Decode an SPDM or APP message from a transport layer message. * diff --git a/library/spdm_transport_pcidoe_lib/libspdm_doe_pcidoe.c b/library/spdm_transport_pcidoe_lib/libspdm_doe_pcidoe.c index ceeae529bf5..b8d46aeb94e 100644 --- a/library/spdm_transport_pcidoe_lib/libspdm_doe_pcidoe.c +++ b/library/spdm_transport_pcidoe_lib/libspdm_doe_pcidoe.c @@ -128,6 +128,50 @@ libspdm_return_t libspdm_pci_doe_encode_message(const uint32_t *session_id, return LIBSPDM_STATUS_SUCCESS; } +libspdm_return_t libspdm_pci_doe_encode_discovery(size_t message_size, void *message, + size_t *transport_message_size, + void **transport_message) +{ + size_t aligned_message_size; + size_t alignment; + pci_doe_data_object_header_t *pci_doe_header; + + alignment = LIBSPDM_PCI_DOE_ALIGNMENT; + aligned_message_size = + (message_size + (alignment - 1)) & ~(alignment - 1); + + LIBSPDM_ASSERT(*transport_message_size >= + aligned_message_size + sizeof(pci_doe_data_object_header_t)); + if (*transport_message_size < + aligned_message_size + sizeof(pci_doe_data_object_header_t)) { + *transport_message_size = aligned_message_size + + sizeof(pci_doe_data_object_header_t); + return LIBSPDM_STATUS_BUFFER_TOO_SMALL; + } + + *transport_message_size = + aligned_message_size + sizeof(pci_doe_data_object_header_t); + *transport_message = (uint8_t *)message - sizeof(pci_doe_data_object_header_t); + pci_doe_header = *transport_message; + pci_doe_header->vendor_id = PCI_DOE_VENDOR_ID_PCISIG; + pci_doe_header->data_object_type = PCI_DOE_DATA_OBJECT_TYPE_DOE_DISCOVERY; + pci_doe_header->reserved = 0; + + if (*transport_message_size > PCI_DOE_MAX_SIZE_IN_BYTE) { + return LIBSPDM_STATUS_BUFFER_FULL; + } else if (*transport_message_size == PCI_DOE_MAX_SIZE_IN_BYTE) { + pci_doe_header->length = 0; + } else { + pci_doe_header->length = + (uint32_t)*transport_message_size / sizeof(uint32_t); + } + + libspdm_zero_mem((uint8_t *)message + message_size, + aligned_message_size - message_size); + + return LIBSPDM_STATUS_SUCCESS; +} + /** * Decode a transport message to a normal message or secured message. * diff --git a/unit_test/fuzzing/test_transport/test_spdm_transport_pci_doe_encode_message/spdm_transport_pci_doe_encode_message.c b/unit_test/fuzzing/test_transport/test_spdm_transport_pci_doe_encode_message/spdm_transport_pci_doe_encode_message.c index 6af71899bd6..1ccb0d5eaaa 100644 --- a/unit_test/fuzzing/test_transport/test_spdm_transport_pci_doe_encode_message/spdm_transport_pci_doe_encode_message.c +++ b/unit_test/fuzzing/test_transport/test_spdm_transport_pci_doe_encode_message/spdm_transport_pci_doe_encode_message.c @@ -54,6 +54,34 @@ libspdm_test_context_t m_libspdm_transport_pci_doe_test_context = { false, }; +void libspdm_test_transport_pci_doe_encode_discovery(void **State) +{ + libspdm_test_context_t *spdm_test_context; + size_t transport_message_size; + uint8_t *transport_message; + size_t record_header_max_size; + + spdm_test_context = *State; + + /* limit the encoding buffer to avoid assert, because the input buffer is controlled by the the libspdm consumer. */ + record_header_max_size = sizeof(pci_doe_data_object_header_t) + + sizeof(spdm_secured_message_a_data_header1_t) + + 0 + /* PCI_DOE_SEQUENCE_NUMBER_COUNT */ + sizeof(spdm_secured_message_a_data_header2_t) + + sizeof(spdm_secured_message_cipher_header_t) + + 0; /* PCI_DOE_MAX_RANDOM_NUMBER_COUNT */ + LIBSPDM_ASSERT(spdm_test_context->test_buffer_size > record_header_max_size); + + transport_message_size = LIBSPDM_MAX_SENDER_RECEIVER_BUFFER_SIZE; + transport_message = spdm_test_context->test_buffer; + + libspdm_pci_doe_encode_discovery(spdm_test_context->test_buffer_size - record_header_max_size, + (uint8_t *)spdm_test_context->test_buffer + record_header_max_size, + &transport_message_size, + (void **)&transport_message); +} + + void libspdm_run_test_harness(void *test_buffer, size_t test_buffer_size) { void *State;