Skip to content

Commit 5e7e0b0

Browse files
committed
Added full support for Vendor Defined Requests and Responses.
New public API methods: Responder: libspdm_vendor_response_callback_func response_callback; libspdm_register_vendor_callback_func( ... response_callback); Requester: libspdm_vendor_request(... request ... response ...); Signed-off-by: Ionut Ursachi <[email protected]>
1 parent ca2fde8 commit 5e7e0b0

17 files changed

+1168
-24
lines changed

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -900,6 +900,7 @@ else()
900900
ADD_SUBDIRECTORY(unit_test/test_spdm_crypt)
901901
ADD_SUBDIRECTORY(unit_test/test_spdm_fips)
902902
ADD_SUBDIRECTORY(unit_test/test_spdm_secured_message)
903+
ADD_SUBDIRECTORY(unit_test/test_spdm_vendor_cmds)
903904
endif()
904905

905906
if((NOT TOOLCHAIN STREQUAL "ARM_DS2022") AND (NOT TOOLCHAIN STREQUAL "RISCV_XPACK"))

doc/user_guide.md

Lines changed: 45 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -249,10 +249,9 @@ Refer to spdm_client_init() in [spdm_requester.c](https://github.com/DMTF/spdm-e
249249

250250
6. Send and receive message in an SPDM session
251251

252-
6.1, Use the SPDM vendor defined message.
253-
(SPDM vendor defined message + transport layer header (SPDM) => application message)
252+
6.1, Use the SPDM vendor defined request.
254253
```
255-
libspdm_send_receive_data (spdm_context, &session_id, FALSE, &request, request_size, &response, &response_size);
254+
libspdm_vendor_request (spdm_context, standard_id, vendor_id_len, &vendor_id, &request, request_size, &response, &response_size);
256255
```
257256

258257
6.2, Use the transport layer application message.
@@ -435,27 +434,49 @@ Refer to spdm_server_init() in [spdm_responder.c](https://github.com/DMTF/spdm-e
435434

436435
3. Register message process callback
437436

438-
This callback need handle both SPDM vendor defined message and transport layer application message.
439-
```
440-
return_status libspdm_get_response_vendor_defined_request (
441-
void *spdm_context,
442-
const uint32_t *session_id,
443-
bool is_app_message,
444-
size_t request_size,
445-
const void *request,
446-
size_t *response_size,
447-
void *response
448-
)
449-
{
450-
if (is_app_message) {
451-
// this is a transport layer application message
452-
} else {
453-
// this is a SPDM vendor defined message (without transport layer header)
454-
}
455-
}
456-
457-
libspdm_register_get_response_func (spdm_context, libspdm_get_response_vendor_defined_request);
458-
```
437+
3.1 This callback handles transport layer application message.
438+
```
439+
return_status libspdm_get_response (
440+
void *spdm_context,
441+
const uint32_t *session_id,
442+
bool is_app_message,
443+
size_t request_size,
444+
const void *request,
445+
size_t *response_size,
446+
void *response
447+
)
448+
{
449+
if (is_app_message) {
450+
// this is a transport layer application message
451+
} else {
452+
// other SPDM message
453+
}
454+
}
455+
456+
libspdm_register_get_response_func (spdm_context, libspdm_get_response);
457+
```
458+
3.2 This callback handles SPDM Vendor Defined Commands
459+
```
460+
libspdm_return_t libspdm_vendor_response_func(
461+
void *spdm_context,
462+
uint16_t standard_id,
463+
uint8_t vendor_id_len,
464+
const void *vendor_id,
465+
const void *request,
466+
size_t request_len,
467+
void *resp,
468+
size_t *resp_len)
469+
{
470+
// process request and create response
471+
...
472+
// populate response header and payload
473+
...
474+
475+
return LIBSPDM_STATUS_SUCCESS;
476+
}
477+
478+
libspdm_register_vendor_callback_func(spdm_context, libspdm_vendor_response_func);
479+
```
459480
460481
4. Free the memory of contexts within the SPDM context when all flow is over.
461482
This function doesn't free the SPDM context itself.

include/internal/libspdm_common_lib.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -606,6 +606,9 @@ typedef struct {
606606
* This field is ignored for other SPDM versions */
607607
uint8_t spdm_10_11_verify_signature_endian;
608608

609+
#if LIBSPDM_ENABLE_VENDOR_DEFINED_MESSAGES
610+
libspdm_vendor_response_callback_func vendor_response_callback;
611+
#endif /* LIBSPDM_ENABLE_VENDOR_DEFINED_MESSAGES */
609612
} libspdm_context_t;
610613

611614
#define LIBSPDM_CONTEXT_SIZE_WITHOUT_SECURED_CONTEXT (sizeof(libspdm_context_t))

include/internal/libspdm_responder_lib.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -743,6 +743,31 @@ libspdm_return_t libspdm_get_response_chunk_send(libspdm_context_t *spdm_context
743743

744744
#endif /* LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP */
745745

746+
#if LIBSPDM_ENABLE_VENDOR_DEFINED_MESSAGES
747+
/**
748+
* Process the SPDM VENDOR_DEFINED_REQUEST request and return the response.
749+
*
750+
* @param spdm_context A pointer to the SPDM context.
751+
* @param request_size size in bytes of the request data.
752+
* @param request A pointer to the request data.
753+
* @param response_size size in bytes of the response data.
754+
* On input, it means the size in bytes of response data buffer.
755+
* On output, it means the size in bytes of copied response data
756+
* @param response A pointer to the response data.
757+
*
758+
* @retval RETURN_SUCCESS The request is processed and the response is returned.
759+
* @retval RETURN_BUFFER_TOO_SMALL The buffer is too small to hold the data.
760+
* @retval RETURN_DEVICE_ERROR A device error occurs when communicates with the device.
761+
* @retval RETURN_SECURITY_VIOLATION Any verification fails.
762+
**/
763+
764+
libspdm_return_t libspdm_get_vendor_defined_response(libspdm_context_t *spdm_context,
765+
size_t request_size,
766+
const void *request,
767+
size_t *response_size,
768+
void *response);
769+
#endif /* LIBSPDM_ENABLE_VENDOR_DEFINED_MESSAGES */
770+
746771
/**
747772
* This function allocates half of session ID for a responder.
748773
*

include/library/spdm_common_lib.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -946,4 +946,34 @@ uint32_t libspdm_module_version(void);
946946
/*true: FIPS enabled, false: FIPS disabled*/
947947
bool libspdm_get_fips_mode(void);
948948

949+
#if LIBSPDM_ENABLE_VENDOR_DEFINED_MESSAGES
950+
951+
/**
952+
* Vendor Response Callback Prototype.
953+
* First 2 bytes are the response length, followed by the actual response
954+
*
955+
* @param spdm_context A pointer to the SPDM context.
956+
* @param standard_id Registry or Standards body used
957+
* @param vendor_id_len Length in bytes of the vendor id field
958+
* @param vendor_id Vendor ID assigned by the Registry or Standards Body. Little-endian format
959+
* @param request The vendor defined request
960+
* @param request_len Length of the request
961+
* @param response The vendor defined response (including response length as first 2 bytes)
962+
* @param response_len Length of the vendor response
963+
*
964+
* @retval LIBSPDM_STATUS_SUCCESS Success
965+
* @retval LIBSPDM_STATUS_INVALID_PARAMETER Some parameters invalid or NULL
966+
**/
967+
typedef libspdm_return_t (*libspdm_vendor_response_callback_func)(
968+
void *spdm_context,
969+
uint16_t standard_id,
970+
uint8_t vendor_id_len,
971+
const void *vendor_id,
972+
const void *request,
973+
size_t request_len,
974+
void *response,
975+
size_t *response_len);
976+
977+
#endif /* LIBSPDM_ENABLE_VENDOR_DEFINED_MESSAGES */
978+
949979
#endif /* SPDM_COMMON_LIB_H */

include/library/spdm_lib_config.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,11 @@
7676
#define LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN 1024
7777
#endif
7878

79+
/* Maximum size of a vendor defined response message */
80+
#ifndef LIBSPDM_MAX_VENDOR_DEFINED_RESPONSE_LEN
81+
#define LIBSPDM_MAX_VENDOR_DEFINED_RESPONSE_LEN 1024
82+
#endif
83+
7984
/* To ensure integrity in communication between the Requester and the Responder libspdm calculates
8085
* cryptographic digests and signatures over multiple requests and responses. This value specifies
8186
* whether libspdm will use a running calculation over the transcript, where requests and responses
@@ -268,6 +273,10 @@
268273
#define LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP 1
269274
#endif
270275

276+
#ifndef LIBSPDM_ENABLE_VENDOR_DEFINED_MESSAGES
277+
#define LIBSPDM_ENABLE_VENDOR_DEFINED_MESSAGES 1
278+
#endif
279+
271280
/* If 1 then endpoint supports sending GET_CERTIFICATE and GET_DIGESTS requests.
272281
* If enabled and endpoint is a Responder then LIBSPDM_ENABLE_CAPABILITY_ENCAP_CAP
273282
* must also be enabled.

include/library/spdm_requester_lib.h

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -759,4 +759,44 @@ size_t libspdm_get_msg_log_size (void *spdm_context);
759759
void libspdm_reset_msg_log (void *spdm_context);
760760
#endif /* LIBSPDM_ENABLE_MSG_LOG */
761761

762+
#if LIBSPDM_ENABLE_VENDOR_DEFINED_MESSAGES
763+
764+
/**
765+
* This function sends VENDOR_DEFINED_REQUEST to the device and gets back a VENDOR_DEFINED_RESPONSE.
766+
*
767+
* This is useful for creating unique requests/responses to devices.
768+
*
769+
* @param spdm_context A pointer to the SPDM context.
770+
* @param standard_id Registry or Standards body used
771+
* @param vendor_id_len Length in bytes of the vendor id field
772+
* @param vendor_id Vendor ID assigned by the Registry or Standards Body. Little-endian format
773+
* @param request The vendor defined request
774+
* @param request_len Length of the request
775+
* @param response The vendor defined response
776+
* @param response_len Length of the vendor response
777+
*
778+
* @retval LIBSPDM_STATUS_SUCCESS
779+
* VENDOR_DEFINED_REQUEST was sent and VENDOR_DEFINED_RESPONSE was received.
780+
* @retval LIBSPDM_STATUS_INVALID_STATE_LOCAL
781+
* Cannot send VENDOR_DEFINED_REQUEST due to Requester's state.
782+
* @retval LIBSPDM_STATUS_ERROR_PEER
783+
* The Responder returned an unexpected error.
784+
* @retval LIBSPDM_STATUS_BUSY_PEER
785+
* The Responder continually returned Busy error messages.
786+
* @retval LIBSPDM_STATUS_RESYNCH_PEER
787+
* The Responder returned a RequestResynch error message.
788+
* @retval LIBSPDM_STATUS_BUFFER_FULL
789+
* The buffer used to store transcripts is exhausted.
790+
**/
791+
libspdm_return_t libspdm_vendor_request(void *spdm_context,
792+
uint16_t standard_id,
793+
uint8_t vendor_id_len,
794+
void *vendor_id,
795+
void *request,
796+
size_t request_len,
797+
void *response,
798+
size_t *response_len);
799+
800+
#endif /* LIBSPDM_ENABLE_VENDOR_DEFINED_MESSAGES */
801+
762802
#endif /* SPDM_REQUESTER_LIB_H */

include/library/spdm_responder_lib.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,4 +262,22 @@ void libspdm_register_cert_chain_buffer(
262262
void *spdm_context, void *cert_chain_buffer, size_t cert_chain_buffer_max_size);
263263
#endif
264264

265+
#if LIBSPDM_ENABLE_VENDOR_DEFINED_MESSAGES
266+
267+
/**
268+
* This function registers the callback function for doing a VENDOR_DEFINED_RESPONSE to the device.
269+
*
270+
* This is useful for creating unique requests to devices.
271+
*
272+
* @param spdm_context A pointer to the SPDM context.
273+
* @param resp_callback_func Response callback function
274+
*
275+
* @retval LIBSPDM_STATUS_SUCCESS Success
276+
* @retval LIBSPDM_STATUS_INVALID_PARAMETER Some parameters invalid or NULL
277+
**/
278+
libspdm_return_t libspdm_register_vendor_callback_func(void *spdm_context,
279+
libspdm_vendor_response_callback_func resp_callback);
280+
281+
#endif /* LIBSPDM_ENABLE_VENDOR_DEFINED_MESSAGES */
282+
265283
#endif /* SPDM_RESPONDER_LIB_H */

library/spdm_requester_lib/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ SET(src_spdm_requester_lib
2929
libspdm_req_send_receive.c
3030
libspdm_req_set_certificate.c
3131
libspdm_req_get_csr.c
32+
libspdm_req_vendor_request.c
3233
)
3334

3435
ADD_LIBRARY(spdm_requester_lib STATIC ${src_spdm_requester_lib})

0 commit comments

Comments
 (0)