LCOV - code coverage report
Current view: top level - library/spdm_requester_lib - libspdm_req_finish.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 82.8 % 203 168
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              :     uint8_t signature[LIBSPDM_MAX_ASYM_KEY_SIZE];
      16              :     uint8_t verify_data[LIBSPDM_MAX_HASH_SIZE];
      17              : } libspdm_finish_request_mine_t;
      18              : 
      19              : typedef struct {
      20              :     spdm_message_header_t header;
      21              :     uint8_t verify_data[LIBSPDM_MAX_HASH_SIZE];
      22              : } libspdm_finish_response_mine_t;
      23              : #pragma pack()
      24              : 
      25            9 : bool libspdm_verify_finish_rsp_hmac(libspdm_context_t *spdm_context,
      26              :                                     libspdm_session_info_t *session_info,
      27              :                                     const void *hmac_data, size_t hmac_data_size)
      28              : {
      29              :     size_t hash_size;
      30              :     uint8_t calc_hmac_data[LIBSPDM_MAX_HASH_SIZE];
      31              :     bool result;
      32              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
      33              :     uint8_t slot_id;
      34              :     uint8_t *cert_chain_buffer;
      35              :     size_t cert_chain_buffer_size;
      36              :     uint8_t *mut_cert_chain_buffer;
      37              :     size_t mut_cert_chain_buffer_size;
      38              :     uint8_t *th_curr_data;
      39              :     size_t th_curr_data_size;
      40              :     libspdm_th_managed_buffer_t th_curr;
      41              :     uint8_t hash_data[LIBSPDM_MAX_HASH_SIZE];
      42              : #endif
      43              : 
      44            9 :     hash_size = libspdm_get_hash_size(spdm_context->connection_info.algorithm.base_hash_algo);
      45            9 :     LIBSPDM_ASSERT(hash_size == hmac_data_size);
      46              : 
      47              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
      48              :     slot_id = spdm_context->connection_info.peer_used_cert_chain_slot_id;
      49              :     LIBSPDM_ASSERT((slot_id < SPDM_MAX_SLOT_COUNT) || (slot_id == 0xFF));
      50              :     if (slot_id == 0xFF) {
      51              :         result = libspdm_get_peer_public_key_buffer(
      52              :             spdm_context, (const void **)&cert_chain_buffer, &cert_chain_buffer_size);
      53              :     } else {
      54              :         result = libspdm_get_peer_cert_chain_buffer(
      55              :             spdm_context, (const void **)&cert_chain_buffer, &cert_chain_buffer_size);
      56              :     }
      57              :     if (!result) {
      58              :         return false;
      59              :     }
      60              : 
      61              :     if (session_info->mut_auth_requested != 0) {
      62              :         slot_id = spdm_context->connection_info.local_used_cert_chain_slot_id;
      63              :         LIBSPDM_ASSERT((slot_id < SPDM_MAX_SLOT_COUNT) || (slot_id == 0xFF));
      64              :         if (slot_id == 0xFF) {
      65              :             result = libspdm_get_local_public_key_buffer(
      66              :                 spdm_context, (const void **)&mut_cert_chain_buffer, &mut_cert_chain_buffer_size);
      67              :         } else {
      68              :             result = libspdm_get_local_cert_chain_buffer(
      69              :                 spdm_context, (const void **)&mut_cert_chain_buffer, &mut_cert_chain_buffer_size);
      70              :         }
      71              :         if (!result) {
      72              :             return false;
      73              :         }
      74              :     } else {
      75              :         mut_cert_chain_buffer = NULL;
      76              :         mut_cert_chain_buffer_size = 0;
      77              :     }
      78              : 
      79              :     result = libspdm_calculate_th_for_finish(
      80              :         spdm_context, session_info, cert_chain_buffer,
      81              :         cert_chain_buffer_size, mut_cert_chain_buffer,
      82              :         mut_cert_chain_buffer_size, &th_curr);
      83              :     if (!result) {
      84              :         return false;
      85              :     }
      86              :     th_curr_data = libspdm_get_managed_buffer(&th_curr);
      87              :     th_curr_data_size = libspdm_get_managed_buffer_size(&th_curr);
      88              : 
      89              :     result = libspdm_hash_all (spdm_context->connection_info.algorithm.base_hash_algo,
      90              :                                th_curr_data, th_curr_data_size, hash_data);
      91              :     if (!result) {
      92              :         return false;
      93              :     }
      94              : 
      95              :     result = libspdm_hmac_all_with_response_finished_key(
      96              :         session_info->secured_message_context, hash_data,
      97              :         hash_size, calc_hmac_data);
      98              :     if (!result) {
      99              :         return false;
     100              :     }
     101              : #else
     102            9 :     result = libspdm_calculate_th_hmac_for_finish_rsp(
     103              :         spdm_context, session_info, &hash_size, calc_hmac_data);
     104            9 :     if (!result) {
     105            0 :         return false;
     106              :     }
     107              : #endif
     108            9 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "th_curr hmac - "));
     109            9 :     LIBSPDM_INTERNAL_DUMP_DATA(calc_hmac_data, hash_size);
     110            9 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "\n"));
     111              : 
     112            9 :     if (!libspdm_consttime_is_mem_equal(calc_hmac_data, hmac_data, hash_size)) {
     113            2 :         LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "!!! verify_finish_rsp_hmac - FAIL !!!\n"));
     114            2 :         return false;
     115              :     }
     116            7 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "!!! verify_finish_rsp_hmac - PASS !!!\n"));
     117              : 
     118            7 :     return true;
     119              : }
     120              : 
     121           37 : bool libspdm_generate_finish_req_hmac(libspdm_context_t *spdm_context,
     122              :                                       libspdm_session_info_t *session_info,
     123              :                                       void *hmac)
     124              : {
     125              :     size_t hash_size;
     126              :     uint8_t calc_hmac_data[LIBSPDM_MAX_HASH_SIZE];
     127              :     bool result;
     128              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
     129              :     uint8_t slot_id;
     130              :     uint8_t *cert_chain_buffer;
     131              :     size_t cert_chain_buffer_size;
     132              :     uint8_t *mut_cert_chain_buffer;
     133              :     size_t mut_cert_chain_buffer_size;
     134              :     uint8_t *th_curr_data;
     135              :     size_t th_curr_data_size;
     136              :     libspdm_th_managed_buffer_t th_curr;
     137              :     uint8_t hash_data[LIBSPDM_MAX_HASH_SIZE];
     138              : #endif
     139              : 
     140           37 :     hash_size = libspdm_get_hash_size(spdm_context->connection_info.algorithm.base_hash_algo);
     141              : 
     142              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
     143              :     slot_id = spdm_context->connection_info.peer_used_cert_chain_slot_id;
     144              :     LIBSPDM_ASSERT((slot_id < SPDM_MAX_SLOT_COUNT) || (slot_id == 0xFF));
     145              :     if (slot_id == 0xFF) {
     146              :         result = libspdm_get_peer_public_key_buffer(
     147              :             spdm_context, (const void **)&cert_chain_buffer, &cert_chain_buffer_size);
     148              :     } else {
     149              :         result = libspdm_get_peer_cert_chain_buffer(
     150              :             spdm_context, (const void **)&cert_chain_buffer, &cert_chain_buffer_size);
     151              :     }
     152              :     if (!result) {
     153              :         return false;
     154              :     }
     155              : 
     156              :     if (session_info->mut_auth_requested != 0) {
     157              :         slot_id = spdm_context->connection_info.local_used_cert_chain_slot_id;
     158              :         LIBSPDM_ASSERT((slot_id < SPDM_MAX_SLOT_COUNT) || (slot_id == 0xFF));
     159              :         if (slot_id == 0xFF) {
     160              :             result = libspdm_get_local_public_key_buffer(
     161              :                 spdm_context, (const void **)&mut_cert_chain_buffer, &mut_cert_chain_buffer_size);
     162              :         } else {
     163              :             result = libspdm_get_local_cert_chain_buffer(
     164              :                 spdm_context, (const void **)&mut_cert_chain_buffer, &mut_cert_chain_buffer_size);
     165              :         }
     166              :         if (!result) {
     167              :             return false;
     168              :         }
     169              :     } else {
     170              :         mut_cert_chain_buffer = NULL;
     171              :         mut_cert_chain_buffer_size = 0;
     172              :     }
     173              : 
     174              :     result = libspdm_calculate_th_for_finish(
     175              :         spdm_context, session_info, cert_chain_buffer,
     176              :         cert_chain_buffer_size, mut_cert_chain_buffer,
     177              :         mut_cert_chain_buffer_size, &th_curr);
     178              :     if (!result) {
     179              :         return false;
     180              :     }
     181              :     th_curr_data = libspdm_get_managed_buffer(&th_curr);
     182              :     th_curr_data_size = libspdm_get_managed_buffer_size(&th_curr);
     183              : 
     184              :     result = libspdm_hash_all (spdm_context->connection_info.algorithm.base_hash_algo,
     185              :                                th_curr_data, th_curr_data_size, hash_data);
     186              :     if (!result) {
     187              :         return false;
     188              :     }
     189              : 
     190              :     result = libspdm_hmac_all_with_request_finished_key(
     191              :         session_info->secured_message_context, hash_data,
     192              :         hash_size, calc_hmac_data);
     193              :     if (!result) {
     194              :         return false;
     195              :     }
     196              : #else
     197           37 :     result = libspdm_calculate_th_hmac_for_finish_req(
     198              :         spdm_context, session_info, &hash_size, calc_hmac_data);
     199           37 :     if (!result) {
     200            0 :         return false;
     201              :     }
     202              : #endif
     203           37 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "th_curr hmac - "));
     204           37 :     LIBSPDM_INTERNAL_DUMP_DATA(calc_hmac_data, hash_size);
     205           37 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "\n"));
     206              : 
     207           37 :     libspdm_copy_mem(hmac, hash_size, calc_hmac_data, hash_size);
     208              : 
     209           37 :     return true;
     210              : }
     211              : 
     212              : #if LIBSPDM_ENABLE_CAPABILITY_MUT_AUTH_CAP
     213              : 
     214            5 : bool libspdm_generate_finish_req_signature(libspdm_context_t *spdm_context,
     215              :                                            libspdm_session_info_t *session_info,
     216              :                                            uint8_t *signature)
     217              : {
     218              :     bool result;
     219              :     size_t signature_size;
     220              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
     221              :     uint8_t slot_id;
     222              :     uint8_t *cert_chain_buffer;
     223              :     size_t cert_chain_buffer_size;
     224              :     uint8_t *mut_cert_chain_buffer;
     225              :     size_t mut_cert_chain_buffer_size;
     226              :     uint8_t *th_curr_data;
     227              :     size_t th_curr_data_size;
     228              :     libspdm_th_managed_buffer_t th_curr;
     229              : #endif
     230              : #if !(LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT) || (LIBSPDM_DEBUG_PRINT_ENABLE)
     231              :     size_t hash_size;
     232              : #endif
     233              : #if ((LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT) && (LIBSPDM_DEBUG_BLOCK_ENABLE)) || \
     234              :     !(LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT)
     235              :     uint8_t hash_data[LIBSPDM_MAX_HASH_SIZE];
     236              : #endif
     237              : 
     238           10 :     signature_size = libspdm_get_req_asym_signature_size(
     239            5 :         spdm_context->connection_info.algorithm.req_base_asym_alg);
     240              : 
     241              : #if !(LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT) || (LIBSPDM_DEBUG_PRINT_ENABLE)
     242            5 :     hash_size = libspdm_get_hash_size(spdm_context->connection_info.algorithm.base_hash_algo);
     243              : #endif
     244              : 
     245              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
     246              :     slot_id = spdm_context->connection_info.peer_used_cert_chain_slot_id;
     247              :     LIBSPDM_ASSERT((slot_id < SPDM_MAX_SLOT_COUNT) || (slot_id == 0xFF));
     248              :     if (slot_id == 0xFF) {
     249              :         result = libspdm_get_peer_public_key_buffer(
     250              :             spdm_context, (const void **)&cert_chain_buffer, &cert_chain_buffer_size);
     251              :     } else {
     252              :         result = libspdm_get_peer_cert_chain_buffer(
     253              :             spdm_context, (const void **)&cert_chain_buffer, &cert_chain_buffer_size);
     254              :     }
     255              :     if (!result) {
     256              :         return false;
     257              :     }
     258              : 
     259              :     slot_id = spdm_context->connection_info.local_used_cert_chain_slot_id;
     260              :     LIBSPDM_ASSERT((slot_id < SPDM_MAX_SLOT_COUNT) || (slot_id == 0xFF));
     261              :     if (slot_id == 0xFF) {
     262              :         result = libspdm_get_local_public_key_buffer(
     263              :             spdm_context, (const void **)&mut_cert_chain_buffer, &mut_cert_chain_buffer_size);
     264              :     } else {
     265              :         result = libspdm_get_local_cert_chain_buffer(
     266              :             spdm_context, (const void **)&mut_cert_chain_buffer, &mut_cert_chain_buffer_size);
     267              :     }
     268              :     if (!result) {
     269              :         return false;
     270              :     }
     271              : 
     272              :     result = libspdm_calculate_th_for_finish(
     273              :         spdm_context, session_info, cert_chain_buffer,
     274              :         cert_chain_buffer_size, mut_cert_chain_buffer,
     275              :         mut_cert_chain_buffer_size, &th_curr);
     276              :     if (!result) {
     277              :         return false;
     278              :     }
     279              :     th_curr_data = libspdm_get_managed_buffer(&th_curr);
     280              :     th_curr_data_size = libspdm_get_managed_buffer_size(&th_curr);
     281              : 
     282              :     /* Debug code only - required for debug print of th_curr below*/
     283              :     LIBSPDM_DEBUG_CODE(
     284              :         if (!libspdm_hash_all(
     285              :                 spdm_context->connection_info.algorithm.base_hash_algo,
     286              :                 th_curr_data, th_curr_data_size, hash_data)) {
     287              :         return false;
     288              :     }
     289              :         );
     290              : #else
     291            5 :     result = libspdm_calculate_th_hash_for_finish(
     292              :         spdm_context, session_info, &hash_size, hash_data);
     293            5 :     if (!result) {
     294            0 :         return false;
     295              :     }
     296              : #endif
     297            5 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "th_curr hash - "));
     298            5 :     LIBSPDM_INTERNAL_DUMP_DATA(hash_data, hash_size);
     299            5 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "\n"));
     300              : 
     301              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
     302              :     result = libspdm_requester_data_sign(
     303              : #if LIBSPDM_HAL_PASS_SPDM_CONTEXT
     304              :         spdm_context,
     305              : #endif
     306              :         spdm_context->connection_info.version, SPDM_FINISH,
     307              :         spdm_context->connection_info.algorithm.req_base_asym_alg,
     308              :         spdm_context->connection_info.algorithm.base_hash_algo,
     309              :         false, th_curr_data, th_curr_data_size, signature, &signature_size);
     310              : #else
     311            5 :     result = libspdm_requester_data_sign(
     312              : #if LIBSPDM_HAL_PASS_SPDM_CONTEXT
     313              :         spdm_context,
     314              : #endif
     315            5 :         spdm_context->connection_info.version, SPDM_FINISH,
     316            5 :         spdm_context->connection_info.algorithm.req_base_asym_alg,
     317              :         spdm_context->connection_info.algorithm.base_hash_algo,
     318              :         true, hash_data, hash_size, signature, &signature_size);
     319              : #endif
     320            5 :     if (result) {
     321            5 :         LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "signature - "));
     322            5 :         LIBSPDM_INTERNAL_DUMP_DATA(signature, signature_size);
     323            5 :         LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "\n"));
     324              :     }
     325              : 
     326            5 :     return result;
     327              : }
     328              : #endif /* LIBSPDM_ENABLE_CAPABILITY_MUT_AUTH_CAP */
     329              : 
     330              : /**
     331              :  * This function sends FINISH and receives FINISH_RSP for SPDM finish.
     332              :  *
     333              :  * @param  spdm_context       A pointer to the SPDM context.
     334              :  * @param  session_id         session_id to the FINISH request.
     335              :  * @param  req_slot_id_param  req_slot_id_param to the FINISH request.
     336              :  *
     337              :  * @retval RETURN_SUCCESS               The FINISH is sent and the FINISH_RSP is received.
     338              :  * @retval RETURN_DEVICE_ERROR          A device error occurs when communicates with the device.
     339              :  **/
     340           41 : static libspdm_return_t libspdm_try_send_receive_finish(libspdm_context_t *spdm_context,
     341              :                                                         uint32_t session_id,
     342              :                                                         uint8_t req_slot_id_param)
     343              : {
     344              :     libspdm_return_t status;
     345              :     libspdm_finish_request_mine_t *spdm_request;
     346              :     size_t spdm_request_size;
     347              :     size_t signature_size;
     348              :     size_t hmac_size;
     349              :     libspdm_finish_response_mine_t *spdm_response;
     350              :     size_t spdm_response_size;
     351              :     libspdm_session_info_t *session_info;
     352              :     uint8_t *ptr;
     353              :     bool result;
     354              :     uint8_t th2_hash_data[LIBSPDM_MAX_HASH_SIZE];
     355              :     libspdm_session_state_t session_state;
     356              :     uint8_t *message;
     357              :     size_t message_size;
     358              :     size_t transport_header_size;
     359              : 
     360              :     /* -=[Check Parameters Phase]=- */
     361           41 :     if (libspdm_get_connection_version(spdm_context) < SPDM_MESSAGE_VERSION_11) {
     362            0 :         return LIBSPDM_STATUS_UNSUPPORTED_CAP;
     363              :     }
     364              : 
     365           41 :     session_info = libspdm_get_session_info_via_session_id(spdm_context, session_id);
     366           41 :     if (session_info == NULL) {
     367            0 :         status = LIBSPDM_STATUS_INVALID_PARAMETER;
     368            0 :         goto error;
     369              :     }
     370              : 
     371              :     /* -=[Verify State Phase]=- */
     372           41 :     if (!libspdm_is_capabilities_flag_supported(
     373              :             spdm_context, true,
     374              :             SPDM_GET_CAPABILITIES_REQUEST_FLAGS_KEY_EX_CAP,
     375              :             SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_KEY_EX_CAP)) {
     376            1 :         status = LIBSPDM_STATUS_UNSUPPORTED_CAP;
     377            1 :         goto error;
     378              :     }
     379              : 
     380           40 :     if (spdm_context->connection_info.connection_state < LIBSPDM_CONNECTION_STATE_NEGOTIATED) {
     381            2 :         status = LIBSPDM_STATUS_INVALID_STATE_LOCAL;
     382            2 :         goto error;
     383              :     }
     384              : 
     385           38 :     session_state = libspdm_secured_message_get_session_state(
     386              :         session_info->secured_message_context);
     387           38 :     if (session_state != LIBSPDM_SESSION_STATE_HANDSHAKING) {
     388            1 :         status = LIBSPDM_STATUS_INVALID_STATE_LOCAL;
     389            1 :         goto error;
     390              :     }
     391           37 :     if (session_info->mut_auth_requested != 0) {
     392            5 :         if ((req_slot_id_param >= SPDM_MAX_SLOT_COUNT) && (req_slot_id_param != 0xFF)) {
     393            0 :             status = LIBSPDM_STATUS_INVALID_PARAMETER;
     394            0 :             goto error;
     395              :         }
     396              :     } else {
     397           32 :         if (req_slot_id_param != 0) {
     398            0 :             status = LIBSPDM_STATUS_INVALID_PARAMETER;
     399            0 :             goto error;
     400              :         }
     401              :     }
     402              : 
     403              :     /* -=[Construct Request Phase]=- */
     404           37 :     transport_header_size = spdm_context->local_context.capability.transport_header_size;
     405           37 :     status = libspdm_acquire_sender_buffer (spdm_context, &message_size, (void **)&message);
     406           37 :     if (LIBSPDM_STATUS_IS_ERROR(status)) {
     407            0 :         goto error;
     408              :     }
     409           37 :     LIBSPDM_ASSERT (message_size >= transport_header_size +
     410              :                     spdm_context->local_context.capability.transport_tail_size);
     411           37 :     spdm_request = (void *)(message + transport_header_size);
     412           37 :     spdm_request_size = message_size - transport_header_size -
     413           37 :                         spdm_context->local_context.capability.transport_tail_size;
     414              : 
     415           37 :     LIBSPDM_ASSERT(spdm_request_size >= sizeof(spdm_request->header));
     416           37 :     spdm_request->header.spdm_version = libspdm_get_connection_version (spdm_context);
     417           37 :     spdm_request->header.request_response_code = SPDM_FINISH;
     418           37 :     spdm_request->header.param1 = 0;
     419           37 :     spdm_request->header.param2 = 0;
     420           37 :     signature_size = 0;
     421              : #if LIBSPDM_ENABLE_CAPABILITY_MUT_AUTH_CAP
     422           37 :     if (session_info->mut_auth_requested != 0) {
     423            5 :         spdm_request->header.param1 = SPDM_FINISH_REQUEST_ATTRIBUTES_SIGNATURE_INCLUDED;
     424            5 :         spdm_request->header.param2 = req_slot_id_param;
     425            5 :         signature_size = libspdm_get_req_asym_signature_size(
     426            5 :             spdm_context->connection_info.algorithm.req_base_asym_alg);
     427              :     }
     428              : #endif
     429              : 
     430           37 :     spdm_context->connection_info.local_used_cert_chain_slot_id = req_slot_id_param;
     431           37 :     if ((session_info->mut_auth_requested != 0) && (req_slot_id_param != 0xFF)) {
     432            5 :         LIBSPDM_ASSERT(req_slot_id_param < SPDM_MAX_SLOT_COUNT);
     433            5 :         spdm_context->connection_info.local_used_cert_chain_buffer =
     434            5 :             spdm_context->local_context.local_cert_chain_provision[req_slot_id_param];
     435            5 :         spdm_context->connection_info.local_used_cert_chain_buffer_size =
     436            5 :             spdm_context->local_context.local_cert_chain_provision_size[req_slot_id_param];
     437              :     }
     438              : 
     439           37 :     hmac_size = libspdm_get_hash_size(spdm_context->connection_info.algorithm.base_hash_algo);
     440           37 :     LIBSPDM_ASSERT (spdm_request_size >= sizeof(spdm_finish_request_t) + signature_size +
     441              :                     hmac_size);
     442           37 :     spdm_request_size = sizeof(spdm_finish_request_t) + signature_size + hmac_size;
     443           37 :     ptr = spdm_request->signature;
     444              : 
     445           37 :     status = libspdm_append_message_f(spdm_context, session_info, true, (uint8_t *)spdm_request,
     446              :                                       sizeof(spdm_finish_request_t));
     447           37 :     if (LIBSPDM_STATUS_IS_ERROR(status)) {
     448            0 :         libspdm_release_sender_buffer (spdm_context);
     449            0 :         goto error;
     450              :     }
     451              : #if LIBSPDM_ENABLE_CAPABILITY_MUT_AUTH_CAP
     452           37 :     if (session_info->mut_auth_requested != 0) {
     453            5 :         result = libspdm_generate_finish_req_signature(spdm_context, session_info, ptr);
     454            5 :         if (!result) {
     455            0 :             libspdm_release_sender_buffer (spdm_context);
     456            0 :             status = LIBSPDM_STATUS_CRYPTO_ERROR;
     457            0 :             goto error;
     458              :         }
     459            5 :         status = libspdm_append_message_f(spdm_context, session_info, true, ptr, signature_size);
     460            5 :         if (LIBSPDM_STATUS_IS_ERROR(status)) {
     461            0 :             libspdm_release_sender_buffer (spdm_context);
     462            0 :             goto error;
     463              :         }
     464            5 :         ptr += signature_size;
     465              :     }
     466              : #endif
     467              : 
     468           37 :     result = libspdm_generate_finish_req_hmac(spdm_context, session_info, ptr);
     469           37 :     if (!result) {
     470            0 :         libspdm_release_sender_buffer (spdm_context);
     471            0 :         status = LIBSPDM_STATUS_CRYPTO_ERROR;
     472            0 :         goto error;
     473              :     }
     474              : 
     475           37 :     status = libspdm_append_message_f(spdm_context, session_info, true, ptr, hmac_size);
     476           37 :     if (LIBSPDM_STATUS_IS_ERROR(status)) {
     477            0 :         libspdm_release_sender_buffer (spdm_context);
     478            0 :         goto error;
     479              :     }
     480              : 
     481              :     /* -=[Send Request Phase]=- */
     482           37 :     status = libspdm_send_spdm_request(spdm_context, &session_id, spdm_request_size, spdm_request);
     483           37 :     if (LIBSPDM_STATUS_IS_ERROR(status)) {
     484            1 :         libspdm_release_sender_buffer (spdm_context);
     485            1 :         goto error;
     486              :     }
     487              : 
     488           36 :     libspdm_reset_message_buffer_via_request_code(spdm_context, session_info, SPDM_FINISH);
     489              : 
     490           36 :     libspdm_release_sender_buffer (spdm_context);
     491           36 :     spdm_request = (void *)spdm_context->last_spdm_request;
     492              : 
     493              :     /* -=[Receive Response Phase]=- */
     494           36 :     status = libspdm_acquire_receiver_buffer (spdm_context, &message_size, (void **)&message);
     495           36 :     if (LIBSPDM_STATUS_IS_ERROR(status)) {
     496            0 :         goto error;
     497              :     }
     498           36 :     LIBSPDM_ASSERT (message_size >= transport_header_size);
     499           36 :     spdm_response = (void *)(message);
     500           36 :     spdm_response_size = message_size;
     501              : 
     502           36 :     status = libspdm_receive_spdm_response(
     503              :         spdm_context, &session_id, &spdm_response_size, (void **)&spdm_response);
     504           36 :     if (LIBSPDM_STATUS_IS_ERROR(status)) {
     505            0 :         goto receive_done;
     506              :     }
     507              : 
     508              :     /* -=[Validate Response Phase]=- */
     509           36 :     if (spdm_response_size < sizeof(spdm_message_header_t)) {
     510            0 :         status = LIBSPDM_STATUS_INVALID_MSG_SIZE;
     511            0 :         goto receive_done;
     512              :     }
     513           36 :     if (spdm_response->header.spdm_version != spdm_request->header.spdm_version) {
     514            0 :         status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
     515            0 :         goto receive_done;
     516              :     }
     517           36 :     if (spdm_response->header.request_response_code == SPDM_ERROR) {
     518           25 :         if (spdm_response->header.param1 == SPDM_ERROR_CODE_DECRYPT_ERROR) {
     519            2 :             status = LIBSPDM_STATUS_SESSION_MSG_ERROR;
     520            2 :             goto receive_done;
     521              :         }
     522           23 :         if (spdm_response->header.param1 != SPDM_ERROR_CODE_RESPONSE_NOT_READY) {
     523           21 :             libspdm_reset_message_f (spdm_context, session_info);
     524              :         }
     525           23 :         status = libspdm_handle_error_response_main(
     526              :             spdm_context, &session_id,
     527              :             &spdm_response_size, (void **)&spdm_response,
     528              :             SPDM_FINISH, SPDM_FINISH_RSP);
     529           23 :         if (LIBSPDM_STATUS_IS_ERROR(status)) {
     530           22 :             goto receive_done;
     531              :         }
     532           11 :     } else if (spdm_response->header.request_response_code != SPDM_FINISH_RSP) {
     533            1 :         status = LIBSPDM_STATUS_INVALID_MSG_FIELD;
     534            1 :         goto receive_done;
     535              :     }
     536              : 
     537           11 :     if (!libspdm_is_capabilities_flag_supported(
     538              :             spdm_context, true,
     539              :             SPDM_GET_CAPABILITIES_REQUEST_FLAGS_HANDSHAKE_IN_THE_CLEAR_CAP,
     540              :             SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_HANDSHAKE_IN_THE_CLEAR_CAP)) {
     541            1 :         hmac_size = 0;
     542              :     }
     543              : 
     544           11 :     if (spdm_response_size < sizeof(spdm_finish_response_t) + hmac_size) {
     545            1 :         status = LIBSPDM_STATUS_INVALID_MSG_SIZE;
     546            1 :         goto receive_done;
     547              :     }
     548              : 
     549           10 :     status = libspdm_append_message_f(spdm_context, session_info, true, spdm_response,
     550              :                                       sizeof(spdm_finish_response_t));
     551           10 :     if (LIBSPDM_STATUS_IS_ERROR(status)) {
     552            0 :         goto receive_done;
     553              :     }
     554              : 
     555           10 :     if (libspdm_is_capabilities_flag_supported(
     556              :             spdm_context, true,
     557              :             SPDM_GET_CAPABILITIES_REQUEST_FLAGS_HANDSHAKE_IN_THE_CLEAR_CAP,
     558              :             SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_HANDSHAKE_IN_THE_CLEAR_CAP)) {
     559            9 :         LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "verify_data (0x%zx):\n", hmac_size));
     560            9 :         LIBSPDM_INTERNAL_DUMP_HEX(spdm_response->verify_data, hmac_size);
     561            9 :         result = libspdm_verify_finish_rsp_hmac(spdm_context, session_info,
     562            9 :                                                 spdm_response->verify_data,
     563              :                                                 hmac_size);
     564            9 :         if (!result) {
     565            2 :             status = LIBSPDM_STATUS_VERIF_FAIL;
     566            2 :             goto receive_done;
     567              :         }
     568              : 
     569            7 :         status = libspdm_append_message_f(
     570              :             spdm_context, session_info, true,
     571            7 :             (uint8_t *)spdm_response +
     572              :             sizeof(spdm_finish_response_t),
     573              :             hmac_size);
     574            7 :         if (LIBSPDM_STATUS_IS_ERROR(status)) {
     575            0 :             goto receive_done;
     576              :         }
     577              :     }
     578              : 
     579              :     /* -=[Process Response Phase]=- */
     580            8 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "libspdm_generate_session_data_key[%x]\n", session_id));
     581            8 :     result = libspdm_calculate_th2_hash(spdm_context, session_info, true, th2_hash_data);
     582            8 :     if (!result) {
     583            0 :         status = LIBSPDM_STATUS_CRYPTO_ERROR;
     584            0 :         goto receive_done;
     585              :     }
     586            8 :     result = libspdm_generate_session_data_key(
     587              :         session_info->secured_message_context, th2_hash_data);
     588            8 :     if (!result) {
     589            0 :         status = LIBSPDM_STATUS_CRYPTO_ERROR;
     590            0 :         goto receive_done;
     591              :     }
     592              : 
     593              :     /* -=[Update State Phase]=- */
     594            8 :     libspdm_secured_message_set_session_state(
     595              :         session_info->secured_message_context, LIBSPDM_SESSION_STATE_ESTABLISHED);
     596              : 
     597              :     /* -=[Log Message Phase]=- */
     598              :     #if LIBSPDM_ENABLE_MSG_LOG
     599            8 :     libspdm_append_msg_log(spdm_context, spdm_response, spdm_response_size);
     600              :     #endif /* LIBSPDM_ENABLE_MSG_LOG */
     601              : 
     602            8 :     libspdm_release_receiver_buffer (spdm_context);
     603              : 
     604            8 :     return LIBSPDM_STATUS_SUCCESS;
     605              : 
     606           28 : receive_done:
     607           28 :     libspdm_release_receiver_buffer (spdm_context);
     608           33 : error:
     609           33 :     if (status != LIBSPDM_STATUS_BUSY_PEER) {
     610           31 :         libspdm_free_session_id(spdm_context, session_id);
     611              :     }
     612              : 
     613           33 :     return status;
     614              : }
     615              : 
     616           40 : libspdm_return_t libspdm_send_receive_finish(libspdm_context_t *spdm_context,
     617              :                                              uint32_t session_id,
     618              :                                              uint8_t req_slot_id_param)
     619              : {
     620              :     size_t retry;
     621              :     uint64_t retry_delay_time;
     622              :     libspdm_return_t status;
     623              : 
     624           40 :     spdm_context->crypto_request = true;
     625           40 :     retry = spdm_context->retry_times;
     626           40 :     retry_delay_time = spdm_context->retry_delay_time;
     627              :     do {
     628           41 :         status = libspdm_try_send_receive_finish(spdm_context, session_id,
     629              :                                                  req_slot_id_param);
     630           41 :         if (status != LIBSPDM_STATUS_BUSY_PEER) {
     631           39 :             return status;
     632              :         }
     633              : 
     634            2 :         libspdm_sleep(retry_delay_time);
     635            2 :     } while (retry-- != 0);
     636              : 
     637            1 :     return status;
     638              : }
     639              : 
     640              : #endif /* LIBSPDM_ENABLE_CAPABILITY_KEY_EX_CAP*/
        

Generated by: LCOV version 2.0-1