Skip to content

Commit b00d055

Browse files
committed
Fix : vendor_response_get_id should not exist
Signed-off-by: Shital Jumbad <[email protected]>
1 parent 8ccc0f3 commit b00d055

File tree

9 files changed

+159
-234
lines changed

9 files changed

+159
-234
lines changed

doc/user_guide.md

Lines changed: 26 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -453,42 +453,33 @@ Refer to spdm_server_init() in [spdm_responder.c](https://github.com/DMTF/spdm-e
453453
454454
libspdm_register_get_response_func (spdm_context, libspdm_get_response);
455455
```
456-
3.2 This callbacks handle SPDM Vendor Defined Commands
457-
```C
458-
libspdm_return_t libspdm_vendor_get_id_func(
459-
void *spdm_context,
460-
uint16_t *resp_standard_id,
461-
uint8_t *resp_vendor_id_len,
462-
void *resp_vendor_id)
463-
{
464-
// return responder vendor id
465-
...
466-
467-
return LIBSPDM_STATUS_SUCCESS;
468-
}
469-
470-
vendor_response_get_id
471-
libspdm_return_t libspdm_vendor_response_func(
472-
void *spdm_context,
473-
uint16_t req_standard_id,
474-
uint8_t req_vendor_id_len,
475-
const void *req_vendor_id,
476-
uint16_t req_size,
477-
const void *req_data,
478-
uint16_t *resp_size,
479-
void *resp_data)
480-
{
481-
// process request and create response
482-
...
483-
// populate response header and payload
484-
...
485-
486-
return LIBSPDM_STATUS_SUCCESS;
487-
}
456+
3.2 This callback handles SPDM Vendor Defined Commands
457+
```C
458+
libspdm_return_t libspdm_vendor_response_func(
459+
void *spdm_context,
460+
const uint32_t *session_id,
461+
uint16_t req_standard_id,
462+
uint8_t req_vendor_id_len,
463+
const void *req_vendor_id,
464+
uint32_t req_size,
465+
const void *req_data,
466+
uint16_t *resp_standard_id,
467+
uint8_t *resp_vendor_id_len,
468+
void *resp_vendor_id,
469+
uint32_t *resp_size,
470+
void *resp_data)
471+
{
472+
// set response Vendor/Standard IDs
473+
*resp_standard_id = /* your standard id */;
474+
*resp_vendor_id_len = /* your vendor id length */;
475+
// write Vendor ID bytes into resp_vendor_id[0..*resp_vendor_id_len-1]
476+
477+
// write payload to resp_data and set *resp_size to payload size
478+
return LIBSPDM_STATUS_SUCCESS;
479+
}
488480
489-
libspdm_register_vendor_get_id_callback_func(spdm_context, libspdm_vendor_get_id_func);
490-
libspdm_register_vendor_callback_func(spdm_context, libspdm_vendor_response_func);
491-
```
481+
libspdm_register_vendor_callback_func(spdm_context, libspdm_vendor_response_func);
482+
```
492483

493484
4. Free the memory of contexts within the SPDM context when all flow is over.
494485
This function does not free the SPDM context itself.

include/internal/libspdm_common_lib.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -676,7 +676,6 @@ typedef struct {
676676

677677
#if LIBSPDM_ENABLE_VENDOR_DEFINED_MESSAGES
678678
libspdm_vendor_response_callback_func vendor_response_callback;
679-
libspdm_vendor_get_id_callback_func vendor_response_get_id;
680679
#endif /* LIBSPDM_ENABLE_VENDOR_DEFINED_MESSAGES */
681680

682681
#if LIBSPDM_EVENT_RECIPIENT_SUPPORT

include/library/spdm_common_lib.h

Lines changed: 20 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -946,37 +946,25 @@ bool libspdm_get_fips_mode(void);
946946
#if LIBSPDM_ENABLE_VENDOR_DEFINED_MESSAGES
947947

948948
/**
949-
* Vendor Response Get Vendor ID Callback Function Pointer.
950-
* Required to be able to compose the Vendor Defined Response correctly
949+
* Vendor Response Callback Function Pointer
951950
*
952-
* @param spdm_context A pointer to the SPDM context.
953-
* @param session_id If non-NULL then message is within a secure session.
954-
* If NULL then message is outside a secure session.
955-
* @param resp_standard_id Registry or Standards body used for response
956-
* @param resp_vendor_id_len Length in bytes of the vendor id field for the response
957-
* @param resp_vendor_id Vendor ID assigned by the Registry or Standards Body. Little-endian format
958-
**/
959-
typedef libspdm_return_t (*libspdm_vendor_get_id_callback_func)(
960-
void *spdm_context,
961-
const uint32_t *session_id,
962-
uint16_t *resp_standard_id,
963-
uint8_t *resp_vendor_id_len,
964-
void *resp_vendor_id);
965-
966-
/**
967-
* Vendor Response Callback Function Pointer.
951+
* The library invokes this callback once. The integrator should:
952+
* - Set resp_standard_id, resp_vendor_id_len, resp_vendor_id
953+
* - Fill resp_data and set *resp_size based on the request parameters
968954
*
969-
* @param spdm_context A pointer to the SPDM context.
970-
* @param session_id If non-NULL then message is within a secure session.
971-
* If NULL then message is outside a secure session.
972-
* @param req_standard_id Registry or Standards body used for request
973-
* @param req_vendor_id_len Length in bytes of the vendor id field for the request
974-
* @param req_vendor_id Vendor ID assigned by the Registry or Standards Body. Little-endian format
975-
* @param req_size Length of the request
976-
* @param req_data The vendor defined request
977-
* @param resp_size Length of the response
978-
* @param resp_data The vendor defined response
979-
**/
955+
* @param spdm_context A pointer to the SPDM context.
956+
* @param session_id If non-NULL then message is within a secure session; otherwise NULL.
957+
* @param req_standard_id Registry or Standards body used for request (from request header).
958+
* @param req_vendor_id_len Length in bytes of the vendor id field for the request.
959+
* @param req_vendor_id Request vendor ID (little-endian where applicable).
960+
* @param req_size Length of the request.
961+
* @param req_data Pointer to the request payload.
962+
* @param resp_standard_id Registry/standards body used for response (header field).
963+
* @param resp_vendor_id_len On input, capacity of resp_vendor_id; on output, bytes written.
964+
* @param resp_vendor_id Buffer to receive response vendor ID.
965+
* @param resp_size On input, capacity of resp_data; on output, bytes written.
966+
* @param resp_data Buffer to receive the response payload.
967+
*/
980968
typedef libspdm_return_t (*libspdm_vendor_response_callback_func)(
981969
void *spdm_context,
982970
const uint32_t *session_id,
@@ -985,6 +973,9 @@ typedef libspdm_return_t (*libspdm_vendor_response_callback_func)(
985973
const void *req_vendor_id,
986974
uint32_t req_size,
987975
const void *req_data,
976+
uint16_t *resp_standard_id,
977+
uint8_t *resp_vendor_id_len,
978+
void *resp_vendor_id,
988979
uint32_t *resp_size,
989980
void *resp_data);
990981

include/library/spdm_responder_lib.h

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -285,26 +285,12 @@ void libspdm_register_cert_chain_buffer(
285285
#if LIBSPDM_ENABLE_VENDOR_DEFINED_MESSAGES
286286

287287
/**
288-
* This function registers the callback function for getting the Vendor ID for a VENDOR_DEFINED_RESPONSE to the device.
288+
* Register the request-aware vendor-defined response callback.
289289
*
290290
* This is useful for creating unique responses to devices.
291291
*
292292
* @param spdm_context A pointer to the SPDM context.
293-
* @param resp_callback_func Response callback function
294-
*
295-
* @retval LIBSPDM_STATUS_SUCCESS Success
296-
* @retval LIBSPDM_STATUS_INVALID_PARAMETER Some parameters invalid or NULL
297-
**/
298-
libspdm_return_t libspdm_register_vendor_get_id_callback_func(void *spdm_context,
299-
libspdm_vendor_get_id_callback_func resp_callback);
300-
301-
/**
302-
* This function registers the callback function for doing a VENDOR_DEFINED_RESPONSE to the device.
303-
*
304-
* This is useful for creating unique responses to devices.
305-
*
306-
* @param spdm_context A pointer to the SPDM context.
307-
* @param resp_callback_func Response callback function
293+
* @param resp_callback Response callback function
308294
*
309295
* @retval LIBSPDM_STATUS_SUCCESS Success
310296
* @retval LIBSPDM_STATUS_INVALID_PARAMETER Some parameters invalid or NULL

library/spdm_responder_lib/libspdm_rsp_vendor_response.c

Lines changed: 49 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,6 @@
1111
/* expected number of bytes for VENDOR MESSAGE HEADERS */
1212
#define SPDM_VENDOR_DEFINED_FIXED_HEADER_LEN 7
1313

14-
libspdm_return_t libspdm_register_vendor_get_id_callback_func(void *spdm_context,
15-
libspdm_vendor_get_id_callback_func resp_callback)
16-
{
17-
18-
libspdm_context_t *context = (libspdm_context_t *)spdm_context;
19-
context->vendor_response_get_id = resp_callback;
20-
return LIBSPDM_STATUS_SUCCESS;
21-
}
22-
2314
libspdm_return_t libspdm_register_vendor_callback_func(void *spdm_context,
2415
libspdm_vendor_response_callback_func resp_callback)
2516
{
@@ -79,9 +70,8 @@ libspdm_return_t libspdm_get_vendor_defined_response(libspdm_context_t *spdm_con
7970
session_id = &session_info->session_id;
8071
}
8172

82-
/* Check if caller is using the old Vendor Defined API. */
83-
if ((spdm_context->vendor_response_callback == NULL ||
84-
spdm_context->vendor_response_get_id == NULL)) {
73+
/* Check if vendor callback is registered. */
74+
if (spdm_context->vendor_response_callback == NULL) {
8575
if (spdm_context->get_response_func != NULL) {
8676
return ((libspdm_get_response_func)spdm_context->get_response_func)(
8777
spdm_context,
@@ -182,8 +172,8 @@ libspdm_return_t libspdm_get_vendor_defined_response(libspdm_context_t *spdm_con
182172
libspdm_reset_message_buffer_via_request_code(spdm_context, NULL,
183173
spdm_request->header.request_response_code);
184174

185-
/* length of spdm request/response header before payload start */
186-
header_length = sizeof(spdm_vendor_defined_response_msg_t) + spdm_request->len +
175+
/* reserve max vendor ID in header */
176+
header_length = sizeof(spdm_vendor_defined_response_msg_t) + SPDM_MAX_VENDOR_ID_LENGTH +
187177
sizeof(uint16_t);
188178
if (use_large_payload) {
189179
header_length += sizeof(uint32_t);
@@ -221,7 +211,7 @@ libspdm_return_t libspdm_get_vendor_defined_response(libspdm_context_t *spdm_con
221211
* Len2 bytes Response Payload
222212
*/
223213

224-
/* replace capacity with size */
214+
/* Set up pointers for the callback */
225215
spdm_response->len = SPDM_MAX_VENDOR_ID_LENGTH;
226216
resp_data = ((uint8_t *)response) + sizeof(spdm_vendor_defined_response_msg_t);
227217

@@ -237,39 +227,60 @@ libspdm_return_t libspdm_get_vendor_defined_response(libspdm_context_t *spdm_con
237227
sizeof(uint16_t);
238228
}
239229

240-
status = spdm_context->vendor_response_get_id(
241-
spdm_context,
242-
session_id,
243-
&spdm_response->standard_id,
244-
&spdm_response->len,
245-
resp_data);
230+
/* Compute response pointers and maximum payload capacity. */
231+
uint8_t *resp_vendor_id_ptr = resp_data;
232+
uint8_t *resp_payload_ptr;
233+
size_t len_field_size;
246234

247-
/* move pointer and adjust buffer size */
248235
if (use_large_payload) {
249-
resp_data += spdm_response->len + sizeof(uint16_t) + sizeof(uint32_t);
250-
response_capacity -= spdm_response->len + sizeof(uint16_t) + sizeof(uint32_t);
236+
len_field_size = sizeof(uint16_t) + sizeof(uint32_t);
251237
resp_size = (uint32_t)response_capacity;
252238
} else {
253-
resp_data += spdm_response->len + sizeof(uint16_t);
254-
response_capacity -= spdm_response->len + sizeof(uint16_t);
239+
len_field_size = sizeof(uint16_t);
255240
resp_size = (uint16_t)response_capacity;
256241
}
257242

258-
status = spdm_context->vendor_response_callback(spdm_context,
259-
session_id,
260-
spdm_request->standard_id,
261-
spdm_request->len,
262-
req_vendor_id, req_size, req_data,
263-
&resp_size,
264-
resp_data);
243+
/* reserve max Vendor ID; compact after callback */
244+
resp_payload_ptr = resp_vendor_id_ptr + spdm_response->len + len_field_size;
245+
246+
status = spdm_context->vendor_response_callback(
247+
spdm_context,
248+
session_id,
249+
spdm_request->standard_id,
250+
spdm_request->len,
251+
req_vendor_id,
252+
req_size,
253+
req_data,
254+
&spdm_response->standard_id,
255+
&spdm_response->len,
256+
resp_vendor_id_ptr,
257+
&resp_size,
258+
resp_payload_ptr);
259+
260+
if (LIBSPDM_STATUS_IS_ERROR(status)) {
261+
return status;
262+
}
263+
264+
/* compact payload after Vendor ID */
265+
uint8_t *new_payload_ptr = resp_vendor_id_ptr + spdm_response->len + len_field_size;
266+
if (new_payload_ptr != resp_payload_ptr && resp_size != 0) {
267+
uint32_t bytes_to_move = resp_size;
268+
uint8_t *src = resp_payload_ptr;
269+
uint8_t *dst = new_payload_ptr;
270+
while (bytes_to_move-- != 0) {
271+
*(dst++) = *(src++);
272+
}
273+
}
265274

266-
/* store back the response payload size */
275+
/* store response payload size */
267276
if (use_large_payload) {
268-
libspdm_write_uint32((uint8_t *)(resp_data - sizeof(uint32_t)), resp_size);
269-
*response_size = resp_size + (size_t)header_length;
277+
libspdm_write_uint32((uint8_t *)(resp_data + spdm_response->len + sizeof(uint16_t)), resp_size);
278+
*response_size = resp_size + sizeof(spdm_vendor_defined_response_msg_t) +
279+
spdm_response->len + sizeof(uint16_t) + sizeof(uint32_t);
270280
} else {
271-
libspdm_write_uint16((uint8_t *)(resp_data - sizeof(uint16_t)), (uint16_t)resp_size);
272-
*response_size = (uint16_t)resp_size + (size_t)header_length;
281+
libspdm_write_uint16((uint8_t *)(resp_data + spdm_response->len), (uint16_t)resp_size);
282+
*response_size = (uint16_t)resp_size + sizeof(spdm_vendor_defined_response_msg_t) +
283+
spdm_response->len + sizeof(uint16_t);
273284
}
274285

275286
LIBSPDM_ASSERT(sizeof(spdm_vendor_defined_request_msg_t) ==

unit_test/fuzzing/test_responder/test_spdm_responder_vendor_cmds/vendor_cmds.c

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,6 @@ size_t libspdm_get_max_buffer_size(void)
1515
return LIBSPDM_MAX_SPDM_MSG_SIZE;
1616
}
1717

18-
libspdm_return_t libspdm_vendor_get_id_func_test(
19-
void *spdm_context,
20-
const uint32_t *session_id,
21-
uint16_t *resp_standard_id,
22-
uint8_t *resp_vendor_id_len,
23-
void *resp_vendor_id)
24-
{
25-
return LIBSPDM_STATUS_SUCCESS;
26-
}
27-
2818
libspdm_return_t libspdm_vendor_response_func_test(
2919
void *spdm_context,
3020
const uint32_t *session_id,
@@ -33,9 +23,29 @@ libspdm_return_t libspdm_vendor_response_func_test(
3323
const void *req_vendor_id,
3424
uint32_t req_size,
3525
const void *req_data,
26+
uint16_t *resp_standard_id,
27+
uint8_t *resp_vendor_id_len,
28+
void *resp_vendor_id,
3629
uint32_t *resp_size,
3730
void *resp_data)
3831
{
32+
/* Validate required parameters */
33+
if (resp_standard_id == NULL || resp_vendor_id_len == NULL || resp_vendor_id == NULL ||
34+
resp_size == NULL || resp_data == NULL)
35+
return LIBSPDM_STATUS_INVALID_PARAMETER;
36+
37+
/* Set response IDs */
38+
*resp_standard_id = 6;
39+
if (*resp_vendor_id_len >= 2) {
40+
*resp_vendor_id_len = 2;
41+
((uint8_t*)resp_vendor_id)[0] = 0xAA;
42+
((uint8_t*)resp_vendor_id)[1] = 0xAA;
43+
} else {
44+
return LIBSPDM_STATUS_INVALID_PARAMETER;
45+
}
46+
47+
/* Set response payload */
48+
*resp_size = 0;
3949
return LIBSPDM_STATUS_SUCCESS;
4050
}
4151

@@ -59,8 +69,6 @@ void libspdm_test_responder_vendor_cmds_case1(void **State)
5969
LIBSPDM_CONNECTION_STATE_NEGOTIATED;
6070
spdm_context->local_context.is_requester = true;
6171

62-
libspdm_register_vendor_get_id_callback_func(spdm_context,
63-
libspdm_vendor_get_id_func_test);
6472
libspdm_register_vendor_callback_func(spdm_context,
6573
libspdm_vendor_response_func_test);
6674

0 commit comments

Comments
 (0)