LCOV - code coverage report
Current view: top level - library/spdm_responder_lib - libspdm_rsp_finish.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 81.0 % 174 141
Test Date: 2025-06-29 08:09:00 Functions: 100.0 % 4 4

            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_responder_lib.h"
       8              : #include "internal/libspdm_secured_message_lib.h"
       9              : 
      10              : #if LIBSPDM_ENABLE_CAPABILITY_KEY_EX_CAP
      11              : 
      12           15 : bool libspdm_verify_finish_req_hmac(libspdm_context_t *spdm_context,
      13              :                                     libspdm_session_info_t *session_info,
      14              :                                     const uint8_t *hmac, size_t hmac_size)
      15              : {
      16              :     uint8_t hmac_data[LIBSPDM_MAX_HASH_SIZE];
      17              :     size_t hash_size;
      18              :     bool result;
      19              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
      20              :     uint8_t slot_id;
      21              :     uint8_t *cert_chain_buffer;
      22              :     size_t cert_chain_buffer_size;
      23              :     uint8_t *mut_cert_chain_buffer;
      24              :     size_t mut_cert_chain_buffer_size;
      25              :     uint8_t *th_curr_data;
      26              :     size_t th_curr_data_size;
      27              :     libspdm_th_managed_buffer_t th_curr;
      28              :     uint8_t hash_data[LIBSPDM_MAX_HASH_SIZE];
      29              : #endif /* LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT */
      30              : 
      31           15 :     hash_size = libspdm_get_hash_size(spdm_context->connection_info.algorithm.base_hash_algo);
      32           15 :     LIBSPDM_ASSERT(hmac_size == hash_size);
      33              : 
      34              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
      35              :     slot_id = spdm_context->connection_info.local_used_cert_chain_slot_id;
      36              :     LIBSPDM_ASSERT((slot_id < SPDM_MAX_SLOT_COUNT) || (slot_id == 0xFF));
      37              :     if (slot_id == 0xFF) {
      38              :         result = libspdm_get_local_public_key_buffer(
      39              :             spdm_context, (const void **)&cert_chain_buffer, &cert_chain_buffer_size);
      40              :     } else {
      41              :         result = libspdm_get_local_cert_chain_buffer(
      42              :             spdm_context, (const void **)&cert_chain_buffer, &cert_chain_buffer_size);
      43              :     }
      44              :     if (!result) {
      45              :         return false;
      46              :     }
      47              : 
      48              :     if (session_info->mut_auth_requested != 0) {
      49              :         slot_id = spdm_context->connection_info.peer_used_cert_chain_slot_id;
      50              :         LIBSPDM_ASSERT((slot_id < SPDM_MAX_SLOT_COUNT) || (slot_id == 0xFF));
      51              :         if (slot_id == 0xFF) {
      52              :             result = libspdm_get_peer_public_key_buffer(
      53              :                 spdm_context, (const void **)&mut_cert_chain_buffer, &mut_cert_chain_buffer_size);
      54              :         } else {
      55              :             result = libspdm_get_peer_cert_chain_buffer(
      56              :                 spdm_context, (const void **)&mut_cert_chain_buffer, &mut_cert_chain_buffer_size);
      57              :         }
      58              :         if (!result) {
      59              :             return false;
      60              :         }
      61              :     } else {
      62              :         mut_cert_chain_buffer = NULL;
      63              :         mut_cert_chain_buffer_size = 0;
      64              :     }
      65              : 
      66              :     result = libspdm_calculate_th_for_finish(
      67              :         spdm_context, session_info, cert_chain_buffer,
      68              :         cert_chain_buffer_size, mut_cert_chain_buffer,
      69              :         mut_cert_chain_buffer_size, &th_curr);
      70              :     if (!result) {
      71              :         return false;
      72              :     }
      73              :     th_curr_data = libspdm_get_managed_buffer(&th_curr);
      74              :     th_curr_data_size = libspdm_get_managed_buffer_size(&th_curr);
      75              : 
      76              :     result = libspdm_hash_all (spdm_context->connection_info.algorithm.base_hash_algo,
      77              :                                th_curr_data, th_curr_data_size, hash_data);
      78              :     if (!result) {
      79              :         return false;
      80              :     }
      81              : 
      82              :     result = libspdm_hmac_all_with_request_finished_key(
      83              :         session_info->secured_message_context, hash_data, hash_size, hmac_data);
      84              :     if (!result) {
      85              :         return false;
      86              :     }
      87              : #else
      88           15 :     result = libspdm_calculate_th_hmac_for_finish_req(
      89              :         spdm_context, session_info, &hash_size, hmac_data);
      90           15 :     if (!result) {
      91            0 :         return false;
      92              :     }
      93              : #endif /* LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT */
      94           15 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "th_curr hmac - "));
      95           15 :     LIBSPDM_INTERNAL_DUMP_DATA(hmac_data, hash_size);
      96           15 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "\n"));
      97              : 
      98           15 :     if (!libspdm_consttime_is_mem_equal(hmac, hmac_data, hash_size)) {
      99            2 :         LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR, "!!! verify_finish_req_hmac - FAIL !!!\n"));
     100            2 :         return false;
     101              :     }
     102           13 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "!!! verify_finish_req_hmac - PASS !!!\n"));
     103           13 :     return true;
     104              : }
     105              : 
     106              : #if LIBSPDM_ENABLE_CAPABILITY_MUT_AUTH_CAP
     107           11 : bool libspdm_verify_finish_req_signature(libspdm_context_t *spdm_context,
     108              :                                          libspdm_session_info_t *session_info,
     109              :                                          const void *sign_data,
     110              :                                          const size_t sign_data_size)
     111              : {
     112              :     bool result;
     113              :     void *context;
     114              :     uint8_t slot_id;
     115              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
     116              :     uint8_t *cert_chain_buffer;
     117              :     size_t cert_chain_buffer_size;
     118              :     uint8_t *mut_cert_chain_buffer;
     119              :     size_t mut_cert_chain_buffer_size;
     120              :     uint8_t *th_curr_data;
     121              :     size_t th_curr_data_size;
     122              :     libspdm_th_managed_buffer_t th_curr;
     123              :     const uint8_t *mut_cert_chain_data;
     124              :     size_t mut_cert_chain_data_size;
     125              :     const uint8_t *mut_cert_buffer;
     126              :     size_t mut_cert_buffer_size;
     127              : #endif
     128              : #if ((LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT) && (LIBSPDM_DEBUG_BLOCK_ENABLE)) || \
     129              :     !(LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT)
     130              :     uint8_t hash_data[LIBSPDM_MAX_HASH_SIZE];
     131              : #endif
     132              : #if !(LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT) || (LIBSPDM_DEBUG_PRINT_ENABLE)
     133              :     size_t hash_size;
     134              : 
     135           11 :     hash_size = libspdm_get_hash_size(spdm_context->connection_info.algorithm.base_hash_algo);
     136              : #endif
     137              : 
     138              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
     139              :     slot_id = spdm_context->connection_info.local_used_cert_chain_slot_id;
     140              :     LIBSPDM_ASSERT((slot_id < SPDM_MAX_SLOT_COUNT) || (slot_id == 0xFF));
     141              :     if (slot_id == 0xFF) {
     142              :         result = libspdm_get_local_public_key_buffer(
     143              :             spdm_context, (const void **)&cert_chain_buffer, &cert_chain_buffer_size);
     144              :     } else {
     145              :         result = libspdm_get_local_cert_chain_buffer(
     146              :             spdm_context, (const void **)&cert_chain_buffer, &cert_chain_buffer_size);
     147              :     }
     148              :     if (!result) {
     149              :         return false;
     150              :     }
     151              : 
     152              :     slot_id = spdm_context->connection_info.peer_used_cert_chain_slot_id;
     153              :     LIBSPDM_ASSERT((slot_id < SPDM_MAX_SLOT_COUNT) || (slot_id == 0xFF));
     154              :     if (slot_id == 0xFF) {
     155              :         result = libspdm_get_peer_public_key_buffer(
     156              :             spdm_context, (const void **)&mut_cert_chain_buffer, &mut_cert_chain_buffer_size);
     157              :     } else {
     158              :         result = libspdm_get_peer_cert_chain_buffer(
     159              :             spdm_context, (const void **)&mut_cert_chain_buffer, &mut_cert_chain_buffer_size);
     160              :     }
     161              :     if (!result) {
     162              :         return false;
     163              :     }
     164              : 
     165              :     result = libspdm_calculate_th_for_finish(
     166              :         spdm_context, session_info, cert_chain_buffer,
     167              :         cert_chain_buffer_size, mut_cert_chain_buffer,
     168              :         mut_cert_chain_buffer_size, &th_curr);
     169              :     if (!result) {
     170              :         return false;
     171              :     }
     172              :     th_curr_data = libspdm_get_managed_buffer(&th_curr);
     173              :     th_curr_data_size = libspdm_get_managed_buffer_size(&th_curr);
     174              : 
     175              :     /* Debug code only - required for debug print of th_curr below*/
     176              :     LIBSPDM_DEBUG_CODE(
     177              :         if (!libspdm_hash_all(
     178              :                 spdm_context->connection_info.algorithm.base_hash_algo,
     179              :                 th_curr_data, th_curr_data_size, hash_data)) {
     180              :         return false;
     181              :     }
     182              :         );
     183              : #else
     184           11 :     result = libspdm_calculate_th_hash_for_finish(
     185              :         spdm_context, session_info, &hash_size, hash_data);
     186           11 :     if (!result) {
     187            0 :         return false;
     188              :     }
     189              : #endif /* LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT */
     190           11 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "th_curr hash - "));
     191           11 :     LIBSPDM_INTERNAL_DUMP_DATA(hash_data, hash_size);
     192           11 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "\n"));
     193              : 
     194           11 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "signature - "));
     195           11 :     LIBSPDM_INTERNAL_DUMP_DATA(sign_data, sign_data_size);
     196           11 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "\n"));
     197              : 
     198           11 :     slot_id = spdm_context->connection_info.peer_used_cert_chain_slot_id;
     199           11 :     LIBSPDM_ASSERT((slot_id < SPDM_MAX_SLOT_COUNT) || (slot_id == 0xFF));
     200              : 
     201           11 :     if (slot_id == 0xFF) {
     202            1 :         result = libspdm_req_asym_get_public_key_from_der(
     203            1 :             spdm_context->connection_info.algorithm.req_base_asym_alg,
     204            1 :             spdm_context->local_context.peer_public_key_provision,
     205              :             spdm_context->local_context.peer_public_key_provision_size,
     206              :             &context);
     207            1 :         if (!result) {
     208            0 :             return false;
     209              :         }
     210              :     } else {
     211              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
     212              :         /* Get leaf cert from cert chain*/
     213              :         result = libspdm_get_peer_cert_chain_data(spdm_context,
     214              :                                                   (const void **)&mut_cert_chain_data,
     215              :                                                   &mut_cert_chain_data_size);
     216              :         if (!result) {
     217              :             return false;
     218              :         }
     219              : 
     220              :         result = libspdm_x509_get_cert_from_cert_chain(mut_cert_chain_data,
     221              :                                                        mut_cert_chain_data_size, -1,
     222              :                                                        &mut_cert_buffer,
     223              :                                                        &mut_cert_buffer_size);
     224              :         if (!result) {
     225              :             return false;
     226              :         }
     227              : 
     228              :         result = libspdm_req_asym_get_public_key_from_x509(
     229              :             spdm_context->connection_info.algorithm.req_base_asym_alg,
     230              :             mut_cert_buffer, mut_cert_buffer_size, &context);
     231              :         if (!result) {
     232              :             return false;
     233              :         }
     234              : #else
     235           10 :         context = spdm_context->connection_info.peer_used_cert_chain[slot_id].leaf_cert_public_key;
     236           10 :         LIBSPDM_ASSERT(context != NULL);
     237              : #endif
     238              :     }
     239              : 
     240              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
     241              :     result = libspdm_req_asym_verify_ex(
     242              :         spdm_context->connection_info.version, SPDM_FINISH,
     243              :         spdm_context->connection_info.algorithm.req_base_asym_alg,
     244              :         spdm_context->connection_info.algorithm.base_hash_algo,
     245              :         context, th_curr_data, th_curr_data_size, sign_data, sign_data_size,
     246              :         &spdm_context->spdm_10_11_verify_signature_endian);
     247              :     libspdm_req_asym_free(spdm_context->connection_info.algorithm.req_base_asym_alg, context);
     248              : #else
     249           11 :     result = libspdm_req_asym_verify_hash_ex(
     250           11 :         spdm_context->connection_info.version, SPDM_FINISH,
     251           11 :         spdm_context->connection_info.algorithm.req_base_asym_alg,
     252              :         spdm_context->connection_info.algorithm.base_hash_algo,
     253              :         context, hash_data, hash_size, sign_data, sign_data_size,
     254              :         &spdm_context->spdm_10_11_verify_signature_endian);
     255           11 :     if (slot_id == 0xFF) {
     256            1 :         libspdm_req_asym_free(spdm_context->connection_info.algorithm.req_base_asym_alg, context);
     257              :     }
     258              : #endif /* LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT */
     259              : 
     260           11 :     if (!result) {
     261            4 :         LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR, "!!! VerifyFinishSignature - FAIL !!!\n"));
     262            4 :         return false;
     263              :     }
     264            7 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "!!! VerifyFinishSignature - PASS !!!\n"));
     265              : 
     266            7 :     return true;
     267              : }
     268              : #endif /* LIBSPDM_ENABLE_CAPABILITY_MUT_AUTH_CAP */
     269              : 
     270           12 : bool libspdm_generate_finish_rsp_hmac(libspdm_context_t *spdm_context,
     271              :                                       libspdm_session_info_t *session_info,
     272              :                                       uint8_t *hmac)
     273              : {
     274              :     uint8_t hmac_data[LIBSPDM_MAX_HASH_SIZE];
     275              :     size_t hash_size;
     276              :     bool result;
     277              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
     278              :     uint8_t slot_id;
     279              :     uint8_t *cert_chain_buffer;
     280              :     size_t cert_chain_buffer_size;
     281              :     uint8_t *mut_cert_chain_buffer;
     282              :     size_t mut_cert_chain_buffer_size;
     283              :     uint8_t *th_curr_data;
     284              :     size_t th_curr_data_size;
     285              :     libspdm_th_managed_buffer_t th_curr;
     286              :     uint8_t hash_data[LIBSPDM_MAX_HASH_SIZE];
     287              : #endif
     288              : 
     289           12 :     hash_size = libspdm_get_hash_size(spdm_context->connection_info.algorithm.base_hash_algo);
     290              : 
     291              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
     292              :     slot_id = spdm_context->connection_info.local_used_cert_chain_slot_id;
     293              :     LIBSPDM_ASSERT((slot_id < SPDM_MAX_SLOT_COUNT) || (slot_id == 0xFF));
     294              :     if (slot_id == 0xFF) {
     295              :         result = libspdm_get_local_public_key_buffer(
     296              :             spdm_context, (const void **)&cert_chain_buffer, &cert_chain_buffer_size);
     297              :     } else {
     298              :         result = libspdm_get_local_cert_chain_buffer(
     299              :             spdm_context, (const void **)&cert_chain_buffer, &cert_chain_buffer_size);
     300              :     }
     301              :     if (!result) {
     302              :         return false;
     303              :     }
     304              : 
     305              :     if (session_info->mut_auth_requested != 0) {
     306              :         slot_id = spdm_context->connection_info.peer_used_cert_chain_slot_id;
     307              :         LIBSPDM_ASSERT((slot_id < SPDM_MAX_SLOT_COUNT) || (slot_id == 0xFF));
     308              :         if (slot_id == 0xFF) {
     309              :             result = libspdm_get_peer_public_key_buffer(
     310              :                 spdm_context, (const void **)&mut_cert_chain_buffer, &mut_cert_chain_buffer_size);
     311              :         } else {
     312              :             result = libspdm_get_peer_cert_chain_buffer(
     313              :                 spdm_context, (const void **)&mut_cert_chain_buffer, &mut_cert_chain_buffer_size);
     314              :         }
     315              :         if (!result) {
     316              :             return false;
     317              :         }
     318              :     } else {
     319              :         mut_cert_chain_buffer = NULL;
     320              :         mut_cert_chain_buffer_size = 0;
     321              :     }
     322              : 
     323              :     result = libspdm_calculate_th_for_finish(
     324              :         spdm_context, session_info, cert_chain_buffer,
     325              :         cert_chain_buffer_size, mut_cert_chain_buffer,
     326              :         mut_cert_chain_buffer_size, &th_curr);
     327              :     if (!result) {
     328              :         return false;
     329              :     }
     330              :     th_curr_data = libspdm_get_managed_buffer(&th_curr);
     331              :     th_curr_data_size = libspdm_get_managed_buffer_size(&th_curr);
     332              : 
     333              :     result = libspdm_hash_all (spdm_context->connection_info.algorithm.base_hash_algo,
     334              :                                th_curr_data, th_curr_data_size, hash_data);
     335              :     if (!result) {
     336              :         return false;
     337              :     }
     338              : 
     339              :     result = libspdm_hmac_all_with_response_finished_key(
     340              :         session_info->secured_message_context, hash_data, hash_size, hmac_data);
     341              :     if (!result) {
     342              :         return false;
     343              :     }
     344              : #else
     345           12 :     result = libspdm_calculate_th_hmac_for_finish_rsp(
     346              :         spdm_context, session_info, &hash_size, hmac_data);
     347           12 :     if (!result) {
     348            0 :         return false;
     349              :     }
     350              : #endif
     351           12 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "th_curr hmac - "));
     352           12 :     LIBSPDM_INTERNAL_DUMP_DATA(hmac_data, hash_size);
     353           12 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "\n"));
     354              : 
     355           12 :     libspdm_copy_mem(hmac, hash_size, hmac_data, hash_size);
     356              : 
     357           12 :     return true;
     358              : }
     359              : 
     360           28 : libspdm_return_t libspdm_get_response_finish(libspdm_context_t *spdm_context, size_t request_size,
     361              :                                              const void *request,
     362              :                                              size_t *response_size,
     363              :                                              void *response)
     364              : {
     365              :     uint32_t session_id;
     366              :     bool result;
     367              :     uint32_t hmac_size;
     368              :     uint32_t signature_size;
     369              :     uint8_t req_slot_id;
     370              :     const spdm_finish_request_t *spdm_request;
     371              :     spdm_finish_response_t *spdm_response;
     372              :     libspdm_session_info_t *session_info;
     373              :     uint8_t th2_hash_data[LIBSPDM_MAX_HASH_SIZE];
     374              :     libspdm_return_t status;
     375              :     libspdm_session_state_t session_state;
     376              : 
     377           28 :     spdm_request = request;
     378              : 
     379              :     /* -=[Check Parameters Phase]=- */
     380           28 :     LIBSPDM_ASSERT(spdm_request->header.request_response_code == SPDM_FINISH);
     381              : 
     382           28 :     if (libspdm_get_connection_version(spdm_context) < SPDM_MESSAGE_VERSION_11) {
     383            0 :         return libspdm_generate_error_response(spdm_context,
     384              :                                                SPDM_ERROR_CODE_UNSUPPORTED_REQUEST,
     385              :                                                SPDM_FINISH,
     386              :                                                response_size, response);
     387              :     }
     388              : 
     389           28 :     if (spdm_request->header.spdm_version != libspdm_get_connection_version(spdm_context)) {
     390            0 :         return libspdm_generate_error_response(spdm_context,
     391              :                                                SPDM_ERROR_CODE_VERSION_MISMATCH, 0,
     392              :                                                response_size, response);
     393              :     }
     394           28 :     if (spdm_context->response_state != LIBSPDM_RESPONSE_STATE_NORMAL) {
     395            3 :         return libspdm_responder_handle_response_state(
     396              :             spdm_context,
     397            3 :             spdm_request->header.request_response_code,
     398              :             response_size, response);
     399              :     }
     400           25 :     if (!libspdm_is_capabilities_flag_supported(
     401              :             spdm_context, false,
     402              :             SPDM_GET_CAPABILITIES_REQUEST_FLAGS_KEY_EX_CAP,
     403              :             SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_KEY_EX_CAP)) {
     404            1 :         return libspdm_generate_error_response(
     405              :             spdm_context, SPDM_ERROR_CODE_UNSUPPORTED_REQUEST,
     406              :             SPDM_FINISH, response_size, response);
     407              :     }
     408           24 :     if (spdm_context->connection_info.connection_state < LIBSPDM_CONNECTION_STATE_NEGOTIATED) {
     409            1 :         return libspdm_generate_error_response(spdm_context,
     410              :                                                SPDM_ERROR_CODE_UNEXPECTED_REQUEST,
     411              :                                                0, response_size, response);
     412              :     }
     413           23 :     if (!libspdm_is_capabilities_flag_supported(
     414              :             spdm_context, false,
     415              :             SPDM_GET_CAPABILITIES_REQUEST_FLAGS_HANDSHAKE_IN_THE_CLEAR_CAP,
     416              :             SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_HANDSHAKE_IN_THE_CLEAR_CAP)) {
     417              :         /* No handshake in clear, then it must be in a session.*/
     418            1 :         if (!spdm_context->last_spdm_request_session_id_valid) {
     419            0 :             if (libspdm_get_connection_version(spdm_context) >= SPDM_MESSAGE_VERSION_12) {
     420            0 :                 return libspdm_generate_error_response(
     421              :                     spdm_context, SPDM_ERROR_CODE_SESSION_REQUIRED, 0, response_size, response);
     422              :             } else {
     423            0 :                 return libspdm_generate_error_response(
     424              :                     spdm_context, SPDM_ERROR_CODE_UNSPECIFIED, 0, response_size, response);
     425              :             }
     426              :         }
     427              :     } else {
     428              :         /* handshake in clear, then it must not be in a session.*/
     429           22 :         if (spdm_context->last_spdm_request_session_id_valid) {
     430            0 :             if (libspdm_get_connection_version(spdm_context) >= SPDM_MESSAGE_VERSION_12) {
     431            0 :                 return libspdm_generate_error_response(
     432              :                     spdm_context, SPDM_ERROR_CODE_SESSION_REQUIRED, 0, response_size, response);
     433              :             } else {
     434            0 :                 return libspdm_generate_error_response(
     435              :                     spdm_context, SPDM_ERROR_CODE_UNSPECIFIED, 0, response_size, response);
     436              :             }
     437              :         }
     438              :     }
     439           23 :     if (spdm_context->last_spdm_request_session_id_valid) {
     440            1 :         session_id = spdm_context->last_spdm_request_session_id;
     441              :     } else {
     442           22 :         session_id = spdm_context->latest_session_id;
     443              :     }
     444           23 :     session_info = libspdm_get_session_info_via_session_id(spdm_context, session_id);
     445           23 :     if (session_info == NULL) {
     446            0 :         if (libspdm_get_connection_version(spdm_context) >= SPDM_MESSAGE_VERSION_12) {
     447            0 :             return libspdm_generate_error_response(spdm_context,
     448              :                                                    SPDM_ERROR_CODE_SESSION_REQUIRED, 0,
     449              :                                                    response_size, response);
     450              :         } else {
     451            0 :             return libspdm_generate_error_response(spdm_context,
     452              :                                                    SPDM_ERROR_CODE_UNSPECIFIED, 0,
     453              :                                                    response_size, response);
     454              :         }
     455              :     }
     456           23 :     if (session_info->use_psk) {
     457            0 :         return libspdm_generate_error_response(spdm_context,
     458              :                                                SPDM_ERROR_CODE_UNEXPECTED_REQUEST, 0,
     459              :                                                response_size, response);
     460              :     }
     461           23 :     session_state = libspdm_secured_message_get_session_state(
     462              :         session_info->secured_message_context);
     463           23 :     if (session_state != LIBSPDM_SESSION_STATE_HANDSHAKING) {
     464            1 :         return libspdm_generate_error_response(spdm_context,
     465              :                                                SPDM_ERROR_CODE_UNEXPECTED_REQUEST, 0,
     466              :                                                response_size, response);
     467              :     }
     468              : 
     469           22 :     if (((session_info->mut_auth_requested == 0) &&
     470            9 :          ((spdm_request->header.param1 & SPDM_FINISH_REQUEST_ATTRIBUTES_SIGNATURE_INCLUDED) !=
     471           22 :           0)) ||
     472           22 :         ((session_info->mut_auth_requested != 0) &&
     473           13 :          ((spdm_request->header.param1 & SPDM_FINISH_REQUEST_ATTRIBUTES_SIGNATURE_INCLUDED) ==
     474              :           0))) {
     475            0 :         return libspdm_generate_error_response(spdm_context,
     476              :                                                SPDM_ERROR_CODE_INVALID_REQUEST, 0,
     477              :                                                response_size, response);
     478              :     }
     479              : 
     480           22 :     hmac_size = libspdm_get_hash_size(spdm_context->connection_info.algorithm.base_hash_algo);
     481           22 :     signature_size = 0;
     482              : #if LIBSPDM_ENABLE_CAPABILITY_MUT_AUTH_CAP
     483           22 :     if (session_info->mut_auth_requested != 0) {
     484           13 :         signature_size = libspdm_get_req_asym_signature_size(
     485           13 :             spdm_context->connection_info.algorithm.req_base_asym_alg);
     486              :     }
     487              : #endif /* LIBSPDM_ENABLE_CAPABILITY_MUT_AUTH_CAP */
     488              : 
     489           22 :     if (request_size < sizeof(spdm_finish_request_t) + signature_size + hmac_size) {
     490            1 :         return libspdm_generate_error_response(spdm_context,
     491              :                                                SPDM_ERROR_CODE_INVALID_REQUEST, 0,
     492              :                                                response_size, response);
     493              :     }
     494              : 
     495           21 :     if ((spdm_request->header.param1 & SPDM_FINISH_REQUEST_ATTRIBUTES_SIGNATURE_INCLUDED) != 0) {
     496           13 :         req_slot_id = spdm_request->header.param2;
     497           13 :         if ((req_slot_id != 0xFF) && (req_slot_id >= SPDM_MAX_SLOT_COUNT)) {
     498            1 :             return libspdm_generate_error_response(spdm_context,
     499              :                                                    SPDM_ERROR_CODE_INVALID_REQUEST, 0,
     500              :                                                    response_size, response);
     501              :         }
     502              : 
     503           12 :         if (libspdm_is_capabilities_flag_supported(
     504              :                 spdm_context, false,
     505              :                 SPDM_GET_CAPABILITIES_REQUEST_FLAGS_HANDSHAKE_IN_THE_CLEAR_CAP,
     506              :                 SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_HANDSHAKE_IN_THE_CLEAR_CAP)) {
     507           12 :             if (((session_info->mut_auth_requested ==
     508           11 :                   SPDM_KEY_EXCHANGE_RESPONSE_MUT_AUTH_REQUESTED_WITH_ENCAP_REQUEST) ||
     509           11 :                  (session_info->mut_auth_requested ==
     510            1 :                   SPDM_KEY_EXCHANGE_RESPONSE_MUT_AUTH_REQUESTED_WITH_GET_DIGESTS)) &&
     511            1 :                 (req_slot_id != spdm_context->encap_context.req_slot_id)) {
     512            1 :                 return libspdm_generate_error_response(spdm_context,
     513              :                                                        SPDM_ERROR_CODE_INVALID_REQUEST, 0,
     514              :                                                        response_size, response);
     515              :             }
     516              :         }
     517              :     }
     518              : 
     519           19 :     libspdm_reset_message_buffer_via_request_code(spdm_context, session_info,
     520           19 :                                                   spdm_request->header.request_response_code);
     521              : 
     522           19 :     status = libspdm_append_message_f(spdm_context, session_info, false, request,
     523              :                                       sizeof(spdm_finish_request_t));
     524           19 :     if (LIBSPDM_STATUS_IS_ERROR(status)) {
     525            0 :         return libspdm_generate_error_response(spdm_context,
     526              :                                                SPDM_ERROR_CODE_UNSPECIFIED, 0,
     527              :                                                response_size, response);
     528              :     }
     529              : #if LIBSPDM_ENABLE_CAPABILITY_MUT_AUTH_CAP
     530           19 :     if (session_info->mut_auth_requested != 0) {
     531           11 :         result = libspdm_verify_finish_req_signature(
     532              :             spdm_context, session_info,
     533              :             (const uint8_t *)request + sizeof(spdm_finish_request_t), signature_size);
     534           11 :         if (!result) {
     535            4 :             if((spdm_context->handle_error_return_policy &
     536              :                 LIBSPDM_DATA_HANDLE_ERROR_RETURN_POLICY_DROP_ON_DECRYPT_ERROR) == 0) {
     537            4 :                 return libspdm_generate_error_response(
     538              :                     spdm_context, SPDM_ERROR_CODE_DECRYPT_ERROR, 0,
     539              :                     response_size, response);
     540              :             } else {
     541              :                 /**
     542              :                  * just ignore this message
     543              :                  * return UNSUPPORTED and clear response_size to continue the dispatch without send response.
     544              :                  **/
     545            0 :                 *response_size = 0;
     546            0 :                 return LIBSPDM_STATUS_UNSUPPORTED_CAP;
     547              :             }
     548              :         }
     549            7 :         status = libspdm_append_message_f(
     550              :             spdm_context, session_info, false,
     551              :             (const uint8_t *)request + sizeof(spdm_finish_request_t), signature_size);
     552            7 :         if (LIBSPDM_STATUS_IS_ERROR(status)) {
     553            0 :             return libspdm_generate_error_response(
     554              :                 spdm_context, SPDM_ERROR_CODE_UNSPECIFIED,
     555              :                 0, response_size, response);
     556              :         }
     557              :     }
     558              : #endif /* LIBSPDM_ENABLE_CAPABILITY_MUT_AUTH_CAP */
     559              : 
     560           15 :     result = libspdm_verify_finish_req_hmac(
     561           15 :         spdm_context, session_info, (const uint8_t *)request + signature_size +
     562              :         sizeof(spdm_finish_request_t), hmac_size);
     563           15 :     if (!result) {
     564            2 :         if((spdm_context->handle_error_return_policy &
     565              :             LIBSPDM_DATA_HANDLE_ERROR_RETURN_POLICY_DROP_ON_DECRYPT_ERROR) == 0) {
     566            2 :             return libspdm_generate_error_response(
     567              :                 spdm_context, SPDM_ERROR_CODE_DECRYPT_ERROR, 0,
     568              :                 response_size, response);
     569              :         } else {
     570              :             /**
     571              :              * just ignore this message
     572              :              * return UNSUPPORTED and clear response_size to continue the dispatch without send response
     573              :              **/
     574            0 :             *response_size = 0;
     575            0 :             return LIBSPDM_STATUS_UNSUPPORTED_CAP;
     576              :         }
     577              :     }
     578              : 
     579           13 :     status = libspdm_append_message_f(spdm_context, session_info, false,
     580           13 :                                       (const uint8_t *)request + signature_size +
     581              :                                       sizeof(spdm_finish_request_t),
     582              :                                       hmac_size);
     583           13 :     if (LIBSPDM_STATUS_IS_ERROR(status)) {
     584            0 :         return libspdm_generate_error_response(spdm_context,
     585              :                                                SPDM_ERROR_CODE_UNSPECIFIED, 0,
     586              :                                                response_size, response);
     587              :     }
     588              : 
     589           13 :     if (!libspdm_is_capabilities_flag_supported(
     590              :             spdm_context, false,
     591              :             SPDM_GET_CAPABILITIES_REQUEST_FLAGS_HANDSHAKE_IN_THE_CLEAR_CAP,
     592              :             SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_HANDSHAKE_IN_THE_CLEAR_CAP)) {
     593            1 :         hmac_size = 0;
     594              :     }
     595              : 
     596           13 :     LIBSPDM_ASSERT(*response_size >= sizeof(spdm_finish_response_t) + hmac_size);
     597           13 :     *response_size = sizeof(spdm_finish_response_t) + hmac_size;
     598           13 :     libspdm_zero_mem(response, *response_size);
     599           13 :     spdm_response = response;
     600              : 
     601           13 :     spdm_response->header.spdm_version = spdm_request->header.spdm_version;
     602           13 :     spdm_response->header.request_response_code = SPDM_FINISH_RSP;
     603           13 :     spdm_response->header.param1 = 0;
     604           13 :     spdm_response->header.param2 = 0;
     605              : 
     606           13 :     status = libspdm_append_message_f(spdm_context, session_info, false, spdm_response,
     607              :                                       sizeof(spdm_finish_response_t));
     608           13 :     if (LIBSPDM_STATUS_IS_ERROR(status)) {
     609            0 :         return libspdm_generate_error_response(spdm_context,
     610              :                                                SPDM_ERROR_CODE_UNSPECIFIED, 0,
     611              :                                                response_size, response);
     612              :     }
     613              : 
     614           13 :     if (libspdm_is_capabilities_flag_supported(
     615              :             spdm_context, false,
     616              :             SPDM_GET_CAPABILITIES_REQUEST_FLAGS_HANDSHAKE_IN_THE_CLEAR_CAP,
     617              :             SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_HANDSHAKE_IN_THE_CLEAR_CAP)) {
     618           12 :         result = libspdm_generate_finish_rsp_hmac(
     619              :             spdm_context, session_info, (uint8_t *)spdm_response + sizeof(spdm_finish_request_t));
     620           12 :         if (!result) {
     621            0 :             return libspdm_generate_error_response(
     622              :                 spdm_context,
     623              :                 SPDM_ERROR_CODE_UNSPECIFIED,
     624              :                 0, response_size, response);
     625              :         }
     626              : 
     627           12 :         status = libspdm_append_message_f(
     628              :             spdm_context, session_info, false,
     629              :             (uint8_t *)spdm_response + sizeof(spdm_finish_request_t), hmac_size);
     630           12 :         if (LIBSPDM_STATUS_IS_ERROR(status)) {
     631            0 :             return libspdm_generate_error_response(
     632              :                 spdm_context, SPDM_ERROR_CODE_UNSPECIFIED,
     633              :                 0, response_size, response);
     634              :         }
     635              :     }
     636              : 
     637           13 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "libspdm_generate_session_data_key[%x]\n", session_id));
     638           13 :     result = libspdm_calculate_th2_hash(spdm_context, session_info, false, th2_hash_data);
     639           13 :     if (!result) {
     640            0 :         return libspdm_generate_error_response(spdm_context,
     641              :                                                SPDM_ERROR_CODE_UNSPECIFIED, 0,
     642              :                                                response_size, response);
     643              :     }
     644           13 :     result = libspdm_generate_session_data_key(
     645              :         session_info->secured_message_context, th2_hash_data);
     646           13 :     if (!result) {
     647            0 :         return libspdm_generate_error_response(spdm_context,
     648              :                                                SPDM_ERROR_CODE_UNSPECIFIED, 0,
     649              :                                                response_size, response);
     650              :     }
     651              : 
     652              :     #if LIBSPDM_ENABLE_CAPABILITY_HBEAT_CAP
     653           13 :     if (libspdm_is_capabilities_flag_supported(
     654              :             spdm_context, false,
     655              :             SPDM_GET_CAPABILITIES_REQUEST_FLAGS_HBEAT_CAP,
     656              :             SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_HBEAT_CAP)) {
     657            0 :         result = libspdm_start_watchdog(
     658            0 :             session_id, spdm_context->local_context.heartbeat_period * 2);
     659            0 :         if (!result) {
     660            0 :             return libspdm_generate_error_response(spdm_context,
     661              :                                                    SPDM_ERROR_CODE_UNSPECIFIED, 0,
     662              :                                                    response_size, response);
     663              :         }
     664              :     }
     665              :     #endif /* LIBSPDM_ENABLE_CAPABILITY_HBEAT_CAP */
     666              : 
     667           13 :     return LIBSPDM_STATUS_SUCCESS;
     668              : }
     669              : 
     670              : #endif /* LIBSPDM_ENABLE_CAPABILITY_KEY_EX_CAP */
        

Generated by: LCOV version 2.0-1