LCOV - code coverage report
Current view: top level - spdm_responder_lib - libspdm_rsp_psk_exchange_rsp.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 79.9 % 234 187
Test Date: 2026-10-01 20:56:25 Functions: 100.0 % 2 2
Branches: 68.3 % 126 86

             Branch data     Line data    Source code
       1                 :             : /**
       2                 :             :  *  Copyright Notice:
       3                 :             :  *  Copyright 2021-2026 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_PSK_CAP
      11                 :             : 
      12                 :             : /**
      13                 :             :  * This function generates the PSK exchange HMAC based upon TH.
      14                 :             :  *
      15                 :             :  * @param  spdm_context                  A pointer to the SPDM context.
      16                 :             :  * @param  session_info                  The session info of an SPDM session.
      17                 :             :  * @param  hmac                         The buffer to store the PSK exchange HMAC.
      18                 :             :  *
      19                 :             :  * @retval true  PSK exchange HMAC is generated.
      20                 :             :  * @retval false PSK exchange HMAC is not generated.
      21                 :             :  **/
      22                 :          14 : static bool libspdm_generate_psk_exchange_rsp_hmac(libspdm_context_t *spdm_context,
      23                 :             :                                                    libspdm_session_info_t *session_info,
      24                 :             :                                                    uint8_t *hmac)
      25                 :             : {
      26                 :             :     uint8_t hmac_data[LIBSPDM_MAX_HASH_SIZE];
      27                 :             :     size_t hash_size;
      28                 :             :     bool result;
      29                 :             : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
      30                 :             :     uint8_t *th_curr_data;
      31                 :             :     size_t th_curr_data_size;
      32                 :             :     libspdm_th_managed_buffer_t th_curr;
      33                 :             :     uint8_t hash_data[LIBSPDM_MAX_HASH_SIZE];
      34                 :             : #endif
      35                 :             : 
      36                 :          14 :     hash_size = libspdm_get_hash_size(spdm_context->connection_info.algorithm.base_hash_algo);
      37                 :             : 
      38                 :             : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
      39                 :             :     result = libspdm_calculate_th_for_exchange(spdm_context, session_info,
      40                 :             :                                                NULL, 0, &th_curr);
      41                 :             :     if (!result) {
      42                 :             :         return false;
      43                 :             :     }
      44                 :             :     th_curr_data = libspdm_get_managed_buffer(&th_curr);
      45                 :             :     th_curr_data_size = libspdm_get_managed_buffer_size(&th_curr);
      46                 :             : 
      47                 :             :     result = libspdm_hash_all (spdm_context->connection_info.algorithm.base_hash_algo,
      48                 :             :                                th_curr_data, th_curr_data_size, hash_data);
      49                 :             :     if (!result) {
      50                 :             :         return false;
      51                 :             :     }
      52                 :             : 
      53                 :             :     result = libspdm_hmac_all_with_response_finished_key(
      54                 :             :         session_info->secured_message_context, hash_data,
      55                 :             :         hash_size, hmac_data);
      56                 :             :     if (!result) {
      57                 :             :         return false;
      58                 :             :     }
      59                 :             : #else
      60                 :          14 :     result = libspdm_calculate_th_hmac_for_exchange_rsp(
      61                 :             :         spdm_context, session_info, &hash_size, hmac_data);
      62         [ -  + ]:          14 :     if (!result) {
      63                 :           0 :         return false;
      64                 :             :     }
      65                 :             : #endif
      66                 :          14 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "th_curr hmac - "));
      67                 :          14 :     LIBSPDM_INTERNAL_DUMP_DATA(hmac_data, hash_size);
      68                 :          14 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "\n"));
      69                 :             : 
      70                 :          14 :     libspdm_copy_mem(hmac, hash_size, hmac_data, hash_size);
      71                 :             : 
      72                 :          14 :     return true;
      73                 :             : }
      74                 :             : 
      75                 :          22 : libspdm_return_t libspdm_get_response_psk_exchange(libspdm_context_t *spdm_context,
      76                 :             :                                                    size_t request_size,
      77                 :             :                                                    const void *request,
      78                 :             :                                                    size_t *response_size,
      79                 :             :                                                    void *response)
      80                 :             : {
      81                 :             :     const spdm_psk_exchange_request_t *spdm_request;
      82                 :             :     spdm_psk_exchange_response_t *spdm_response;
      83                 :             :     bool result;
      84                 :             :     uint32_t session_id;
      85                 :             :     uint32_t measurement_summary_hash_size;
      86                 :             :     uint32_t hmac_size;
      87                 :             :     const uint8_t *req_opaque_data;
      88                 :             :     uint8_t *rsp_opaque_data;
      89                 :             :     uint8_t *ptr;
      90                 :             :     libspdm_session_info_t *session_info;
      91                 :             :     size_t total_size;
      92                 :             :     uint16_t req_session_id;
      93                 :             :     uint16_t rsp_session_id;
      94                 :             :     libspdm_return_t status;
      95                 :             :     size_t opaque_psk_exchange_rsp_size;
      96                 :             :     bool use_default_opaque_data;
      97                 :             :     uint8_t th1_hash_data[LIBSPDM_MAX_HASH_SIZE];
      98                 :             :     uint8_t th2_hash_data[LIBSPDM_MAX_HASH_SIZE];
      99                 :             :     uint32_t algo_size;
     100                 :             :     uint16_t context_length;
     101                 :             :     const void *psk_hint;
     102                 :             :     size_t psk_hint_size;
     103                 :             :     spdm_version_number_t secured_message_version;
     104                 :          22 :     uint8_t peer_aead_limit_exponent = SECURED_MESSAGE_AEAD_LIMIT_EXPONENT_DEFAULT;
     105                 :             : 
     106                 :          22 :     spdm_request = request;
     107                 :             : 
     108                 :             :     /* -=[Check Parameters Phase]=- */
     109         [ -  + ]:          22 :     LIBSPDM_ASSERT(spdm_request->header.request_response_code == SPDM_PSK_EXCHANGE);
     110                 :             : 
     111         [ -  + ]:          22 :     if (libspdm_get_connection_version(spdm_context) < SPDM_MESSAGE_VERSION_11) {
     112                 :           0 :         return libspdm_generate_error_response(spdm_context,
     113                 :             :                                                SPDM_ERROR_CODE_UNSUPPORTED_REQUEST,
     114                 :             :                                                SPDM_PSK_EXCHANGE,
     115                 :             :                                                response_size, response);
     116                 :             :     }
     117                 :             : 
     118         [ -  + ]:          22 :     if (spdm_request->header.spdm_version != libspdm_get_connection_version(spdm_context)) {
     119                 :           0 :         return libspdm_generate_error_response(spdm_context,
     120                 :             :                                                SPDM_ERROR_CODE_VERSION_MISMATCH, 0,
     121                 :             :                                                response_size, response);
     122                 :             :     }
     123         [ +  + ]:          22 :     if (spdm_context->response_state != LIBSPDM_RESPONSE_STATE_NORMAL) {
     124                 :           3 :         return libspdm_responder_handle_response_state(
     125                 :             :             spdm_context,
     126                 :           3 :             spdm_request->header.request_response_code,
     127                 :             :             response_size, response);
     128                 :             :     }
     129                 :             :     /* Check capabilities even if GET_CAPABILITIES is not sent.
     130                 :             :      * Assuming capabilities are provisioned.*/
     131         [ -  + ]:          19 :     if (!libspdm_is_capabilities_flag_supported(
     132                 :             :             spdm_context, false,
     133                 :             :             SPDM_GET_CAPABILITIES_REQUEST_FLAGS_PSK_CAP,
     134                 :             :             SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_PSK_CAP)) {
     135                 :           0 :         return libspdm_generate_error_response(
     136                 :             :             spdm_context, SPDM_ERROR_CODE_UNSUPPORTED_REQUEST,
     137                 :             :             SPDM_PSK_EXCHANGE, response_size, response);
     138                 :             :     }
     139                 :             : 
     140                 :             :     /* While clearing MAC_CAP and setting ENCRYPT_CAP is legal according to DSP0274, libspdm
     141                 :             :      * also implements DSP0277 secure messages, which requires at least MAC_CAP to be set.
     142                 :             :      */
     143         [ +  + ]:          19 :     if (!libspdm_is_capabilities_flag_supported(
     144                 :             :             spdm_context, false,
     145                 :             :             SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MAC_CAP,
     146                 :             :             SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MAC_CAP)) {
     147                 :           1 :         return libspdm_generate_error_response(
     148                 :             :             spdm_context, SPDM_ERROR_CODE_INVALID_REQUEST,
     149                 :             :             SPDM_KEY_EXCHANGE, response_size, response);
     150                 :             :     }
     151                 :             : 
     152         [ +  + ]:          18 :     if (spdm_context->connection_info.connection_state < LIBSPDM_CONNECTION_STATE_NEGOTIATED) {
     153                 :           1 :         return libspdm_generate_error_response(spdm_context,
     154                 :             :                                                SPDM_ERROR_CODE_UNEXPECTED_REQUEST,
     155                 :             :                                                0, response_size, response);
     156                 :             :     }
     157         [ +  + ]:          17 :     if (libspdm_get_connection_version(spdm_context) >= SPDM_MESSAGE_VERSION_12) {
     158         [ -  + ]:           3 :         if ((spdm_context->connection_info.algorithm.other_params_support &
     159                 :             :              SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_MASK) != SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_1) {
     160                 :           0 :             return libspdm_generate_error_response(
     161                 :             :                 spdm_context, SPDM_ERROR_CODE_INVALID_REQUEST,
     162                 :             :                 0, response_size, response);
     163                 :             :         }
     164                 :             :     }
     165         [ -  + ]:          17 :     if (spdm_context->last_spdm_request_session_id_valid) {
     166                 :           0 :         return libspdm_generate_error_response(spdm_context,
     167                 :             :                                                SPDM_ERROR_CODE_UNEXPECTED_REQUEST,
     168                 :             :                                                0, response_size, response);
     169                 :             :     }
     170                 :             : 
     171                 :             :     {
     172                 :             :         /* Double check if algorithm has been provisioned, because NEGOTIATE_ALGORITHMS might be skipped.*/
     173         [ -  + ]:          17 :         if (libspdm_is_capabilities_flag_supported(
     174                 :             :                 spdm_context, true, 0,
     175                 :             :                 SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP)) {
     176                 :           0 :             if (spdm_context->connection_info.algorithm
     177         [ #  # ]:           0 :                 .measurement_spec != SPDM_MEASUREMENT_SPECIFICATION_DMTF) {
     178                 :           0 :                 return libspdm_generate_error_response(
     179                 :             :                     spdm_context,
     180                 :             :                     SPDM_ERROR_CODE_INVALID_REQUEST,
     181                 :             :                     0, response_size,
     182                 :             :                     response);
     183                 :             :             }
     184                 :           0 :             algo_size = libspdm_get_measurement_hash_size(
     185                 :             :                 spdm_context->connection_info.algorithm
     186                 :             :                 .measurement_hash_algo);
     187         [ #  # ]:           0 :             if (algo_size == 0) {
     188                 :           0 :                 return libspdm_generate_error_response(
     189                 :             :                     spdm_context,
     190                 :             :                     SPDM_ERROR_CODE_INVALID_REQUEST,
     191                 :             :                     0, response_size,
     192                 :             :                     response);
     193                 :             :             }
     194                 :             :         }
     195                 :          17 :         algo_size = libspdm_get_hash_size(spdm_context->connection_info.algorithm.base_hash_algo);
     196         [ -  + ]:          17 :         if (algo_size == 0) {
     197                 :           0 :             return libspdm_generate_error_response(
     198                 :             :                 spdm_context,
     199                 :             :                 SPDM_ERROR_CODE_INVALID_REQUEST,
     200                 :             :                 0, response_size, response);
     201                 :             :         }
     202         [ -  + ]:          17 :         if (spdm_context->connection_info.algorithm.key_schedule !=
     203                 :             :             SPDM_ALGORITHMS_KEY_SCHEDULE_SPDM) {
     204                 :           0 :             return libspdm_generate_error_response(
     205                 :             :                 spdm_context,
     206                 :             :                 SPDM_ERROR_CODE_INVALID_REQUEST,
     207                 :             :                 0, response_size, response);
     208                 :             :         }
     209                 :             :     }
     210                 :             : 
     211         [ +  + ]:          17 :     if (spdm_request->header.param1 > 0) {
     212         [ +  + ]:           4 :         if (!libspdm_is_capabilities_flag_supported(
     213                 :             :                 spdm_context, false,
     214                 :           3 :                 0, SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP) ||
     215         [ +  - ]:           3 :             (spdm_context->connection_info.algorithm.measurement_spec == 0) ||
     216         [ -  + ]:           3 :             (spdm_context->connection_info.algorithm.measurement_hash_algo == 0) ) {
     217                 :           1 :             return libspdm_generate_error_response(
     218                 :             :                 spdm_context, SPDM_ERROR_CODE_INVALID_REQUEST,
     219                 :             :                 0, response_size, response);
     220                 :             :         }
     221                 :             :     }
     222                 :             : 
     223                 :          16 :     measurement_summary_hash_size = libspdm_get_measurement_summary_hash_size(
     224                 :          16 :         spdm_context, false, spdm_request->header.param1);
     225         [ +  + ]:          16 :     if ((measurement_summary_hash_size == 0) &&
     226         [ +  + ]:          14 :         (spdm_request->header.param1 != SPDM_PSK_EXCHANGE_REQUEST_NO_MEASUREMENT_SUMMARY_HASH)) {
     227                 :           1 :         return libspdm_generate_error_response(spdm_context,
     228                 :             :                                                SPDM_ERROR_CODE_INVALID_REQUEST,
     229                 :             :                                                0, response_size, response);
     230                 :             :     }
     231                 :             : 
     232                 :          15 :     hmac_size = libspdm_get_hash_size(spdm_context->connection_info.algorithm.base_hash_algo);
     233                 :             : 
     234         [ -  + ]:          15 :     if (request_size < sizeof(spdm_psk_exchange_request_t)) {
     235                 :           0 :         return libspdm_generate_error_response(spdm_context,
     236                 :             :                                                SPDM_ERROR_CODE_INVALID_REQUEST, 0,
     237                 :             :                                                response_size, response);
     238                 :             :     }
     239                 :          15 :     if (request_size < sizeof(spdm_psk_exchange_request_t) +
     240                 :          15 :         spdm_request->psk_hint_length +
     241                 :          15 :         spdm_request->context_length +
     242         [ +  + ]:          15 :         spdm_request->opaque_length) {
     243                 :           1 :         return libspdm_generate_error_response(spdm_context,
     244                 :             :                                                SPDM_ERROR_CODE_INVALID_REQUEST, 0,
     245                 :             :                                                response_size, response);
     246                 :             :     }
     247                 :          14 :     request_size = sizeof(spdm_psk_exchange_request_t) +
     248                 :          14 :                    spdm_request->psk_hint_length +
     249                 :          14 :                    spdm_request->context_length +
     250                 :          14 :                    spdm_request->opaque_length;
     251                 :             : 
     252         [ +  + ]:          14 :     if (libspdm_is_capabilities_flag_supported(
     253                 :             :             spdm_context, false, 0,
     254                 :             :             SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_PSK_CAP_RESPONDER_WITH_CONTEXT)) {
     255                 :          12 :         context_length = LIBSPDM_PSK_CONTEXT_LENGTH;
     256                 :             :     } else {
     257                 :           2 :         context_length = 0;
     258                 :             :     }
     259                 :             : 
     260         [ +  + ]:          14 :     if (spdm_request->psk_hint_length == 0) {
     261                 :           2 :         psk_hint_size = 0;
     262                 :           2 :         psk_hint = NULL;
     263         [ +  - ]:          12 :     } else if (spdm_request->psk_hint_length <= LIBSPDM_PSK_MAX_HINT_LENGTH ) {
     264                 :          12 :         psk_hint_size = spdm_request->psk_hint_length;
     265                 :          12 :         psk_hint = (const uint8_t *)request +
     266                 :             :                    sizeof(spdm_psk_exchange_request_t);
     267                 :             :     } else {
     268                 :           0 :         return libspdm_generate_error_response(
     269                 :             :             spdm_context, SPDM_ERROR_CODE_INVALID_REQUEST, 0,
     270                 :             :             response_size, response);
     271                 :             :     }
     272                 :             : 
     273                 :          14 :     secured_message_version = 0;
     274                 :          14 :     opaque_psk_exchange_rsp_size = 0;
     275         [ +  + ]:          14 :     if (spdm_request->opaque_length != 0) {
     276                 :          12 :         req_opaque_data = (const uint8_t *)request + sizeof(spdm_psk_exchange_request_t) +
     277                 :          12 :                           spdm_request->psk_hint_length + spdm_request->context_length;
     278                 :             : 
     279                 :             :         /*
     280                 :             :          * Here allows integrator generate own opaque data for PSK Exchange Response.
     281                 :             :          * If libspdm_psk_exchange_rsp_opaque_data() returns false,
     282                 :             :          * libspdm will generate version selection opaque data.
     283                 :             :          */
     284                 :          12 :         opaque_psk_exchange_rsp_size = *response_size - sizeof(spdm_psk_exchange_response_t) -
     285                 :          12 :                                        measurement_summary_hash_size - context_length -
     286                 :             :                                        hmac_size;
     287                 :          12 :         use_default_opaque_data = false;
     288                 :          12 :         result = libspdm_psk_exchange_rsp_opaque_data(
     289                 :          12 :             spdm_context, psk_hint, spdm_request->psk_hint_length,
     290                 :          12 :             spdm_request->header.spdm_version,
     291                 :          12 :             spdm_request->header.param1,
     292                 :          12 :             req_opaque_data, spdm_request->opaque_length, NULL,
     293                 :             :             &opaque_psk_exchange_rsp_size);
     294         [ +  + ]:          12 :         if (!result) {
     295                 :          11 :             use_default_opaque_data = true;
     296                 :          11 :             opaque_psk_exchange_rsp_size =
     297                 :          11 :                 libspdm_get_opaque_data_version_selection_data_size(spdm_context);
     298                 :             :         }
     299                 :             : 
     300         [ +  + ]:          12 :         if (use_default_opaque_data) {
     301                 :          11 :             result = libspdm_process_general_opaque_data_check(spdm_context,
     302                 :          11 :                                                                spdm_request->opaque_length, req_opaque_data);
     303         [ -  + ]:          11 :             if (!result) {
     304                 :           0 :                 return libspdm_generate_error_response(spdm_context,
     305                 :             :                                                        SPDM_ERROR_CODE_INVALID_REQUEST, 0,
     306                 :             :                                                        response_size, response);
     307                 :             :             }
     308                 :          11 :             status = libspdm_process_opaque_data_supported_version_data(
     309                 :          11 :                 spdm_context, spdm_request->opaque_length, req_opaque_data, &secured_message_version);
     310         [ -  + ]:          11 :             if (LIBSPDM_STATUS_IS_ERROR(status)) {
     311                 :           0 :                 return libspdm_generate_error_response(spdm_context,
     312                 :             :                                                        SPDM_ERROR_CODE_INVALID_REQUEST, 0,
     313                 :             :                                                        response_size, response);
     314                 :             :             }
     315                 :             :             /* DSP0277 1.3: reserve room for this Responder's AEADlimitOE. The size helper returns 0
     316                 :             :              * unless the negotiated secured message version is 1.3 or later. */
     317                 :          11 :             opaque_psk_exchange_rsp_size +=
     318                 :          11 :                 libspdm_get_opaque_data_aead_limit_element_size(spdm_context,
     319                 :             :                                                                 secured_message_version);
     320                 :             :         } else {
     321                 :             :             /* use response buffer to temporarily store opaque data */
     322                 :           1 :             rsp_opaque_data = (uint8_t *)response;
     323                 :           1 :             result = libspdm_psk_exchange_rsp_opaque_data(
     324                 :           1 :                 spdm_context, psk_hint, spdm_request->psk_hint_length,
     325                 :           1 :                 spdm_request->header.spdm_version,
     326                 :           1 :                 spdm_request->header.param1,
     327                 :           1 :                 req_opaque_data, spdm_request->opaque_length, rsp_opaque_data,
     328                 :             :                 &opaque_psk_exchange_rsp_size);
     329         [ -  + ]:           1 :             if (!result) {
     330                 :           0 :                 return libspdm_generate_error_response(spdm_context,
     331                 :             :                                                        SPDM_ERROR_CODE_UNSPECIFIED, 0,
     332                 :             :                                                        response_size, response);
     333                 :             :             }
     334                 :             :             /*
     335                 :             :              * parse responder opaque data from integrator
     336                 :             :              * to get secured_message_version.
     337                 :             :              */
     338                 :           1 :             status = libspdm_process_opaque_data_version_selection_data(
     339                 :             :                 spdm_context, opaque_psk_exchange_rsp_size,
     340                 :             :                 rsp_opaque_data, &secured_message_version);
     341         [ -  + ]:           1 :             if (LIBSPDM_STATUS_IS_ERROR(status)) {
     342                 :           0 :                 return libspdm_generate_error_response(spdm_context,
     343                 :             :                                                        SPDM_ERROR_CODE_UNSPECIFIED, 0,
     344                 :             :                                                        response_size, response);
     345                 :             :             }
     346                 :             :         }
     347                 :             :         /* DSP0277 1.3: read the Requester's AEAD limit from the request (absent -> default 64).
     348                 :             :          * This is independent of whether the Responder builds default or custom response opaque
     349                 :             :          * data, so it runs for both paths. */
     350                 :          12 :         status = libspdm_process_opaque_data_aead_limit(
     351                 :          12 :             spdm_context, secured_message_version, spdm_request->opaque_length, req_opaque_data,
     352                 :             :             &peer_aead_limit_exponent);
     353         [ -  + ]:          12 :         if (LIBSPDM_STATUS_IS_ERROR(status)) {
     354                 :           0 :             return libspdm_generate_error_response(spdm_context,
     355                 :             :                                                    SPDM_ERROR_CODE_INVALID_REQUEST, 0,
     356                 :             :                                                    response_size, response);
     357                 :             :         }
     358                 :             :     }
     359                 :             : 
     360                 :          14 :     total_size = sizeof(spdm_psk_exchange_response_t) +
     361                 :          14 :                  measurement_summary_hash_size + context_length +
     362                 :          14 :                  opaque_psk_exchange_rsp_size + hmac_size;
     363                 :             : 
     364         [ -  + ]:          14 :     LIBSPDM_ASSERT(*response_size >= total_size);
     365                 :          14 :     *response_size = total_size;
     366                 :          14 :     libspdm_zero_mem(response, *response_size);
     367                 :          14 :     spdm_response = response;
     368                 :             : 
     369                 :          14 :     spdm_response->header.spdm_version = spdm_request->header.spdm_version;
     370                 :          14 :     spdm_response->header.request_response_code = SPDM_PSK_EXCHANGE_RSP;
     371         [ +  + ]:          14 :     if (libspdm_is_capabilities_flag_supported(
     372                 :             :             spdm_context, false,
     373                 :             :             SPDM_GET_CAPABILITIES_REQUEST_FLAGS_HBEAT_CAP,
     374                 :             :             SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_HBEAT_CAP)) {
     375                 :           2 :         spdm_response->header.param1 = spdm_context->local_context.heartbeat_period;
     376                 :             :     } else {
     377                 :          12 :         spdm_response->header.param1 = 0x00;
     378                 :             :     }
     379                 :             : 
     380                 :          14 :     req_session_id = spdm_request->req_session_id;
     381                 :          14 :     rsp_session_id = libspdm_allocate_rsp_session_id(spdm_context, true);
     382         [ -  + ]:          14 :     if (rsp_session_id == ((INVALID_SESSION_ID & 0xFFFF0000) >> 16)) {
     383                 :           0 :         return libspdm_generate_error_response(
     384                 :             :             spdm_context, SPDM_ERROR_CODE_SESSION_LIMIT_EXCEEDED, 0,
     385                 :             :             response_size, response);
     386                 :             :     }
     387                 :          14 :     session_id = libspdm_generate_session_id(req_session_id, rsp_session_id);
     388                 :          14 :     session_info = libspdm_assign_session_id(spdm_context, session_id, secured_message_version,
     389                 :             :                                              true);
     390         [ -  + ]:          14 :     if (session_info == NULL) {
     391                 :           0 :         return libspdm_generate_error_response(
     392                 :             :             spdm_context, SPDM_ERROR_CODE_SESSION_LIMIT_EXCEEDED, 0,
     393                 :             :             response_size, response);
     394                 :             :     }
     395                 :          14 :     libspdm_session_info_set_psk_hint(session_info, psk_hint, psk_hint_size);
     396                 :             : 
     397                 :             :     /* DSP0277 1.3: program the session's AEAD limit (min of local and peer) when secured message
     398                 :             :      * version 1.3 was negotiated. */
     399         [ +  + ]:          14 :     if (libspdm_get_version_from_version_number(secured_message_version) >=
     400                 :             :         SECURED_SPDM_VERSION_13) {
     401                 :          11 :         libspdm_apply_aead_limit_to_session(spdm_context, session_info,
     402                 :             :                                             peer_aead_limit_exponent);
     403                 :             :     }
     404                 :             : 
     405                 :          14 :     libspdm_reset_message_buffer_via_request_code(spdm_context, NULL,
     406                 :          14 :                                                   spdm_request->header.request_response_code);
     407                 :             : 
     408                 :          14 :     spdm_response->rsp_session_id = rsp_session_id;
     409                 :          14 :     spdm_response->reserved = 0;
     410                 :             : 
     411                 :          14 :     spdm_response->context_length = context_length;
     412                 :          14 :     spdm_response->opaque_length = (uint16_t)opaque_psk_exchange_rsp_size;
     413                 :             : 
     414                 :          14 :     ptr = (void *)(spdm_response + 1);
     415                 :             : 
     416                 :             : #if LIBSPDM_ENABLE_CAPABILITY_MEAS_CAP
     417         [ +  + ]:          14 :     if (libspdm_is_capabilities_flag_supported(
     418                 :           2 :             spdm_context, false, 0, SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP) &&
     419         [ +  + ]:           2 :         ((spdm_request->header.param1 == SPDM_REQUEST_TCB_COMPONENT_MEASUREMENT_HASH) ||
     420         [ +  - ]:           1 :          (spdm_request->header.param1 == SPDM_REQUEST_ALL_MEASUREMENTS_HASH))) {
     421                 :           2 :         result = libspdm_generate_measurement_summary_hash(
     422                 :             :             spdm_context,
     423                 :           2 :             spdm_context->connection_info.version,
     424                 :             :             spdm_context->connection_info.algorithm.base_hash_algo,
     425                 :           2 :             spdm_context->connection_info.algorithm.measurement_spec,
     426                 :             :             spdm_context->connection_info.algorithm.measurement_hash_algo,
     427                 :           2 :             spdm_request->header.param1,
     428                 :             :             ptr,
     429                 :             :             measurement_summary_hash_size);
     430                 :             : 
     431         [ -  + ]:           2 :         if (!result) {
     432                 :           0 :             libspdm_free_session_id(spdm_context, session_id);
     433                 :           0 :             return libspdm_generate_error_response(spdm_context,
     434                 :             :                                                    SPDM_ERROR_CODE_UNSPECIFIED, 0,
     435                 :             :                                                    response_size, response);
     436                 :             :         }
     437                 :             :     }
     438                 :             : #endif /* LIBSPDM_ENABLE_CAPABILITY_MEAS_CAP */
     439                 :             : 
     440                 :          14 :     ptr += measurement_summary_hash_size;
     441                 :             : 
     442         [ +  + ]:          14 :     if (context_length != 0) {
     443         [ -  + ]:          12 :         if (!libspdm_get_random_number(context_length, ptr)) {
     444                 :           0 :             libspdm_free_session_id(spdm_context, session_id);
     445                 :           0 :             return libspdm_generate_error_response(spdm_context,
     446                 :             :                                                    SPDM_ERROR_CODE_UNSPECIFIED, 0,
     447                 :             :                                                    response_size, response);
     448                 :             :         }
     449                 :          12 :         ptr += context_length;
     450                 :             :     }
     451                 :             : 
     452         [ +  + ]:          14 :     if (opaque_psk_exchange_rsp_size != 0) {
     453         [ +  + ]:          12 :         if (use_default_opaque_data) {
     454                 :          11 :             size_t version_selection_size =
     455                 :          11 :                 libspdm_get_opaque_data_version_selection_data_size(spdm_context);
     456                 :          11 :             libspdm_build_opaque_data_version_selection_data(
     457                 :             :                 spdm_context, secured_message_version, &version_selection_size, ptr);
     458                 :             :             /* DSP0277 1.3: advertise this Responder's own AEAD limit. opaque_psk_exchange_rsp_size
     459                 :             :              * is the reserved opaque data capacity (version selection + AEAD limit); the append is a
     460                 :             :              * no-op unless the negotiated secured message version is 1.3 or later. */
     461                 :          11 :             libspdm_build_opaque_data_aead_limit_element(
     462                 :             :                 spdm_context, secured_message_version, &opaque_psk_exchange_rsp_size, ptr);
     463                 :             :         } else {
     464                 :           1 :             result = libspdm_psk_exchange_rsp_opaque_data(
     465                 :           1 :                 spdm_context, psk_hint, spdm_request->psk_hint_length,
     466                 :           1 :                 spdm_request->header.spdm_version,
     467                 :           1 :                 spdm_request->header.param1,
     468                 :           1 :                 req_opaque_data, spdm_request->opaque_length, ptr,
     469                 :             :                 &opaque_psk_exchange_rsp_size);
     470         [ -  + ]:           1 :             if (!result) {
     471                 :           0 :                 libspdm_free_session_id(spdm_context, session_id);
     472                 :           0 :                 return libspdm_generate_error_response(spdm_context,
     473                 :             :                                                        SPDM_ERROR_CODE_UNSPECIFIED, 0,
     474                 :             :                                                        response_size, response);
     475                 :             :             }
     476                 :             :         }
     477                 :          12 :         ptr += opaque_psk_exchange_rsp_size;
     478                 :             :     }
     479                 :             : 
     480                 :          14 :     status = libspdm_append_message_k(spdm_context, session_info, false, request, request_size);
     481         [ -  + ]:          14 :     if (LIBSPDM_STATUS_IS_ERROR(status)) {
     482                 :           0 :         libspdm_free_session_id(spdm_context, session_id);
     483                 :           0 :         return libspdm_generate_error_response(spdm_context,
     484                 :             :                                                SPDM_ERROR_CODE_UNSPECIFIED, 0,
     485                 :             :                                                response_size, response);
     486                 :             :     }
     487                 :             : 
     488                 :          14 :     status = libspdm_append_message_k(spdm_context, session_info, false, spdm_response,
     489                 :          14 :                                       (size_t)ptr - (size_t)spdm_response);
     490         [ -  + ]:          14 :     if (LIBSPDM_STATUS_IS_ERROR(status)) {
     491                 :           0 :         libspdm_free_session_id(spdm_context, session_id);
     492                 :           0 :         return libspdm_generate_error_response(spdm_context,
     493                 :             :                                                SPDM_ERROR_CODE_UNSPECIFIED, 0,
     494                 :             :                                                response_size, response);
     495                 :             :     }
     496                 :             : 
     497                 :          14 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "libspdm_generate_session_handshake_key[%x]\n",
     498                 :             :                    session_id));
     499                 :          14 :     result = libspdm_calculate_th1_hash(spdm_context, session_info, false,
     500                 :             :                                         th1_hash_data);
     501         [ -  + ]:          14 :     if (!result) {
     502                 :           0 :         libspdm_free_session_id(spdm_context, session_id);
     503                 :           0 :         return libspdm_generate_error_response(spdm_context,
     504                 :             :                                                SPDM_ERROR_CODE_UNSPECIFIED, 0,
     505                 :             :                                                response_size, response);
     506                 :             :     }
     507                 :          14 :     result = libspdm_generate_session_handshake_key(
     508                 :             :         session_info->secured_message_context, th1_hash_data);
     509         [ -  + ]:          14 :     if (!result) {
     510                 :           0 :         libspdm_free_session_id(spdm_context, session_id);
     511                 :           0 :         return libspdm_generate_error_response(spdm_context,
     512                 :             :                                                SPDM_ERROR_CODE_UNSPECIFIED, 0,
     513                 :             :                                                response_size, response);
     514                 :             :     }
     515                 :             : 
     516                 :          14 :     result = libspdm_generate_psk_exchange_rsp_hmac(spdm_context, session_info,
     517                 :             :                                                     ptr);
     518         [ -  + ]:          14 :     if (!result) {
     519                 :           0 :         libspdm_free_session_id(spdm_context, session_id);
     520                 :           0 :         return libspdm_generate_error_response(
     521                 :             :             spdm_context, SPDM_ERROR_CODE_UNSPECIFIED,
     522                 :             :             0, response_size, response);
     523                 :             :     }
     524                 :          14 :     status = libspdm_append_message_k(spdm_context, session_info, false, ptr, hmac_size);
     525         [ -  + ]:          14 :     if (LIBSPDM_STATUS_IS_ERROR(status)) {
     526                 :           0 :         libspdm_free_session_id(spdm_context, session_id);
     527                 :           0 :         return libspdm_generate_error_response(spdm_context,
     528                 :             :                                                SPDM_ERROR_CODE_UNSPECIFIED, 0,
     529                 :             :                                                response_size, response);
     530                 :             :     }
     531                 :          14 :     ptr += hmac_size;
     532                 :             : 
     533         [ +  + ]:          14 :     if (spdm_request->header.spdm_version >= SPDM_MESSAGE_VERSION_12) {
     534                 :           3 :         session_info->session_policy = spdm_request->header.param2;
     535                 :             :     }
     536                 :          14 :     libspdm_set_session_state(spdm_context, session_id, LIBSPDM_SESSION_STATE_HANDSHAKING);
     537                 :             : 
     538         [ +  + ]:          14 :     if (!libspdm_is_capabilities_flag_supported(
     539                 :             :             spdm_context, false, 0,
     540                 :             :             SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_PSK_CAP_RESPONDER_WITH_CONTEXT)) {
     541                 :             :         /* No need to receive PSK_FINISH, enter application phase directly.*/
     542                 :             : 
     543                 :           2 :         LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "libspdm_generate_session_data_key[%x]\n",
     544                 :             :                        session_id));
     545                 :           2 :         result = libspdm_calculate_th2_hash(spdm_context, session_info,
     546                 :             :                                             false, th2_hash_data);
     547         [ -  + ]:           2 :         if (!result) {
     548                 :           0 :             libspdm_free_session_id(spdm_context, session_id);
     549                 :           0 :             return libspdm_generate_error_response(
     550                 :             :                 spdm_context, SPDM_ERROR_CODE_UNSPECIFIED,
     551                 :             :                 0, response_size, response);
     552                 :             :         }
     553                 :           2 :         result = libspdm_generate_session_data_key(
     554                 :             :             session_info->secured_message_context, th2_hash_data);
     555         [ -  + ]:           2 :         if (!result) {
     556                 :           0 :             libspdm_free_session_id(spdm_context, session_id);
     557                 :           0 :             return libspdm_generate_error_response(
     558                 :             :                 spdm_context, SPDM_ERROR_CODE_UNSPECIFIED,
     559                 :             :                 0, response_size, response);
     560                 :             :         }
     561                 :             : 
     562                 :             :         #if LIBSPDM_ENABLE_CAPABILITY_HBEAT_CAP
     563   [ +  +  +  - ]:           3 :         if ((spdm_context->local_context.heartbeat_period != 0) &&
     564                 :           1 :             libspdm_is_capabilities_flag_supported(
     565                 :             :                 spdm_context, false,
     566                 :             :                 SPDM_GET_CAPABILITIES_REQUEST_FLAGS_HBEAT_CAP,
     567                 :             :                 SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_HBEAT_CAP)) {
     568                 :           1 :             result = libspdm_start_watchdog(
     569                 :           1 :                 spdm_context, session_id, spdm_context->local_context.heartbeat_period * 2);
     570         [ -  + ]:           1 :             if (!result) {
     571                 :           0 :                 libspdm_free_session_id(spdm_context, session_id);
     572                 :           0 :                 return libspdm_generate_error_response(
     573                 :             :                     spdm_context, SPDM_ERROR_CODE_UNSPECIFIED,
     574                 :             :                     0, response_size, response);
     575                 :             :             }
     576                 :             :         }
     577                 :             :         #endif /* LIBSPDM_ENABLE_CAPABILITY_HBEAT_CAP */
     578                 :             : 
     579                 :           2 :         libspdm_set_session_state(spdm_context, session_id, LIBSPDM_SESSION_STATE_ESTABLISHED);
     580                 :             :     }
     581                 :             : 
     582         [ +  + ]:          14 :     if (libspdm_is_capabilities_flag_supported(
     583                 :             :             spdm_context, false,
     584                 :             :             SPDM_GET_CAPABILITIES_REQUEST_FLAGS_HBEAT_CAP,
     585                 :             :             SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_HBEAT_CAP)) {
     586                 :           2 :         session_info->heartbeat_period = spdm_context->local_context.heartbeat_period;
     587                 :             :     } else {
     588                 :          12 :         session_info->heartbeat_period = 0x00;
     589                 :             :     }
     590                 :             : 
     591                 :          14 :     return LIBSPDM_STATUS_SUCCESS;
     592                 :             : }
     593                 :             : 
     594                 :             : #endif /* LIBSPDM_ENABLE_CAPABILITY_PSK_CAP*/
        

Generated by: LCOV version 2.0-1