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

Generated by: LCOV version 2.0-1