Skip to content
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
10 changes: 9 additions & 1 deletion include/industry_standard/spdm.h
Original file line number Diff line number Diff line change
Expand Up @@ -1112,6 +1112,8 @@ typedef struct {
spdm_message_header_t header;
/* param1 == signature_included
* param2 == req_slot_id
* uint16_t opaque_length; // 1.4+
* uint8_t opaque_data[opaque_length]; // 1.4+
* uint8_t signature[S];
* uint8_t verify_data[H];*/
} spdm_finish_request_t;
Expand All @@ -1124,6 +1126,8 @@ typedef struct {
spdm_message_header_t header;
/* param1 == RSVD
* param2 == RSVD
* uint16_t opaque_length; // 1.4+
* uint8_t opaque_data[opaque_length]; // 1.4+
* uint8_t verify_data[H];*/
} spdm_finish_response_t;

Expand Down Expand Up @@ -1171,14 +1175,18 @@ typedef struct {
spdm_message_header_t header;
/* param1 == RSVD
* param2 == RSVD
* uint16_t opaque_length; // 1.4+
* uint8_t opaque_data[opaque_length]; // 1.4+
* uint8_t verify_data[H];*/
} spdm_psk_finish_request_t;

/* SPDM PSK_FINISH response */
typedef struct {
spdm_message_header_t header;
/* param1 == RSVD
* param2 == RSVD*/
* param2 == RSVD
* uint16_t opaque_length; // 1.4+
* uint8_t opaque_data[opaque_length]; // 1.4+ */
} spdm_psk_finish_response_t;


