LCOV - code coverage report
Current view: top level - library/spdm_requester_lib - libspdm_req_key_exchange.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 79.5 % 396 315
Test Date: 2025-06-29 08:09:00 Functions: 100.0 % 5 5

            Line data    Source code
       1              : /**
       2              :  *  Copyright Notice:
       3              :  *  Copyright 2021-2025 DMTF. All rights reserved.
       4              :  *  License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/libspdm/blob/main/LICENSE.md
       5              :  **/
       6              : 
       7              : #include "internal/libspdm_requester_lib.h"
       8              : #include "internal/libspdm_secured_message_lib.h"
       9              : 
      10              : #if LIBSPDM_ENABLE_CAPABILITY_KEY_EX_CAP
      11              : 
      12              : #pragma pack(1)
      13              : typedef struct {
      14              :     spdm_message_header_t header;
      15              :     uint16_t req_session_id;
      16              :     uint8_t session_policy;
      17              :     uint8_t reserved;
      18              :     uint8_t random_data[SPDM_RANDOM_DATA_SIZE];
      19              :     uint8_t exchange_data[LIBSPDM_MAX_DHE_KEY_SIZE];
      20              :     uint16_t opaque_length;
      21              :     uint8_t opaque_data[SPDM_MAX_OPAQUE_DATA_SIZE];
      22              : } libspdm_key_exchange_request_mine_t;
      23              : 
      24              : typedef struct {
      25              :     spdm_message_header_t header;
      26              :     uint16_t rsp_session_id;
      27              :     uint8_t mut_auth_requested;
      28              :     uint8_t req_slot_id_param;
      29              :     uint8_t random_data[SPDM_RANDOM_DATA_SIZE];
      30              :     uint8_t exchange_data[LIBSPDM_MAX_DHE_KEY_SIZE];
      31              :     uint8_t measurement_summary_hash[LIBSPDM_MAX_HASH_SIZE];
      32              :     uint16_t opaque_length;
      33              :     uint8_t opaque_data[SPDM_MAX_OPAQUE_DATA_SIZE];
      34              :     uint8_t signature[LIBSPDM_MAX_ASYM_KEY_SIZE];
      35              :     uint8_t verify_data[LIBSPDM_MAX_HASH_SIZE];
      36              : } libspdm_key_exchange_response_max_t;
      37              : #pragma pack()
      38              : 
      39           19 : bool libspdm_verify_key_exchange_rsp_hmac(libspdm_context_t *spdm_context,
      40              :                                           libspdm_session_info_t *session_info,
      41              :                                           const void *hmac_data,
      42              :                                           size_t hmac_data_size)
      43              : {
      44              :     size_t hash_size;
      45              :     uint8_t calc_hmac_data[LIBSPDM_MAX_HASH_SIZE];
      46              :     bool result;
      47              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
      48              :     uint8_t slot_id;
      49              :     uint8_t *cert_chain_buffer;
      50              :     size_t cert_chain_buffer_size;
      51              :     uint8_t *th_curr_data;
      52              :     size_t th_curr_data_size;
      53              :     libspdm_th_managed_buffer_t th_curr;
      54              :     uint8_t hash_data[LIBSPDM_MAX_HASH_SIZE];
      55              : #endif
      56              : 
      57           19 :     hash_size = libspdm_get_hash_size(spdm_context->connection_info.algorithm.base_hash_algo);
      58           19 :     LIBSPDM_ASSERT(hash_size == hmac_data_size);
      59              : 
      60              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
      61              :     slot_id = spdm_context->connection_info.peer_used_cert_chain_slot_id;
      62              :     LIBSPDM_ASSERT((slot_id < SPDM_MAX_SLOT_COUNT) || (slot_id == 0xFF));
      63              :     if (slot_id == 0xFF) {
      64              :         result = libspdm_get_peer_public_key_buffer(
      65              :             spdm_context, (const void **)&cert_chain_buffer, &cert_chain_buffer_size);
      66              :     } else {
      67              :         result = libspdm_get_peer_cert_chain_buffer(
      68              :             spdm_context, (const void **)&cert_chain_buffer, &cert_chain_buffer_size);
      69              :     }
      70              :     if (!result) {
      71              :         return false;
      72              :     }
      73              : 
      74              :     result = libspdm_calculate_th_for_exchange(
      75              :         spdm_context, session_info, cert_chain_buffer,
      76              :         cert_chain_buffer_size, &th_curr);
      77              :     if (!result) {
      78              :         return false;
      79              :     }
      80              :     th_curr_data = libspdm_get_managed_buffer(&th_curr);
      81              :     th_curr_data_size = libspdm_get_managed_buffer_size(&th_curr);
      82              : 
      83              :     result = libspdm_hash_all (spdm_context->connection_info.algorithm.base_hash_algo,
      84              :                                th_curr_data, th_curr_data_size, hash_data);
      85              :     if (!result) {
      86              :         return false;
      87              :     }
      88              : 
      89              :     result = libspdm_hmac_all_with_response_finished_key(
      90              :         session_info->secured_message_context, hash_data,
      91              :         hash_size, calc_hmac_data);
      92              :     if (!result) {
      93              :         return false;
      94              :     }
      95              : #else
      96           19 :     result = libspdm_calculate_th_hmac_for_exchange_rsp(
      97              :         spdm_context, session_info, true, &hash_size, calc_hmac_data);
      98           19 :     if (!result) {
      99            0 :         return false;
     100              :     }
     101              : #endif
     102           19 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "th_curr hmac - "));
     103           19 :     LIBSPDM_INTERNAL_DUMP_DATA(calc_hmac_data, hash_size);
     104           19 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "\n"));
     105              : 
     106           19 :     if (!libspdm_consttime_is_mem_equal(calc_hmac_data, hmac_data, hash_size)) {
     107            0 :         LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR, "!!! verify_key_exchange_hmac - FAIL !!!\n"));
     108            0 :         return false;
     109              :     }
     110           19 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "!!! verify_key_exchange_hmac - PASS !!!\n"));
     111              : 
     112           19 :     return true;
     113              : }
     114              : 
     115           22 : bool libspdm_verify_key_exchange_rsp_signature(
     116              :     libspdm_context_t *spdm_context, libspdm_session_info_t *session_info,
     117              :     const void *sign_data, const size_t sign_data_size)
     118              : {
     119              :     bool result;
     120              :     void *context;
     121              :     uint8_t slot_id;
     122              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
     123              :     uint8_t *cert_chain_buffer;
     124              :     size_t cert_chain_buffer_size;
     125              :     uint8_t *th_curr_data;
     126              :     size_t th_curr_data_size;
     127              :     libspdm_th_managed_buffer_t th_curr;
     128              :     const uint8_t *cert_chain_data;
     129              :     size_t cert_chain_data_size;
     130              :     const uint8_t *cert_buffer;
     131              :     size_t cert_buffer_size;
     132              : #endif
     133              : #if !(LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT) || (LIBSPDM_DEBUG_PRINT_ENABLE)
     134              :     size_t hash_size;
     135              :     uint8_t hash_data[LIBSPDM_MAX_HASH_SIZE];
     136              : 
     137           22 :     hash_size = libspdm_get_hash_size(spdm_context->connection_info.algorithm.base_hash_algo);
     138              : #endif
     139              : 
     140           22 :     slot_id = spdm_context->connection_info.peer_used_cert_chain_slot_id;
     141           22 :     LIBSPDM_ASSERT((slot_id < SPDM_MAX_SLOT_COUNT) || (slot_id == 0xFF));
     142              : 
     143              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
     144              :     if (slot_id == 0xFF) {
     145              :         result = libspdm_get_peer_public_key_buffer(
     146              :             spdm_context, (const void **)&cert_chain_buffer, &cert_chain_buffer_size);
     147              :     } else {
     148              :         result = libspdm_get_peer_cert_chain_buffer(
     149              :             spdm_context, (const void **)&cert_chain_buffer, &cert_chain_buffer_size);
     150              :     }
     151              :     if (!result) {
     152              :         return false;
     153              :     }
     154              : 
     155              :     result = libspdm_calculate_th_for_exchange(
     156              :         spdm_context, session_info, cert_chain_buffer,
     157              :         cert_chain_buffer_size, &th_curr);
     158              :     if (!result) {
     159              :         return false;
     160              :     }
     161              :     th_curr_data = libspdm_get_managed_buffer(&th_curr);
     162              :     th_curr_data_size = libspdm_get_managed_buffer_size(&th_curr);
     163              : 
     164              :     /* Debug code only - required for debug print of th_curr hash below*/
     165              :     LIBSPDM_DEBUG_CODE(
     166              :         if (!libspdm_hash_all(
     167              :                 spdm_context->connection_info.algorithm.base_hash_algo,
     168              :                 th_curr_data, th_curr_data_size, hash_data)) {
     169              :         return false;
     170              :     }
     171              :         );
     172              : #else
     173           22 :     result = libspdm_calculate_th_hash_for_exchange(
     174              :         spdm_context, session_info, &hash_size, hash_data);
     175           22 :     if (!result) {
     176            0 :         return false;
     177              :     }
     178              : #endif
     179           22 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "th_curr hash - "));
     180           22 :     LIBSPDM_INTERNAL_DUMP_DATA(hash_data, hash_size);
     181           22 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "\n"));
     182              : 
     183           22 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "signature - "));
     184           22 :     LIBSPDM_INTERNAL_DUMP_DATA(sign_data, sign_data_size);
     185           22 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "\n"));
     186              : 
     187           22 :     if (slot_id == 0xFF) {
     188            1 :         result = libspdm_asym_get_public_key_from_der(
     189              :             spdm_context->connection_info.algorithm.base_asym_algo,
     190            1 :             spdm_context->local_context.peer_public_key_provision,
     191              :             spdm_context->local_context.peer_public_key_provision_size,
     192              :             &context);
     193            1 :         if (!result) {
     194            0 :             return false;
     195              :         }
     196              :     } else {
     197              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
     198              :         /* Get leaf cert from cert chain*/
     199              :         result = libspdm_get_peer_cert_chain_data(
     200              :             spdm_context, (const void **)&cert_chain_data, &cert_chain_data_size);
     201              :         if (!result) {
     202              :             return false;
     203              :         }
     204              :         result = libspdm_x509_get_cert_from_cert_chain(
     205              :             cert_chain_data, cert_chain_data_size, -1, &cert_buffer, &cert_buffer_size);
     206              :         if (!result) {
     207              :             return false;
     208              :         }
     209              : 
     210              :         result = libspdm_asym_get_public_key_from_x509(
     211              :             spdm_context->connection_info.algorithm.base_asym_algo,
     212              :             cert_buffer, cert_buffer_size, &context);
     213              :         if (!result) {
     214              :             return false;
     215              :         }
     216              : #else
     217           21 :         context = spdm_context->connection_info.peer_used_cert_chain[slot_id].leaf_cert_public_key;
     218           21 :         LIBSPDM_ASSERT(context != NULL);
     219              : #endif
     220              :     }
     221              : 
     222              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
     223              :     result = libspdm_asym_verify_ex(
     224              :         spdm_context->connection_info.version, SPDM_KEY_EXCHANGE_RSP,
     225              :         spdm_context->connection_info.algorithm.base_asym_algo,
     226              :         spdm_context->connection_info.algorithm.base_hash_algo,
     227              :         context, th_curr_data, th_curr_data_size, sign_data, sign_data_size,
     228              :         &spdm_context->spdm_10_11_verify_signature_endian);
     229              :     libspdm_asym_free(spdm_context->connection_info.algorithm.base_asym_algo, context);
     230              : #else
     231           22 :     result = libspdm_asym_verify_hash_ex(
     232           22 :         spdm_context->connection_info.version, SPDM_KEY_EXCHANGE_RSP,
     233              :         spdm_context->connection_info.algorithm.base_asym_algo,
     234              :         spdm_context->connection_info.algorithm.base_hash_algo,
     235              :         context, hash_data, hash_size, sign_data, sign_data_size,
     236              :         &spdm_context->spdm_10_11_verify_signature_endian);
     237           22 :     if (slot_id == 0xFF) {
     238            1 :         libspdm_asym_free(spdm_context->connection_info.algorithm.base_asym_algo, context);
     239              :     }
     240              : #endif
     241           22 :     if (!result) {
     242            2 :         LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR, "!!! verify_key_exchange_signature - FAIL !!!\n"));
     243            2 :         return false;
     244              :     }
     245           20 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "!!! verify_key_exchange_signature - PASS !!!\n"));
     246              : 
     247           20 :     return true;
     248              : }
     249              : 
     250              : /**
     251              :  * This function sends KEY_EXCHANGE and receives KEY_EXCHANGE_RSP for SPDM key exchange.
     252              :  *
     253              :  * @param  spdm_context           A pointer to the SPDM context.
     254              :  * @param  measurement_hash_type  Measurement_hash_type to the KEY_EXCHANGE request.
     255              :  * @param  slot_id                slot_id to the KEY_EXCHANGE request.
     256              :  * @param  session_policy         The policy for the session.
     257              :  * @param  session_id             session_id from the KEY_EXCHANGE_RSP response.
     258              :  * @param  heartbeat_period       Heartbeat_period from the KEY_EXCHANGE_RSP response.
     259              :  * @param  req_slot_id_param      req_slot_id_param from the KEY_EXCHANGE_RSP response.
     260              :  * @param  measurement_hash       Measurement_hash from the KEY_EXCHANGE_RSP response.
     261              :  * @param  requester_nonce_in     If not NULL, a buffer that holds the requester nonce (32 bytes)
     262              :  * @param  requester_nonce        If not NULL, a buffer to hold the requester nonce (32 bytes).
     263              :  * @param  responder_nonce        If not NULL, a buffer to hold the responder nonce (32 bytes).
     264              :  **/
     265           95 : static libspdm_return_t libspdm_try_send_receive_key_exchange(
     266              :     libspdm_context_t *spdm_context, uint8_t measurement_hash_type,
     267              :     uint8_t slot_id, uint8_t session_policy, uint32_t *session_id,
     268              :     uint8_t *heartbeat_period,
     269              :     uint8_t *req_slot_id_param, void *measurement_hash,
     270              :     const void *requester_random_in,
     271              :     void *requester_random, void *responder_random,
     272              :     const void *requester_opaque_data, size_t requester_opaque_data_size,
     273              :     void *responder_opaque_data, size_t *responder_opaque_data_size)
     274              : {
     275              :     bool result;
     276              :     libspdm_return_t status;
     277              :     libspdm_key_exchange_request_mine_t *spdm_request;
     278              :     size_t spdm_request_size;
     279              :     libspdm_key_exchange_response_max_t *spdm_response;
     280              :     size_t spdm_response_size;
     281              :     size_t dhe_key_size;
     282              :     uint32_t measurement_summary_hash_size;
     283              :     uint32_t signature_size;
     284              :     uint32_t hmac_size;
     285              :     uint8_t *ptr;
     286              :     void *measurement_summary_hash;
     287              :     uint16_t opaque_length;
     288              :     uint8_t *signature;
     289              :     uint8_t *verify_data;
     290              :     void *dhe_context;
     291              :     uint16_t req_session_id;
     292              :     uint16_t rsp_session_id;
     293              :     libspdm_session_info_t *session_info;
     294              :     size_t opaque_key_exchange_req_size;
     295              :     uint8_t th1_hash_data[LIBSPDM_MAX_HASH_SIZE];
     296              :     uint8_t *message;
     297              :     size_t message_size;
     298              :     size_t transport_header_size;
     299              :     uint8_t mut_auth_requested;
     300              : 
     301              :     /* -=[Check Parameters Phase]=- */
     302           95 :     LIBSPDM_ASSERT((slot_id < SPDM_MAX_SLOT_COUNT) || (slot_id == 0xff));
     303           95 :     LIBSPDM_ASSERT((slot_id != 0xff) ||
     304              :                    (spdm_context->local_context.peer_public_key_provision_size != 0));
     305           95 :     LIBSPDM_ASSERT(measurement_hash_type == SPDM_KEY_EXCHANGE_REQUEST_NO_MEASUREMENT_SUMMARY_HASH ||
     306              :                    measurement_hash_type == SPDM_KEY_EXCHANGE_REQUEST_TCB_COMPONENT_MEASUREMENT_HASH ||
     307              :                    measurement_hash_type == SPDM_KEY_EXCHANGE_REQUEST_ALL_MEASUREMENTS_HASH);
     308           95 :     LIBSPDM_ASSERT((libspdm_get_connection_version(spdm_context) < SPDM_MESSAGE_VERSION_13) ||
     309              :                    ((session_policy & SPDM_KEY_EXCHANGE_REQUEST_SESSION_POLICY_EVENT_ALL_POLICY)
     310              :                     == 0) ||
     311              :                    libspdm_is_capabilities_flag_supported(
     312              :                        spdm_context, true, 0, SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_EVENT_CAP));
     313              : 
     314              :     /* -=[Verify State Phase]=- */
     315           95 :     if (libspdm_get_connection_version(spdm_context) < SPDM_MESSAGE_VERSION_11) {
     316            0 :         return LIBSPDM_STATUS_UNSUPPORTED_CAP;
     317              :     }
     318              : 
     319           95 :     if (!libspdm_is_capabilities_flag_supported(
     320              :             spdm_context, true,
     321              :             SPDM_GET_CAPABILITIES_REQUEST_FLAGS_KEY_EX_CAP,
     322              :             SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_KEY_EX_CAP)) {
     323            1 :         return LIBSPDM_STATUS_UNSUPPORTED_CAP;
     324              :     }
     325              : 
     326              :     /* While clearing MAC_CAP and setting ENCRYPT_CAP is legal according to DSP0274, libspdm
     327              :      * also implements DSP0277 secure messages, which requires at least MAC_CAP to be set.
     328              :      */
     329           94 :     if (!libspdm_is_capabilities_flag_supported(
     330              :             spdm_context, true,
     331              :             SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MAC_CAP,
     332              :             SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MAC_CAP)) {
     333            0 :         return LIBSPDM_STATUS_UNSUPPORTED_CAP;
     334              :     }
     335              : 
     336           94 :     if (spdm_context->connection_info.connection_state < LIBSPDM_CONNECTION_STATE_NEGOTIATED) {
     337            2 :         return LIBSPDM_STATUS_INVALID_STATE_LOCAL;
     338              :     }
     339              : 
     340           92 :     if (libspdm_get_connection_version(spdm_context) >= SPDM_MESSAGE_VERSION_12) {
     341            3 :         if ((spdm_context->connection_info.algorithm.other_params_support &
     342              :              SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_MASK) != SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_1) {
     343            0 :             return LIBSPDM_STATUS_INVALID_STATE_PEER;
     344              :         }
     345              :     }
     346              : 
     347           92 :     req_session_id = libspdm_allocate_req_session_id(spdm_context, false);
     348           92 :     if (req_session_id == (INVALID_SESSION_ID & 0xFFFF)) {
     349            0 :         return LIBSPDM_STATUS_SESSION_NUMBER_EXCEED;
     350              :     }
     351              : 
     352           92 :     libspdm_reset_message_buffer_via_request_code(spdm_context, NULL, SPDM_KEY_EXCHANGE);
     353              : 
     354              :     /* -=[Construct Request Phase]=- */
     355           92 :     spdm_context->connection_info.peer_used_cert_chain_slot_id = slot_id;
     356           92 :     transport_header_size = spdm_context->local_context.capability.transport_header_size;
     357           92 :     status = libspdm_acquire_sender_buffer (spdm_context, &message_size, (void **)&message);
     358           92 :     if (LIBSPDM_STATUS_IS_ERROR(status)) {
     359            1 :         return status;
     360              :     }
     361           91 :     LIBSPDM_ASSERT (message_size >= transport_header_size +
     362              :                     spdm_context->local_context.capability.transport_tail_size);
     363           91 :     spdm_request = (void *)(message + transport_header_size);
     364           91 :     spdm_request_size = message_size - transport_header_size -
     365           91 :                         spdm_context->local_context.capability.transport_tail_size;
     366              : 
     367           91 :     LIBSPDM_ASSERT (spdm_request_size >= sizeof(spdm_key_exchange_request_t));
     368           91 :     spdm_request->header.spdm_version = libspdm_get_connection_version (spdm_context);
     369           91 :     spdm_request->header.request_response_code = SPDM_KEY_EXCHANGE;
     370           91 :     spdm_request->header.param1 = measurement_hash_type;
     371           91 :     spdm_request->header.param2 = slot_id;
     372           91 :     if (requester_random_in == NULL) {
     373           90 :         if(!libspdm_get_random_number(SPDM_RANDOM_DATA_SIZE, spdm_request->random_data)) {
     374            0 :             libspdm_release_sender_buffer (spdm_context);
     375            0 :             return LIBSPDM_STATUS_LOW_ENTROPY;
     376              :         }
     377              :     } else {
     378            1 :         libspdm_copy_mem(spdm_request->random_data, sizeof(spdm_request->random_data),
     379              :                          requester_random_in, SPDM_RANDOM_DATA_SIZE);
     380              :     }
     381           91 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "RequesterRandomData (0x%x) - ",
     382              :                    SPDM_RANDOM_DATA_SIZE));
     383           91 :     LIBSPDM_INTERNAL_DUMP_DATA(spdm_request->random_data, SPDM_RANDOM_DATA_SIZE);
     384           91 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "\n"));
     385           91 :     if (requester_random != NULL) {
     386            1 :         libspdm_copy_mem(requester_random, SPDM_RANDOM_DATA_SIZE,
     387            1 :                          spdm_request->random_data, SPDM_RANDOM_DATA_SIZE);
     388              :     }
     389              : 
     390           91 :     spdm_request->req_session_id = req_session_id;
     391           91 :     if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_12) {
     392            3 :         spdm_request->session_policy = session_policy;
     393              :     } else {
     394           88 :         spdm_request->session_policy = 0;
     395              :     }
     396           91 :     spdm_request->reserved = 0;
     397              : 
     398           91 :     ptr = spdm_request->exchange_data;
     399          182 :     dhe_key_size = libspdm_get_dhe_pub_key_size(
     400           91 :         spdm_context->connection_info.algorithm.dhe_named_group);
     401           91 :     dhe_context = libspdm_secured_message_dhe_new(
     402           91 :         spdm_context->connection_info.version,
     403           91 :         spdm_context->connection_info.algorithm.dhe_named_group, true);
     404           91 :     if (dhe_context == NULL) {
     405            0 :         libspdm_release_sender_buffer (spdm_context);
     406            0 :         return LIBSPDM_STATUS_CRYPTO_ERROR;
     407              :     }
     408              : 
     409           91 :     LIBSPDM_ASSERT (spdm_request_size >= sizeof(spdm_key_exchange_request_t) + dhe_key_size);
     410           91 :     result = libspdm_secured_message_dhe_generate_key(
     411           91 :         spdm_context->connection_info.algorithm.dhe_named_group,
     412              :         dhe_context, ptr, &dhe_key_size);
     413           91 :     if (!result) {
     414            0 :         libspdm_secured_message_dhe_free(
     415            0 :             spdm_context->connection_info.algorithm.dhe_named_group, dhe_context);
     416            0 :         libspdm_release_sender_buffer (spdm_context);
     417            0 :         return LIBSPDM_STATUS_CRYPTO_ERROR;
     418              :     }
     419           91 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "RequesterKey (0x%zx):\n", dhe_key_size));
     420           91 :     LIBSPDM_INTERNAL_DUMP_HEX(ptr, dhe_key_size);
     421           91 :     ptr += dhe_key_size;
     422              : 
     423           91 :     if (requester_opaque_data != NULL) {
     424            1 :         LIBSPDM_ASSERT(requester_opaque_data_size <= SPDM_MAX_OPAQUE_DATA_SIZE);
     425              : 
     426            1 :         LIBSPDM_ASSERT (spdm_request_size >= sizeof(spdm_key_exchange_request_t) + dhe_key_size +
     427              :                         sizeof(uint16_t) + requester_opaque_data_size);
     428              : 
     429            1 :         libspdm_write_uint16(ptr, (uint16_t)requester_opaque_data_size);
     430            1 :         ptr += sizeof(uint16_t);
     431              : 
     432            1 :         libspdm_copy_mem(ptr,
     433            1 :                          (spdm_request_size - (sizeof(spdm_key_exchange_request_t) + dhe_key_size)),
     434              :                          requester_opaque_data, requester_opaque_data_size);
     435            1 :         opaque_key_exchange_req_size = requester_opaque_data_size;
     436              :     } else {
     437           90 :         opaque_key_exchange_req_size =
     438           90 :             libspdm_get_opaque_data_supported_version_data_size(spdm_context);
     439           90 :         LIBSPDM_ASSERT (spdm_request_size >= sizeof(spdm_key_exchange_request_t) + dhe_key_size +
     440              :                         sizeof(uint16_t) + opaque_key_exchange_req_size);
     441              : 
     442           90 :         libspdm_write_uint16(ptr, (uint16_t)opaque_key_exchange_req_size);
     443           90 :         ptr += sizeof(uint16_t);
     444              : 
     445           90 :         libspdm_build_opaque_data_supported_version_data(
     446              :             spdm_context, &opaque_key_exchange_req_size, ptr);
     447              :     }
     448           91 :     ptr += opaque_key_exchange_req_size;
     449              : 
     450           91 :     spdm_request_size = (size_t)ptr - (size_t)spdm_request;
     451              : 
     452              :     /* -=[Send Request Phase]=- */
     453           91 :     status = libspdm_send_spdm_request(spdm_context, NULL, spdm_request_size, spdm_request);
     454           91 :     if (LIBSPDM_STATUS_IS_ERROR(status)) {
     455            2 :         libspdm_secured_message_dhe_free(
     456            2 :             spdm_context->connection_info.algorithm.dhe_named_group, dhe_context);
     457            2 :         libspdm_release_sender_buffer (spdm_context);
     458            2 :         return status;
     459              :     }
     460           89 :     libspdm_release_sender_buffer (spdm_context);
     461           89 :     spdm_request = (void *)spdm_context->last_spdm_request;
     462              : 
     463              :     /* -=[Receive Response Phase]=- */
     464           89 :     status = libspdm_acquire_receiver_buffer (spdm_context, &message_size, (void **)&message);
     465           89 :     if (LIBSPDM_STATUS_IS_ERROR(status)) {
     466            1 :         libspdm_secured_message_dhe_free(
     467            1 :             spdm_context->connection_info.algorithm.dhe_named_group, dhe_context);
     468            1 :         return status;
     469              :     }
     470           88 :     LIBSPDM_ASSERT (message_size >= transport_header_size);
     471           88 :     spdm_response = (void *)(message);
     472           88 :     spdm_response_size = message_size;
     473              : 
     474           88 :     status = libspdm_receive_spdm_response(
     475              :         spdm_context, NULL, &spdm_response_size, (void **)&spdm_response);
     476           88 :     if (LIBSPDM_STATUS_IS_ERROR(status)) {
     477            0 :         libspdm_secured_message_dhe_free(
     478            0 :             spdm_context->connection_info.algorithm.dhe_named_group, dhe_context);
     479            0 :         goto receive_done;
     480              :     }
     481              : 
     482              :     /* -=[Validate Response Phase]=- */
     483           88 :     if (spdm_response_size < sizeof(spdm_message_header_t)) {
     484            0 :         libspdm_secured_message_dhe_free(
     485            0 :             spdm_context->connection_info.algorithm.dhe_named_group, dhe_context);
     486            0 :         status = LIBSPDM_STATUS_INVALID_MSG_SIZE;
     487            0 :         goto receive_done;
     488              :     }
     489           88 :     if (spdm_response->header.spdm_version != spdm_request->header.spdm_version) {
     490            1 :         libspdm_secured_message_dhe_free(
     491            1 :             spdm_context->connection_info.algorithm.dhe_named_group, dhe_context);
     492            1 :         status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
     493            1 :         goto receive_done;
     494              :     }
     495           87 :     if (spdm_response->header.request_response_code == SPDM_ERROR) {
     496           46 :         status = libspdm_handle_error_response_main(
     497              :             spdm_context, NULL, &spdm_response_size,
     498              :             (void **)&spdm_response, SPDM_KEY_EXCHANGE,
     499              :             SPDM_KEY_EXCHANGE_RSP);
     500           46 :         if (LIBSPDM_STATUS_IS_ERROR(status)) {
     501           45 :             libspdm_secured_message_dhe_free(
     502           45 :                 spdm_context->connection_info.algorithm.dhe_named_group, dhe_context);
     503           45 :             goto receive_done;
     504              :         }
     505           41 :     } else if (spdm_response->header.request_response_code != SPDM_KEY_EXCHANGE_RSP) {
     506            1 :         libspdm_secured_message_dhe_free(
     507            1 :             spdm_context->connection_info.algorithm.dhe_named_group, dhe_context);
     508            1 :         status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
     509            1 :         goto receive_done;
     510              :     }
     511           41 :     if (spdm_response_size < sizeof(spdm_key_exchange_response_t)) {
     512            0 :         libspdm_secured_message_dhe_free(
     513            0 :             spdm_context->connection_info.algorithm.dhe_named_group, dhe_context);
     514            0 :         status = LIBSPDM_STATUS_INVALID_MSG_SIZE;
     515            0 :         goto receive_done;
     516              :     }
     517              : 
     518           41 :     if (!libspdm_is_capabilities_flag_supported(
     519              :             spdm_context, true,
     520              :             SPDM_GET_CAPABILITIES_REQUEST_FLAGS_HBEAT_CAP,
     521              :             SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_HBEAT_CAP)) {
     522           39 :         if (spdm_response->header.param1 != 0) {
     523            2 :             libspdm_secured_message_dhe_free(
     524            2 :                 spdm_context->connection_info.algorithm.dhe_named_group, dhe_context);
     525            2 :             status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
     526            2 :             goto receive_done;
     527              :         }
     528              :     }
     529           39 :     if (heartbeat_period != NULL) {
     530           35 :         *heartbeat_period = spdm_response->header.param1;
     531              :     }
     532              : 
     533           39 :     *req_slot_id_param = spdm_response->req_slot_id_param & 0xf;
     534           39 :     mut_auth_requested = spdm_response->mut_auth_requested & 0x7;
     535              : 
     536           39 :     if (mut_auth_requested != 0) {
     537           13 :         const bool mut_auth_cap_both = libspdm_is_capabilities_flag_supported(
     538              :             spdm_context, true,
     539              :             SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MUT_AUTH_CAP,
     540              :             SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MUT_AUTH_CAP);
     541           13 :         const bool cert_cap = libspdm_is_capabilities_flag_supported(
     542              :             spdm_context, true,
     543              :             SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CERT_CAP,
     544              :             0);
     545           13 :         const bool pub_key_id_cap = libspdm_is_capabilities_flag_supported(
     546              :             spdm_context, true,
     547              :             SPDM_GET_CAPABILITIES_REQUEST_FLAGS_PUB_KEY_ID_CAP,
     548              :             0);
     549              : 
     550           13 :         if (!mut_auth_cap_both) {
     551            1 :             libspdm_secured_message_dhe_free(
     552            1 :                 spdm_context->connection_info.algorithm.dhe_named_group, dhe_context);
     553            1 :             status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
     554            1 :             goto receive_done;
     555              :         }
     556           12 :         if ((mut_auth_requested != SPDM_KEY_EXCHANGE_RESPONSE_MUT_AUTH_REQUESTED) &&
     557              :             (mut_auth_requested !=
     558            7 :              SPDM_KEY_EXCHANGE_RESPONSE_MUT_AUTH_REQUESTED_WITH_ENCAP_REQUEST) &&
     559              :             (mut_auth_requested !=
     560              :              SPDM_KEY_EXCHANGE_RESPONSE_MUT_AUTH_REQUESTED_WITH_GET_DIGESTS)) {
     561            6 :             libspdm_secured_message_dhe_free(
     562            6 :                 spdm_context->connection_info.algorithm.dhe_named_group, dhe_context);
     563            6 :             status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
     564            6 :             goto receive_done;
     565              :         }
     566              : 
     567            6 :         if (mut_auth_requested == SPDM_KEY_EXCHANGE_RESPONSE_MUT_AUTH_REQUESTED) {
     568              :             /* Non-encapsulated flow.
     569              :              * Requester has either CERT_CAP or PUB_KEY_ID_CAP set. */
     570              : 
     571            2 :             if ((cert_cap && (*req_slot_id_param >= SPDM_MAX_SLOT_COUNT)) ||
     572            0 :                 (pub_key_id_cap && (*req_slot_id_param != 0xf))) {
     573            1 :                 libspdm_secured_message_dhe_free(
     574            1 :                     spdm_context->connection_info.algorithm.dhe_named_group, dhe_context);
     575            1 :                 status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
     576            1 :                 goto receive_done;
     577              :             }
     578            1 :             if ((spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_13) &&
     579            0 :                 spdm_context->connection_info.multi_key_conn_req &&
     580            0 :                 (*req_slot_id_param != 0xf)) {
     581            0 :                 if ((spdm_context->local_context.local_key_usage_bit_mask[*req_slot_id_param] &
     582              :                      SPDM_KEY_USAGE_BIT_MASK_KEY_EX_USE) == 0) {
     583            0 :                     libspdm_secured_message_dhe_free(
     584            0 :                         spdm_context->connection_info.algorithm.dhe_named_group, dhe_context);
     585            0 :                     status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
     586            0 :                     goto receive_done;
     587              :                 }
     588              :             }
     589              :         } else {
     590              :             /* Encapsulated flow. */
     591              : 
     592              :             /* If Responder has Requester's public key then it cannot use the encapsulated flow. */
     593            4 :             if (pub_key_id_cap) {
     594            1 :                 libspdm_secured_message_dhe_free(
     595            1 :                     spdm_context->connection_info.algorithm.dhe_named_group, dhe_context);
     596            1 :                 status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
     597            1 :                 goto receive_done;
     598              :             }
     599              :             /* Encapsulated flow requires support for encapsulated messages by both endpoints. */
     600            3 :             if (!libspdm_is_encap_supported(spdm_context)) {
     601            1 :                 libspdm_secured_message_dhe_free(
     602            1 :                     spdm_context->connection_info.algorithm.dhe_named_group, dhe_context);
     603            1 :                 status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
     604            1 :                 goto receive_done;
     605              :             }
     606              :         }
     607              :     }
     608              : 
     609           29 :     signature_size = libspdm_get_asym_signature_size(
     610              :         spdm_context->connection_info.algorithm.base_asym_algo);
     611           29 :     measurement_summary_hash_size = libspdm_get_measurement_summary_hash_size(
     612              :         spdm_context, true, measurement_hash_type);
     613           29 :     hmac_size = libspdm_get_hash_size(spdm_context->connection_info.algorithm.base_hash_algo);
     614              : 
     615           29 :     if (libspdm_is_capabilities_flag_supported(
     616              :             spdm_context, true,
     617              :             SPDM_GET_CAPABILITIES_REQUEST_FLAGS_HANDSHAKE_IN_THE_CLEAR_CAP,
     618              :             SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_HANDSHAKE_IN_THE_CLEAR_CAP)) {
     619            1 :         hmac_size = 0;
     620              :     }
     621              : 
     622           29 :     if (spdm_response_size <
     623           29 :         sizeof(spdm_key_exchange_response_t) + dhe_key_size +
     624           29 :         measurement_summary_hash_size + sizeof(uint16_t) + signature_size + hmac_size) {
     625            4 :         libspdm_secured_message_dhe_free(
     626            4 :             spdm_context->connection_info.algorithm.dhe_named_group, dhe_context);
     627            4 :         status = LIBSPDM_STATUS_INVALID_MSG_SIZE;
     628            4 :         goto receive_done;
     629              :     }
     630              : 
     631           25 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "ResponderRandomData (0x%x) - ", SPDM_RANDOM_DATA_SIZE));
     632           25 :     LIBSPDM_INTERNAL_DUMP_DATA(spdm_response->random_data, SPDM_RANDOM_DATA_SIZE);
     633           25 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "\n"));
     634           25 :     if (responder_random != NULL) {
     635            1 :         libspdm_copy_mem(responder_random, SPDM_RANDOM_DATA_SIZE,
     636            1 :                          spdm_response->random_data, SPDM_RANDOM_DATA_SIZE);
     637              :     }
     638              : 
     639           25 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "ResponderKey (0x%zx):\n", dhe_key_size));
     640           25 :     LIBSPDM_INTERNAL_DUMP_HEX(spdm_response->exchange_data, dhe_key_size);
     641              : 
     642           25 :     ptr = spdm_response->exchange_data;
     643           25 :     ptr += dhe_key_size;
     644              : 
     645           25 :     measurement_summary_hash = ptr;
     646           25 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "measurement_summary_hash (0x%x) - ",
     647              :                    measurement_summary_hash_size));
     648           25 :     LIBSPDM_INTERNAL_DUMP_DATA(measurement_summary_hash, measurement_summary_hash_size);
     649           25 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "\n"));
     650              : 
     651           25 :     ptr += measurement_summary_hash_size;
     652              : 
     653           25 :     opaque_length = libspdm_read_uint16((const uint8_t *)ptr);
     654           25 :     if (opaque_length > SPDM_MAX_OPAQUE_DATA_SIZE) {
     655            1 :         libspdm_secured_message_dhe_free(
     656            1 :             spdm_context->connection_info.algorithm.dhe_named_group, dhe_context);
     657            1 :         status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
     658            1 :         goto receive_done;
     659              :     }
     660           24 :     ptr += sizeof(uint16_t);
     661           24 :     if (spdm_response_size <
     662           24 :         sizeof(spdm_key_exchange_response_t) + dhe_key_size +
     663           24 :         measurement_summary_hash_size + sizeof(uint16_t) +
     664           24 :         opaque_length + signature_size + hmac_size) {
     665            2 :         libspdm_secured_message_dhe_free(
     666            2 :             spdm_context->connection_info.algorithm.dhe_named_group, dhe_context);
     667            2 :         status = LIBSPDM_STATUS_INVALID_MSG_SIZE;
     668            2 :         goto receive_done;
     669              :     }
     670           22 :     if (opaque_length != 0) {
     671           22 :         result = libspdm_process_general_opaque_data_check(spdm_context, opaque_length, ptr);
     672           22 :         if (!result) {
     673            0 :             libspdm_secured_message_dhe_free(
     674            0 :                 spdm_context->connection_info.algorithm.dhe_named_group, dhe_context);
     675            0 :             status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
     676            0 :             goto receive_done;
     677              :         }
     678           22 :         status = libspdm_process_opaque_data_version_selection_data(
     679              :             spdm_context, opaque_length, ptr);
     680           22 :         if (LIBSPDM_STATUS_IS_ERROR(status)) {
     681            0 :             libspdm_secured_message_dhe_free(
     682            0 :                 spdm_context->connection_info.algorithm.dhe_named_group, dhe_context);
     683            0 :             status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
     684            0 :             goto receive_done;
     685              :         }
     686              :     }
     687              : 
     688           22 :     if ((responder_opaque_data != NULL) && (responder_opaque_data_size != NULL)) {
     689            1 :         if (opaque_length >= *responder_opaque_data_size) {
     690            0 :             libspdm_secured_message_dhe_free(
     691            0 :                 spdm_context->connection_info.algorithm.dhe_named_group, dhe_context);
     692            0 :             status = LIBSPDM_STATUS_BUFFER_TOO_SMALL;
     693            0 :             goto receive_done;
     694              :         }
     695            1 :         libspdm_copy_mem(responder_opaque_data, *responder_opaque_data_size, ptr, opaque_length);
     696            1 :         *responder_opaque_data_size = opaque_length;
     697              :     }
     698              : 
     699           22 :     ptr += opaque_length;
     700              : 
     701           22 :     spdm_response_size = sizeof(spdm_key_exchange_response_t) +
     702           22 :                          dhe_key_size + measurement_summary_hash_size +
     703           22 :                          sizeof(uint16_t) + opaque_length + signature_size + hmac_size;
     704              : 
     705           22 :     rsp_session_id = spdm_response->rsp_session_id;
     706           22 :     *session_id = libspdm_generate_session_id(req_session_id, rsp_session_id);
     707           22 :     session_info = libspdm_assign_session_id(spdm_context, *session_id, false);
     708              : 
     709           22 :     if (session_info == NULL) {
     710            0 :         libspdm_secured_message_dhe_free(
     711            0 :             spdm_context->connection_info.algorithm.dhe_named_group, dhe_context);
     712            0 :         status = LIBSPDM_STATUS_SESSION_NUMBER_EXCEED;
     713            0 :         goto receive_done;
     714              :     }
     715              : 
     716              :     /* -=[Process Response Phase]=- */
     717           22 :     status = libspdm_append_message_k(spdm_context, session_info, true, spdm_request,
     718              :                                       spdm_request_size);
     719           22 :     if (LIBSPDM_STATUS_IS_ERROR(status)) {
     720            0 :         libspdm_free_session_id(spdm_context, *session_id);
     721            0 :         libspdm_secured_message_dhe_free(
     722            0 :             spdm_context->connection_info.algorithm.dhe_named_group, dhe_context);
     723            0 :         goto receive_done;
     724              :     }
     725              : 
     726           22 :     status = libspdm_append_message_k(spdm_context, session_info, true, spdm_response,
     727           22 :                                       spdm_response_size - signature_size - hmac_size);
     728           22 :     if (LIBSPDM_STATUS_IS_ERROR(status)) {
     729            0 :         libspdm_free_session_id(spdm_context, *session_id);
     730            0 :         libspdm_secured_message_dhe_free(
     731            0 :             spdm_context->connection_info.algorithm.dhe_named_group, dhe_context);
     732            0 :         goto receive_done;
     733              :     }
     734              : 
     735           22 :     signature = ptr;
     736           22 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "signature (0x%x):\n", signature_size));
     737           22 :     LIBSPDM_INTERNAL_DUMP_HEX(signature, signature_size);
     738           22 :     ptr += signature_size;
     739           22 :     result = libspdm_verify_key_exchange_rsp_signature(
     740              :         spdm_context, session_info, signature, signature_size);
     741           22 :     if (!result) {
     742            2 :         libspdm_free_session_id(spdm_context, *session_id);
     743            2 :         libspdm_secured_message_dhe_free(
     744            2 :             spdm_context->connection_info.algorithm.dhe_named_group, dhe_context);
     745            2 :         status = LIBSPDM_STATUS_VERIF_FAIL;
     746            2 :         goto receive_done;
     747              :     }
     748              : 
     749           20 :     status = libspdm_append_message_k(spdm_context, session_info, true, signature, signature_size);
     750           20 :     if (LIBSPDM_STATUS_IS_ERROR(status)) {
     751            0 :         libspdm_free_session_id(spdm_context, *session_id);
     752            0 :         libspdm_secured_message_dhe_free(
     753            0 :             spdm_context->connection_info.algorithm.dhe_named_group, dhe_context);
     754            0 :         goto receive_done;
     755              :     }
     756              : 
     757           20 :     result = libspdm_secured_message_dhe_compute_key(
     758           20 :         spdm_context->connection_info.algorithm.dhe_named_group,
     759           20 :         dhe_context, spdm_response->exchange_data, dhe_key_size,
     760              :         session_info->secured_message_context);
     761           20 :     libspdm_secured_message_dhe_free(
     762           20 :         spdm_context->connection_info.algorithm.dhe_named_group, dhe_context);
     763           20 :     if (!result) {
     764            0 :         libspdm_free_session_id(spdm_context, *session_id);
     765            0 :         status = LIBSPDM_STATUS_CRYPTO_ERROR;
     766            0 :         goto receive_done;
     767              :     }
     768              : 
     769           20 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "libspdm_generate_session_handshake_key[%x]\n",
     770              :                    *session_id));
     771           20 :     result = libspdm_calculate_th1_hash(spdm_context, session_info, true, th1_hash_data);
     772           20 :     if (!result) {
     773            0 :         libspdm_free_session_id(spdm_context, *session_id);
     774            0 :         status = LIBSPDM_STATUS_CRYPTO_ERROR;
     775            0 :         goto receive_done;
     776              :     }
     777           20 :     result = libspdm_generate_session_handshake_key(
     778              :         session_info->secured_message_context, th1_hash_data);
     779           20 :     if (!result) {
     780            0 :         libspdm_free_session_id(spdm_context, *session_id);
     781            0 :         status = LIBSPDM_STATUS_CRYPTO_ERROR;
     782            0 :         goto receive_done;
     783              :     }
     784              : 
     785           20 :     if (!libspdm_is_capabilities_flag_supported(
     786              :             spdm_context, true,
     787              :             SPDM_GET_CAPABILITIES_REQUEST_FLAGS_HANDSHAKE_IN_THE_CLEAR_CAP,
     788              :             SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_HANDSHAKE_IN_THE_CLEAR_CAP)) {
     789           19 :         verify_data = ptr;
     790           19 :         LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "verify_data (0x%x):\n", hmac_size));
     791           19 :         LIBSPDM_INTERNAL_DUMP_HEX(verify_data, hmac_size);
     792           19 :         result = libspdm_verify_key_exchange_rsp_hmac(
     793              :             spdm_context, session_info, verify_data, hmac_size);
     794           19 :         if (!result) {
     795            0 :             libspdm_free_session_id(spdm_context, *session_id);
     796            0 :             status = LIBSPDM_STATUS_VERIF_FAIL;
     797            0 :             goto receive_done;
     798              :         }
     799           19 :         ptr += hmac_size;
     800              : 
     801           19 :         status = libspdm_append_message_k(spdm_context, session_info, true, verify_data, hmac_size);
     802           19 :         if (LIBSPDM_STATUS_IS_ERROR(status)) {
     803            0 :             libspdm_free_session_id(spdm_context, *session_id);
     804            0 :             goto receive_done;
     805              :         }
     806              :     }
     807              : 
     808           20 :     if (measurement_hash != NULL) {
     809           20 :         libspdm_copy_mem(measurement_hash, measurement_summary_hash_size,
     810              :                          measurement_summary_hash, measurement_summary_hash_size);
     811              :     }
     812           20 :     session_info->heartbeat_period = spdm_response->header.param1;
     813           20 :     session_info->mut_auth_requested = mut_auth_requested;
     814           20 :     session_info->session_policy = session_policy;
     815              : 
     816              :     /* -=[Update State Phase]=- */
     817           20 :     libspdm_secured_message_set_session_state(
     818              :         session_info->secured_message_context, LIBSPDM_SESSION_STATE_HANDSHAKING);
     819              : 
     820              :     /* -=[Log Message Phase]=- */
     821              :     #if LIBSPDM_ENABLE_MSG_LOG
     822           20 :     libspdm_append_msg_log(spdm_context, spdm_response, spdm_response_size);
     823              :     #endif /* LIBSPDM_ENABLE_MSG_LOG */
     824              : 
     825           20 :     status = LIBSPDM_STATUS_SUCCESS;
     826              : 
     827           88 : receive_done:
     828           88 :     libspdm_release_receiver_buffer (spdm_context);
     829           88 :     return status;
     830              : }
     831              : 
     832           93 : libspdm_return_t libspdm_send_receive_key_exchange(
     833              :     libspdm_context_t *spdm_context, uint8_t measurement_hash_type,
     834              :     uint8_t slot_id, uint8_t session_policy, uint32_t *session_id,
     835              :     uint8_t *heartbeat_period,
     836              :     uint8_t *req_slot_id_param, void *measurement_hash)
     837              : {
     838              :     size_t retry;
     839              :     uint64_t retry_delay_time;
     840              :     libspdm_return_t status;
     841              : 
     842           93 :     spdm_context->crypto_request = true;
     843           93 :     retry = spdm_context->retry_times;
     844           93 :     retry_delay_time = spdm_context->retry_delay_time;
     845              :     do {
     846           94 :         status = libspdm_try_send_receive_key_exchange(
     847              :             spdm_context, measurement_hash_type, slot_id, session_policy,
     848              :             session_id, heartbeat_period, req_slot_id_param,
     849              :             measurement_hash,
     850              :             NULL, NULL, NULL, NULL, 0, NULL, NULL);
     851           94 :         if (status != LIBSPDM_STATUS_BUSY_PEER) {
     852           91 :             return status;
     853              :         }
     854              : 
     855            3 :         libspdm_sleep(retry_delay_time);
     856            3 :     } while (retry-- != 0);
     857              : 
     858            2 :     return status;
     859              : }
     860              : 
     861            1 : libspdm_return_t libspdm_send_receive_key_exchange_ex(
     862              :     libspdm_context_t *spdm_context, uint8_t measurement_hash_type,
     863              :     uint8_t slot_id, uint8_t session_policy, uint32_t *session_id,
     864              :     uint8_t *heartbeat_period,
     865              :     uint8_t *req_slot_id_param, void *measurement_hash,
     866              :     const void *requester_random_in,
     867              :     void *requester_random, void *responder_random,
     868              :     const void *requester_opaque_data,
     869              :     size_t requester_opaque_data_size,
     870              :     void *responder_opaque_data,
     871              :     size_t *responder_opaque_data_size)
     872              : {
     873              :     size_t retry;
     874              :     uint64_t retry_delay_time;
     875              :     libspdm_return_t status;
     876              : 
     877            1 :     spdm_context->crypto_request = true;
     878            1 :     retry = spdm_context->retry_times;
     879            1 :     retry_delay_time = spdm_context->retry_delay_time;
     880              :     do {
     881            1 :         status = libspdm_try_send_receive_key_exchange(
     882              :             spdm_context, measurement_hash_type, slot_id, session_policy,
     883              :             session_id, heartbeat_period, req_slot_id_param,
     884              :             measurement_hash, requester_random_in,
     885              :             requester_random, responder_random,
     886              :             requester_opaque_data, requester_opaque_data_size,
     887              :             responder_opaque_data, responder_opaque_data_size);
     888            1 :         if (status != LIBSPDM_STATUS_BUSY_PEER) {
     889            1 :             return status;
     890              :         }
     891              : 
     892            0 :         libspdm_sleep(retry_delay_time);
     893            0 :     } while (retry-- != 0);
     894              : 
     895            0 :     return status;
     896              : }
     897              : 
     898              : #endif /* LIBSPDM_ENABLE_CAPABILITY_KEY_EX_CAP */
        

Generated by: LCOV version 2.0-1