From 4a010ad0bb8d398e65a60d67d6d4e9bbbc6964b7 Mon Sep 17 00:00:00 2001 From: Jiewen Yao Date: Mon, 20 Nov 2023 10:53:22 +0800 Subject: [PATCH] Add 1.3 Challenge for BasicMutAuth Signed-off-by: Jiewen Yao --- include/internal/libspdm_common_lib.h | 1 + .../libspdm_req_encap_challenge_auth.c | 23 +++++- .../libspdm_rsp_encap_challenge.c | 79 ++++++++++++++----- 3 files changed, 83 insertions(+), 20 deletions(-) diff --git a/include/internal/libspdm_common_lib.h b/include/internal/libspdm_common_lib.h index 7c77da5408d..32c1970e78c 100644 --- a/include/internal/libspdm_common_lib.h +++ b/include/internal/libspdm_common_lib.h @@ -423,6 +423,7 @@ typedef struct { spdm_message_header_t last_encap_request_header; size_t last_encap_request_size; uint16_t cert_chain_total_len; + uint8_t req_context[SPDM_REQ_CONTEXT_SIZE]; } libspdm_encap_context_t; #if LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP diff --git a/library/spdm_requester_lib/libspdm_req_encap_challenge_auth.c b/library/spdm_requester_lib/libspdm_req_encap_challenge_auth.c index 50ceb920f25..37e79ba6f85 100644 --- a/library/spdm_requester_lib/libspdm_req_encap_challenge_auth.c +++ b/library/spdm_requester_lib/libspdm_req_encap_challenge_auth.c @@ -28,6 +28,7 @@ libspdm_return_t libspdm_get_encap_response_challenge_auth( uint8_t slot_mask; uint8_t *opaque_data; size_t opaque_data_size; + size_t spdm_request_size; size_t spdm_response_size; context = spdm_context; @@ -58,6 +59,15 @@ libspdm_return_t libspdm_get_encap_response_challenge_auth( context, SPDM_ERROR_CODE_INVALID_REQUEST, 0, response_size, response); } + spdm_request_size = sizeof(spdm_challenge_request_t); + if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_13) { + if (request_size < sizeof(spdm_challenge_request_t) + SPDM_REQ_CONTEXT_SIZE) { + return libspdm_generate_encap_error_response( + context, SPDM_ERROR_CODE_INVALID_REQUEST, 0, + response_size, response); + } + spdm_request_size += SPDM_REQ_CONTEXT_SIZE; + } if (spdm_request->header.param2 != SPDM_CHALLENGE_REQUEST_NO_MEASUREMENT_SUMMARY_HASH) { return libspdm_generate_encap_error_response( @@ -86,7 +96,7 @@ libspdm_return_t libspdm_get_encap_response_challenge_auth( /* response_size should be large enough to hold a challenge response without opaque data. */ LIBSPDM_ASSERT(*response_size >= sizeof(spdm_challenge_auth_response_t) + hash_size + SPDM_NONCE_SIZE + measurement_summary_hash_size + sizeof(uint16_t) + - signature_size); + SPDM_REQ_CONTEXT_SIZE + signature_size); libspdm_zero_mem(response, *response_size); spdm_response = response; @@ -155,11 +165,20 @@ libspdm_return_t libspdm_get_encap_response_challenge_auth( /*the opaque_data is stored by libspdm_encap_challenge_opaque_data*/ ptr += opaque_data_size; + if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_13) { + libspdm_copy_mem(ptr, SPDM_REQ_CONTEXT_SIZE, + spdm_request + 1, SPDM_REQ_CONTEXT_SIZE); + ptr += SPDM_REQ_CONTEXT_SIZE; + } + /*get actual response size*/ spdm_response_size = sizeof(spdm_challenge_auth_response_t) + hash_size + SPDM_NONCE_SIZE + measurement_summary_hash_size + sizeof(uint16_t) + opaque_data_size + signature_size; + if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_13) { + spdm_response_size += SPDM_REQ_CONTEXT_SIZE; + } LIBSPDM_ASSERT(*response_size >= spdm_response_size); @@ -168,7 +187,7 @@ libspdm_return_t libspdm_get_encap_response_challenge_auth( /* Calc Sign*/ status = libspdm_append_message_mut_c(context, spdm_request, - request_size); + spdm_request_size); if (LIBSPDM_STATUS_IS_ERROR(status)) { return libspdm_generate_encap_error_response( context, SPDM_ERROR_CODE_UNSPECIFIED, 0, diff --git a/library/spdm_responder_lib/libspdm_rsp_encap_challenge.c b/library/spdm_responder_lib/libspdm_rsp_encap_challenge.c index 6cbc1b3ef60..038f1c6bec8 100644 --- a/library/spdm_responder_lib/libspdm_rsp_encap_challenge.c +++ b/library/spdm_responder_lib/libspdm_rsp_encap_challenge.c @@ -14,6 +14,7 @@ libspdm_return_t libspdm_get_encap_request_challenge(libspdm_context_t *spdm_con void *encap_request) { spdm_challenge_request_t *spdm_request; + size_t spdm_request_size; libspdm_return_t status; spdm_context->encap_context.last_encap_request_size = 0; @@ -28,10 +29,15 @@ libspdm_return_t libspdm_get_encap_request_challenge(libspdm_context_t *spdm_con return LIBSPDM_STATUS_UNSUPPORTED_CAP; } - if(*encap_request_size < sizeof(spdm_challenge_request_t)) { + spdm_request_size = sizeof(spdm_challenge_request_t); + if (libspdm_get_connection_version (spdm_context) >= SPDM_MESSAGE_VERSION_13) { + spdm_request_size = sizeof(spdm_challenge_request_t) + SPDM_REQ_CONTEXT_SIZE; + } + + if(*encap_request_size < spdm_request_size) { return LIBSPDM_STATUS_INVALID_MSG_SIZE; } - *encap_request_size = sizeof(spdm_challenge_request_t); + *encap_request_size = spdm_request_size; spdm_request = encap_request; @@ -46,6 +52,13 @@ libspdm_return_t libspdm_get_encap_request_challenge(libspdm_context_t *spdm_con LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "Encap RequesterNonce - ")); LIBSPDM_INTERNAL_DUMP_DATA(spdm_request->nonce, SPDM_NONCE_SIZE); LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "\n")); + if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_13) { + libspdm_copy_mem(spdm_request + 1, SPDM_REQ_CONTEXT_SIZE, + spdm_context->encap_context.req_context, SPDM_REQ_CONTEXT_SIZE); + LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "Encap RequesterContext - ")); + LIBSPDM_INTERNAL_DUMP_DATA((uint8_t *)(spdm_request + 1), SPDM_REQ_CONTEXT_SIZE); + LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "\n")); + } libspdm_reset_message_buffer_via_request_code(spdm_context, NULL, spdm_request->header.request_response_code); @@ -54,7 +67,7 @@ libspdm_return_t libspdm_get_encap_request_challenge(libspdm_context_t *spdm_con /* Cache data*/ status = libspdm_append_message_mut_c(spdm_context, spdm_request, - *encap_request_size); + spdm_request_size); if (LIBSPDM_STATUS_IS_ERROR(status)) { return LIBSPDM_STATUS_BUFFER_FULL; } @@ -62,7 +75,7 @@ libspdm_return_t libspdm_get_encap_request_challenge(libspdm_context_t *spdm_con libspdm_copy_mem(&spdm_context->encap_context.last_encap_request_header, sizeof(spdm_context->encap_context.last_encap_request_header), &spdm_request->header, sizeof(spdm_message_header_t)); - spdm_context->encap_context.last_encap_request_size = *encap_request_size; + spdm_context->encap_context.last_encap_request_size = spdm_request_size; return LIBSPDM_STATUS_SUCCESS; } @@ -106,6 +119,11 @@ libspdm_return_t libspdm_process_encap_response_challenge_auth( if (spdm_response_size < sizeof(spdm_challenge_auth_response_t)) { return LIBSPDM_STATUS_INVALID_MSG_SIZE; } + if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_13) { + if (spdm_response_size < sizeof(spdm_challenge_auth_response_t) + SPDM_REQ_CONTEXT_SIZE) { + return LIBSPDM_STATUS_INVALID_MSG_SIZE; + } + } auth_attribute = spdm_response->header.param1; if (spdm_context->encap_context.req_slot_id == 0xFF) { @@ -182,20 +200,28 @@ libspdm_return_t libspdm_process_encap_response_challenge_auth( } ptr += sizeof(uint16_t); - if (spdm_response_size < - sizeof(spdm_challenge_auth_response_t) + hash_size + - SPDM_NONCE_SIZE + measurement_summary_hash_size + - sizeof(uint16_t) + opaque_length + signature_size) { - return LIBSPDM_STATUS_INVALID_MSG_SIZE; - } - spdm_response_size = sizeof(spdm_challenge_auth_response_t) + - hash_size + SPDM_NONCE_SIZE + - measurement_summary_hash_size + sizeof(uint16_t) + - opaque_length + signature_size; - status = libspdm_append_message_mut_c(spdm_context, spdm_response, - spdm_response_size - signature_size); - if (LIBSPDM_STATUS_IS_ERROR(status)) { - return LIBSPDM_STATUS_BUFFER_FULL; + if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_13) { + if (spdm_response_size < + sizeof(spdm_challenge_auth_response_t) + hash_size + + SPDM_NONCE_SIZE + measurement_summary_hash_size + + sizeof(uint16_t) + opaque_length + SPDM_REQ_CONTEXT_SIZE + signature_size) { + return LIBSPDM_STATUS_INVALID_MSG_SIZE; + } + spdm_response_size = sizeof(spdm_challenge_auth_response_t) + + hash_size + SPDM_NONCE_SIZE + + measurement_summary_hash_size + sizeof(uint16_t) + + opaque_length + SPDM_REQ_CONTEXT_SIZE + signature_size; + } else { + if (spdm_response_size < + sizeof(spdm_challenge_auth_response_t) + hash_size + + SPDM_NONCE_SIZE + measurement_summary_hash_size + + sizeof(uint16_t) + opaque_length + signature_size) { + return LIBSPDM_STATUS_INVALID_MSG_SIZE; + } + spdm_response_size = sizeof(spdm_challenge_auth_response_t) + + hash_size + SPDM_NONCE_SIZE + + measurement_summary_hash_size + sizeof(uint16_t) + + opaque_length + signature_size; } LIBSPDM_DEBUG_CODE( @@ -206,6 +232,23 @@ libspdm_return_t libspdm_process_encap_response_challenge_auth( ); ptr += opaque_length; + if (spdm_response->header.spdm_version >= SPDM_MESSAGE_VERSION_13) { + if (!libspdm_consttime_is_mem_equal(spdm_context->encap_context.req_context, ptr, + SPDM_REQ_CONTEXT_SIZE)) { + return LIBSPDM_STATUS_INVALID_MSG_FIELD; + } + LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "Encap RequesterContext - ")); + LIBSPDM_INTERNAL_DUMP_DATA(ptr, SPDM_REQ_CONTEXT_SIZE); + LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "\n")); + ptr += SPDM_REQ_CONTEXT_SIZE; + } + + status = libspdm_append_message_mut_c(spdm_context, spdm_response, + spdm_response_size - signature_size); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + return LIBSPDM_STATUS_BUFFER_FULL; + } + signature = ptr; LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "Encap signature (0x%x):\n", signature_size)); LIBSPDM_INTERNAL_DUMP_HEX(signature, signature_size);