Expand Down
17 changes: 17 additions & 0 deletions include/internal/libspdm_requester_lib.h
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,15 @@ libspdm_return_t libspdm_send_receive_key_exchange_ex(
libspdm_return_t libspdm_send_receive_finish(libspdm_context_t *spdm_context,
uint32_t session_id,
uint8_t req_slot_id_param);

libspdm_return_t libspdm_send_receive_finish_ex(
libspdm_context_t *spdm_context,
uint32_t session_id,
uint8_t req_slot_id_param,
const void *requester_opaque_data,
size_t requester_opaque_data_size,
void *responder_opaque_data,
size_t *responder_opaque_data_size);
#endif /* LIBSPDM_ENABLE_CAPABILITY_KEY_EX_CAP */

#if LIBSPDM_ENABLE_CAPABILITY_PSK_CAP
Expand Down Expand Up @@ -338,6 +347,14 @@ libspdm_return_t libspdm_send_receive_psk_exchange_ex(libspdm_context_t *spdm_co
**/
libspdm_return_t libspdm_send_receive_psk_finish(libspdm_context_t *spdm_context,
uint32_t session_id);

libspdm_return_t libspdm_send_receive_psk_finish_ex(
libspdm_context_t *spdm_context,
uint32_t session_id,
const void *requester_opaque_data,
size_t requester_opaque_data_size,
void *responder_opaque_data,
size_t *responder_opaque_data_size);
#endif /* LIBSPDM_ENABLE_CAPABILITY_PSK_CAP */

#if (LIBSPDM_ENABLE_CAPABILITY_KEY_EX_CAP) || (LIBSPDM_ENABLE_CAPABILITY_PSK_CAP)
Expand Down
148 changes: 129 additions & 19 deletions library/spdm_requester_lib/libspdm_req_finish.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,16 @@
#pragma pack(1)
typedef struct {
spdm_message_header_t header;
uint16_t opaque_length;
uint8_t opaque_data[SPDM_MAX_OPAQUE_DATA_SIZE];
uint8_t signature[LIBSPDM_REQ_SIGNATURE_DATA_MAX_SIZE];
uint8_t verify_data[LIBSPDM_MAX_HASH_SIZE];
} libspdm_finish_request_mine_t;

typedef struct {
spdm_message_header_t header;
uint16_t opaque_length;
uint8_t opaque_data[SPDM_MAX_OPAQUE_DATA_SIZE];
uint8_t verify_data[LIBSPDM_MAX_HASH_SIZE];
} libspdm_finish_response_mine_t;
#pragma pack()
Expand Down Expand Up @@ -344,9 +348,14 @@ bool libspdm_generate_finish_req_signature(libspdm_context_t *spdm_context,
* @retval RETURN_SUCCESS The FINISH is sent and the FINISH_RSP is received.
* @retval RETURN_DEVICE_ERROR A device error occurs when communicates with the device.
**/
static libspdm_return_t libspdm_try_send_receive_finish(libspdm_context_t *spdm_context,
uint32_t session_id,
uint8_t req_slot_id_param)
static libspdm_return_t libspdm_try_send_receive_finish(
libspdm_context_t *spdm_context,
uint32_t session_id,
uint8_t req_slot_id_param,
const void *requester_opaque_data,
size_t requester_opaque_data_size,
void *responder_opaque_data,
size_t *responder_opaque_data_size)
{
libspdm_return_t status;
libspdm_finish_request_mine_t *spdm_request;
Expand All @@ -363,6 +372,8 @@ static libspdm_return_t libspdm_try_send_receive_finish(libspdm_context_t *spdm_
uint8_t *message;
size_t message_size;
size_t transport_header_size;
size_t opaque_data_entry_size;
size_t opaque_data_size;

/* -=[Check Parameters Phase]=- */
if (libspdm_get_connection_version(spdm_context) < SPDM_MESSAGE_VERSION_11) {
Expand Down Expand Up @@ -424,6 +435,36 @@ static libspdm_return_t libspdm_try_send_receive_finish(libspdm_context_t *spdm_
spdm_request->header.request_response_code = SPDM_FINISH;
spdm_request->header.param1 = 0;
spdm_request->header.param2 = 0;

ptr = (uint8_t *)spdm_request + sizeof(spdm_finish_request_t);
if (libspdm_get_connection_version(spdm_context) >= SPDM_MESSAGE_VERSION_14) {
if (requester_opaque_data != NULL) {
LIBSPDM_ASSERT(requester_opaque_data_size <= SPDM_MAX_OPAQUE_DATA_SIZE);
LIBSPDM_ASSERT (spdm_request_size >= sizeof(spdm_finish_request_t) +
sizeof(uint16_t) + requester_opaque_data_size);

libspdm_write_uint16(ptr, (uint16_t)requester_opaque_data_size);
ptr += sizeof(uint16_t);

libspdm_copy_mem(ptr,
(spdm_request_size - (sizeof(spdm_finish_request_t) +
sizeof(uint16_t))),
requester_opaque_data, requester_opaque_data_size);
opaque_data_size = requester_opaque_data_size;
} else {
opaque_data_size = 0;
LIBSPDM_ASSERT (spdm_request_size >= sizeof(spdm_finish_request_t) +
sizeof(uint16_t) + opaque_data_size);

libspdm_write_uint16(ptr, (uint16_t)opaque_data_size);
ptr += sizeof(uint16_t);
}
ptr += opaque_data_size;
opaque_data_entry_size = sizeof(uint16_t) + opaque_data_size;
} else {
opaque_data_entry_size = 0;
}

signature_size = 0;
#if LIBSPDM_ENABLE_CAPABILITY_MUT_AUTH_CAP
if (session_info->mut_auth_requested != 0) {
Expand All @@ -449,13 +490,13 @@ static libspdm_return_t libspdm_try_send_receive_finish(libspdm_context_t *spdm_
}

hmac_size = libspdm_get_hash_size(spdm_context->connection_info.algorithm.base_hash_algo);
LIBSPDM_ASSERT (spdm_request_size >= sizeof(spdm_finish_request_t) + signature_size +
hmac_size);
spdm_request_size = sizeof(spdm_finish_request_t) + signature_size + hmac_size;
ptr = spdm_request->signature;
LIBSPDM_ASSERT (spdm_request_size >= sizeof(spdm_finish_request_t) + opaque_data_entry_size +
signature_size + hmac_size);
spdm_request_size = sizeof(spdm_finish_request_t) + opaque_data_entry_size +
signature_size + hmac_size;

status = libspdm_append_message_f(spdm_context, session_info, true, (uint8_t *)spdm_request,
sizeof(spdm_finish_request_t));
spdm_request_size - signature_size - hmac_size);
if (LIBSPDM_STATUS_IS_ERROR(status)) {
libspdm_release_sender_buffer (spdm_context);
goto error;
Expand Down Expand Up @@ -553,13 +594,51 @@ static libspdm_return_t libspdm_try_send_receive_finish(libspdm_context_t *spdm_
hmac_size = 0;
}

if (spdm_response_size < sizeof(spdm_finish_response_t) + hmac_size) {
status = LIBSPDM_STATUS_INVALID_MSG_SIZE;
goto receive_done;
ptr = (uint8_t *)spdm_response + sizeof(spdm_finish_response_t);

if (libspdm_get_connection_version(spdm_context) >= SPDM_MESSAGE_VERSION_14) {
if (spdm_response_size < sizeof(spdm_finish_response_t) + sizeof(uint16_t) + hmac_size) {
status = LIBSPDM_STATUS_INVALID_MSG_SIZE;
goto receive_done;
}
opaque_data_size = libspdm_read_uint16((const uint8_t *)ptr);
ptr += sizeof(uint16_t);
if (opaque_data_size > SPDM_MAX_OPAQUE_DATA_SIZE) {
status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
goto receive_done;
}
if (spdm_response_size < sizeof(spdm_finish_response_t) + sizeof(uint16_t) +
opaque_data_size + hmac_size) {
status = LIBSPDM_STATUS_INVALID_MSG_SIZE;
goto receive_done;
}

if ((responder_opaque_data != NULL) && (responder_opaque_data_size != NULL)) {
if (opaque_data_size >= *responder_opaque_data_size) {
status = LIBSPDM_STATUS_BUFFER_TOO_SMALL;
goto receive_done;
}
libspdm_copy_mem(responder_opaque_data, *responder_opaque_data_size,
ptr, opaque_data_size);
*responder_opaque_data_size = opaque_data_size;
}

ptr += opaque_data_size;
opaque_data_entry_size = sizeof(uint16_t) + opaque_data_size;
} else {
if (spdm_response_size < sizeof(spdm_finish_response_t) + hmac_size) {
status = LIBSPDM_STATUS_INVALID_MSG_SIZE;
goto receive_done;
}
if ((responder_opaque_data != NULL) && (responder_opaque_data_size != NULL)) {
*responder_opaque_data_size = 0;
}
opaque_data_entry_size = 0;
}
spdm_response_size = sizeof(spdm_finish_response_t) + opaque_data_entry_size + hmac_size;

status = libspdm_append_message_f(spdm_context, session_info, true, spdm_response,
sizeof(spdm_finish_response_t));
spdm_response_size - hmac_size);
if (LIBSPDM_STATUS_IS_ERROR(status)) {
goto receive_done;
}
Expand All @@ -569,20 +648,17 @@ static libspdm_return_t libspdm_try_send_receive_finish(libspdm_context_t *spdm_
SPDM_GET_CAPABILITIES_REQUEST_FLAGS_HANDSHAKE_IN_THE_CLEAR_CAP,
SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_HANDSHAKE_IN_THE_CLEAR_CAP)) {
LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "verify_data (0x%zx):\n", hmac_size));
LIBSPDM_INTERNAL_DUMP_HEX(spdm_response->verify_data, hmac_size);
LIBSPDM_INTERNAL_DUMP_HEX(ptr, hmac_size);
result = libspdm_verify_finish_rsp_hmac(spdm_context, session_info,
spdm_response->verify_data,
hmac_size);
ptr, hmac_size);
if (!result) {
status = LIBSPDM_STATUS_VERIF_FAIL;
goto receive_done;
}

status = libspdm_append_message_f(
spdm_context, session_info, true,
(uint8_t *)spdm_response +
sizeof(spdm_finish_response_t),
hmac_size);
ptr, hmac_size);
if (LIBSPDM_STATUS_IS_ERROR(status)) {
goto receive_done;
}
Expand Down Expand Up @@ -638,7 +714,41 @@ libspdm_return_t libspdm_send_receive_finish(libspdm_context_t *spdm_context,
retry_delay_time = spdm_context->retry_delay_time;
do {
status = libspdm_try_send_receive_finish(spdm_context, session_id,
req_slot_id_param);
req_slot_id_param,
NULL, 0, NULL, NULL);
if (status != LIBSPDM_STATUS_BUSY_PEER) {
return status;
}

libspdm_sleep(retry_delay_time);
} while (retry-- != 0);

return status;
}

libspdm_return_t libspdm_send_receive_finish_ex(
libspdm_context_t *spdm_context,
uint32_t session_id,
uint8_t req_slot_id_param,
const void *requester_opaque_data,
size_t requester_opaque_data_size,
void *responder_opaque_data,
size_t *responder_opaque_data_size)
{
size_t retry;
uint64_t retry_delay_time;
libspdm_return_t status;

spdm_context->crypto_request = true;
retry = spdm_context->retry_times;
retry_delay_time = spdm_context->retry_delay_time;
do {
status = libspdm_try_send_receive_finish(spdm_context, session_id,
req_slot_id_param,
requester_opaque_data,
requester_opaque_data_size,
responder_opaque_data,
responder_opaque_data_size);
if (status != LIBSPDM_STATUS_BUSY_PEER) {
return status;
}
Expand Down
Loading
Loading