LCOV - code coverage report
Current view: top level - library/spdm_responder_lib - libspdm_rsp_receive_send.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 40.8 % 382 156
Test Date: 2026-09-13 08:13:44 Functions: 60.0 % 15 9

            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           19 : libspdm_get_spdm_response_func libspdm_get_response_func_via_request_code(uint8_t request_code)
      11              : {
      12           19 :     switch (request_code) {
      13            2 :     case SPDM_GET_VERSION: return libspdm_get_response_version;
      14            2 :     case SPDM_GET_CAPABILITIES: return libspdm_get_response_capabilities;
      15            2 :     case SPDM_NEGOTIATE_ALGORITHMS: return libspdm_get_response_algorithms;
      16              : 
      17              :     #if LIBSPDM_ENABLE_CAPABILITY_CERT_CAP
      18            2 :     case SPDM_GET_DIGESTS: return libspdm_get_response_digests;
      19            1 :     case SPDM_GET_CERTIFICATE: return libspdm_get_response_certificate;
      20              :     #endif /* LIBSPDM_ENABLE_CAPABILITY_CERT_CAP */
      21              : 
      22              :     #if LIBSPDM_ENABLE_CAPABILITY_CHAL_CAP
      23            1 :     case SPDM_CHALLENGE: return libspdm_get_response_challenge_auth;
      24              :     #endif /* LIBSPDM_ENABLE_CAPABILITY_CHAL_CAP*/
      25              : 
      26              :     #if LIBSPDM_ENABLE_CAPABILITY_MEAS_CAP
      27            3 :     case SPDM_GET_MEASUREMENTS: return libspdm_get_response_measurements;
      28              :     #endif /* LIBSPDM_ENABLE_CAPABILITY_MEAS_CAP*/
      29              : 
      30              :     #if LIBSPDM_ENABLE_CAPABILITY_MEL_CAP
      31            0 :     case SPDM_GET_MEASUREMENT_EXTENSION_LOG: return libspdm_get_response_measurement_extension_log;
      32              :     #endif /* LIBSPDM_ENABLE_CAPABILITY_MEL_CAP */
      33              : 
      34              :     #if LIBSPDM_ENABLE_CAPABILITY_KEY_EX_CAP
      35            1 :     case SPDM_KEY_EXCHANGE: return libspdm_get_response_key_exchange;
      36              :     #endif /* LIBSPDM_ENABLE_CAPABILITY_KEY_EX_CAP*/
      37              : 
      38              :     #if LIBSPDM_ENABLE_CAPABILITY_PSK_CAP
      39            1 :     case SPDM_PSK_EXCHANGE: return libspdm_get_response_psk_exchange;
      40              :     #endif /* LIBSPDM_ENABLE_CAPABILITY_PSK_CAP*/
      41              : 
      42              :     #if LIBSPDM_ENABLE_CAPABILITY_ENCAP_CAP
      43            0 :     case SPDM_GET_ENCAPSULATED_REQUEST: return libspdm_get_response_encapsulated_request;
      44            0 :     case SPDM_DELIVER_ENCAPSULATED_RESPONSE: return libspdm_get_response_encapsulated_response_ack;
      45              :     #endif /* LIBSPDM_ENABLE_CAPABILITY_ENCAP_CAP */
      46              : 
      47              :     #if LIBSPDM_RESPOND_IF_READY_SUPPORT
      48            0 :     case SPDM_RESPOND_IF_READY: return libspdm_get_response_respond_if_ready;
      49              :     #endif /* LIBSPDM_RESPOND_IF_READY_SUPPORT */
      50              : 
      51              :     #if LIBSPDM_ENABLE_CAPABILITY_KEY_EX_CAP
      52            1 :     case SPDM_FINISH: return libspdm_get_response_finish;
      53              :     #endif /* LIBSPDM_ENABLE_CAPABILITY_KEY_EX_CAP*/
      54              : 
      55              :     #if LIBSPDM_ENABLE_CAPABILITY_PSK_CAP
      56            1 :     case SPDM_PSK_FINISH: return libspdm_get_response_psk_finish;
      57              :     #endif /* LIBSPDM_ENABLE_CAPABILITY_PSK_CAP*/
      58              : 
      59              :     #if (LIBSPDM_ENABLE_CAPABILITY_KEY_EX_CAP) || (LIBSPDM_ENABLE_CAPABILITY_PSK_CAP)
      60            0 :     case SPDM_END_SESSION: return libspdm_get_response_end_session;
      61            0 :     case SPDM_HEARTBEAT: return libspdm_get_response_heartbeat;
      62            0 :     case SPDM_KEY_UPDATE: return libspdm_get_response_key_update;
      63              :     #endif /* LIBSPDM_ENABLE_CAPABILITY_KEY_EX_CAP || LIBSPDM_ENABLE_CAPABILITY_PSK_CAP*/
      64              : 
      65              :     #if LIBSPDM_ENABLE_CAPABILITY_ENDPOINT_INFO_CAP
      66            0 :     case SPDM_GET_ENDPOINT_INFO: return libspdm_get_response_endpoint_info;
      67              :     #endif /*LIBSPDM_ENABLE_CAPABILITY_ENDPOINT_INFO_CAP*/
      68              : 
      69              :     #if LIBSPDM_ENABLE_CAPABILITY_CSR_CAP
      70            0 :     case SPDM_GET_CSR: return libspdm_get_response_csr;
      71              :     #endif /*LIBSPDM_ENABLE_CAPABILITY_CSR_CAP*/
      72              : 
      73              :     #if LIBSPDM_ENABLE_CAPABILITY_SET_CERT_CAP
      74            0 :     case SPDM_SET_CERTIFICATE: return libspdm_get_response_set_certificate;
      75              :     #endif /*LIBSPDM_ENABLE_CAPABILITY_SET_CERT_CAP*/
      76              : 
      77              :     #if LIBSPDM_ENABLE_CAPABILITY_GET_KEY_PAIR_INFO_CAP
      78            0 :     case SPDM_GET_KEY_PAIR_INFO: return libspdm_get_response_key_pair_info;
      79              :     #endif /*LIBSPDM_ENABLE_CAPABILITY_GET_KEY_PAIR_INFO_CAP*/
      80              : 
      81              :     #if LIBSPDM_ENABLE_CAPABILITY_SET_KEY_PAIR_INFO_CAP
      82            0 :     case SPDM_SET_KEY_PAIR_INFO: return libspdm_get_response_set_key_pair_info_ack;
      83              :     #endif /*LIBSPDM_ENABLE_CAPABILITY_SET_KEY_PAIR_INFO_CAP*/
      84              : 
      85              :     #if LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP
      86            0 :     case SPDM_CHUNK_GET: return libspdm_get_response_chunk_get;
      87            0 :     case SPDM_CHUNK_SEND: return libspdm_get_response_chunk_send;
      88              :     #endif /* LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP */
      89              : 
      90              :     #if LIBSPDM_ENABLE_CAPABILITY_EVENT_CAP
      91            0 :     case SPDM_GET_SUPPORTED_EVENT_TYPES: return libspdm_get_response_supported_event_types;
      92            0 :     case SPDM_SUBSCRIBE_EVENT_TYPES: return libspdm_get_response_subscribe_event_types_ack;
      93              :     #endif /* LIBSPDM_ENABLE_CAPABILITY_EVENT_CAP */
      94              : 
      95              :     #if LIBSPDM_EVENT_RECIPIENT_SUPPORT
      96            0 :     case SPDM_SEND_EVENT: return libspdm_get_response_event_ack;
      97              :     #endif /* LIBSPDM_EVENT_RECIPIENT_SUPPORT */
      98              : 
      99              :     #if LIBSPDM_ENABLE_VENDOR_DEFINED_MESSAGES
     100            2 :     case SPDM_VENDOR_DEFINED_REQUEST: return libspdm_get_vendor_defined_response;
     101              :     #endif /*LIBSPDM_ENABLE_VENDOR_DEFINED_MESSAGES*/
     102              : 
     103            0 :     default: return NULL;
     104              :     }
     105              : }
     106              : 
     107              : /**
     108              :  * Return the GET_SPDM_RESPONSE function via last request.
     109              :  *
     110              :  * @param  spdm_context                  The SPDM context for the device.
     111              :  *
     112              :  * @return GET_SPDM_RESPONSE function according to the last request.
     113              :  **/
     114            8 : static libspdm_get_spdm_response_func libspdm_get_response_func_via_last_request(
     115              :     libspdm_context_t *spdm_context)
     116              : {
     117              :     spdm_message_header_t *spdm_request;
     118              : 
     119            8 :     spdm_request = (void *)spdm_context->last_spdm_request;
     120            8 :     return libspdm_get_response_func_via_request_code(spdm_request->request_response_code);
     121              : }
     122              : 
     123            0 : libspdm_return_t libspdm_process_request(void *spdm_context, uint32_t **session_id,
     124              :                                          bool *is_app_message,
     125              :                                          size_t request_size, void *request)
     126              : {
     127              :     libspdm_context_t *context;
     128              :     void *temp_session_context;
     129              :     libspdm_return_t status;
     130              :     libspdm_session_info_t *session_info;
     131              :     uint32_t *message_session_id;
     132              :     uint8_t *decoded_message_ptr;
     133              :     size_t decoded_message_size;
     134              :     uint8_t *backup_decoded_message_ptr;
     135              :     size_t backup_decoded_message_size;
     136              :     bool result;
     137              :     bool reset_key_update;
     138              : 
     139            0 :     context = spdm_context;
     140              :     size_t transport_header_size;
     141              :     uint8_t *scratch_buffer;
     142              :     size_t scratch_buffer_size;
     143              : 
     144            0 :     if (request == NULL) {
     145            0 :         return LIBSPDM_STATUS_INVALID_PARAMETER;
     146              :     }
     147            0 :     if (request_size == 0) {
     148            0 :         return LIBSPDM_STATUS_INVALID_PARAMETER;
     149              :     }
     150              : 
     151            0 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "SpdmReceiveRequest[.] ...\n"));
     152              : 
     153            0 :     message_session_id = NULL;
     154            0 :     context->last_spdm_request_session_id_valid = false;
     155            0 :     context->last_spdm_request_size =
     156            0 :         libspdm_get_scratch_buffer_last_spdm_request_capacity(context);
     157              : 
     158              :     /* always use scratch buffer to response.
     159              :      * if it is secured message, this scratch buffer will be used.
     160              :      * if it is normal message, the response ptr will point to receiver buffer. */
     161            0 :     transport_header_size = context->local_context.capability.transport_header_size;
     162            0 :     libspdm_get_scratch_buffer (context, (void **)&scratch_buffer, &scratch_buffer_size);
     163              :     #if LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP
     164            0 :     decoded_message_ptr = scratch_buffer +
     165            0 :                           libspdm_get_scratch_buffer_secure_message_offset() +
     166              :                           transport_header_size;
     167            0 :     decoded_message_size = libspdm_get_scratch_buffer_secure_message_capacity(context) -
     168              :                            transport_header_size;
     169              :     #else
     170              :     decoded_message_ptr = scratch_buffer + transport_header_size;
     171              :     decoded_message_size = scratch_buffer_size - transport_header_size;
     172              :     #endif /* LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP */
     173              : 
     174            0 :     backup_decoded_message_ptr = decoded_message_ptr;
     175            0 :     backup_decoded_message_size = decoded_message_size;
     176              : 
     177            0 :     status = context->transport_decode_message(
     178              :         context, &message_session_id, is_app_message, true,
     179              :         request_size, request, &decoded_message_size,
     180              :         (void **)&decoded_message_ptr);
     181              : 
     182            0 :     reset_key_update = false;
     183            0 :     temp_session_context = NULL;
     184              : 
     185            0 :     if (status == LIBSPDM_STATUS_SESSION_TRY_DISCARD_KEY_UPDATE) {
     186              :         /* Failed to decode, but have backup keys. Try rolling back before aborting.
     187              :          * message_session_id must be valid for us to have attempted decryption. */
     188            0 :         if (message_session_id == NULL) {
     189            0 :             return LIBSPDM_STATUS_INVALID_STATE_LOCAL;
     190              :         }
     191            0 :         temp_session_context = libspdm_get_secured_message_context_via_session_id(
     192              :             context, *message_session_id);
     193            0 :         if (temp_session_context == NULL) {
     194            0 :             return LIBSPDM_STATUS_INVALID_STATE_LOCAL;
     195              :         }
     196              : 
     197            0 :         result = libspdm_activate_update_session_data_key(
     198              :             temp_session_context, LIBSPDM_KEY_UPDATE_ACTION_REQUESTER, false);
     199            0 :         if (!result) {
     200            0 :             return LIBSPDM_STATUS_INVALID_STATE_LOCAL;
     201              :         }
     202            0 :         libspdm_trigger_key_update_callback(
     203              :             context, *message_session_id,
     204              :             LIBSPDM_KEY_UPDATE_OPERATION_DISCARD_UPDATE,
     205              :             LIBSPDM_KEY_UPDATE_ACTION_REQUESTER);
     206              : 
     207              :         /* Retry decoding message with backup Requester key.
     208              :          * Must reset some of the parameters in case they were modified */
     209            0 :         message_session_id = NULL;
     210            0 :         decoded_message_ptr = backup_decoded_message_ptr;
     211            0 :         decoded_message_size = backup_decoded_message_size;
     212            0 :         status = context->transport_decode_message(
     213              :             context, &message_session_id, is_app_message, true,
     214              :             request_size, request, &decoded_message_size,
     215              :             (void **)&decoded_message_ptr);
     216              : 
     217            0 :         reset_key_update = true;
     218              :     }
     219              : 
     220            0 :     if (LIBSPDM_STATUS_IS_ERROR(status)) {
     221            0 :         LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "transport_decode_message : %xu\n", status));
     222            0 :         if (context->last_spdm_error.error_code != 0) {
     223              :             /* If the SPDM error code is Non-Zero, that means we need send the error message back to requester.
     224              :              * In this case, we need return SUCCESS and let caller invoke libspdm_build_response() to send an ERROR message.*/
     225            0 :             *session_id = &context->last_spdm_error.session_id;
     226            0 :             *is_app_message = false;
     227            0 :             return LIBSPDM_STATUS_SUCCESS;
     228              :         }
     229            0 :         return status;
     230              :     }
     231              : 
     232              :     /* Handle special case for bi-directional communication:
     233              :      * If the Requester returns RESPONSE_NOT_READY error to KEY_UPDATE, the Responder needs
     234              :      * to activate backup key to parse the error. Then later the Requester will return SUCCESS,
     235              :      * the Responder needs new key. So we need to restore the environment by
     236              :      * libspdm_create_update_session_data_key() again.*/
     237            0 :     if (reset_key_update) {
     238              :         /* temp_session_context and message_session_id must necessarily
     239              :          * be valid for us to reach here. */
     240            0 :         if (temp_session_context == NULL || message_session_id == NULL) {
     241            0 :             return LIBSPDM_STATUS_INVALID_STATE_LOCAL;
     242              :         }
     243            0 :         result = libspdm_create_update_session_data_key(
     244              :             temp_session_context, LIBSPDM_KEY_UPDATE_ACTION_REQUESTER);
     245            0 :         if (!result) {
     246            0 :             return LIBSPDM_STATUS_INVALID_STATE_LOCAL;
     247              :         }
     248            0 :         libspdm_trigger_key_update_callback(
     249              :             context, *message_session_id,
     250              :             LIBSPDM_KEY_UPDATE_OPERATION_CREATE_UPDATE,
     251              :             LIBSPDM_KEY_UPDATE_ACTION_REQUESTER);
     252              :     }
     253              : 
     254              :     /*
     255              :      * decoded_message may contain padding zeros due to transport layer alignment requirements.
     256              :      * trim the decoded_message size to the maximum data_transfer_size.
     257              :      */
     258            0 :     decoded_message_size = LIBSPDM_MIN(decoded_message_size,
     259              :                                        context->local_context.capability.data_transfer_size);
     260              : 
     261            0 :     context->last_spdm_request_size = decoded_message_size;
     262            0 :     libspdm_copy_mem (context->last_spdm_request,
     263            0 :                       libspdm_get_scratch_buffer_last_spdm_request_capacity(context),
     264              :                       decoded_message_ptr,
     265              :                       decoded_message_size);
     266            0 :     libspdm_zero_mem (decoded_message_ptr, decoded_message_size);
     267              : 
     268            0 :     if (!(*is_app_message)) {
     269              :         /* Check for minimal SPDM message size. */
     270            0 :         if (context->last_spdm_request_size < sizeof(spdm_message_header_t)) {
     271            0 :             return LIBSPDM_STATUS_UNSUPPORTED_CAP;
     272              :         }
     273              :     }
     274              : 
     275            0 :     *session_id = message_session_id;
     276              : 
     277            0 :     if (message_session_id != NULL) {
     278            0 :         session_info = libspdm_get_session_info_via_session_id(context, *message_session_id);
     279            0 :         if (session_info == NULL) {
     280            0 :             return LIBSPDM_STATUS_UNSUPPORTED_CAP;
     281              :         }
     282            0 :         context->last_spdm_request_session_id = *message_session_id;
     283            0 :         context->last_spdm_request_session_id_valid = true;
     284              :     }
     285              : 
     286            0 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "SpdmReceiveRequest[%x] msg %s(0x%x), size (0x%zx): \n",
     287              :                    (message_session_id != NULL) ? *message_session_id : 0,
     288              :                    libspdm_get_code_str(((spdm_message_header_t *)context->last_spdm_request)->
     289              :                                         request_response_code),
     290              :                    ((spdm_message_header_t *)context->last_spdm_request)->request_response_code,
     291              :                    context->last_spdm_request_size));
     292            0 :     LIBSPDM_INTERNAL_DUMP_HEX((uint8_t *)context->last_spdm_request,
     293              :                               context->last_spdm_request_size);
     294              : 
     295            0 :     return LIBSPDM_STATUS_SUCCESS;
     296              : }
     297              : 
     298              : /**
     299              :  * Notify the session state to a session APP.
     300              :  *
     301              :  * @param  spdm_context                  A pointer to the SPDM context.
     302              :  * @param  session_id                    The session_id of a session.
     303              :  * @param  session_state                 The state of a session.
     304              :  **/
     305           29 : static void libspdm_trigger_session_state_callback(libspdm_context_t *spdm_context,
     306              :                                                    uint32_t session_id,
     307              :                                                    libspdm_session_state_t session_state)
     308              : {
     309           29 :     if (spdm_context->spdm_session_state_callback != NULL) {
     310            0 :         ((libspdm_session_state_callback_func)
     311            0 :          spdm_context->spdm_session_state_callback)(spdm_context, session_id, session_state);
     312              :     }
     313           29 : }
     314              : 
     315           29 : void libspdm_set_session_state(libspdm_context_t *spdm_context,
     316              :                                uint32_t session_id,
     317              :                                libspdm_session_state_t session_state)
     318              : {
     319              :     libspdm_session_info_t *session_info;
     320              :     libspdm_session_state_t old_session_state;
     321              : 
     322           29 :     session_info = libspdm_get_session_info_via_session_id(spdm_context, session_id);
     323           29 :     if (session_info == NULL) {
     324            0 :         LIBSPDM_ASSERT(false);
     325            0 :         return;
     326              :     }
     327              : 
     328           29 :     old_session_state = libspdm_secured_message_get_session_state(
     329              :         session_info->secured_message_context);
     330           29 :     if (old_session_state != session_state) {
     331           29 :         libspdm_secured_message_set_session_state(
     332              :             session_info->secured_message_context, session_state);
     333           29 :         libspdm_trigger_session_state_callback(
     334              :             spdm_context, session_info->session_id, session_state);
     335              :     }
     336              : }
     337              : 
     338            0 : libspdm_return_t libspdm_terminate_session(
     339              :     void *spdm_context, uint32_t session_id)
     340              : {
     341              :     libspdm_session_info_t *session_info;
     342              : 
     343            0 :     session_info = libspdm_get_session_info_via_session_id(spdm_context, session_id);
     344            0 :     if (session_info == NULL) {
     345            0 :         return LIBSPDM_STATUS_INVALID_PARAMETER;
     346              :     }
     347              : 
     348            0 :     libspdm_set_session_state(spdm_context, session_id, LIBSPDM_SESSION_STATE_NOT_STARTED);
     349            0 :     libspdm_free_session_id(spdm_context, session_id);
     350            0 :     return LIBSPDM_STATUS_SUCCESS;
     351              : }
     352              : 
     353              : /**
     354              :  * Notify the connection state to an SPDM context register.
     355              :  *
     356              :  * @param  spdm_context                  A pointer to the SPDM context.
     357              :  * @param  connection_state              Indicate the SPDM connection state.
     358              :  **/
     359           87 : static void libspdm_trigger_connection_state_callback(libspdm_context_t *spdm_context,
     360              :                                                       libspdm_connection_state_t connection_state)
     361              : {
     362           87 :     if (spdm_context->spdm_connection_state_callback != NULL) {
     363            0 :         ((libspdm_connection_state_callback_func)
     364            0 :          spdm_context->spdm_connection_state_callback)(spdm_context, connection_state);
     365              :     }
     366           87 : }
     367              : 
     368           89 : void libspdm_set_connection_state(libspdm_context_t *spdm_context,
     369              :                                   libspdm_connection_state_t connection_state)
     370              : {
     371           89 :     if (spdm_context->connection_info.connection_state != connection_state) {
     372           87 :         spdm_context->connection_info.connection_state = connection_state;
     373           87 :         libspdm_trigger_connection_state_callback(spdm_context, connection_state);
     374              :     }
     375           89 : }
     376              : 
     377           15 : void libspdm_trigger_key_update_callback(void *spdm_context, uint32_t session_id,
     378              :                                          libspdm_key_update_operation_t key_update_op,
     379              :                                          libspdm_key_update_action_t key_update_action)
     380              : {
     381              :     libspdm_context_t *context;
     382              : 
     383           15 :     context = spdm_context;
     384           15 :     if (context->spdm_key_update_callback != NULL) {
     385            0 :         ((libspdm_key_update_callback_func)
     386            0 :          context->spdm_key_update_callback)(context, session_id, key_update_op, key_update_action);
     387              :     }
     388           15 : }
     389              : 
     390            8 : libspdm_return_t libspdm_build_response(void *spdm_context, const uint32_t *session_id,
     391              :                                         bool is_app_message,
     392              :                                         size_t *response_size,
     393              :                                         void **response)
     394              : {
     395              :     libspdm_context_t *context;
     396              :     uint8_t *my_response;
     397              :     size_t my_response_size;
     398              :     libspdm_return_t status;
     399              :     libspdm_get_spdm_response_func get_response_func;
     400              :     libspdm_session_info_t *session_info;
     401              :     spdm_message_header_t *spdm_request;
     402              :     spdm_message_header_t *spdm_response;
     403              :     size_t transport_header_size;
     404              :     uint8_t *scratch_buffer;
     405              :     size_t scratch_buffer_size;
     406              :     uint8_t request_response_code;
     407              :     uint32_t actual_size;
     408              : 
     409              :     #if LIBSPDM_ENABLE_CAPABILITY_HBEAT_CAP
     410              :     bool result;
     411              :     #endif /* LIBSPDM_ENABLE_CAPABILITY_HBEAT_CAP */
     412              : 
     413              :     #if LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP
     414              :     uint8_t *large_buffer;
     415              :     size_t large_buffer_size;
     416              :     libspdm_chunk_info_t *get_info;
     417              :     spdm_chunk_response_response_t *chunk_rsp;
     418              :     uint8_t *chunk_ptr;
     419              :     size_t chunk_send_ack_response_header_size;
     420              :     #endif /* LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP */
     421              : 
     422            8 :     context = spdm_context;
     423            8 :     status = LIBSPDM_STATUS_UNSUPPORTED_CAP;
     424              : 
     425              :     /* For secure message, setup my_response to scratch buffer
     426              :      * For non-secure message, setup my_response to sender buffer*/
     427            8 :     transport_header_size = context->local_context.capability.transport_header_size;
     428            8 :     if (session_id != NULL) {
     429            0 :         libspdm_get_scratch_buffer (context, (void **)&scratch_buffer, &scratch_buffer_size);
     430              :         #if LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP
     431            0 :         my_response = scratch_buffer + libspdm_get_scratch_buffer_secure_message_offset() +
     432              :                       transport_header_size;
     433            0 :         my_response_size = libspdm_get_scratch_buffer_secure_message_capacity(context) -
     434            0 :                            transport_header_size -
     435            0 :                            context->local_context.capability.transport_tail_size;
     436              :         #else
     437              :         my_response = scratch_buffer + transport_header_size;
     438              :         my_response_size = scratch_buffer_size - transport_header_size -
     439              :                            context->local_context.capability.transport_tail_size;
     440              :         #endif /* LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP */
     441              :     } else {
     442            8 :         my_response = (uint8_t *)*response + transport_header_size;
     443            8 :         my_response_size = *response_size - transport_header_size -
     444            8 :                            context->local_context.capability.transport_tail_size;
     445              :     }
     446            8 :     libspdm_zero_mem(my_response, my_response_size);
     447              : 
     448            8 :     spdm_response = (void *)my_response;
     449              : 
     450            8 :     if (context->last_spdm_error.error_code != 0) {
     451              :         /* Error in libspdm_process_request(), and we need send error message directly. */
     452            0 :         switch (context->last_spdm_error.error_code) {
     453            0 :         case SPDM_ERROR_CODE_DECRYPT_ERROR:
     454              :             /* session ID is valid. Use it to encrypt the error message.*/
     455            0 :             if ((context->handle_error_return_policy &
     456              :                  LIBSPDM_DATA_HANDLE_ERROR_RETURN_POLICY_DROP_ON_DECRYPT_ERROR) == 0) {
     457            0 :                 status = libspdm_generate_error_response(
     458              :                     context, SPDM_ERROR_CODE_DECRYPT_ERROR, 0,
     459              :                     &my_response_size, my_response);
     460              :             } else {
     461              :                 /**
     462              :                  * just ignore this message
     463              :                  * return UNSUPPORTED and clear response_size to continue the dispatch without send response
     464              :                  **/
     465            0 :                 *response_size = 0;
     466            0 :                 status = LIBSPDM_STATUS_UNSUPPORTED_CAP;
     467              :             }
     468            0 :             break;
     469            0 :         case SPDM_ERROR_CODE_INVALID_SESSION:
     470              :             /**
     471              :              * don't use session ID, because we dont know which right session ID should be used.
     472              :              * just ignore this message
     473              :              * return UNSUPPORTED and clear response_size to continue the dispatch without send response
     474              :              **/
     475            0 :             *response_size = 0;
     476            0 :             status = LIBSPDM_STATUS_UNSUPPORTED_CAP;
     477            0 :             break;
     478            0 :         default:
     479            0 :             LIBSPDM_ASSERT(false);
     480            0 :             status = LIBSPDM_STATUS_UNSUPPORTED_CAP;
     481              :         }
     482              : 
     483            0 :         if (LIBSPDM_STATUS_IS_ERROR(status)) {
     484            0 :             if ((session_id != NULL) &&
     485            0 :                 (context->last_spdm_error.error_code == SPDM_ERROR_CODE_DECRYPT_ERROR)) {
     486            0 :                 libspdm_free_session_id(context, *session_id);
     487              :             }
     488            0 :             return status;
     489              :         }
     490              : 
     491            0 :         LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "SpdmSendResponse[%x]: msg %s(0x%x), size (0x%zx): \n",
     492              :                        (session_id != NULL) ? *session_id : 0,
     493              :                        libspdm_get_code_str(spdm_response->request_response_code),
     494              :                        spdm_response->request_response_code, my_response_size));
     495            0 :         LIBSPDM_INTERNAL_DUMP_HEX(my_response, my_response_size);
     496              : 
     497            0 :         status = context->transport_encode_message(
     498              :             context, session_id, false, false,
     499              :             my_response_size, my_response, response_size, response);
     500            0 :         if (LIBSPDM_STATUS_IS_ERROR(status)) {
     501            0 :             if ((session_id != NULL) &&
     502            0 :                 ((status == LIBSPDM_STATUS_SEQUENCE_NUMBER_OVERFLOW) ||
     503              :                  (status == LIBSPDM_STATUS_CRYPTO_ERROR))) {
     504            0 :                 libspdm_free_session_id(context, *session_id);
     505              :             }
     506            0 :             LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "transport_encode_message : %xu\n", status));
     507            0 :             return status;
     508              :         }
     509              : 
     510            0 :         if ((session_id != NULL) &&
     511            0 :             (context->last_spdm_error.error_code == SPDM_ERROR_CODE_DECRYPT_ERROR)) {
     512            0 :             libspdm_free_session_id(context, *session_id);
     513              :         }
     514              : 
     515            0 :         libspdm_zero_mem(&context->last_spdm_error, sizeof(context->last_spdm_error));
     516            0 :         return LIBSPDM_STATUS_SUCCESS;
     517              :     }
     518              : 
     519            8 :     if (session_id != NULL) {
     520            0 :         session_info = libspdm_get_session_info_via_session_id(context, *session_id);
     521            0 :         if (session_info == NULL) {
     522            0 :             LIBSPDM_ASSERT(false);
     523            0 :             return LIBSPDM_STATUS_UNSUPPORTED_CAP;
     524              :         }
     525              :     }
     526              : 
     527            8 :     if (*response == NULL) {
     528            0 :         return LIBSPDM_STATUS_INVALID_PARAMETER;
     529              :     }
     530            8 :     if ((response_size == NULL) || (*response_size == 0)) {
     531            0 :         return LIBSPDM_STATUS_INVALID_PARAMETER;
     532              :     }
     533              : 
     534            8 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "SpdmSendResponse[%x] ...\n",
     535              :                    (session_id != NULL) ? *session_id : 0));
     536              : 
     537            8 :     spdm_request = (void *)context->last_spdm_request;
     538            8 :     if (context->last_spdm_request_size == 0) {
     539            0 :         return LIBSPDM_STATUS_INVALID_STATE_LOCAL;
     540              :     }
     541              : 
     542            8 :     get_response_func = NULL;
     543            8 :     if (!is_app_message) {
     544            8 :         get_response_func = libspdm_get_response_func_via_last_request(context);
     545              : 
     546              :         #if LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP
     547              :         /* Per DSP0274: The chunked transfer shall not be interrupted by any commands
     548              :          * that are not part of the chunk transfer sequence, with the exception of
     549              :          * GET_VERSION. The Responder shall return ErrorCode=UnexpectedRequest if an
     550              :          * unexpected command is received during the chunked transfer. These error codes
     551              :          * shall not interrupt the chunk transfer sequence. */
     552            8 :         if (context->chunk_context.get.chunk_in_use
     553            2 :             && get_response_func != libspdm_get_response_chunk_get) {
     554              : 
     555            2 :             if (get_response_func == libspdm_get_response_version) {
     556              :                 /* GET_VERSION is allowed to interrupt chunk transfer.
     557              :                  * Reset chunk get context and proceed normally. */
     558            1 :                 if (context->chunk_context.get.large_message != NULL) {
     559            1 :                     libspdm_zero_mem(context->chunk_context.get.large_message,
     560              :                                      context->chunk_context.get.large_message_capacity);
     561              :                 }
     562            1 :                 context->chunk_context.get.chunk_in_use = false;
     563            1 :                 context->chunk_context.get.chunk_handle++;
     564            1 :                 context->chunk_context.get.chunk_seq_no = 0;
     565            1 :                 context->chunk_context.get.large_message = NULL;
     566            1 :                 context->chunk_context.get.large_message_size = 0;
     567            1 :                 context->chunk_context.get.large_message_capacity = 0;
     568            1 :                 context->chunk_context.get.chunk_bytes_transferred = 0;
     569              :             } else {
     570              :                 /* Reject with UnexpectedRequest without terminating
     571              :                  * the chunk transfer sequence. */
     572            1 :                 status = libspdm_generate_error_response(
     573              :                     context, SPDM_ERROR_CODE_UNEXPECTED_REQUEST, 0,
     574              :                     &my_response_size, my_response);
     575            1 :                 goto response_dispatched;
     576              :             }
     577              :         }
     578            7 :         if (context->chunk_context.send.chunk_in_use
     579            2 :             && get_response_func != libspdm_get_response_chunk_send) {
     580              : 
     581            2 :             if (get_response_func == libspdm_get_response_version) {
     582              :                 /* GET_VERSION is allowed to interrupt chunk transfer.
     583              :                  * Reset chunk send context and proceed normally. */
     584            1 :                 if (context->chunk_context.send.large_message != NULL) {
     585            1 :                     libspdm_zero_mem(context->chunk_context.send.large_message,
     586              :                                      context->chunk_context.send.large_message_capacity);
     587              :                 }
     588            1 :                 context->chunk_context.send.chunk_in_use = false;
     589            1 :                 context->chunk_context.send.chunk_handle = 0;
     590            1 :                 context->chunk_context.send.chunk_seq_no = 0;
     591            1 :                 context->chunk_context.send.large_message = NULL;
     592            1 :                 context->chunk_context.send.large_message_size = 0;
     593            1 :                 context->chunk_context.send.large_message_capacity = 0;
     594            1 :                 context->chunk_context.send.chunk_bytes_transferred = 0;
     595              :             } else {
     596              :                 /* Reject with UnexpectedRequest without terminating
     597              :                  * the chunk transfer sequence. */
     598            1 :                 status = libspdm_generate_error_response(
     599              :                     context, SPDM_ERROR_CODE_UNEXPECTED_REQUEST, 0,
     600              :                     &my_response_size, my_response);
     601            1 :                 goto response_dispatched;
     602              :             }
     603              :         }
     604              :         #endif /* LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP */
     605              : 
     606            6 :         if (get_response_func != NULL) {
     607            6 :             status = get_response_func(
     608              :                 context,
     609              :                 context->last_spdm_request_size,
     610            6 :                 context->last_spdm_request,
     611              :                 &my_response_size, my_response);
     612              :         }
     613              :     }
     614            6 :     if (is_app_message || (get_response_func == NULL)) {
     615            0 :         if (context->get_response_func != NULL) {
     616            0 :             status = ((libspdm_get_response_func) context->get_response_func)(
     617              :                 context, session_id, is_app_message,
     618              :                 context->last_spdm_request_size,
     619            0 :                 context->last_spdm_request,
     620              :                 &my_response_size, my_response);
     621              :         } else {
     622            0 :             status = LIBSPDM_STATUS_UNSUPPORTED_CAP;
     623              :         }
     624              :     }
     625              : 
     626              :     #if LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP
     627            6 : response_dispatched:
     628            8 :     if (libspdm_get_connection_version(context) < SPDM_MESSAGE_VERSION_14) {
     629            8 :         chunk_send_ack_response_header_size = sizeof(spdm_chunk_send_ack_response_t);
     630              :     } else {
     631            0 :         chunk_send_ack_response_header_size = sizeof(spdm_chunk_send_ack_response_14_t);
     632              :     }
     633              :     #endif /* LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP */
     634              : 
     635            8 :     if (status == LIBSPDM_STATUS_SUCCESS) {
     636            8 :         LIBSPDM_ASSERT (my_response_size <= context->local_context.capability.max_spdm_msg_size);
     637              :         /* large SPDM message is the SPDM message whose size is greater than the DataTransferSize of the receiving
     638              :          * SPDM endpoint or greater than the transmit buffer size of the sending SPDM endpoint */
     639            8 :         if ((context->connection_info.capability.max_spdm_msg_size != 0) &&
     640            6 :             (my_response_size > context->connection_info.capability.max_spdm_msg_size)) {
     641            1 :             LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR, "my_response_size > req max_spdm_msg_size\n"));
     642            1 :             actual_size = (uint32_t)my_response_size;
     643            1 :             status = libspdm_generate_extended_error_response(context,
     644              :                                                               SPDM_ERROR_CODE_RESPONSE_TOO_LARGE,
     645              :                                                               0,
     646              :                                                               sizeof(uint32_t),
     647              :                                                               (uint8_t *)&actual_size,
     648              :                                                               &my_response_size, my_response);
     649            7 :         } else if ((((context->connection_info.capability.data_transfer_size != 0) &&
     650            5 :                      (my_response_size > context->connection_info.capability.data_transfer_size)) ||
     651            6 :                     ((context->local_context.capability.sender_data_transfer_size != 0) &&
     652            6 :                      (my_response_size >
     653            9 :                       context->local_context.capability.sender_data_transfer_size))) &&
     654            3 :                    libspdm_is_capabilities_flag_supported(
     655              :                        context, false, SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP,
     656              :                        SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHUNK_CAP)) {
     657              :             #if LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP
     658              : 
     659            3 :             get_info = &context->chunk_context.get;
     660              : 
     661              :             /* Saving multiple large responses is not an expected use case.
     662              :              * Therefore, if the requester did not perform chunk_get requests for
     663              :              * previous large responses, they will be lost. */
     664            3 :             if (get_info->chunk_in_use) {
     665            0 :                 LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR,
     666              :                                "Warning: Overwriting previous unrequested chunk_get info.\n"));
     667              :             }
     668              : 
     669            3 :             libspdm_get_scratch_buffer(context, (void **)&scratch_buffer, &scratch_buffer_size);
     670              : 
     671              :             /* The first section of the scratch
     672              :              * buffer may be used for other purposes. Use only after that section. */
     673            6 :             large_buffer = (uint8_t *)scratch_buffer +
     674            3 :                            libspdm_get_scratch_buffer_large_message_offset(spdm_context);
     675            3 :             large_buffer_size = libspdm_get_scratch_buffer_large_message_capacity(spdm_context);
     676              : 
     677            3 :             get_info->chunk_in_use = true;
     678              :             /* Increment chunk_handle here as opposed to end of chunk_get handler
     679              :              * in case requester never issues chunk_get. */
     680            3 :             get_info->chunk_handle++;
     681            3 :             get_info->chunk_seq_no = 0;
     682            3 :             get_info->chunk_bytes_transferred = 0;
     683            3 :             get_info->large_message_capacity = large_buffer_size;
     684              : 
     685            3 :             libspdm_zero_mem(large_buffer, large_buffer_size);
     686              : 
     687              :             /* It's possible that the large response that was to be sent to the requester was
     688              :              * a CHUNK_SEND_ACK + non-chunk response. In this case, to prevent chunking within
     689              :              * chunking, only send back the actual response, by saving only non-chunk portion
     690              :              * in the scratch buffer, used to respond to the next CHUNK_GET request. */
     691            3 :             if (((spdm_message_header_t *)my_response)
     692            3 :                 ->request_response_code == SPDM_CHUNK_SEND_ACK) {
     693            0 :                 libspdm_copy_mem(large_buffer, large_buffer_size,
     694            0 :                                  my_response + chunk_send_ack_response_header_size,
     695              :                                  my_response_size - chunk_send_ack_response_header_size);
     696            0 :                 get_info->large_message = large_buffer;
     697            0 :                 get_info->large_message_size =
     698            0 :                     my_response_size - chunk_send_ack_response_header_size;
     699              :             } else {
     700            3 :                 libspdm_copy_mem(large_buffer, large_buffer_size, my_response, my_response_size);
     701              : 
     702            3 :                 get_info->large_message = large_buffer;
     703            3 :                 get_info->large_message_size = my_response_size;
     704              :             }
     705              : 
     706            3 :             status = libspdm_generate_extended_error_response(context,
     707              :                                                               SPDM_ERROR_CODE_LARGE_RESPONSE, 0,
     708              :                                                               sizeof(uint8_t),
     709            3 :                                                               &get_info->chunk_handle,
     710              :                                                               &my_response_size, my_response);
     711              :             #else
     712              :             LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR,
     713              :                            "Warning: Could not save chunk. Scratch buffer too small.\n"));
     714              : 
     715              :             status = libspdm_generate_extended_error_response(context,
     716              :                                                               SPDM_ERROR_CODE_LARGE_RESPONSE,
     717              :                                                               0, 0, NULL,
     718              :                                                               &my_response_size, my_response);
     719              :             #endif /* LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP */
     720              : 
     721            3 :             if (LIBSPDM_STATUS_IS_ERROR(status)) {
     722            0 :                 return status;
     723              :             }
     724              :         }
     725              :     }
     726              : 
     727              :     /* if return the status: Responder drop the response
     728              :      * just ignore this message
     729              :      * return UNSUPPORTED and clear response_size to continue the dispatch without send response.*/
     730            8 :     if ((my_response_size == 0) && (status == LIBSPDM_STATUS_UNSUPPORTED_CAP)) {
     731            0 :         *response_size = 0;
     732            0 :         status = LIBSPDM_STATUS_UNSUPPORTED_CAP;
     733            0 :         goto done;
     734              :     }
     735              : 
     736            8 :     if (LIBSPDM_STATUS_IS_ERROR(status)) {
     737            0 :         status = libspdm_generate_error_response(
     738              :             context, SPDM_ERROR_CODE_UNSUPPORTED_REQUEST,
     739            0 :             spdm_request->request_response_code, &my_response_size, my_response);
     740            0 :         if (LIBSPDM_STATUS_IS_ERROR(status)) {
     741            0 :             goto done;
     742              :         }
     743              :     }
     744              : 
     745            8 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "SpdmSendResponse[%x]: msg %s(0x%x), size (0x%zx): \n",
     746              :                    (session_id != NULL) ? *session_id : 0,
     747              :                    libspdm_get_code_str(spdm_response->request_response_code),
     748              :                    spdm_response->request_response_code,
     749              :                    my_response_size));
     750            8 :     LIBSPDM_INTERNAL_DUMP_HEX(my_response, my_response_size);
     751              : 
     752            8 :     status = context->transport_encode_message(
     753              :         context, session_id, is_app_message, false,
     754              :         my_response_size, my_response, response_size, response);
     755            8 :     if (LIBSPDM_STATUS_IS_ERROR(status)) {
     756            0 :         if ((session_id != NULL) &&
     757            0 :             ((status == LIBSPDM_STATUS_SEQUENCE_NUMBER_OVERFLOW) ||
     758              :              (status == LIBSPDM_STATUS_CRYPTO_ERROR))) {
     759            0 :             libspdm_free_session_id(context, *session_id);
     760              :         }
     761            0 :         LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "transport_encode_message : %xu\n", status));
     762            0 :         goto done;
     763              :     }
     764              : 
     765            8 :     request_response_code = spdm_response->request_response_code;
     766              :     #if LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP
     767            8 :     switch (request_response_code) {
     768            0 :     case SPDM_CHUNK_SEND_ACK:
     769            0 :         if (my_response_size > chunk_send_ack_response_header_size) {
     770            0 :             request_response_code =
     771            0 :                 ((spdm_message_header_t *)(my_response + chunk_send_ack_response_header_size))
     772              :                 ->request_response_code;
     773              :         }
     774            0 :         break;
     775            0 :     case SPDM_CHUNK_RESPONSE:
     776            0 :         chunk_rsp = (spdm_chunk_response_response_t *)my_response;
     777            0 :         chunk_ptr = (uint8_t *)(((uint32_t *)(chunk_rsp + 1)) + 1);
     778            0 :         if (chunk_rsp->chunk_seq_no == 0) {
     779            0 :             request_response_code = ((spdm_message_header_t *)chunk_ptr)->request_response_code;
     780              :         }
     781            0 :         break;
     782            8 :     default:
     783            8 :         break;
     784              :     }
     785              :     #endif /* LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP */
     786              : 
     787            8 :     if (session_id != NULL) {
     788            0 :         switch (request_response_code) {
     789            0 :         case SPDM_FINISH_RSP:
     790            0 :             if (!libspdm_is_capabilities_flag_supported(
     791              :                     context, false,
     792              :                     SPDM_GET_CAPABILITIES_REQUEST_FLAGS_HANDSHAKE_IN_THE_CLEAR_CAP,
     793              :                     SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_HANDSHAKE_IN_THE_CLEAR_CAP)) {
     794            0 :                 libspdm_set_session_state(
     795              :                     context, *session_id,
     796              :                     LIBSPDM_SESSION_STATE_ESTABLISHED);
     797              :             }
     798            0 :             break;
     799            0 :         case SPDM_PSK_FINISH_RSP:
     800            0 :             libspdm_set_session_state(context, *session_id, LIBSPDM_SESSION_STATE_ESTABLISHED);
     801            0 :             break;
     802            0 :         case SPDM_END_SESSION_ACK:
     803              :             #if LIBSPDM_ENABLE_CAPABILITY_HBEAT_CAP
     804            0 :             if (libspdm_is_capabilities_flag_supported(
     805              :                     context, false,
     806              :                     SPDM_GET_CAPABILITIES_REQUEST_FLAGS_HBEAT_CAP,
     807              :                     SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_HBEAT_CAP)) {
     808            0 :                 result = libspdm_stop_watchdog(*session_id);
     809            0 :                 if (!result) {
     810            0 :                     LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR, "libspdm_stop_watchdog error\n"));
     811              :                     /* No need to return error for internal watchdog error. */
     812              :                 }
     813              :             }
     814              :             #endif /* LIBSPDM_ENABLE_CAPABILITY_HBEAT_CAP */
     815            0 :             libspdm_terminate_session(context, *session_id);
     816            0 :             break;
     817            0 :         default:
     818              :             #if LIBSPDM_ENABLE_CAPABILITY_HBEAT_CAP
     819            0 :             if (libspdm_is_capabilities_flag_supported(
     820              :                     context, false,
     821              :                     SPDM_GET_CAPABILITIES_REQUEST_FLAGS_HBEAT_CAP,
     822              :                     SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_HBEAT_CAP)) {
     823              :                 /* reset watchdog in any session messages. */
     824            0 :                 result = libspdm_reset_watchdog(*session_id);
     825            0 :                 if (!result) {
     826            0 :                     LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR, "libspdm_reset_watchdog error\n"));
     827              :                     /* No need to return error for internal watchdog error. */
     828              :                 }
     829              :             }
     830              :             #endif /* LIBSPDM_ENABLE_CAPABILITY_HBEAT_CAP */
     831            0 :             break;
     832              :         }
     833              :     } else {
     834            8 :         switch (request_response_code) {
     835            0 :         case SPDM_FINISH_RSP:
     836            0 :             if (libspdm_is_capabilities_flag_supported(
     837              :                     context, false,
     838              :                     SPDM_GET_CAPABILITIES_REQUEST_FLAGS_HANDSHAKE_IN_THE_CLEAR_CAP,
     839              :                     SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_HANDSHAKE_IN_THE_CLEAR_CAP)) {
     840            0 :                 libspdm_set_session_state(
     841              :                     context,
     842              :                     context->latest_session_id,
     843              :                     LIBSPDM_SESSION_STATE_ESTABLISHED);
     844              :             }
     845            0 :             break;
     846            8 :         default:
     847              :             /* No session state update needed */
     848            8 :             break;
     849              :         }
     850              :     }
     851              : 
     852            8 :     status = LIBSPDM_STATUS_SUCCESS;
     853            8 : done:
     854            8 :     if (session_id != NULL) {
     855              :         /* clean plain text in scratch buffer */
     856            0 :         libspdm_zero_mem (my_response, my_response_size);
     857              :     }
     858            8 :     libspdm_zero_mem (context->last_spdm_request,
     859            8 :                       libspdm_get_scratch_buffer_last_spdm_request_capacity(context));
     860            8 :     context->last_spdm_request_size = 0;
     861            8 :     context->last_spdm_request_session_id_valid = false;
     862            8 :     return status;
     863              : }
     864              : 
     865            0 : void libspdm_register_get_response_func(void *context, libspdm_get_response_func get_response_func)
     866              : {
     867              :     libspdm_context_t *spdm_context;
     868              : 
     869            0 :     spdm_context = context;
     870            0 :     spdm_context->get_response_func = (void *)get_response_func;
     871            0 : }
     872              : 
     873            0 : void libspdm_register_session_state_callback_func(
     874              :     void *spdm_context,
     875              :     libspdm_session_state_callback_func spdm_session_state_callback)
     876              : {
     877              :     libspdm_context_t *context;
     878              : 
     879            0 :     LIBSPDM_ASSERT(spdm_context != NULL);
     880              : 
     881            0 :     context = spdm_context;
     882              : 
     883            0 :     context->spdm_session_state_callback = (void *)spdm_session_state_callback;
     884            0 : }
     885              : 
     886            0 : void libspdm_register_connection_state_callback_func(
     887              :     void *spdm_context,
     888              :     libspdm_connection_state_callback_func spdm_connection_state_callback)
     889              : {
     890              :     libspdm_context_t *context;
     891              : 
     892            0 :     LIBSPDM_ASSERT(spdm_context != NULL);
     893              : 
     894            0 :     context = spdm_context;
     895            0 :     context->spdm_connection_state_callback = (void *)spdm_connection_state_callback;
     896            0 : }
     897              : 
     898            0 : void libspdm_register_key_update_callback_func(
     899              :     void *spdm_context, libspdm_key_update_callback_func spdm_key_update_callback)
     900              : {
     901              :     libspdm_context_t *context;
     902              : 
     903            0 :     LIBSPDM_ASSERT(spdm_context != NULL);
     904              : 
     905            0 :     context = spdm_context;
     906            0 :     context->spdm_key_update_callback = (void *)spdm_key_update_callback;
     907            0 : }
     908              : 
     909              : #if (LIBSPDM_ENABLE_CAPABILITY_MUT_AUTH_CAP) && (LIBSPDM_ENABLE_CAPABILITY_ENCAP_CAP) && \
     910              :     (LIBSPDM_SEND_GET_CERTIFICATE_SUPPORT)
     911          118 : void libspdm_register_cert_chain_buffer(
     912              :     void *spdm_context, void *cert_chain_buffer, size_t cert_chain_buffer_max_size)
     913              : {
     914              :     libspdm_context_t *context;
     915              : 
     916          118 :     LIBSPDM_ASSERT(spdm_context != NULL);
     917              : 
     918          118 :     context = spdm_context;
     919          118 :     context->mut_auth_cert_chain_buffer = cert_chain_buffer;
     920          118 :     context->mut_auth_cert_chain_buffer_max_size = cert_chain_buffer_max_size;
     921          118 :     context->mut_auth_cert_chain_buffer_size = 0;
     922          118 : }
     923              : #endif
        

Generated by: LCOV version 2.0-1