diff --git a/include/internal/libspdm_common_lib.h b/include/internal/libspdm_common_lib.h index ff550476abd..7c77da5408d 100644 --- a/include/internal/libspdm_common_lib.h +++ b/include/internal/libspdm_common_lib.h @@ -146,48 +146,63 @@ typedef struct { uint8_t buffer[LIBSPDM_MAX_MESSAGE_VCA_BUFFER_SIZE]; } libspdm_vca_managed_buffer_t; +/* + * +--------------------------+------------------------------------------+---------+ + * | DIGESTS 1.3 | 4 + (H [+ 4]) * SlotNum = [36, 548] | [1, 18] | + * +--------------------------+------------------------------------------+---------+ + * It is for multi-key. + */ +#define LIBSPDM_MAX_MESSAGE_D_BUFFER_SIZE (4 + \ + (LIBSPDM_MAX_HASH_SIZE + 4) * SPDM_MAX_SLOT_COUNT) + +typedef struct { + size_t max_buffer_size; + size_t buffer_size; + uint8_t buffer[LIBSPDM_MAX_MESSAGE_D_BUFFER_SIZE]; +} libspdm_message_d_managed_buffer_t; + #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT /* * +--------------------------+------------------------------------------+---------+ - * | GET_DIGESTS 1.2 | 4 | 1 | - * | DIGESTS 1.2 | 4 + H * SlotNum = [36, 516] | [1, 18] | + * | GET_DIGESTS 1.3 | 4 | 1 | + * | DIGESTS 1.3 | 4 + (H [+ 4]) * SlotNum = [36, 548] | [1, 18] | * +--------------------------+------------------------------------------+---------+ - * | GET_CERTIFICATE 1.2 | 8 | 1 | - * | CERTIFICATE 1.2 | 8 + PortionLen | [1, ] | + * | GET_CERTIFICATE 1.3 | 8 | 1 | + * | CERTIFICATE 1.3 | 8 + PortionLen | [1, ] | * +--------------------------+------------------------------------------+---------+ */ #define LIBSPDM_MAX_MESSAGE_B_BUFFER_SIZE (24 + \ - LIBSPDM_MAX_HASH_SIZE * SPDM_MAX_SLOT_COUNT + \ + (LIBSPDM_MAX_HASH_SIZE + 4) * SPDM_MAX_SLOT_COUNT + \ LIBSPDM_MAX_CERT_CHAIN_SIZE) /* * +--------------------------+------------------------------------------+---------+ - * | CHALLENGE 1.2 | 40 | 1 | - * | CHALLENGE_AUTH 1.2 | 38 + H * 2 + S [+ O] = [166, 678] | [6, 23] | + * | CHALLENGE 1.3 | 44 | 1 | + * | CHALLENGE_AUTH 1.3 | 46 + H * 2 + S [+ O] = [166, 678] | [6, 23] | * +--------------------------+------------------------------------------+---------+ */ -#define LIBSPDM_MAX_MESSAGE_C_BUFFER_SIZE (78 + \ +#define LIBSPDM_MAX_MESSAGE_C_BUFFER_SIZE (90 + \ LIBSPDM_MAX_HASH_SIZE * 2 + \ LIBSPDM_MAX_ASYM_KEY_SIZE + SPDM_MAX_OPAQUE_DATA_SIZE) /* * +--------------------------+------------------------------------------+---------+ - * | GET_MEASUREMENTS 1.2 | 5 + Nonce (0 or 32) | 1 | - * | MEASUREMENTS 1.2 | 42 + MeasRecLen (+ S) [+ O] = [106, 554] | [4, 19] | + * | GET_MEASUREMENTS 1.3 | 13 + Nonce (0 or 32) | 1 | + * | MEASUREMENTS 1.3 | 50 + MeasRecLen (+ S) [+ O] = [106, 554] | [4, 19] | * +--------------------------+------------------------------------------+---------+ */ -#define LIBSPDM_MAX_MESSAGE_M_BUFFER_SIZE (47 + SPDM_NONCE_SIZE + \ +#define LIBSPDM_MAX_MESSAGE_M_BUFFER_SIZE (63 + SPDM_NONCE_SIZE + \ LIBSPDM_MAX_MEASUREMENT_RECORD_SIZE + \ LIBSPDM_MAX_ASYM_KEY_SIZE + SPDM_MAX_OPAQUE_DATA_SIZE) /* * +--------------------------+------------------------------------------+---------+ - * | KEY_EXCHANGE 1.2 | 42 + D [+ O] = [106, 554] | [4, 19] | - * | KEY_EXCHANGE_RSP 1.2 | 42 + D + H + S (+ H) [+ O] = [234, 1194] | [8, 40] | + * | KEY_EXCHANGE 1.3 | 42 + D [+ O] = [106, 554] | [4, 19] | + * | KEY_EXCHANGE_RSP 1.3 | 42 + D + H + S (+ H) [+ O] = [234, 1194] | [8, 40] | * +--------------------------+------------------------------------------+---------+ - * | PSK_EXCHANGE 1.2 | 12 [+ PSKHint] + R [+ O] = 44 | 2 | - * | PSK_EXCHANGE_RSP 1.2 | 12 + R + H (+ H) [+ O] = [108, 172] | [4, 6] | + * | PSK_EXCHANGE 1.3 | 12 [+ PSKHint] + R [+ O] = 44 | 2 | + * | PSK_EXCHANGE_RSP 1.3 | 12 + R + H (+ H) [+ O] = [108, 172] | [4, 6] | * +--------------------------+------------------------------------------+---------+ */ #define LIBSPDM_MAX_MESSAGE_K_BUFFER_SIZE (84 + LIBSPDM_MAX_DHE_KEY_SIZE * 2 + \ @@ -196,11 +211,11 @@ typedef struct { /* * +--------------------------+------------------------------------------+---------+ - * | FINISH 1.2 | 4 (+ S) + H = [100, 580] | [4, 20] | - * | FINISH_RSP 1.2 | 4 (+ H) = [36, 69] | [1, 3] | + * | FINISH 1.3 | 4 (+ S) + H = [100, 580] | [4, 20] | + * | FINISH_RSP 1.3 | 4 (+ H) = [36, 69] | [1, 3] | * +--------------------------+------------------------------------------+---------+ - * | PSK_FINISH 1.2 | 4 + H = [36, 68] | [1, 3] | - * | PSK_FINISH_RSP 1.2 | 4 | 1 | + * | PSK_FINISH 1.3 | 4 + H = [36, 68] | [1, 3] | + * | PSK_FINISH_RSP 1.3 | 4 | 1 | * +--------------------------+------------------------------------------+---------+ */ #define LIBSPDM_MAX_MESSAGE_F_BUFFER_SIZE (8 + LIBSPDM_MAX_HASH_SIZE * 2 + \ @@ -215,7 +230,9 @@ typedef struct { #define LIBSPDM_MAX_MESSAGE_TH_BUFFER_SIZE \ (LIBSPDM_MAX_MESSAGE_VCA_BUFFER_SIZE + \ + LIBSPDM_MAX_MESSAGE_D_BUFFER_SIZE + \ LIBSPDM_MAX_CERT_CHAIN_SIZE + LIBSPDM_MAX_MESSAGE_K_BUFFER_SIZE + \ + LIBSPDM_MAX_MESSAGE_D_BUFFER_SIZE + \ LIBSPDM_MAX_CERT_CHAIN_SIZE + LIBSPDM_MAX_MESSAGE_F_BUFFER_SIZE) typedef struct { @@ -295,6 +312,7 @@ typedef struct { typedef struct { /* the message_a must be plan text because we do not know the algorithm yet.*/ libspdm_vca_managed_buffer_t message_a; + libspdm_message_d_managed_buffer_t message_d; #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT libspdm_message_b_managed_buffer_t message_b; libspdm_message_c_managed_buffer_t message_c; @@ -308,34 +326,43 @@ typedef struct { #endif } libspdm_transcript_t; -/* TH for KEY_EXCHANGE response signature: Concatenate (A, Ct, K) +/* TH for KEY_EXCHANGE response signature: Concatenate (A, D, Ct, K) + * D = DIGEST, if MULTI_KEY_CONN_RSP * Ct = certificate chain * K = Concatenate (KEY_EXCHANGE request, KEY_EXCHANGE response\signature+verify_data)*/ -/* TH for KEY_EXCHANGE response HMAC: Concatenate (A, Ct, K) +/* TH for KEY_EXCHANGE response HMAC: Concatenate (A, D, Ct, K) + * D = DIGEST, if MULTI_KEY_CONN_RSP * Ct = certificate chain * K = Concatenate (KEY_EXCHANGE request, KEY_EXCHANGE response\verify_data)*/ -/* TH for FINISH request signature: Concatenate (A, Ct, K, CM, F) +/* TH for FINISH request signature: Concatenate (A, D, Ct, K, EncapD, CM, F) + * D = DIGEST, if MULTI_KEY_CONN_RSP * Ct = certificate chain - * K = Concatenate (KEY_EXCHANGE request, KEY_EXCHANGE response)*/ -/* CM = mutual certificate chain * + * K = Concatenate (KEY_EXCHANGE request, KEY_EXCHANGE response) + * EncapD = Encap DIGEST, if MULTI_KEY_CONN_REQ + * CM = mutual certificate chain * F = Concatenate (FINISH request\signature+verify_data)*/ -/* TH for FINISH response HMAC: Concatenate (A, Ct, K, CM, F) +/* TH for FINISH response HMAC: Concatenate (A, D, Ct, K, EncapD, CM, F) + * D = DIGEST, if MULTI_KEY_CONN_RSP * Ct = certificate chain - * K = Concatenate (KEY_EXCHANGE request, KEY_EXCHANGE response)*/ -/* CM = mutual certificate chain * + * K = Concatenate (KEY_EXCHANGE request, KEY_EXCHANGE response) + * EncapD = Encap DIGEST, if MULTI_KEY_CONN_REQ + * CM = mutual certificate chain, if MutAuth * F = Concatenate (FINISH request\verify_data)*/ -/* th1: Concatenate (A, Ct, K) +/* th1: Concatenate (A, D, Ct, K) + * D = DIGEST, if MULTI_KEY_CONN_RSP * Ct = certificate chain * K = Concatenate (KEY_EXCHANGE request, KEY_EXCHANGE response)*/ -/* th2: Concatenate (A, Ct, K, CM, F) +/* th2: Concatenate (A, D, Ct, K, EncapD, CM, F) + * D = DIGEST, if MULTI_KEY_CONN_RSP * Ct = certificate chain - * K = Concatenate (KEY_EXCHANGE request, KEY_EXCHANGE response)*/ -/* CM = mutual certificate chain * + * K = Concatenate (KEY_EXCHANGE request, KEY_EXCHANGE response) + * EncapD = Encap DIGEST, if MULTI_KEY_CONN_REQ + * CM = mutual certificate chain, if MutAuth * F = Concatenate (FINISH request, FINISH response)*/ /* TH for PSK_EXCHANGE response HMAC: Concatenate (A, K) @@ -357,6 +384,7 @@ typedef struct { * F = Concatenate (PSK_FINISH request, PSK_FINISH response)*/ typedef struct { + libspdm_message_d_managed_buffer_t message_encap_d; #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT libspdm_message_k_managed_buffer_t message_k; libspdm_message_f_managed_buffer_t message_f; @@ -1172,6 +1200,14 @@ void libspdm_append_msg_log(libspdm_context_t *spdm_context, void *message, size **/ void libspdm_reset_message_a(libspdm_context_t *spdm_context); +/** + * Reset message D cache in SPDM context. + * + * @param spdm_context A pointer to the SPDM context. + * @param spdm_session_info A pointer to the SPDM session context. + **/ +void libspdm_reset_message_d(libspdm_context_t *spdm_context); + /** * Reset message B cache in SPDM context. * @@ -1218,6 +1254,14 @@ void libspdm_reset_message_m(libspdm_context_t *spdm_context, void *session_info **/ void libspdm_reset_message_k(libspdm_context_t *spdm_context, void *spdm_session_info); +/** + * Reset message EncapD cache in SPDM context. + * + * @param spdm_context A pointer to the SPDM context. + * @param spdm_session_info A pointer to the SPDM session context. + **/ +void libspdm_reset_message_encap_d(libspdm_context_t *spdm_context, void *spdm_session_info); + /** * Reset message F cache in SPDM context. * @@ -1238,6 +1282,20 @@ void libspdm_reset_message_f(libspdm_context_t *spdm_context, void *spdm_session **/ libspdm_return_t libspdm_append_message_a(libspdm_context_t *spdm_context, const void *message, size_t message_size); + +/** + * Append message D cache in SPDM context. + * + * @param spdm_context A pointer to the SPDM context. + * @param message Message buffer. + * @param message_size Size in bytes of message buffer. + * + * @return RETURN_SUCCESS message is appended. + * @return RETURN_OUT_OF_RESOURCES message is not appended because the internal cache is full. + **/ +libspdm_return_t libspdm_append_message_d(libspdm_context_t *spdm_context, const void *message, + size_t message_size); + /** * Append message B cache in SPDM context. * @@ -1324,6 +1382,23 @@ libspdm_return_t libspdm_append_message_k(libspdm_context_t *spdm_context, bool is_requester, const void *message, size_t message_size); +/** + * Append message EncapD cache in SPDM context. + * + * @param spdm_context A pointer to the SPDM context. + * @param spdm_session_info A pointer to the SPDM session context. + * @param is_requester Indicate of the key generation for a requester or a responder. + * @param message Message buffer. + * @param message_size Size in bytes of message buffer. + * + * @return RETURN_SUCCESS message is appended. + * @return RETURN_OUT_OF_RESOURCES message is not appended because the internal cache is full. + **/ +libspdm_return_t libspdm_append_message_encap_d(libspdm_context_t *spdm_context, + void *spdm_session_info, + bool is_requester, const void *message, + size_t message_size); + /** * Append message F cache in SPDM context. * diff --git a/include/library/spdm_common_lib.h b/include/library/spdm_common_lib.h index 11d1b5b9b9a..3a056f4c42c 100644 --- a/include/library/spdm_common_lib.h +++ b/include/library/spdm_common_lib.h @@ -137,6 +137,9 @@ typedef enum { LIBSPDM_DATA_SEQUENCE_NUMBER_ENDIAN, LIBSPDM_DATA_SESSION_SEQUENCE_NUMBER_ENDIAN, + LIBSPDM_DATA_MULTI_KEY_CONN_REQ, + LIBSPDM_DATA_MULTI_KEY_CONN_RSP, + /* MAX */ LIBSPDM_DATA_MAX } libspdm_data_type_t; @@ -234,16 +237,16 @@ typedef enum { /* * +--------------------------+------------------------------------------+---------+ * | GET_VERSION | 4 | 1 | - * | VERSION {1.0, 1.1, 1.2} | 6 + 2 * 3 = 12 | 1 | + * | VERSION {1.0 ~ 1.3} | 6 + 2 * 4 = 14 | 1 | * +--------------------------+------------------------------------------+---------+ - * | GET_CAPABILITIES 1.2 | 20 | 1 | - * | CAPABILITIES 1.2 | 20 | 1 | + * | GET_CAPABILITIES 1.3 | 20 | 1 | + * | CAPABILITIES 1.3 | 20 [+ 46] | 1 | * +--------------------------+------------------------------------------+---------+ - * | NEGOTIATE_ALGORITHMS 1.2 | 32 + 4 * 4 = 48 | 2 | - * | ALGORITHMS 1.2 | 36 + 4 * 4 = 52 | 2 | + * | NEGOTIATE_ALGORITHMS 1.3 | 32 + 4 * 4 = 48 | 2 | + * | ALGORITHMS 1.3 | 36 + 4 * 4 = 52 | 2 | * +--------------------------+------------------------------------------+---------+ */ -#define LIBSPDM_MAX_MESSAGE_VCA_BUFFER_SIZE (150 + 2 * LIBSPDM_MAX_VERSION_COUNT) +#define LIBSPDM_MAX_MESSAGE_VCA_BUFFER_SIZE (200 + 2 * LIBSPDM_MAX_VERSION_COUNT) /** * Set an SPDM context data. diff --git a/library/spdm_common_lib/libspdm_com_context_data.c b/library/spdm_common_lib/libspdm_com_context_data.c index 00accb8cfae..4b09b54b9e7 100644 --- a/library/spdm_common_lib/libspdm_com_context_data.c +++ b/library/spdm_common_lib/libspdm_com_context_data.c @@ -705,6 +705,25 @@ libspdm_return_t libspdm_set_data(void *spdm_context, libspdm_data_type_t data_t return LIBSPDM_STATUS_INVALID_PARAMETER; } context->sequence_number_endian = *(uint8_t *)data; + break; + case LIBSPDM_DATA_MULTI_KEY_CONN_REQ: + if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) { + return LIBSPDM_STATUS_INVALID_PARAMETER; + } + if (data_size != sizeof(bool)) { + return LIBSPDM_STATUS_INVALID_PARAMETER; + } + context->connection_info.multi_key_conn_req = *(bool *)data; + break; + case LIBSPDM_DATA_MULTI_KEY_CONN_RSP: + if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) { + return LIBSPDM_STATUS_INVALID_PARAMETER; + } + if (data_size != sizeof(bool)) { + return LIBSPDM_STATUS_INVALID_PARAMETER; + } + context->connection_info.multi_key_conn_rsp = *(bool *)data; + break; default: return LIBSPDM_STATUS_UNSUPPORTED_CAP; break; @@ -994,9 +1013,25 @@ libspdm_return_t libspdm_get_data(void *spdm_context, libspdm_data_type_t data_t case LIBSPDM_DATA_SEQUENCE_NUMBER_ENDIAN: target_data_size = sizeof(uint8_t); target_data = &context->sequence_number_endian; + break; case LIBSPDM_DATA_SESSION_SEQUENCE_NUMBER_ENDIAN: target_data_size = sizeof(uint8_t); target_data = &secured_context->sequence_number_endian; + break; + case LIBSPDM_DATA_MULTI_KEY_CONN_REQ: + if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) { + return LIBSPDM_STATUS_INVALID_PARAMETER; + } + target_data_size = sizeof(bool); + target_data = &context->connection_info.multi_key_conn_req; + break; + case LIBSPDM_DATA_MULTI_KEY_CONN_RSP: + if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) { + return LIBSPDM_STATUS_INVALID_PARAMETER; + } + target_data_size = sizeof(bool); + target_data = &context->connection_info.multi_key_conn_rsp; + break; default: return LIBSPDM_STATUS_UNSUPPORTED_CAP; break; @@ -1089,6 +1124,16 @@ void libspdm_reset_message_a(libspdm_context_t *spdm_context) libspdm_reset_managed_buffer(&spdm_context->transcript.message_a); } +/** + * Reset message D cache in SPDM context. + * + * @param spdm_context A pointer to the SPDM context. + **/ +void libspdm_reset_message_d(libspdm_context_t *spdm_context) +{ + libspdm_reset_managed_buffer(&spdm_context->transcript.message_d); +} + /** * Reset message B cache in SPDM context. * @@ -1226,6 +1271,20 @@ void libspdm_reset_message_k(libspdm_context_t *spdm_context, void *session_info #endif } +/** + * Reset message EncapD cache in SPDM context. + * + * @param spdm_context A pointer to the SPDM context. + * @param spdm_session_info A pointer to the SPDM session context. + **/ +void libspdm_reset_message_encap_d(libspdm_context_t *spdm_context, void *session_info) +{ + libspdm_session_info_t *spdm_session_info; + + spdm_session_info = session_info; + libspdm_reset_managed_buffer(&spdm_session_info->session_transcript.message_encap_d); +} + /** * Reset message F cache in SPDM context. * @@ -1327,6 +1386,24 @@ libspdm_return_t libspdm_append_message_a(libspdm_context_t *spdm_context, const message, message_size); } +/** + * Append message D cache in SPDM context. + * + * @param spdm_context A pointer to the SPDM context. + * @param message Message buffer. + * @param message_size Size in bytes of message buffer. + * + * @return RETURN_SUCCESS message is appended. + * @return RETURN_OUT_OF_RESOURCES message is not appended because the internal cache is full. + **/ +libspdm_return_t libspdm_append_message_d(libspdm_context_t *spdm_context, const void *message, + size_t message_size) +{ + libspdm_reset_message_d (spdm_context); + return libspdm_append_managed_buffer(&spdm_context->transcript.message_d, + message, message_size); +} + /** * Append message B cache in SPDM context. * @@ -1836,6 +1913,19 @@ libspdm_return_t libspdm_append_message_k(libspdm_context_t *spdm_context, return LIBSPDM_STATUS_CRYPTO_ERROR; } if (!spdm_session_info->use_psk) { + if (spdm_context->connection_info.multi_key_conn_rsp) { + result = libspdm_hash_update ( + spdm_context->connection_info.algorithm.base_hash_algo, + spdm_session_info->session_transcript.digest_context_th, + libspdm_get_managed_buffer(&spdm_context->transcript.message_d), + libspdm_get_managed_buffer_size(&spdm_context->transcript.message_d)); + if (!result) { + libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo, + spdm_session_info->session_transcript.digest_context_th); + return LIBSPDM_STATUS_CRYPTO_ERROR; + } + } + result = libspdm_hash_update ( spdm_context->connection_info.algorithm.base_hash_algo, spdm_session_info->session_transcript.digest_context_th, @@ -1861,6 +1951,32 @@ libspdm_return_t libspdm_append_message_k(libspdm_context_t *spdm_context, #endif } +/** + * Append message EncapD cache in SPDM context. + * + * @param spdm_context A pointer to the SPDM context. + * @param spdm_session_info A pointer to the SPDM session context. + * @param is_requester Indicate of the key generation for a requester or a responder. + * @param message Message buffer. + * @param message_size Size in bytes of message buffer. + * + * @return RETURN_SUCCESS message is appended. + * @return RETURN_OUT_OF_RESOURCES message is not appended because the internal cache is full. + **/ +libspdm_return_t libspdm_append_message_encap_d(libspdm_context_t *spdm_context, + void *session_info, + bool is_requester, const void *message, + size_t message_size) +{ + libspdm_session_info_t *spdm_session_info; + + spdm_session_info = session_info; + libspdm_reset_message_encap_d(spdm_context, session_info); + return libspdm_append_managed_buffer( + &spdm_session_info->session_transcript.message_encap_d, message, + message_size); +} + /** * Append message F cache in SPDM context. * @@ -1993,6 +2109,22 @@ libspdm_return_t libspdm_append_message_f(libspdm_context_t *spdm_context, LIBSPDM_ASSERT (spdm_session_info->session_transcript.digest_context_th != NULL); if (!spdm_session_info->session_transcript.message_f_initialized) { if (!spdm_session_info->use_psk && spdm_session_info->mut_auth_requested) { + if (spdm_context->connection_info.multi_key_conn_req) { + result = libspdm_hash_update ( + spdm_context->connection_info.algorithm.base_hash_algo, + spdm_session_info->session_transcript.digest_context_th, + libspdm_get_managed_buffer(&spdm_session_info->session_transcript. + message_encap_d), + libspdm_get_managed_buffer_size(&spdm_session_info->session_transcript. + message_encap_d)); + if (!result) { + libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo, + spdm_session_info->session_transcript.digest_context_th); + spdm_session_info->session_transcript.digest_context_th = NULL; + return LIBSPDM_STATUS_CRYPTO_ERROR; + } + } + result = libspdm_hash_update ( spdm_context->connection_info.algorithm.base_hash_algo, spdm_session_info->session_transcript.digest_context_th, @@ -2636,6 +2768,8 @@ libspdm_return_t libspdm_init_context_with_secured_context(void *spdm_context, context->version = LIBSPDM_CONTEXT_STRUCT_VERSION; context->transcript.message_a.max_buffer_size = sizeof(context->transcript.message_a.buffer); + context->transcript.message_d.max_buffer_size = + sizeof(context->transcript.message_d.buffer); #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT context->transcript.message_b.max_buffer_size = sizeof(context->transcript.message_b.buffer); @@ -2669,6 +2803,11 @@ libspdm_return_t libspdm_init_context_with_secured_context(void *spdm_context, context->max_spdm_session_sequence_number = LIBSPDM_MAX_SPDM_SESSION_SEQUENCE_NUMBER; + context->latest_session_id = INVALID_SESSION_ID; + context->last_spdm_request_session_id = INVALID_SESSION_ID; + context->last_spdm_request_session_id_valid = false; + context->last_spdm_request_size = 0; + /* To be updated in libspdm_register_device_buffer_func */ context->local_context.capability.data_transfer_size = 0; context->local_context.capability.sender_data_transfer_size = 0; @@ -2759,6 +2898,7 @@ void libspdm_reset_context(void *spdm_context) #endif context->response_state = LIBSPDM_RESPONSE_STATE_NORMAL; context->current_token = 0; + context->latest_session_id = INVALID_SESSION_ID; context->last_spdm_request_session_id = INVALID_SESSION_ID; context->last_spdm_request_session_id_valid = false; context->last_spdm_request_size = 0; @@ -2812,6 +2952,7 @@ void libspdm_deinit_context(void *spdm_context) #endif libspdm_reset_message_a(context); + libspdm_reset_message_d(context); libspdm_reset_message_b(context); libspdm_reset_message_c(context); libspdm_reset_message_mut_b(context); @@ -2819,6 +2960,7 @@ void libspdm_deinit_context(void *spdm_context) for (session_id = 0; session_id < LIBSPDM_MAX_SESSION_COUNT; session_id++) { session_info = &context->session_info[session_id]; libspdm_reset_message_m(context, session_info); + libspdm_reset_message_encap_d(context, session_info); libspdm_reset_message_k(context, session_info); libspdm_reset_message_f(context, session_info); } diff --git a/library/spdm_common_lib/libspdm_com_context_data_session.c b/library/spdm_common_lib/libspdm_com_context_data_session.c index c5079f8dcfb..22a38c8df06 100644 --- a/library/spdm_common_lib/libspdm_com_context_data_session.c +++ b/library/spdm_common_lib/libspdm_com_context_data_session.c @@ -96,6 +96,8 @@ void libspdm_session_info_init(libspdm_context_t *spdm_context, spdm_context->connection_info.algorithm.dhe_named_group, spdm_context->connection_info.algorithm.aead_cipher_suite, spdm_context->connection_info.algorithm.key_schedule); + session_info->session_transcript.message_encap_d.max_buffer_size = + sizeof(session_info->session_transcript.message_encap_d.buffer); #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT session_info->session_transcript.message_k.max_buffer_size = sizeof(session_info->session_transcript.message_k.buffer); @@ -273,6 +275,10 @@ void libspdm_free_session_id(libspdm_context_t *spdm_context, uint32_t session_i return; } + if (spdm_context->latest_session_id == session_id) { + spdm_context->latest_session_id = INVALID_SESSION_ID; + } + session_info = spdm_context->session_info; for (index = 0; index < LIBSPDM_MAX_SESSION_COUNT; index++) { if (session_info[index].session_id == session_id) { diff --git a/library/spdm_common_lib/libspdm_com_crypto_service_session.c b/library/spdm_common_lib/libspdm_com_crypto_service_session.c index 363f649f90d..afd5365d8fa 100644 --- a/library/spdm_common_lib/libspdm_com_crypto_service_session.c +++ b/library/spdm_common_lib/libspdm_com_crypto_service_session.c @@ -49,6 +49,20 @@ bool libspdm_calculate_th_for_exchange( } if (cert_chain_buffer != NULL) { + if (spdm_context->connection_info.multi_key_conn_rsp) { + LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "message_d data :\n")); + LIBSPDM_INTERNAL_DUMP_HEX( + libspdm_get_managed_buffer(&spdm_context->transcript.message_d), + libspdm_get_managed_buffer_size(&spdm_context->transcript.message_d)); + status = libspdm_append_managed_buffer( + th_curr, + libspdm_get_managed_buffer(&spdm_context->transcript.message_d), + libspdm_get_managed_buffer_size(&spdm_context->transcript.message_d)); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + return false; + } + } + LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "th_message_ct data :\n")); LIBSPDM_INTERNAL_DUMP_HEX(cert_chain_buffer, cert_chain_buffer_size); result = libspdm_hash_all( @@ -236,6 +250,20 @@ bool libspdm_calculate_th_for_finish(libspdm_context_t *spdm_context, } if (cert_chain_buffer != NULL) { + if (spdm_context->connection_info.multi_key_conn_rsp) { + LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "message_d data :\n")); + LIBSPDM_INTERNAL_DUMP_HEX( + libspdm_get_managed_buffer(&spdm_context->transcript.message_d), + libspdm_get_managed_buffer_size(&spdm_context->transcript.message_d)); + status = libspdm_append_managed_buffer( + th_curr, + libspdm_get_managed_buffer(&spdm_context->transcript.message_d), + libspdm_get_managed_buffer_size(&spdm_context->transcript.message_d)); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + return false; + } + } + LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "th_message_ct data :\n")); LIBSPDM_INTERNAL_DUMP_HEX(cert_chain_buffer, cert_chain_buffer_size); result = libspdm_hash_all( @@ -264,6 +292,20 @@ bool libspdm_calculate_th_for_finish(libspdm_context_t *spdm_context, } if (mut_cert_chain_buffer != NULL) { + if (spdm_context->connection_info.multi_key_conn_req) { + LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "message_encap_d data :\n")); + LIBSPDM_INTERNAL_DUMP_HEX( + libspdm_get_managed_buffer(&session_info->session_transcript.message_encap_d), + libspdm_get_managed_buffer_size(&session_info->session_transcript.message_encap_d)); + status = libspdm_append_managed_buffer( + th_curr, + libspdm_get_managed_buffer(&session_info->session_transcript.message_encap_d), + libspdm_get_managed_buffer_size(&session_info->session_transcript.message_encap_d)); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + return false; + } + } + LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "th_message_cm data :\n")); LIBSPDM_INTERNAL_DUMP_HEX(mut_cert_chain_buffer, mut_cert_chain_buffer_size); result = libspdm_hash_all( diff --git a/library/spdm_requester_lib/libspdm_req_encap_digests.c b/library/spdm_requester_lib/libspdm_req_encap_digests.c index c5ac296345b..c1e9c50cd8c 100644 --- a/library/spdm_requester_lib/libspdm_req_encap_digests.c +++ b/library/spdm_requester_lib/libspdm_req_encap_digests.c @@ -27,6 +27,8 @@ libspdm_return_t libspdm_get_encap_response_digest(void *spdm_context, uint8_t slot_count; /*populated solt index*/ uint8_t slot_index; + uint32_t session_id; + libspdm_session_info_t *session_info; context = spdm_context; spdm_request = request; @@ -110,6 +112,28 @@ libspdm_return_t libspdm_get_encap_response_digest(void *spdm_context, response_size, response); } + if (context->last_spdm_request_session_id_valid) { + session_id = context->last_spdm_request_session_id; + } else { + session_id = context->latest_session_id; + } + if (session_id != INVALID_SESSION_ID) { + session_info = libspdm_get_session_info_via_session_id(context, session_id); + } else { + session_info = NULL; + } + if (session_info != NULL) { + if (context->connection_info.multi_key_conn_req) { + status = libspdm_append_message_encap_d(context, session_info, true, + spdm_response, *response_size); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + return libspdm_generate_encap_error_response( + context, SPDM_ERROR_CODE_UNSPECIFIED, 0, + response_size, response); + } + } + } + return LIBSPDM_STATUS_SUCCESS; } diff --git a/library/spdm_requester_lib/libspdm_req_get_digests.c b/library/spdm_requester_lib/libspdm_req_get_digests.c index 5e157267a6e..c8b37387c15 100644 --- a/library/spdm_requester_lib/libspdm_req_get_digests.c +++ b/library/spdm_requester_lib/libspdm_req_get_digests.c @@ -187,6 +187,13 @@ static libspdm_return_t libspdm_try_get_digest(libspdm_context_t *spdm_context, if (LIBSPDM_STATUS_IS_ERROR(status)) { goto receive_done; } + + if (spdm_context->connection_info.multi_key_conn_rsp) { + status = libspdm_append_message_d(spdm_context, spdm_response, spdm_response_size); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + goto receive_done; + } + } } for (index = 0; index < digest_count; index++) { diff --git a/library/spdm_responder_lib/libspdm_rsp_digests.c b/library/spdm_responder_lib/libspdm_rsp_digests.c index baf0bc4c7fe..eb086bb9c5e 100644 --- a/library/spdm_responder_lib/libspdm_rsp_digests.c +++ b/library/spdm_responder_lib/libspdm_rsp_digests.c @@ -150,6 +150,15 @@ libspdm_return_t libspdm_get_response_digests(libspdm_context_t *spdm_context, s SPDM_ERROR_CODE_UNSPECIFIED, 0, response_size, response); } + + if (spdm_context->connection_info.multi_key_conn_rsp) { + status = libspdm_append_message_d(spdm_context, spdm_response, *response_size); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + return libspdm_generate_error_response(spdm_context, + SPDM_ERROR_CODE_UNSPECIFIED, 0, + response_size, response); + } + } } if (spdm_context->connection_info.connection_state < diff --git a/library/spdm_responder_lib/libspdm_rsp_encap_get_digests.c b/library/spdm_responder_lib/libspdm_rsp_encap_get_digests.c index dfb6aef0e6d..8a6fc207e12 100644 --- a/library/spdm_responder_lib/libspdm_rsp_encap_get_digests.c +++ b/library/spdm_responder_lib/libspdm_rsp_encap_get_digests.c @@ -69,6 +69,8 @@ libspdm_return_t libspdm_process_encap_response_digest( size_t digest_count; size_t index; libspdm_return_t status; + uint32_t session_id; + libspdm_session_info_t *session_info; spdm_response = encap_response; spdm_response_size = encap_response_size; @@ -120,6 +122,26 @@ libspdm_return_t libspdm_process_encap_response_digest( return LIBSPDM_STATUS_BUFFER_FULL; } + if (spdm_context->last_spdm_request_session_id_valid) { + session_id = spdm_context->last_spdm_request_session_id; + } else { + session_id = spdm_context->latest_session_id; + } + if (session_id != INVALID_SESSION_ID) { + session_info = libspdm_get_session_info_via_session_id(spdm_context, session_id); + } else { + session_info = NULL; + } + if (session_info != NULL) { + if (spdm_context->connection_info.multi_key_conn_req) { + status = libspdm_append_message_encap_d(spdm_context, session_info, false, + spdm_response, spdm_response_size); + if (LIBSPDM_STATUS_IS_ERROR(status)) { + return LIBSPDM_STATUS_BUFFER_FULL; + } + } + } + for (index = 0; index < digest_count; index++) { LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "digest (0x%x) - ", index)); LIBSPDM_INTERNAL_DUMP_DATA(