LCOV - code coverage report
Current view: top level - library/spdm_common_lib - libspdm_com_context_data.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 43.3 % 1679 727
Test Date: 2025-10-12 08:10:56 Functions: 85.5 % 76 65

            Line data    Source code
       1              : /**
       2              :  *  Copyright Notice:
       3              :  *  Copyright 2021-2025 DMTF. All rights reserved.
       4              :  *  License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/libspdm/blob/main/LICENSE.md
       5              :  **/
       6              : 
       7              : #include "internal/libspdm_common_lib.h"
       8              : #include "internal/libspdm_secured_message_lib.h"
       9              : #include "internal/libspdm_fips_lib.h"
      10              : 
      11              : #if LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP
      12              : /* first section */
      13        68163 : uint32_t libspdm_get_scratch_buffer_secure_message_offset(libspdm_context_t *spdm_context) {
      14        68163 :     return 0;
      15              : }
      16              : 
      17       420298 : uint32_t libspdm_get_scratch_buffer_secure_message_capacity(libspdm_context_t *spdm_context) {
      18       420298 :     return spdm_context->local_context.capability.max_spdm_msg_size +
      19       840596 :            spdm_context->local_context.capability.transport_header_size +
      20       420298 :            spdm_context->local_context.capability.transport_tail_size;
      21              : }
      22              : 
      23              : /* second section */
      24           50 : uint32_t libspdm_get_scratch_buffer_large_message_offset(libspdm_context_t *spdm_context) {
      25           50 :     return libspdm_get_scratch_buffer_secure_message_capacity(spdm_context);
      26              : }
      27              : 
      28       352111 : uint32_t libspdm_get_scratch_buffer_large_message_capacity(libspdm_context_t *spdm_context) {
      29       352111 :     return spdm_context->local_context.capability.max_spdm_msg_size;
      30              : }
      31              : #endif
      32              : 
      33              : /* third section */
      34       202059 : uint32_t libspdm_get_scratch_buffer_sender_receiver_offset(libspdm_context_t *spdm_context) {
      35       202059 :     return 0 +
      36              : #if LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP
      37              :            libspdm_get_scratch_buffer_secure_message_capacity(spdm_context) +
      38       202059 :            libspdm_get_scratch_buffer_large_message_capacity(spdm_context) +
      39              : #endif
      40              :            0;
      41              : }
      42              : 
      43       283881 : uint32_t libspdm_get_scratch_buffer_sender_receiver_capacity(libspdm_context_t *spdm_context) {
      44       283881 :     return spdm_context->local_context.capability.max_spdm_msg_size +
      45       567762 :            spdm_context->local_context.capability.transport_header_size +
      46       283881 :            spdm_context->local_context.capability.transport_tail_size;
      47              : }
      48              : 
      49              : #if LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP
      50              : /* fourth section */
      51        12862 : uint32_t libspdm_get_scratch_buffer_large_sender_receiver_offset(libspdm_context_t *spdm_context) {
      52        12862 :     return libspdm_get_scratch_buffer_secure_message_capacity(spdm_context) +
      53        25724 :            libspdm_get_scratch_buffer_large_message_capacity(spdm_context) +
      54        12862 :            libspdm_get_scratch_buffer_sender_receiver_capacity(spdm_context);
      55              : }
      56              : 
      57       147452 : uint32_t libspdm_get_scratch_buffer_large_sender_receiver_capacity(libspdm_context_t *spdm_context)
      58              : {
      59       147452 :     return spdm_context->local_context.capability.max_spdm_msg_size +
      60       294904 :            spdm_context->local_context.capability.transport_header_size +
      61       147452 :            spdm_context->local_context.capability.transport_tail_size;
      62              : }
      63              : #endif
      64              : 
      65              : /* fifth section */
      66          114 : uint32_t libspdm_get_scratch_buffer_last_spdm_request_offset(libspdm_context_t *spdm_context) {
      67          114 :     return 0 +
      68              : #if LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP
      69          114 :            libspdm_get_scratch_buffer_secure_message_capacity(spdm_context) +
      70          114 :            libspdm_get_scratch_buffer_large_message_capacity(spdm_context) +
      71              : #endif
      72          114 :            libspdm_get_scratch_buffer_sender_receiver_capacity(spdm_context) +
      73              : #if LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP
      74          114 :            libspdm_get_scratch_buffer_large_sender_receiver_capacity(spdm_context) +
      75              : #endif
      76              :            0;
      77              : }
      78              : 
      79       276342 : uint32_t libspdm_get_scratch_buffer_last_spdm_request_capacity(libspdm_context_t *spdm_context) {
      80       276342 :     return spdm_context->local_context.capability.max_spdm_msg_size;
      81              : }
      82              : 
      83              : #if LIBSPDM_RESPOND_IF_READY_SUPPORT
      84              : /* sixth section */
      85          114 : uint32_t libspdm_get_scratch_buffer_cache_spdm_request_offset(libspdm_context_t *spdm_context) {
      86          114 :     return 0 +
      87              : #if LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP
      88          114 :            libspdm_get_scratch_buffer_secure_message_capacity(spdm_context) +
      89          114 :            libspdm_get_scratch_buffer_large_message_capacity(spdm_context) +
      90              : #endif
      91          114 :            libspdm_get_scratch_buffer_sender_receiver_capacity(spdm_context) +
      92              : #if LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP
      93          114 :            libspdm_get_scratch_buffer_large_sender_receiver_capacity(spdm_context) +
      94              : #endif
      95          114 :            libspdm_get_scratch_buffer_last_spdm_request_capacity(spdm_context) +
      96              :            0;
      97              : }
      98              : 
      99       273669 : uint32_t libspdm_get_scratch_buffer_cache_spdm_request_capacity(libspdm_context_t *spdm_context) {
     100       273669 :     return spdm_context->local_context.capability.max_spdm_msg_size;
     101              : }
     102              : #endif
     103              : 
     104              : /* combination */
     105       136936 : uint32_t libspdm_get_scratch_buffer_capacity(libspdm_context_t *spdm_context) {
     106       136936 :     return 0 +
     107              : #if LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP
     108       136936 :            libspdm_get_scratch_buffer_secure_message_capacity(spdm_context) +
     109       136936 :            libspdm_get_scratch_buffer_large_message_capacity(spdm_context) +
     110              : #endif
     111       136936 :            libspdm_get_scratch_buffer_sender_receiver_capacity(spdm_context) +
     112              : #if LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP
     113       136936 :            libspdm_get_scratch_buffer_large_sender_receiver_capacity(spdm_context) +
     114              : #endif
     115       136936 :            libspdm_get_scratch_buffer_last_spdm_request_capacity(spdm_context) +
     116              : #if LIBSPDM_RESPOND_IF_READY_SUPPORT
     117       136936 :            libspdm_get_scratch_buffer_cache_spdm_request_capacity(spdm_context) +
     118              : #endif
     119              :            0;
     120              : }
     121              : 
     122              : /**
     123              :  * Returns if an SPDM data_type requires session info.
     124              :  *
     125              :  * @param data_type  SPDM data type.
     126              :  *
     127              :  * @retval true  session info is required.
     128              :  * @retval false session info is not required.
     129              :  **/
     130           75 : static bool need_session_info_for_data(libspdm_data_type_t data_type)
     131              : {
     132           75 :     switch (data_type) {
     133            0 :     case LIBSPDM_DATA_SESSION_SECURED_MESSAGE_VERSION:
     134              :     case LIBSPDM_DATA_SESSION_USE_PSK:
     135              :     case LIBSPDM_DATA_SESSION_MUT_AUTH_REQUESTED:
     136              :     case LIBSPDM_DATA_SESSION_END_SESSION_ATTRIBUTES:
     137              :     case LIBSPDM_DATA_SESSION_POLICY:
     138              :     case LIBSPDM_DATA_SESSION_SEQUENCE_NUMBER_RSP_DIR:
     139              :     case LIBSPDM_DATA_SESSION_SEQUENCE_NUMBER_REQ_DIR:
     140              :     case LIBSPDM_DATA_SESSION_SEQUENCE_NUMBER_ENDIAN:
     141            0 :         return true;
     142           75 :     default:
     143           75 :         return false;
     144              :     }
     145              : }
     146              : 
     147           19 : libspdm_return_t libspdm_set_data(void *spdm_context, libspdm_data_type_t data_type,
     148              :                                   const libspdm_data_parameter_t *parameter, const void *data,
     149              :                                   size_t data_size)
     150              : {
     151              :     libspdm_context_t *context;
     152              :     uint32_t session_id;
     153              :     uint32_t data32;
     154              :     libspdm_session_info_t *session_info;
     155              :     uint8_t slot_id;
     156              :     uint8_t mut_auth_requested;
     157              :     uint8_t root_cert_index;
     158              :     uint16_t data16;
     159              : #if !(LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT) && LIBSPDM_CERT_PARSE_SUPPORT
     160              :     bool status;
     161              :     const uint8_t *cert_buffer;
     162              :     size_t cert_buffer_size;
     163              : #endif
     164              : 
     165           19 :     if (spdm_context == NULL || data == NULL || data_type >= LIBSPDM_DATA_MAX) {
     166            0 :         return LIBSPDM_STATUS_INVALID_PARAMETER;
     167              :     }
     168              : 
     169           19 :     context = spdm_context;
     170              : 
     171           19 :     if (need_session_info_for_data(data_type)) {
     172            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_SESSION) {
     173            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     174              :         }
     175            0 :         session_id = libspdm_read_uint32(parameter->additional_data);
     176            0 :         session_info = libspdm_get_session_info_via_session_id(context, session_id);
     177            0 :         if (session_info == NULL) {
     178            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     179              :         }
     180              :     } else {
     181           19 :         session_info = NULL;
     182              :     }
     183              : 
     184           19 :     switch (data_type) {
     185            0 :     case LIBSPDM_DATA_SPDM_VERSION:
     186            0 :         LIBSPDM_ASSERT (data_size <= sizeof(spdm_version_number_t) * SPDM_MAX_VERSION_COUNT);
     187            0 :         if (parameter->location == LIBSPDM_DATA_LOCATION_CONNECTION) {
     188              :             /* Only have one connected version */
     189            0 :             LIBSPDM_ASSERT (data_size == sizeof(spdm_version_number_t));
     190            0 :             libspdm_copy_mem(&(context->connection_info.version),
     191              :                              sizeof(context->connection_info.version),
     192              :                              data,
     193              :                              sizeof(spdm_version_number_t));
     194            0 :         } else if (parameter->location == LIBSPDM_DATA_LOCATION_LOCAL) {
     195            0 :             context->local_context.version.spdm_version_count =
     196            0 :                 (uint8_t)(data_size / sizeof(spdm_version_number_t));
     197            0 :             libspdm_copy_mem(context->local_context.version.spdm_version,
     198              :                              sizeof(context->local_context.version.spdm_version),
     199              :                              data,
     200            0 :                              context->local_context.version.spdm_version_count *
     201              :                              sizeof(spdm_version_number_t));
     202              :         } else {
     203            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     204              :         }
     205            0 :         break;
     206            0 :     case LIBSPDM_DATA_SECURED_MESSAGE_VERSION:
     207            0 :         LIBSPDM_ASSERT (data_size <=
     208              :                         sizeof(spdm_version_number_t) * SECURED_SPDM_MAX_VERSION_COUNT);
     209            0 :         if (parameter->location == LIBSPDM_DATA_LOCATION_LOCAL) {
     210            0 :             context->local_context.secured_message_version.spdm_version_count =
     211            0 :                 (uint8_t)(data_size / sizeof(spdm_version_number_t));
     212            0 :             libspdm_copy_mem(context->local_context.secured_message_version.spdm_version,
     213              :                              sizeof(context->local_context.secured_message_version.spdm_version),
     214              :                              data,
     215            0 :                              context->local_context.secured_message_version.spdm_version_count *
     216              :                              sizeof(spdm_version_number_t));
     217              :         } else {
     218            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     219              :         }
     220            0 :         break;
     221            0 :     case LIBSPDM_DATA_CAPABILITY_FLAGS:
     222            0 :         if (data_size != sizeof(uint32_t)) {
     223            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     224              :         }
     225              : 
     226            0 :         data32 = libspdm_read_uint32((const uint8_t *)data);
     227              : 
     228            0 :         if (parameter->location == LIBSPDM_DATA_LOCATION_LOCAL) {
     229              :             #if !(LIBSPDM_ENABLE_CAPABILITY_CERT_CAP)
     230              :             LIBSPDM_ASSERT((data32 & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP) == 0);
     231              :             #endif /* !LIBSPDM_ENABLE_CAPABILITY_CERT_CAP */
     232              : 
     233              :             #if !(LIBSPDM_ENABLE_CAPABILITY_CHAL_CAP)
     234              :             LIBSPDM_ASSERT((data32 & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHAL_CAP) == 0);
     235              :             #endif /* !LIBSPDM_ENABLE_CAPABILITY_CHAL_CAP */
     236              : 
     237              :             #if !(LIBSPDM_ENABLE_CAPABILITY_MEAS_CAP)
     238              :             LIBSPDM_ASSERT((data32 & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP) == 0);
     239              :             #endif /* !LIBSPDM_ENABLE_CAPABILITY_MEAS_CAP */
     240              : 
     241              :             #if !(LIBSPDM_ENABLE_CAPABILITY_MEL_CAP)
     242              :             LIBSPDM_ASSERT((data32 & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEL_CAP) == 0);
     243              :             #endif /* !LIBSPDM_ENABLE_CAPABILITY_MEL_CAP */
     244              : 
     245              :             #if !(LIBSPDM_ENABLE_CAPABILITY_KEY_EX_CAP)
     246              :             LIBSPDM_ASSERT((data32 & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_KEY_EX_CAP) == 0);
     247              :             #endif /* !LIBSPDM_ENABLE_CAPABILITY_KEY_EX_CAP */
     248              : 
     249              :             #if !(LIBSPDM_ENABLE_CAPABILITY_PSK_CAP)
     250              :             LIBSPDM_ASSERT((data32 & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_PSK_CAP) == 0);
     251              :             #endif /* !LIBSPDM_ENABLE_CAPABILITY_PSK_CAP */
     252              : 
     253              :             #if !(LIBSPDM_ENABLE_CAPABILITY_ENDPOINT_INFO_CAP)
     254              :             LIBSPDM_ASSERT((data32 & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_EP_INFO_CAP) == 0);
     255              :             #endif /* !LIBSPDM_ENABLE_CAPABILITY_ENDPOINT_INFO_CAP */
     256              : 
     257            0 :             context->local_context.capability.flags = data32;
     258            0 :         } else if (parameter->location == LIBSPDM_DATA_LOCATION_CONNECTION) {
     259            0 :             context->connection_info.capability.flags = data32;
     260              :         } else {
     261            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     262              :         }
     263            0 :         break;
     264            0 :     case LIBSPDM_DATA_CAPABILITY_EXT_FLAGS:
     265            0 :         if (data_size != sizeof(uint16_t)) {
     266            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     267              :         }
     268              : 
     269            0 :         data16 = libspdm_read_uint16((const uint8_t *)data);
     270              : 
     271            0 :         if (parameter->location == LIBSPDM_DATA_LOCATION_LOCAL) {
     272            0 :             context->local_context.capability.flags = data16;
     273            0 :         } else if (parameter->location == LIBSPDM_DATA_LOCATION_CONNECTION) {
     274            0 :             context->connection_info.capability.flags = data16;
     275              :         } else {
     276            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     277              :         }
     278            0 :         break;
     279            0 :     case LIBSPDM_DATA_CAPABILITY_CT_EXPONENT:
     280            0 :         if (data_size != sizeof(uint8_t)) {
     281            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     282              :         }
     283            0 :         if (parameter->location == LIBSPDM_DATA_LOCATION_CONNECTION) {
     284            0 :             context->connection_info.capability.ct_exponent = *(const uint8_t *)data;
     285            0 :         } else if (parameter->location == LIBSPDM_DATA_LOCATION_LOCAL) {
     286            0 :             context->local_context.capability.ct_exponent = *(const uint8_t *)data;
     287              :         } else {
     288            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     289              :         }
     290            0 :         break;
     291            0 :     case LIBSPDM_DATA_CAPABILITY_RTT_US:
     292            0 :         if (data_size != sizeof(uint64_t)) {
     293            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     294              :         }
     295            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_LOCAL) {
     296            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     297              :         }
     298            0 :         context->local_context.capability.rtt = libspdm_read_uint64((const uint8_t *)data);
     299            0 :         break;
     300            0 :     case LIBSPDM_DATA_CAPABILITY_MAX_SPDM_MSG_SIZE:
     301            0 :         if (data_size != sizeof(uint32_t)) {
     302            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     303              :         }
     304              :         /* The local max_spdm_msg_size is set by libspdm_register_transport_layer_func.
     305              :          * Only the connection's max_spdm_msg_size is settable here. */
     306            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
     307            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     308              :         }
     309            0 :         data32 = libspdm_read_uint32((const uint8_t *)data);
     310            0 :         LIBSPDM_ASSERT (data32 >= SPDM_MIN_DATA_TRANSFER_SIZE_VERSION_12);
     311            0 :         context->connection_info.capability.max_spdm_msg_size = data32;
     312            0 :         break;
     313            0 :     case LIBSPDM_DATA_MEASUREMENT_SPEC:
     314            0 :         if (data_size != sizeof(uint8_t)) {
     315            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     316              :         }
     317            0 :         if (parameter->location == LIBSPDM_DATA_LOCATION_CONNECTION) {
     318            0 :             context->connection_info.algorithm.measurement_spec = *(const uint8_t *)data;
     319            0 :         } else if (parameter->location == LIBSPDM_DATA_LOCATION_LOCAL) {
     320            0 :             context->local_context.algorithm.measurement_spec = *(const uint8_t *)data;
     321              :         } else {
     322            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     323              :         }
     324            0 :         break;
     325            0 :     case LIBSPDM_DATA_MEASUREMENT_HASH_ALGO:
     326            0 :         if (data_size != sizeof(uint32_t)) {
     327            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     328              :         }
     329            0 :         data32 = libspdm_read_uint32((const uint8_t *)data);
     330            0 :         if (parameter->location == LIBSPDM_DATA_LOCATION_CONNECTION) {
     331            0 :             context->connection_info.algorithm.measurement_hash_algo = data32;
     332            0 :         } else if (parameter->location == LIBSPDM_DATA_LOCATION_LOCAL) {
     333            0 :             context->local_context.algorithm.measurement_hash_algo = data32;
     334              :         } else {
     335            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     336              :         }
     337            0 :         break;
     338            0 :     case LIBSPDM_DATA_BASE_ASYM_ALGO:
     339            0 :         if (data_size != sizeof(uint32_t)) {
     340            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     341              :         }
     342            0 :         data32 = libspdm_read_uint32((const uint8_t *)data);
     343            0 :         if (parameter->location == LIBSPDM_DATA_LOCATION_CONNECTION) {
     344            0 :             context->connection_info.algorithm.base_asym_algo = data32;
     345            0 :         } else if (parameter->location == LIBSPDM_DATA_LOCATION_LOCAL) {
     346            0 :             context->local_context.algorithm.base_asym_algo = data32;
     347              :         } else {
     348            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     349              :         }
     350            0 :         break;
     351            0 :     case LIBSPDM_DATA_BASE_HASH_ALGO:
     352            0 :         if (data_size != sizeof(uint32_t)) {
     353            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     354              :         }
     355            0 :         data32 = libspdm_read_uint32((const uint8_t *)data);
     356            0 :         if (parameter->location == LIBSPDM_DATA_LOCATION_CONNECTION) {
     357            0 :             context->connection_info.algorithm.base_hash_algo = data32;
     358            0 :         } else if (parameter->location == LIBSPDM_DATA_LOCATION_LOCAL) {
     359            0 :             context->local_context.algorithm.base_hash_algo = data32;
     360              :         } else {
     361            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     362              :         }
     363            0 :         break;
     364            0 :     case LIBSPDM_DATA_DHE_NAME_GROUP:
     365            0 :         if (data_size != sizeof(uint16_t)) {
     366            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     367              :         }
     368            0 :         data16 = libspdm_read_uint16((const uint8_t *)data);
     369            0 :         if (parameter->location == LIBSPDM_DATA_LOCATION_CONNECTION) {
     370            0 :             context->connection_info.algorithm.dhe_named_group = data16;
     371            0 :         } else if (parameter->location == LIBSPDM_DATA_LOCATION_LOCAL) {
     372            0 :             context->local_context.algorithm.dhe_named_group = data16;
     373              :         } else {
     374            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     375              :         }
     376            0 :         break;
     377            0 :     case LIBSPDM_DATA_AEAD_CIPHER_SUITE:
     378            0 :         if (data_size != sizeof(uint16_t)) {
     379            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     380              :         }
     381            0 :         data16 = libspdm_read_uint16((const uint8_t *)data);
     382            0 :         if (parameter->location == LIBSPDM_DATA_LOCATION_CONNECTION) {
     383            0 :             context->connection_info.algorithm.aead_cipher_suite = data16;
     384            0 :         } else if (parameter->location == LIBSPDM_DATA_LOCATION_LOCAL) {
     385            0 :             context->local_context.algorithm.aead_cipher_suite = data16;
     386              :         } else {
     387            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     388              :         }
     389            0 :         break;
     390            0 :     case LIBSPDM_DATA_REQ_BASE_ASYM_ALG:
     391            0 :         if (data_size != sizeof(uint16_t)) {
     392            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     393              :         }
     394            0 :         data16 = libspdm_read_uint16((const uint8_t *)data);
     395            0 :         if (parameter->location == LIBSPDM_DATA_LOCATION_CONNECTION) {
     396            0 :             context->connection_info.algorithm.req_base_asym_alg = data16;
     397            0 :         } else if (parameter->location == LIBSPDM_DATA_LOCATION_LOCAL) {
     398            0 :             context->local_context.algorithm.req_base_asym_alg = data16;
     399              :         } else {
     400            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     401              :         }
     402            0 :         break;
     403            0 :     case LIBSPDM_DATA_KEY_SCHEDULE:
     404            0 :         if (data_size != sizeof(uint16_t)) {
     405            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     406              :         }
     407            0 :         data16 = libspdm_read_uint16((const uint8_t *)data);
     408            0 :         if (parameter->location == LIBSPDM_DATA_LOCATION_CONNECTION) {
     409            0 :             context->connection_info.algorithm.key_schedule = data16;
     410            0 :         } else if (parameter->location == LIBSPDM_DATA_LOCATION_LOCAL) {
     411            0 :             context->local_context.algorithm.key_schedule = data16;
     412              :         } else {
     413            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     414              :         }
     415            0 :         break;
     416            0 :     case LIBSPDM_DATA_OTHER_PARAMS_SUPPORT:
     417            0 :         if (data_size != sizeof(uint8_t)) {
     418            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     419              :         }
     420            0 :         if (parameter->location == LIBSPDM_DATA_LOCATION_CONNECTION) {
     421            0 :             context->connection_info.algorithm.other_params_support = *(const uint8_t *)data;
     422            0 :         } else if (parameter->location == LIBSPDM_DATA_LOCATION_LOCAL) {
     423            0 :             context->local_context.algorithm.other_params_support = *(const uint8_t *)data;
     424              :         } else {
     425            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     426              :         }
     427            0 :         break;
     428            0 :     case LIBSPDM_DATA_MEL_SPEC:
     429            0 :         if (data_size != sizeof(uint8_t)) {
     430            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     431              :         }
     432            0 :         if (parameter->location == LIBSPDM_DATA_LOCATION_CONNECTION) {
     433            0 :             context->connection_info.algorithm.mel_spec = *(const uint8_t *)data;
     434            0 :         } else if (parameter->location == LIBSPDM_DATA_LOCATION_LOCAL) {
     435            0 :             context->local_context.algorithm.mel_spec = *(const uint8_t *)data;
     436              :         } else {
     437            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     438              :         }
     439            0 :         break;
     440            0 :     case LIBSPDM_DATA_PQC_ASYM_ALGO:
     441            0 :         if (data_size != sizeof(uint32_t)) {
     442            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     443              :         }
     444            0 :         data32 = libspdm_read_uint32((const uint8_t *)data);
     445            0 :         if (parameter->location == LIBSPDM_DATA_LOCATION_CONNECTION) {
     446            0 :             context->connection_info.algorithm.pqc_asym_algo = data32;
     447            0 :         } else if (parameter->location == LIBSPDM_DATA_LOCATION_LOCAL) {
     448            0 :             context->local_context.algorithm.pqc_asym_algo = data32;
     449              :         } else {
     450            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     451              :         }
     452            0 :         break;
     453            0 :     case LIBSPDM_DATA_REQ_PQC_ASYM_ALG:
     454            0 :         if (data_size != sizeof(uint32_t)) {
     455            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     456              :         }
     457            0 :         data32 = libspdm_read_uint32((const uint8_t *)data);
     458            0 :         if (parameter->location == LIBSPDM_DATA_LOCATION_CONNECTION) {
     459            0 :             context->connection_info.algorithm.req_pqc_asym_alg = data32;
     460            0 :         } else if (parameter->location == LIBSPDM_DATA_LOCATION_LOCAL) {
     461            0 :             context->local_context.algorithm.req_pqc_asym_alg = data32;
     462              :         } else {
     463            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     464              :         }
     465            0 :         break;
     466            0 :     case LIBSPDM_DATA_KEM_ALG:
     467            0 :         if (data_size != sizeof(uint32_t)) {
     468            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     469              :         }
     470            0 :         data32 = libspdm_read_uint32((const uint8_t *)data);
     471            0 :         if (parameter->location == LIBSPDM_DATA_LOCATION_CONNECTION) {
     472            0 :             context->connection_info.algorithm.kem_alg = data32;
     473            0 :         } else if (parameter->location == LIBSPDM_DATA_LOCATION_LOCAL) {
     474            0 :             context->local_context.algorithm.kem_alg = data32;
     475              :         } else {
     476            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     477              :         }
     478            0 :         break;
     479            0 :     case LIBSPDM_DATA_ALGO_PRIORITY_PQC_FIRST:
     480            0 :         if (data_size != sizeof(bool)) {
     481            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     482              :         }
     483            0 :         if (parameter->location == LIBSPDM_DATA_LOCATION_LOCAL) {
     484            0 :             context->local_context.algorithm.pqc_first = *(const bool *)data;
     485              :         } else {
     486            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     487              :         }
     488            0 :         break;
     489            0 :     case LIBSPDM_DATA_CONNECTION_STATE:
     490            0 :         if (data_size != sizeof(libspdm_connection_state_t)) {
     491            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     492              :         }
     493            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
     494            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     495              :         }
     496            0 :         context->connection_info.connection_state = libspdm_read_uint32((const uint8_t *)data);
     497            0 :         break;
     498            0 :     case LIBSPDM_DATA_RESPONSE_STATE:
     499            0 :         if (data_size != sizeof(libspdm_response_state_t)) {
     500            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     501              :         }
     502            0 :         context->response_state = libspdm_read_uint32((const uint8_t *)data);
     503            0 :         break;
     504            2 :     case LIBSPDM_DATA_PEER_PUBLIC_ROOT_CERT:
     505            2 :         if (parameter->location != LIBSPDM_DATA_LOCATION_LOCAL) {
     506            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     507              :         }
     508            2 :         root_cert_index = 0;
     509           11 :         while (context->local_context.peer_root_cert_provision[root_cert_index] != NULL) {
     510           10 :             root_cert_index++;
     511           10 :             if (root_cert_index >= LIBSPDM_MAX_ROOT_CERT_SUPPORT) {
     512            1 :                 return LIBSPDM_STATUS_BUFFER_FULL;
     513              :             }
     514              :         }
     515            1 :         context->local_context.peer_root_cert_provision_size[root_cert_index] = data_size;
     516            1 :         context->local_context.peer_root_cert_provision[root_cert_index] = data;
     517            1 :         break;
     518            0 :     case LIBSPDM_DATA_LOCAL_PUBLIC_CERT_CHAIN:
     519            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_LOCAL) {
     520            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     521              :         }
     522            0 :         slot_id = parameter->additional_data[0];
     523            0 :         if (slot_id >= SPDM_MAX_SLOT_COUNT) {
     524            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     525              :         }
     526            0 :         context->local_context.local_cert_chain_provision_size[slot_id] = data_size;
     527            0 :         context->local_context.local_cert_chain_provision[slot_id] = data;
     528            0 :         break;
     529            0 :     case LIBSPDM_DATA_LOCAL_SUPPORTED_SLOT_MASK:
     530            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_LOCAL) {
     531            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     532              :         }
     533            0 :         if (data_size != sizeof(uint8_t)) {
     534            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     535              :         }
     536            0 :         context->local_context.local_supported_slot_mask = *(const uint8_t *)data;
     537            0 :         break;
     538            0 :     case LIBSPDM_DATA_LOCAL_KEY_PAIR_ID:
     539            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_LOCAL) {
     540            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     541              :         }
     542            0 :         slot_id = parameter->additional_data[0];
     543            0 :         if (slot_id >= SPDM_MAX_SLOT_COUNT) {
     544            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     545              :         }
     546            0 :         if (data_size != sizeof(spdm_key_pair_id_t)) {
     547            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     548              :         }
     549            0 :         context->local_context.local_key_pair_id[slot_id] = *(const spdm_key_pair_id_t *)data;
     550            0 :         break;
     551            0 :     case LIBSPDM_DATA_LOCAL_CERT_INFO:
     552            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_LOCAL) {
     553            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     554              :         }
     555            0 :         slot_id = parameter->additional_data[0];
     556            0 :         if (slot_id >= SPDM_MAX_SLOT_COUNT) {
     557            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     558              :         }
     559            0 :         if (data_size != sizeof(spdm_certificate_info_t)) {
     560            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     561              :         }
     562            0 :         context->local_context.local_cert_info[slot_id] = *(const spdm_certificate_info_t *)data;
     563            0 :         break;
     564            0 :     case LIBSPDM_DATA_LOCAL_KEY_USAGE_BIT_MASK:
     565            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_LOCAL) {
     566            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     567              :         }
     568            0 :         slot_id = parameter->additional_data[0];
     569            0 :         if (slot_id >= SPDM_MAX_SLOT_COUNT) {
     570            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     571              :         }
     572            0 :         if (data_size != sizeof(spdm_key_usage_bit_mask_t)) {
     573            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     574              :         }
     575            0 :         context->local_context.local_key_usage_bit_mask[slot_id] =
     576            0 :             libspdm_read_uint16((const uint8_t *)data);
     577            0 :         break;
     578            3 :     case LIBSPDM_DATA_PEER_USED_CERT_CHAIN_BUFFER:
     579            3 :         if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
     580            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     581              :         }
     582            3 :         slot_id = parameter->additional_data[0];
     583            3 :         if (slot_id >= SPDM_MAX_SLOT_COUNT) {
     584            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     585              :         }
     586            3 :         if (data_size > LIBSPDM_MAX_CERT_CHAIN_SIZE) {
     587            0 :             return LIBSPDM_STATUS_BUFFER_FULL;
     588              :         }
     589            3 :         context->connection_info.peer_used_cert_chain_slot_id = slot_id;
     590              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
     591              :         context->connection_info.peer_used_cert_chain[slot_id].buffer_size = data_size;
     592              :         libspdm_copy_mem(context->connection_info.peer_used_cert_chain[slot_id].buffer,
     593              :                          sizeof(context->connection_info.peer_used_cert_chain[slot_id].buffer),
     594              :                          data, data_size);
     595              : #else
     596              : #if LIBSPDM_CERT_PARSE_SUPPORT
     597            3 :         status = libspdm_hash_all(
     598              :             context->connection_info.algorithm.base_hash_algo,
     599              :             data, data_size,
     600            3 :             context->connection_info.peer_used_cert_chain[slot_id].buffer_hash);
     601            3 :         if (!status) {
     602            0 :             return LIBSPDM_STATUS_CRYPTO_ERROR;
     603              :         }
     604              : 
     605            6 :         context->connection_info.peer_used_cert_chain[slot_id].buffer_hash_size =
     606            3 :             libspdm_get_hash_size(context->connection_info.algorithm.base_hash_algo);
     607              : 
     608              :         /*process the SPDM cert header and hash*/
     609            3 :         data = (const uint8_t *)data + sizeof(spdm_cert_chain_t) +
     610            3 :                libspdm_get_hash_size(context->connection_info.algorithm.base_hash_algo);
     611            3 :         data_size = data_size -
     612              :                     (sizeof(spdm_cert_chain_t) +
     613            3 :                      libspdm_get_hash_size(context->connection_info.algorithm.base_hash_algo));
     614              : 
     615              :         /* Get leaf cert from cert chain */
     616            3 :         status = libspdm_x509_get_cert_from_cert_chain(data, data_size, -1,
     617              :                                                        &cert_buffer, &cert_buffer_size);
     618            3 :         if (!status) {
     619            0 :             return LIBSPDM_STATUS_CRYPTO_ERROR;
     620              :         }
     621              : 
     622            3 :         status = false;
     623              : #if (LIBSPDM_RSA_SSA_SUPPORT) || (LIBSPDM_RSA_PSS_SUPPORT)
     624            3 :         if (!status) {
     625            3 :             status = libspdm_rsa_get_public_key_from_x509(
     626              :                 cert_buffer, cert_buffer_size,
     627            3 :                 &context->connection_info.peer_used_cert_chain[slot_id].leaf_cert_public_key);
     628              :         }
     629              : #endif
     630              : #if LIBSPDM_ECDSA_SUPPORT
     631            3 :         if (!status) {
     632            3 :             status = libspdm_ec_get_public_key_from_x509(
     633              :                 cert_buffer, cert_buffer_size,
     634            3 :                 &context->connection_info.peer_used_cert_chain[slot_id].leaf_cert_public_key);
     635              :         }
     636              : #endif
     637              : #if (LIBSPDM_EDDSA_ED25519_SUPPORT) || (LIBSPDM_EDDSA_ED448_SUPPORT)
     638              :         if (!status) {
     639              :             status = libspdm_ecd_get_public_key_from_x509(
     640              :                 cert_buffer, cert_buffer_size,
     641              :                 &context->connection_info.peer_used_cert_chain[slot_id].leaf_cert_public_key);
     642              :         }
     643              : #endif
     644              : #if LIBSPDM_SM2_DSA_SUPPORT
     645              :         if (!status) {
     646              :             status = libspdm_sm2_get_public_key_from_x509(
     647              :                 cert_buffer, cert_buffer_size,
     648              :                 &context->connection_info.peer_used_cert_chain[slot_id].leaf_cert_public_key);
     649              :         }
     650              : #endif
     651            3 :         if (!status) {
     652            0 :             return LIBSPDM_STATUS_INVALID_CERT;
     653              :         }
     654              : #else
     655              :         LIBSPDM_ASSERT (false);
     656              : #endif /* LIBSPDM_CERT_PARSE_SUPPORT */
     657              : #endif /* LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT */
     658            3 :         break;
     659            0 :     case LIBSPDM_DATA_PEER_PUBLIC_KEY:
     660            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_LOCAL) {
     661            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     662              :         }
     663            0 :         context->local_context.peer_public_key_provision_size = data_size;
     664            0 :         context->local_context.peer_public_key_provision = data;
     665            0 :         break;
     666            0 :     case LIBSPDM_DATA_LOCAL_PUBLIC_KEY:
     667            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_LOCAL) {
     668            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     669              :         }
     670            0 :         context->local_context.local_public_key_provision_size = data_size;
     671            0 :         context->local_context.local_public_key_provision = data;
     672            0 :         break;
     673            0 :     case LIBSPDM_DATA_BASIC_MUT_AUTH_REQUESTED:
     674            0 :         if (data_size != sizeof(bool)) {
     675            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     676              :         }
     677            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_LOCAL) {
     678            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     679              :         }
     680            0 :         mut_auth_requested = *(const uint8_t *)data;
     681            0 :         if (((mut_auth_requested != 0) && (mut_auth_requested != 1))) {
     682            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     683              :         }
     684            0 :         context->local_context.basic_mut_auth_requested = mut_auth_requested;
     685            0 :         context->encap_context.request_id = 0;
     686            0 :         slot_id = parameter->additional_data[0];
     687            0 :         if ((slot_id >= SPDM_MAX_SLOT_COUNT) && (slot_id != 0xFF)) {
     688            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     689              :         }
     690            0 :         context->encap_context.req_slot_id = slot_id;
     691              : 
     692              :         #if LIBSPDM_DEBUG_PRINT_ENABLE
     693            0 :         if (mut_auth_requested) {
     694            0 :             LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO,
     695              :                            "Basic mutual authentication is a deprecated feature.\n"));
     696              :         }
     697              :         #endif /* LIBSPDM_DEBUG_PRINT_ENABLE */
     698            0 :         break;
     699            0 :     case LIBSPDM_DATA_MUT_AUTH_REQUESTED:
     700            0 :         if (data_size != sizeof(uint8_t)) {
     701            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     702              :         }
     703            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_LOCAL) {
     704            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     705              :         }
     706            0 :         mut_auth_requested = *(const uint8_t *)data;
     707            0 :         if (((mut_auth_requested != 0) &&
     708              :              (mut_auth_requested !=
     709            0 :               SPDM_KEY_EXCHANGE_RESPONSE_MUT_AUTH_REQUESTED) &&
     710              :              (mut_auth_requested !=
     711            0 :               SPDM_KEY_EXCHANGE_RESPONSE_MUT_AUTH_REQUESTED_WITH_ENCAP_REQUEST) &&
     712              :              (mut_auth_requested !=
     713              :               SPDM_KEY_EXCHANGE_RESPONSE_MUT_AUTH_REQUESTED_WITH_GET_DIGESTS))) {
     714            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     715              :         }
     716            0 :         context->local_context.mut_auth_requested = mut_auth_requested;
     717            0 :         context->encap_context.request_id = 0;
     718            0 :         slot_id = parameter->additional_data[0];
     719            0 :         if ((slot_id >= SPDM_MAX_SLOT_COUNT) && (slot_id != 0xFF)) {
     720            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     721              :         }
     722            0 :         context->encap_context.req_slot_id = slot_id;
     723            0 :         break;
     724            0 :     case LIBSPDM_DATA_MANDATORY_MUT_AUTH:
     725            0 :         if (data_size != sizeof(bool)) {
     726            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     727              :         }
     728            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_LOCAL) {
     729            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     730              :         }
     731            0 :         context->local_context.mandatory_mut_auth = *(const bool *)data;
     732            0 :         break;
     733            0 :     case LIBSPDM_DATA_HEARTBEAT_PERIOD:
     734            0 :         if (data_size != sizeof(uint8_t)) {
     735            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     736              :         }
     737            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_LOCAL) {
     738            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     739              :         }
     740            0 :         context->local_context.heartbeat_period = *(const uint8_t *)data;
     741            0 :         break;
     742            4 :     case LIBSPDM_DATA_APP_CONTEXT_DATA:
     743            4 :         if (data_size != sizeof(void *) || *(void *const *)data == NULL) {
     744            2 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     745              :         }
     746            2 :         context->app_context_data_ptr = *(void *const *)data;
     747            2 :         break;
     748            0 :     case LIBSPDM_DATA_HANDLE_ERROR_RETURN_POLICY:
     749            0 :         if (data_size != sizeof(uint8_t)) {
     750            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     751              :         }
     752            0 :         context->handle_error_return_policy = *(const uint8_t *)data;
     753            0 :         break;
     754            0 :     case LIBSPDM_DATA_VCA_CACHE:
     755            0 :         if (data_size > sizeof(context->transcript.message_a.buffer)) {
     756            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     757              :         }
     758            0 :         context->transcript.message_a.buffer_size = data_size;
     759            0 :         libspdm_copy_mem(context->transcript.message_a.buffer,
     760              :                          sizeof(context->transcript.message_a.buffer),
     761              :                          data, data_size);
     762            0 :         break;
     763            0 :     case LIBSPDM_DATA_IS_REQUESTER:
     764            0 :         if (data_size != sizeof(bool)) {
     765            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     766              :         }
     767            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_LOCAL) {
     768            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     769              :         }
     770            0 :         context->local_context.is_requester = *(const bool *)data;
     771            0 :         break;
     772            0 :     case LIBSPDM_DATA_REQUEST_RETRY_TIMES:
     773            0 :         if (data_size != sizeof(uint8_t)) {
     774            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     775              :         }
     776            0 :         context->retry_times = *(const uint8_t *)data;
     777            0 :         break;
     778            0 :     case LIBSPDM_DATA_REQUEST_RETRY_DELAY_TIME:
     779            0 :         if (data_size != sizeof(uint64_t)) {
     780            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     781              :         }
     782            0 :         context->retry_delay_time = *(const uint64_t *)data;
     783            0 :         break;
     784            5 :     case LIBSPDM_DATA_MAX_DHE_SESSION_COUNT:
     785            5 :         if (data_size != sizeof(uint32_t)) {
     786            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     787              :         }
     788            5 :         if (*(const uint32_t *)data > LIBSPDM_MAX_SESSION_COUNT - context->max_psk_session_count) {
     789            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     790              :         }
     791            5 :         context->max_dhe_session_count = *(const uint32_t *)data;
     792            5 :         break;
     793            5 :     case LIBSPDM_DATA_MAX_PSK_SESSION_COUNT:
     794            5 :         if (data_size != sizeof(uint32_t)) {
     795            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     796              :         }
     797            5 :         if (*(const uint32_t *)data > LIBSPDM_MAX_SESSION_COUNT - context->max_dhe_session_count) {
     798            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     799              :         }
     800            5 :         context->max_psk_session_count = *(const uint32_t *)data;
     801            5 :         break;
     802            0 :     case LIBSPDM_DATA_MAX_SPDM_SESSION_SEQUENCE_NUMBER:
     803            0 :         if (data_size != sizeof(uint64_t)) {
     804            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     805              :         }
     806            0 :         context->max_spdm_session_sequence_number = *(const uint64_t *)data;
     807            0 :         if (context->max_spdm_session_sequence_number == 0) {
     808            0 :             context->max_spdm_session_sequence_number = LIBSPDM_MAX_SPDM_SESSION_SEQUENCE_NUMBER;
     809              :         }
     810            0 :         break;
     811            0 :     case LIBSPDM_DATA_SPDM_VERSION_10_11_VERIFY_SIGNATURE_ENDIAN:
     812            0 :         if (data_size != sizeof(uint8_t)) {
     813            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     814              :         }
     815            0 :         if (*(const uint8_t*)data != LIBSPDM_SPDM_10_11_VERIFY_SIGNATURE_ENDIAN_BIG_ONLY &&
     816            0 :             *(const uint8_t*)data != LIBSPDM_SPDM_10_11_VERIFY_SIGNATURE_ENDIAN_LITTLE_ONLY &&
     817            0 :             *(const uint8_t*)data != LIBSPDM_SPDM_10_11_VERIFY_SIGNATURE_ENDIAN_BIG_OR_LITTLE) {
     818            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     819              :         }
     820            0 :         context->spdm_10_11_verify_signature_endian = *(const uint8_t*)data;
     821            0 :         break;
     822            0 :     case LIBSPDM_DATA_SEQUENCE_NUMBER_ENDIAN:
     823            0 :         if (data_size != sizeof(uint8_t)) {
     824            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     825              :         }
     826            0 :         context->sequence_number_endian = *(const uint8_t *)data;
     827            0 :         break;
     828            0 :     case LIBSPDM_DATA_MULTI_KEY_CONN_REQ:
     829            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
     830            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     831              :         }
     832            0 :         if (data_size != sizeof(bool)) {
     833            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     834              :         }
     835            0 :         context->connection_info.multi_key_conn_req = *(const bool *)data;
     836            0 :         break;
     837            0 :     case LIBSPDM_DATA_MULTI_KEY_CONN_RSP:
     838            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
     839            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     840              :         }
     841            0 :         if (data_size != sizeof(bool)) {
     842            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     843              :         }
     844            0 :         context->connection_info.multi_key_conn_rsp = *(const bool *)data;
     845            0 :         break;
     846            0 :     case LIBSPDM_DATA_TOTAL_KEY_PAIRS:
     847            0 :         if (data_size != sizeof(uint8_t)) {
     848            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     849              :         }
     850            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_LOCAL) {
     851            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     852              :         }
     853            0 :         context->local_context.total_key_pairs = *(const uint8_t *)data;
     854            0 :         break;
     855            0 :     default:
     856            0 :         return LIBSPDM_STATUS_UNSUPPORTED_CAP;
     857              :         break;
     858              :     }
     859              : 
     860           16 :     return LIBSPDM_STATUS_SUCCESS;
     861              : }
     862              : 
     863           56 : libspdm_return_t libspdm_get_data(void *spdm_context, libspdm_data_type_t data_type,
     864              :                                   const libspdm_data_parameter_t *parameter,
     865              :                                   void *data, size_t *data_size)
     866              : {
     867              :     libspdm_context_t *context;
     868           56 :     libspdm_secured_message_context_t *secured_context = NULL;
     869              :     size_t target_data_size;
     870              :     void *target_data;
     871              :     uint32_t session_id;
     872              :     libspdm_session_info_t *session_info;
     873              :     size_t digest_size;
     874              :     size_t digest_count;
     875              :     uint8_t slot_id;
     876              :     size_t index;
     877              : 
     878           56 :     if (spdm_context == NULL || data == NULL || data_size == NULL ||
     879              :         data_type >= LIBSPDM_DATA_MAX) {
     880            0 :         return LIBSPDM_STATUS_INVALID_PARAMETER;
     881              :     }
     882              : 
     883           56 :     context = spdm_context;
     884              : 
     885           56 :     if (data_type == LIBSPDM_DATA_SESSION_END_SESSION_ATTRIBUTES) {
     886              :         /* end_session_attributes is present in both a session context as well as an
     887              :          * spdm context. */
     888            0 :         session_id = libspdm_read_uint32(parameter->additional_data);
     889            0 :         session_info = libspdm_get_session_info_via_session_id(context, session_id);
     890           56 :     } else if (need_session_info_for_data(data_type)) {
     891            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_SESSION) {
     892            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     893              :         }
     894            0 :         session_id = libspdm_read_uint32(parameter->additional_data);
     895            0 :         session_info = libspdm_get_session_info_via_session_id(context, session_id);
     896            0 :         if (session_info == NULL) {
     897            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     898              :         }
     899            0 :         secured_context = session_info->secured_message_context;
     900              :     } else {
     901           56 :         session_info = NULL;
     902              :     }
     903              : 
     904           56 :     switch (data_type) {
     905            0 :     case LIBSPDM_DATA_SPDM_VERSION:
     906            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
     907            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     908              :         }
     909            0 :         target_data_size = sizeof(spdm_version_number_t);
     910            0 :         target_data = &(context->connection_info.version);
     911            0 :         break;
     912            0 :     case LIBSPDM_DATA_SESSION_SECURED_MESSAGE_VERSION:
     913            0 :         target_data_size = sizeof(spdm_version_number_t);
     914            0 :         target_data = &(secured_context->secured_message_version);
     915            0 :         break;
     916            0 :     case LIBSPDM_DATA_CAPABILITY_FLAGS:
     917            0 :         target_data_size = sizeof(uint32_t);
     918            0 :         if (parameter->location == LIBSPDM_DATA_LOCATION_CONNECTION) {
     919            0 :             target_data = &context->connection_info.capability.flags;
     920            0 :         } else if (parameter->location == LIBSPDM_DATA_LOCATION_LOCAL) {
     921            0 :             target_data = &context->local_context.capability.flags;
     922              :         } else {
     923            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     924              :         }
     925            0 :         break;
     926            0 :     case LIBSPDM_DATA_CAPABILITY_EXT_FLAGS:
     927            0 :         target_data_size = sizeof(uint16_t);
     928            0 :         if (parameter->location == LIBSPDM_DATA_LOCATION_CONNECTION) {
     929            0 :             target_data = &context->connection_info.capability.ext_flags;
     930            0 :         } else if (parameter->location == LIBSPDM_DATA_LOCATION_LOCAL) {
     931            0 :             target_data = &context->local_context.capability.ext_flags;
     932              :         } else {
     933            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     934              :         }
     935            0 :         break;
     936            0 :     case LIBSPDM_DATA_CAPABILITY_CT_EXPONENT:
     937            0 :         target_data_size = sizeof(uint8_t);
     938            0 :         if (parameter->location == LIBSPDM_DATA_LOCATION_CONNECTION) {
     939            0 :             target_data = &context->connection_info.capability.ct_exponent;
     940            0 :         } else if (parameter->location == LIBSPDM_DATA_LOCATION_LOCAL) {
     941            0 :             target_data = &context->local_context.capability.ct_exponent;
     942              :         } else {
     943            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     944              :         }
     945            0 :         break;
     946            0 :     case LIBSPDM_DATA_CAPABILITY_DATA_TRANSFER_SIZE:
     947            0 :         target_data_size = sizeof(uint32_t);
     948            0 :         if (parameter->location == LIBSPDM_DATA_LOCATION_CONNECTION) {
     949            0 :             target_data = &context->connection_info.capability.data_transfer_size;
     950            0 :         } else if (parameter->location == LIBSPDM_DATA_LOCATION_LOCAL) {
     951            0 :             target_data = &context->local_context.capability.data_transfer_size;
     952              :         } else {
     953            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     954              :         }
     955            0 :         break;
     956            0 :     case LIBSPDM_DATA_CAPABILITY_MAX_SPDM_MSG_SIZE:
     957            0 :         target_data_size = sizeof(uint32_t);
     958            0 :         if (parameter->location == LIBSPDM_DATA_LOCATION_CONNECTION) {
     959            0 :             target_data = &context->connection_info.capability.max_spdm_msg_size;
     960            0 :         } else if (parameter->location == LIBSPDM_DATA_LOCATION_LOCAL) {
     961            0 :             target_data = &context->local_context.capability.max_spdm_msg_size;
     962              :         } else {
     963            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     964              :         }
     965            0 :         break;
     966            0 :     case LIBSPDM_DATA_CAPABILITY_SENDER_DATA_TRANSFER_SIZE:
     967            0 :         target_data_size = sizeof(uint32_t);
     968            0 :         if (parameter->location == LIBSPDM_DATA_LOCATION_CONNECTION) {
     969            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     970            0 :         } else if (parameter->location == LIBSPDM_DATA_LOCATION_LOCAL) {
     971            0 :             target_data = &context->local_context.capability.sender_data_transfer_size;
     972              :         } else {
     973            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     974              :         }
     975            0 :         break;
     976            0 :     case LIBSPDM_DATA_MEASUREMENT_SPEC:
     977            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
     978            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     979              :         }
     980            0 :         target_data_size = sizeof(uint8_t);
     981            0 :         target_data = &context->connection_info.algorithm.measurement_spec;
     982            0 :         break;
     983            0 :     case LIBSPDM_DATA_MEASUREMENT_HASH_ALGO:
     984            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
     985            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     986              :         }
     987            0 :         target_data_size = sizeof(uint32_t);
     988            0 :         target_data = &context->connection_info.algorithm.measurement_hash_algo;
     989            0 :         break;
     990            0 :     case LIBSPDM_DATA_BASE_ASYM_ALGO:
     991            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
     992            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
     993              :         }
     994            0 :         target_data_size = sizeof(uint32_t);
     995            0 :         target_data = &context->connection_info.algorithm.base_asym_algo;
     996            0 :         break;
     997            0 :     case LIBSPDM_DATA_BASE_HASH_ALGO:
     998            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
     999            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
    1000              :         }
    1001            0 :         target_data_size = sizeof(uint32_t);
    1002            0 :         target_data = &context->connection_info.algorithm.base_hash_algo;
    1003            0 :         break;
    1004            0 :     case LIBSPDM_DATA_DHE_NAME_GROUP:
    1005            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
    1006            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
    1007              :         }
    1008            0 :         target_data_size = sizeof(uint16_t);
    1009            0 :         target_data = &context->connection_info.algorithm.dhe_named_group;
    1010            0 :         break;
    1011            0 :     case LIBSPDM_DATA_AEAD_CIPHER_SUITE:
    1012            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
    1013            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
    1014              :         }
    1015            0 :         target_data_size = sizeof(uint16_t);
    1016            0 :         target_data = &context->connection_info.algorithm.aead_cipher_suite;
    1017            0 :         break;
    1018            0 :     case LIBSPDM_DATA_REQ_BASE_ASYM_ALG:
    1019            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
    1020            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
    1021              :         }
    1022            0 :         target_data_size = sizeof(uint16_t);
    1023            0 :         target_data = &context->connection_info.algorithm.req_base_asym_alg;
    1024            0 :         break;
    1025            0 :     case LIBSPDM_DATA_KEY_SCHEDULE:
    1026            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
    1027            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
    1028              :         }
    1029            0 :         target_data_size = sizeof(uint16_t);
    1030            0 :         target_data = &context->connection_info.algorithm.key_schedule;
    1031            0 :         break;
    1032            0 :     case LIBSPDM_DATA_OTHER_PARAMS_SUPPORT:
    1033            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
    1034            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
    1035              :         }
    1036            0 :         target_data_size = sizeof(uint8_t);
    1037            0 :         target_data = &context->connection_info.algorithm.other_params_support;
    1038            0 :         break;
    1039            0 :     case LIBSPDM_DATA_MEL_SPEC:
    1040            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
    1041            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
    1042              :         }
    1043            0 :         target_data_size = sizeof(uint8_t);
    1044            0 :         target_data = &context->connection_info.algorithm.mel_spec;
    1045            0 :         break;
    1046            0 :     case LIBSPDM_DATA_PQC_ASYM_ALGO:
    1047            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
    1048            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
    1049              :         }
    1050            0 :         target_data_size = sizeof(uint32_t);
    1051            0 :         target_data = &context->connection_info.algorithm.pqc_asym_algo;
    1052            0 :         break;
    1053            0 :     case LIBSPDM_DATA_REQ_PQC_ASYM_ALG:
    1054            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
    1055            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
    1056              :         }
    1057            0 :         target_data_size = sizeof(uint32_t);
    1058            0 :         target_data = &context->connection_info.algorithm.req_pqc_asym_alg;
    1059            0 :         break;
    1060            0 :     case LIBSPDM_DATA_KEM_ALG:
    1061            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
    1062            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
    1063              :         }
    1064            0 :         target_data_size = sizeof(uint32_t);
    1065            0 :         target_data = &context->connection_info.algorithm.kem_alg;
    1066            0 :         break;
    1067            0 :     case LIBSPDM_DATA_CONNECTION_STATE:
    1068            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
    1069            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
    1070              :         }
    1071            0 :         target_data_size = sizeof(libspdm_connection_state_t);
    1072            0 :         target_data = &context->connection_info.connection_state;
    1073            0 :         break;
    1074            0 :     case LIBSPDM_DATA_RESPONSE_STATE:
    1075            0 :         target_data_size = sizeof(libspdm_response_state_t);
    1076            0 :         target_data = &context->response_state;
    1077            0 :         break;
    1078            6 :     case LIBSPDM_DATA_PEER_PROVISIONED_SLOT_MASK:
    1079            6 :         if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
    1080            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
    1081              :         }
    1082            6 :         target_data_size = sizeof(uint8_t);
    1083            6 :         target_data = &context->connection_info.peer_provisioned_slot_mask;
    1084            6 :         break;
    1085            0 :     case LIBSPDM_DATA_PEER_SUPPORTED_SLOT_MASK:
    1086            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
    1087            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
    1088              :         }
    1089            0 :         target_data_size = sizeof(uint8_t);
    1090            0 :         target_data = &context->connection_info.peer_supported_slot_mask;
    1091            0 :         break;
    1092            6 :     case LIBSPDM_DATA_PEER_TOTAL_DIGEST_BUFFER:
    1093            6 :         if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
    1094            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
    1095              :         }
    1096            6 :         digest_count = 0;
    1097           54 :         for (index = 0; index < SPDM_MAX_SLOT_COUNT; index++) {
    1098           48 :             if (context->connection_info.peer_provisioned_slot_mask & (1 << index)) {
    1099           20 :                 digest_count++;
    1100              :             }
    1101              :         }
    1102            6 :         digest_size = libspdm_get_hash_size(context->connection_info.algorithm.base_hash_algo);
    1103            6 :         target_data_size = digest_size * digest_count;
    1104            6 :         target_data = context->connection_info.peer_total_digest_buffer;
    1105            6 :         break;
    1106            0 :     case LIBSPDM_DATA_PEER_KEY_PAIR_ID:
    1107            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
    1108            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
    1109              :         }
    1110            0 :         slot_id = parameter->additional_data[0];
    1111            0 :         if (slot_id >= SPDM_MAX_SLOT_COUNT) {
    1112            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
    1113              :         }
    1114            0 :         target_data_size = sizeof(spdm_key_pair_id_t);
    1115            0 :         target_data = &context->connection_info.peer_key_pair_id[slot_id];
    1116            0 :         break;
    1117            0 :     case LIBSPDM_DATA_PEER_CERT_INFO:
    1118            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
    1119            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
    1120              :         }
    1121            0 :         slot_id = parameter->additional_data[0];
    1122            0 :         if (slot_id >= SPDM_MAX_SLOT_COUNT) {
    1123            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
    1124              :         }
    1125            0 :         target_data_size = sizeof(spdm_certificate_info_t);
    1126            0 :         target_data = &context->connection_info.peer_cert_info[slot_id];
    1127            0 :         break;
    1128            0 :     case LIBSPDM_DATA_PEER_KEY_USAGE_BIT_MASK:
    1129            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
    1130            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
    1131              :         }
    1132            0 :         slot_id = parameter->additional_data[0];
    1133            0 :         if (slot_id >= SPDM_MAX_SLOT_COUNT) {
    1134            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
    1135              :         }
    1136            0 :         target_data_size = sizeof(spdm_key_usage_bit_mask_t);
    1137            0 :         target_data = &context->connection_info.peer_key_usage_bit_mask[slot_id];
    1138            0 :         break;
    1139            0 :     case LIBSPDM_DATA_SESSION_USE_PSK:
    1140            0 :         target_data_size = sizeof(bool);
    1141            0 :         target_data = &session_info->use_psk;
    1142            0 :         break;
    1143            0 :     case LIBSPDM_DATA_SESSION_MUT_AUTH_REQUESTED:
    1144            0 :         target_data_size = sizeof(uint8_t);
    1145            0 :         target_data = &session_info->mut_auth_requested;
    1146            0 :         break;
    1147            0 :     case LIBSPDM_DATA_SESSION_END_SESSION_ATTRIBUTES:
    1148            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
    1149            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
    1150              :         }
    1151            0 :         target_data_size = sizeof(uint8_t);
    1152            0 :         if (session_info == NULL) {
    1153            0 :             target_data = &context->connection_info.end_session_attributes;
    1154              :         } else {
    1155            0 :             target_data = &session_info->end_session_attributes;
    1156              :         }
    1157            0 :         break;
    1158            0 :     case LIBSPDM_DATA_SESSION_POLICY:
    1159            0 :         target_data_size = sizeof(uint8_t);
    1160            0 :         target_data = &session_info->session_policy;
    1161            0 :         break;
    1162            6 :     case LIBSPDM_DATA_APP_CONTEXT_DATA:
    1163            6 :         target_data_size = sizeof(void *);
    1164            6 :         target_data = &context->app_context_data_ptr;
    1165            6 :         break;
    1166            0 :     case LIBSPDM_DATA_HANDLE_ERROR_RETURN_POLICY:
    1167            0 :         target_data_size = sizeof(uint8_t);
    1168            0 :         target_data = &context->handle_error_return_policy;
    1169            0 :         break;
    1170            0 :     case LIBSPDM_DATA_MAX_DHE_SESSION_COUNT:
    1171            0 :         target_data_size = sizeof(uint32_t);
    1172            0 :         target_data = &context->max_dhe_session_count;
    1173            0 :         break;
    1174            0 :     case LIBSPDM_DATA_MAX_PSK_SESSION_COUNT:
    1175            0 :         target_data_size = sizeof(uint32_t);
    1176            0 :         target_data = &context->max_psk_session_count;
    1177            0 :         break;
    1178            0 :     case LIBSPDM_DATA_SESSION_SEQUENCE_NUMBER_REQ_DIR:
    1179            0 :         target_data_size = sizeof(uint64_t);
    1180            0 :         target_data = &secured_context->application_secret.request_data_sequence_number;
    1181            0 :         break;
    1182            0 :     case LIBSPDM_DATA_SESSION_SEQUENCE_NUMBER_RSP_DIR:
    1183            0 :         target_data_size = sizeof(uint64_t);
    1184            0 :         target_data = &secured_context->application_secret.response_data_sequence_number;
    1185            0 :         break;
    1186            0 :     case LIBSPDM_DATA_MAX_SPDM_SESSION_SEQUENCE_NUMBER:
    1187            0 :         target_data_size = sizeof(uint64_t);
    1188            0 :         target_data = &context->max_spdm_session_sequence_number;
    1189            0 :         break;
    1190            0 :     case LIBSPDM_DATA_VCA_CACHE:
    1191            0 :         target_data_size = context->transcript.message_a.buffer_size;
    1192            0 :         target_data = context->transcript.message_a.buffer;
    1193            0 :         break;
    1194            0 :     case LIBSPDM_DATA_REQUEST_AND_SIZE:
    1195            0 :         target_data_size = context->last_spdm_request_size;
    1196            0 :         target_data = context->last_spdm_request;
    1197            0 :         break;
    1198            0 :     case LIBSPDM_DATA_SPDM_VERSION_10_11_VERIFY_SIGNATURE_ENDIAN:
    1199            0 :         target_data_size = sizeof(uint8_t);
    1200            0 :         target_data = &context->spdm_10_11_verify_signature_endian;
    1201            0 :         break;
    1202            0 :     case LIBSPDM_DATA_SEQUENCE_NUMBER_ENDIAN:
    1203            0 :         target_data_size = sizeof(uint8_t);
    1204            0 :         target_data = &context->sequence_number_endian;
    1205            0 :         break;
    1206            0 :     case LIBSPDM_DATA_SESSION_SEQUENCE_NUMBER_ENDIAN:
    1207            0 :         target_data_size = sizeof(uint8_t);
    1208            0 :         target_data = &secured_context->sequence_number_endian;
    1209            0 :         break;
    1210            0 :     case LIBSPDM_DATA_MULTI_KEY_CONN_REQ:
    1211            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
    1212            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
    1213              :         }
    1214            0 :         target_data_size = sizeof(bool);
    1215            0 :         target_data = &context->connection_info.multi_key_conn_req;
    1216            0 :         break;
    1217            0 :     case LIBSPDM_DATA_MULTI_KEY_CONN_RSP:
    1218            0 :         if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
    1219            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
    1220              :         }
    1221            0 :         target_data_size = sizeof(bool);
    1222            0 :         target_data = &context->connection_info.multi_key_conn_rsp;
    1223            0 :         break;
    1224           38 :     case LIBSPDM_DATA_TOTAL_KEY_PAIRS:
    1225           38 :         if (parameter->location != LIBSPDM_DATA_LOCATION_LOCAL) {
    1226            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
    1227              :         }
    1228           38 :         target_data_size = sizeof(uint8_t);
    1229           38 :         target_data = &context->local_context.total_key_pairs;
    1230           38 :         break;
    1231            0 :     default:
    1232            0 :         return LIBSPDM_STATUS_UNSUPPORTED_CAP;
    1233              :         break;
    1234              :     }
    1235              : 
    1236           56 :     if (*data_size < target_data_size) {
    1237            1 :         *data_size = target_data_size;
    1238            1 :         return LIBSPDM_STATUS_BUFFER_TOO_SMALL;
    1239              :     }
    1240           55 :     libspdm_copy_mem(data, *data_size, target_data, target_data_size);
    1241           55 :     *data_size = target_data_size;
    1242              : 
    1243           55 :     return LIBSPDM_STATUS_SUCCESS;
    1244              : }
    1245              : 
    1246              : #if LIBSPDM_CHECK_SPDM_CONTEXT
    1247            3 : bool libspdm_check_context (void *spdm_context)
    1248              : {
    1249              :     libspdm_context_t *context;
    1250              :     size_t index;
    1251              : 
    1252            3 :     context = spdm_context;
    1253              : 
    1254            3 :     if (context->local_context.capability.data_transfer_size <
    1255              :         SPDM_MIN_DATA_TRANSFER_SIZE_VERSION_12) {
    1256            1 :         LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR,
    1257              :                        "data_transfer_size must be greater than or equal "
    1258              :                        "to SPDM_MIN_DATA_TRANSFER_SIZE (%d).\n",
    1259              :                        SPDM_MIN_DATA_TRANSFER_SIZE_VERSION_12));
    1260            1 :         return false;
    1261              :     }
    1262              : 
    1263            2 :     if (context->local_context.capability.max_spdm_msg_size <
    1264            2 :         context->local_context.capability.data_transfer_size) {
    1265            1 :         LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR,
    1266              :                        "max_spdm_msg_size (%d) must be greater than or "
    1267              :                        "equal to data_transfer_size (%d).\n",
    1268              :                        context->local_context.capability.max_spdm_msg_size,
    1269              :                        context->local_context.capability.data_transfer_size));
    1270            1 :         return false;
    1271              :     }
    1272              : 
    1273            1 :     if (context->local_context.capability.sender_data_transfer_size <
    1274              :         SPDM_MIN_DATA_TRANSFER_SIZE_VERSION_12) {
    1275            0 :         LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR,
    1276              :                        "sender_data_transfer_size must be greater than or equal "
    1277              :                        "to %d.\n", SPDM_MIN_DATA_TRANSFER_SIZE_VERSION_12));
    1278            0 :         return false;
    1279              :     }
    1280              : 
    1281            1 :     if (context->local_context.capability.max_spdm_msg_size <
    1282            1 :         context->local_context.capability.sender_data_transfer_size) {
    1283            0 :         LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR,
    1284              :                        "max_spdm_msg_size (%d) must be greater than or "
    1285              :                        "equal to sender_data_transfer_size (%d).\n",
    1286              :                        context->local_context.capability.max_spdm_msg_size,
    1287              :                        context->local_context.capability.sender_data_transfer_size));
    1288            0 :         return false;
    1289              :     }
    1290              : 
    1291            1 :     if (((context->local_context.capability.flags &
    1292            0 :           SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHUNK_CAP) != 0) &&
    1293            0 :         (context->local_context.capability.max_spdm_msg_size != 0)) {
    1294            0 :         for (index = 0; index < SPDM_MAX_SLOT_COUNT; index++) {
    1295            0 :             if ((context->local_context.local_cert_chain_provision_size[index] != 0) &&
    1296            0 :                 (context->local_context.local_cert_chain_provision_size[index] +
    1297              :                  sizeof(spdm_certificate_response_t) >
    1298            0 :                  context->local_context.capability.max_spdm_msg_size)) {
    1299            0 :                 LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR,
    1300              :                                "max_spdm_msg_size (%d) must be greater than or "
    1301              :                                "equal to local_cert_chain_provision_size[%zu] (%zu).\n",
    1302              :                                context->local_context.capability.max_spdm_msg_size, index,
    1303              :                                context->local_context.local_cert_chain_provision_size[index]));
    1304            0 :                 return false;
    1305              :             }
    1306              :         }
    1307              :     }
    1308              : 
    1309            1 :     return true;
    1310              : }
    1311              : #endif /* LIBSPDM_CHECK_CONTEXT */
    1312              : 
    1313              : /**
    1314              :  * Reset message A cache in SPDM context.
    1315              :  *
    1316              :  * @param  spdm_context                  A pointer to the SPDM context.
    1317              :  **/
    1318          677 : void libspdm_reset_message_a(libspdm_context_t *spdm_context)
    1319              : {
    1320          677 :     libspdm_reset_managed_buffer(&spdm_context->transcript.message_a);
    1321          677 : }
    1322              : 
    1323              : /**
    1324              :  * Reset message D cache in SPDM context.
    1325              :  *
    1326              :  * @param  spdm_context                  A pointer to the SPDM context.
    1327              :  **/
    1328           51 : void libspdm_reset_message_d(libspdm_context_t *spdm_context)
    1329              : {
    1330           51 :     libspdm_reset_managed_buffer(&spdm_context->transcript.message_d);
    1331           51 : }
    1332              : 
    1333              : /**
    1334              :  * Reset message B cache in SPDM context.
    1335              :  *
    1336              :  * @param  spdm_context                  A pointer to the SPDM context.
    1337              :  **/
    1338         1003 : void libspdm_reset_message_b(libspdm_context_t *spdm_context)
    1339              : {
    1340              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    1341              :     libspdm_reset_managed_buffer(&spdm_context->transcript.message_b);
    1342              : #else
    1343         1003 :     if (spdm_context->transcript.digest_context_m1m2 != NULL) {
    1344          184 :         libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    1345              :                            spdm_context->transcript.digest_context_m1m2);
    1346          184 :         spdm_context->transcript.digest_context_m1m2 = NULL;
    1347              :     }
    1348              : #endif
    1349         1003 : }
    1350              : 
    1351              : /**
    1352              :  * Reset message C cache in SPDM context.
    1353              :  *
    1354              :  * @param  spdm_context                  A pointer to the SPDM context.
    1355              :  **/
    1356          589 : void libspdm_reset_message_c(libspdm_context_t *spdm_context)
    1357              : {
    1358              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    1359              :     libspdm_reset_managed_buffer(&spdm_context->transcript.message_c);
    1360              : #else
    1361          589 :     if (spdm_context->transcript.digest_context_m1m2 != NULL) {
    1362            0 :         libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    1363              :                            spdm_context->transcript.digest_context_m1m2);
    1364            0 :         spdm_context->transcript.digest_context_m1m2 = NULL;
    1365              :     }
    1366              : #endif
    1367          589 : }
    1368              : 
    1369              : /**
    1370              :  * Reset message MutB cache in SPDM context.
    1371              :  *
    1372              :  * @param  spdm_context                  A pointer to the SPDM context.
    1373              :  **/
    1374          480 : void libspdm_reset_message_mut_b(libspdm_context_t *spdm_context)
    1375              : {
    1376              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    1377              :     libspdm_reset_managed_buffer(&spdm_context->transcript.message_mut_b);
    1378              : #else
    1379          480 :     if (spdm_context->transcript.digest_context_mut_m1m2 != NULL) {
    1380           33 :         libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    1381              :                            spdm_context->transcript.digest_context_mut_m1m2);
    1382           33 :         spdm_context->transcript.digest_context_mut_m1m2 = NULL;
    1383              :     }
    1384              : #endif
    1385          480 : }
    1386              : 
    1387              : /**
    1388              :  * Reset message MutC cache in SPDM context.
    1389              :  *
    1390              :  * @param  spdm_context                  A pointer to the SPDM context.
    1391              :  **/
    1392          458 : void libspdm_reset_message_mut_c(libspdm_context_t *spdm_context)
    1393              : {
    1394              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    1395              :     libspdm_reset_managed_buffer(&spdm_context->transcript.message_mut_c);
    1396              : #else
    1397          458 :     if (spdm_context->transcript.digest_context_mut_m1m2 != NULL) {
    1398            0 :         libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    1399              :                            spdm_context->transcript.digest_context_mut_m1m2);
    1400            0 :         spdm_context->transcript.digest_context_mut_m1m2 = NULL;
    1401              :     }
    1402              : #endif
    1403          458 : }
    1404              : 
    1405              : /**
    1406              :  * Reset message M cache in SPDM context.
    1407              :  * If session_info is NULL, this function will use M cache of SPDM context,
    1408              :  * else will use M cache of SPDM session context.
    1409              :  *
    1410              :  * @param  spdm_context                  A pointer to the SPDM context.
    1411              :  * @param  session_info                  A pointer to the SPDM session context.
    1412              :  **/
    1413         4159 : void libspdm_reset_message_m(libspdm_context_t *spdm_context, void *session_info)
    1414              : {
    1415              :     libspdm_session_info_t *spdm_session_info;
    1416              : 
    1417         4159 :     spdm_session_info = session_info;
    1418              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    1419              :     if (spdm_session_info == NULL) {
    1420              :         libspdm_reset_managed_buffer(&spdm_context->transcript.message_m);
    1421              :     } else {
    1422              :         libspdm_reset_managed_buffer(&spdm_session_info->session_transcript.message_m);
    1423              :     }
    1424              : #else
    1425         4159 :     if (spdm_session_info == NULL) {
    1426         3879 :         if (spdm_context->transcript.digest_context_l1l2 != NULL) {
    1427           62 :             libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    1428              :                                spdm_context->transcript.digest_context_l1l2);
    1429           62 :             spdm_context->transcript.digest_context_l1l2 = NULL;
    1430              :         }
    1431              :     } else {
    1432          280 :         if (spdm_session_info->session_transcript.digest_context_l1l2 != NULL) {
    1433            2 :             libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    1434              :                                spdm_session_info->session_transcript.digest_context_l1l2);
    1435            2 :             spdm_session_info->session_transcript.digest_context_l1l2 = NULL;
    1436              :         }
    1437              :     }
    1438              : #endif
    1439         4159 : }
    1440              : 
    1441              : /**
    1442              :  * Reset message K cache in SPDM context.
    1443              :  *
    1444              :  * @param  spdm_context                  A pointer to the SPDM context.
    1445              :  * @param  spdm_session_info              A pointer to the SPDM session context.
    1446              :  **/
    1447            0 : void libspdm_reset_message_k(libspdm_context_t *spdm_context, void *session_info)
    1448              : {
    1449              :     libspdm_session_info_t *spdm_session_info;
    1450              : 
    1451            0 :     spdm_session_info = session_info;
    1452              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    1453              :     libspdm_reset_managed_buffer(&spdm_session_info->session_transcript.message_k);
    1454              : #else
    1455              :     {
    1456            0 :         if (spdm_session_info->session_transcript.digest_context_th != NULL) {
    1457            0 :             libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    1458              :                                spdm_session_info->session_transcript.digest_context_th);
    1459            0 :             spdm_session_info->session_transcript.digest_context_th = NULL;
    1460              :         }
    1461            0 :         if (spdm_session_info->session_transcript.digest_context_th_backup != NULL) {
    1462            0 :             libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    1463              :                                spdm_session_info->session_transcript.digest_context_th_backup);
    1464            0 :             spdm_session_info->session_transcript.digest_context_th_backup = NULL;
    1465              :         }
    1466              :     }
    1467              : #endif
    1468            0 : }
    1469              : 
    1470              : /**
    1471              :  * Reset message EncapD cache in SPDM context.
    1472              :  *
    1473              :  * @param  spdm_context                  A pointer to the SPDM context.
    1474              :  * @param  spdm_session_info              A pointer to the SPDM session context.
    1475              :  **/
    1476            6 : void libspdm_reset_message_encap_d(libspdm_context_t *spdm_context, void *session_info)
    1477              : {
    1478              :     libspdm_session_info_t *spdm_session_info;
    1479              : 
    1480            6 :     spdm_session_info = session_info;
    1481            6 :     libspdm_reset_managed_buffer(&spdm_session_info->session_transcript.message_encap_d);
    1482            6 : }
    1483              : 
    1484              : /**
    1485              :  * Reset message F cache in SPDM context.
    1486              :  *
    1487              :  * @param  spdm_context                  A pointer to the SPDM context.
    1488              :  * @param  spdm_session_info              A pointer to the SPDM session context.
    1489              :  **/
    1490           21 : void libspdm_reset_message_f(libspdm_context_t *spdm_context, void *session_info)
    1491              : {
    1492              :     libspdm_session_info_t *spdm_session_info;
    1493              : 
    1494           21 :     spdm_session_info = session_info;
    1495              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    1496              :     libspdm_reset_managed_buffer(&spdm_session_info->session_transcript.message_f);
    1497              : #else
    1498              :     {
    1499           21 :         if (spdm_session_info->session_transcript.digest_context_th != NULL) {
    1500           21 :             libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    1501              :                                spdm_session_info->session_transcript.digest_context_th);
    1502           21 :             spdm_session_info->session_transcript.digest_context_th =
    1503           21 :                 spdm_session_info->session_transcript.digest_context_th_backup;
    1504           21 :             spdm_session_info->session_transcript.digest_context_th_backup = NULL;
    1505              :         }
    1506           21 :         spdm_session_info->session_transcript.message_f_initialized = false;
    1507              :     }
    1508              : #endif
    1509           21 : }
    1510              : 
    1511              : /**
    1512              :  * Reset message E cache in SPDM context.
    1513              :  * If session_info is NULL, this function will use E cache of SPDM context,
    1514              :  * else will use E cache of SPDM session context.
    1515              :  *
    1516              :  * @param  spdm_context                  A pointer to the SPDM context.
    1517              :  * @param  spdm_session_info              A pointer to the SPDM session context.
    1518              :  **/
    1519          143 : void libspdm_reset_message_e(libspdm_context_t *spdm_context, void *session_info)
    1520              : {
    1521              :     libspdm_session_info_t *spdm_session_info;
    1522              : 
    1523          143 :     spdm_session_info = session_info;
    1524              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    1525              :     if (spdm_session_info == NULL) {
    1526              :         libspdm_reset_managed_buffer(&spdm_context->transcript.message_e);
    1527              :     } else {
    1528              :         libspdm_reset_managed_buffer(&spdm_session_info->session_transcript.message_e);
    1529              :     }
    1530              : #else
    1531          143 :     if (spdm_session_info == NULL) {
    1532          135 :         if (spdm_context->transcript.digest_context_il1il2 != NULL) {
    1533           14 :             libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    1534              :                                spdm_context->transcript.digest_context_il1il2);
    1535           14 :             spdm_context->transcript.digest_context_il1il2 = NULL;
    1536              :         }
    1537              :     } else {
    1538            8 :         if (spdm_session_info->session_transcript.digest_context_il1il2 != NULL) {
    1539            3 :             libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    1540              :                                spdm_session_info->session_transcript.digest_context_il1il2);
    1541            3 :             spdm_session_info->session_transcript.digest_context_il1il2 = NULL;
    1542              :         }
    1543              :     }
    1544              : #endif
    1545          143 : }
    1546              : 
    1547              : /**
    1548              :  * Reset message encap E cache in SPDM context.
    1549              :  * If session_info is NULL, this function will use encap E cache of SPDM context,
    1550              :  * else will use encap E cache of SPDM session context.
    1551              :  *
    1552              :  * @param  spdm_context                  A pointer to the SPDM context.
    1553              :  * @param  spdm_session_info              A pointer to the SPDM session context.
    1554              :  **/
    1555          102 : void libspdm_reset_message_encap_e(libspdm_context_t *spdm_context, void *session_info)
    1556              : {
    1557              :     libspdm_session_info_t *spdm_session_info;
    1558              : 
    1559          102 :     spdm_session_info = session_info;
    1560              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    1561              :     if (spdm_session_info == NULL) {
    1562              :         libspdm_reset_managed_buffer(&spdm_context->transcript.message_encap_e);
    1563              :     } else {
    1564              :         libspdm_reset_managed_buffer(&spdm_session_info->session_transcript.message_encap_e);
    1565              :     }
    1566              : #else
    1567          102 :     if (spdm_session_info == NULL) {
    1568           95 :         if (spdm_context->transcript.digest_context_encap_il1il2 != NULL) {
    1569           12 :             libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    1570              :                                spdm_context->transcript.digest_context_encap_il1il2);
    1571           12 :             spdm_context->transcript.digest_context_encap_il1il2 = NULL;
    1572              :         }
    1573              :     } else {
    1574            7 :         if (spdm_session_info->session_transcript.digest_context_encap_il1il2 != NULL) {
    1575            2 :             libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    1576              :                                spdm_session_info->session_transcript.digest_context_encap_il1il2);
    1577            2 :             spdm_session_info->session_transcript.digest_context_encap_il1il2 = NULL;
    1578              :         }
    1579              :     }
    1580              : #endif
    1581          102 : }
    1582              : 
    1583              : /**
    1584              :  * Reset message buffer in SPDM context according to request code.
    1585              :  *
    1586              :  * @param  spdm_context                   A pointer to the SPDM context.
    1587              :  * @param  spdm_session_info             A pointer to the SPDM session context.
    1588              :  * @param  spdm_request                   The SPDM request code.
    1589              :  */
    1590         4295 : void libspdm_reset_message_buffer_via_request_code(void *context, void *session_info,
    1591              :                                                    uint8_t request_code)
    1592              : {
    1593              :     libspdm_context_t *spdm_context;
    1594              : 
    1595         4295 :     spdm_context = context;
    1596              :     /**
    1597              :      * Any request other than SPDM_GET_MEASUREMENTS resets L1/L2
    1598              :      */
    1599         4295 :     if (request_code != SPDM_GET_MEASUREMENTS) {
    1600         3870 :         libspdm_reset_message_m(spdm_context, session_info);
    1601              :     }
    1602              :     /**
    1603              :      * If the Requester issued GET_MEASUREMENTS or KEY_EXCHANGE or FINISH or PSK_EXCHANGE
    1604              :      * or PSK_FINISH or KEY_UPDATE or HEARTBEAT or GET_ENCAPSULATED_REQUEST or DELIVER_ENCAPSULATED_RESPONSE
    1605              :      * or END_SESSION request(s) or SPDM_GET_MEASUREMENT_EXTENSION_LOG and skipped CHALLENGE completion, M1 and M2 are reset to null.
    1606              :      */
    1607         4295 :     switch (request_code)
    1608              :     {
    1609          876 :     case SPDM_KEY_EXCHANGE:
    1610              :     case SPDM_GET_MEASUREMENTS:
    1611              :     case SPDM_FINISH:
    1612              :     case SPDM_PSK_EXCHANGE:
    1613              :     case SPDM_PSK_FINISH:
    1614              :     case SPDM_KEY_UPDATE:
    1615              :     case SPDM_HEARTBEAT:
    1616              :     case SPDM_GET_ENCAPSULATED_REQUEST:
    1617              :     case SPDM_END_SESSION:
    1618              :     case SPDM_GET_MEASUREMENT_EXTENSION_LOG:
    1619          876 :         if (spdm_context->connection_info.connection_state <
    1620              :             LIBSPDM_CONNECTION_STATE_AUTHENTICATED) {
    1621          434 :             libspdm_reset_message_b(spdm_context);
    1622          434 :             libspdm_reset_message_c(spdm_context);
    1623          434 :             libspdm_reset_message_mut_b(spdm_context);
    1624          434 :             libspdm_reset_message_mut_c(spdm_context);
    1625              :         }
    1626          876 :         break;
    1627            5 :     case SPDM_DELIVER_ENCAPSULATED_RESPONSE:
    1628            5 :         if (spdm_context->connection_info.connection_state <
    1629              :             LIBSPDM_CONNECTION_STATE_AUTHENTICATED) {
    1630            5 :             libspdm_reset_message_b(spdm_context);
    1631            5 :             libspdm_reset_message_c(spdm_context);
    1632              :         }
    1633            5 :         break;
    1634           60 :     case SPDM_GET_DIGESTS:
    1635           60 :         libspdm_reset_message_b(spdm_context);
    1636           60 :         break;
    1637           56 :     case SPDM_GET_ENDPOINT_INFO:
    1638           56 :         libspdm_reset_message_e(spdm_context, session_info);
    1639           56 :         libspdm_reset_message_encap_e(spdm_context, session_info);
    1640           56 :         break;
    1641         3298 :     default:
    1642         3298 :         break;
    1643              :     }
    1644         4295 : }
    1645              : 
    1646          177 : libspdm_return_t libspdm_append_message_a(libspdm_context_t *spdm_context, const void *message,
    1647              :                                           size_t message_size)
    1648              : {
    1649          177 :     return libspdm_append_managed_buffer(&spdm_context->transcript.message_a,
    1650              :                                          message, message_size);
    1651              : }
    1652              : 
    1653            7 : libspdm_return_t libspdm_append_message_d(libspdm_context_t *spdm_context, const void *message,
    1654              :                                           size_t message_size)
    1655              : {
    1656              :     /* Only the first message D after VCA in connection counts  */
    1657            7 :     if (libspdm_get_managed_buffer_size(&spdm_context->transcript.message_d) != 0) {
    1658            1 :         return LIBSPDM_STATUS_SUCCESS;
    1659              :     }
    1660            6 :     return libspdm_append_managed_buffer(&spdm_context->transcript.message_d,
    1661              :                                          message, message_size);
    1662              : }
    1663              : 
    1664         5934 : libspdm_return_t libspdm_append_message_b(libspdm_context_t *spdm_context, const void *message,
    1665              :                                           size_t message_size)
    1666              : {
    1667              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    1668              :     return libspdm_append_managed_buffer(&spdm_context->transcript.message_b,
    1669              :                                          message, message_size);
    1670              : #else
    1671              :     {
    1672              :         bool result;
    1673              : 
    1674         5934 :         if (spdm_context->transcript.digest_context_m1m2 == NULL) {
    1675          163 :             spdm_context->transcript.digest_context_m1m2 = libspdm_hash_new (
    1676              :                 spdm_context->connection_info.algorithm.base_hash_algo);
    1677          163 :             if (spdm_context->transcript.digest_context_m1m2 == NULL) {
    1678            0 :                 return LIBSPDM_STATUS_CRYPTO_ERROR;
    1679              :             }
    1680          163 :             result = libspdm_hash_init (spdm_context->connection_info.algorithm.base_hash_algo,
    1681              :                                         spdm_context->transcript.digest_context_m1m2);
    1682          163 :             if (!result) {
    1683            0 :                 libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    1684              :                                    spdm_context->transcript.digest_context_m1m2);
    1685            0 :                 spdm_context->transcript.digest_context_m1m2 = NULL;
    1686            0 :                 return LIBSPDM_STATUS_CRYPTO_ERROR;
    1687              :             }
    1688          163 :             result = libspdm_hash_update (spdm_context->connection_info.algorithm.base_hash_algo,
    1689              :                                           spdm_context->transcript.digest_context_m1m2,
    1690          163 :                                           libspdm_get_managed_buffer(&spdm_context->transcript.
    1691              :                                                                      message_a),
    1692          163 :                                           libspdm_get_managed_buffer_size(&spdm_context->transcript.
    1693              :                                                                           message_a));
    1694          163 :             if (!result) {
    1695            0 :                 libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    1696              :                                    spdm_context->transcript.digest_context_m1m2);
    1697            0 :                 spdm_context->transcript.digest_context_m1m2 = NULL;
    1698            0 :                 return LIBSPDM_STATUS_CRYPTO_ERROR;
    1699              :             }
    1700              :         }
    1701              : 
    1702         5934 :         result = libspdm_hash_update (spdm_context->connection_info.algorithm.base_hash_algo,
    1703              :                                       spdm_context->transcript.digest_context_m1m2, message,
    1704              :                                       message_size);
    1705         5934 :         if (!result) {
    1706            0 :             libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    1707              :                                spdm_context->transcript.digest_context_m1m2);
    1708            0 :             spdm_context->transcript.digest_context_m1m2 = NULL;
    1709            0 :             return LIBSPDM_STATUS_CRYPTO_ERROR;
    1710              :         }
    1711              : 
    1712         5934 :         return LIBSPDM_STATUS_SUCCESS;
    1713              :     }
    1714              : #endif
    1715              : }
    1716              : 
    1717           52 : libspdm_return_t libspdm_append_message_c(libspdm_context_t *spdm_context, const void *message,
    1718              :                                           size_t message_size)
    1719              : {
    1720              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    1721              :     return libspdm_append_managed_buffer(&spdm_context->transcript.message_c,
    1722              :                                          message, message_size);
    1723              : #else
    1724              :     {
    1725              :         bool result;
    1726              : 
    1727           52 :         if (spdm_context->transcript.digest_context_m1m2 == NULL) {
    1728           25 :             spdm_context->transcript.digest_context_m1m2 = libspdm_hash_new (
    1729              :                 spdm_context->connection_info.algorithm.base_hash_algo);
    1730           25 :             if (spdm_context->transcript.digest_context_m1m2 == NULL) {
    1731            0 :                 return LIBSPDM_STATUS_CRYPTO_ERROR;
    1732              :             }
    1733           25 :             result = libspdm_hash_init (spdm_context->connection_info.algorithm.base_hash_algo,
    1734              :                                         spdm_context->transcript.digest_context_m1m2);
    1735           25 :             if (!result) {
    1736            0 :                 libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    1737              :                                    spdm_context->transcript.digest_context_m1m2);
    1738            0 :                 spdm_context->transcript.digest_context_m1m2 = NULL;
    1739            0 :                 return LIBSPDM_STATUS_CRYPTO_ERROR;
    1740              :             }
    1741           25 :             result = libspdm_hash_update (spdm_context->connection_info.algorithm.base_hash_algo,
    1742              :                                           spdm_context->transcript.digest_context_m1m2,
    1743           25 :                                           libspdm_get_managed_buffer(&spdm_context->transcript.
    1744              :                                                                      message_a),
    1745           25 :                                           libspdm_get_managed_buffer_size(&spdm_context->transcript.
    1746              :                                                                           message_a));
    1747           25 :             if (!result) {
    1748            0 :                 libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    1749              :                                    spdm_context->transcript.digest_context_m1m2);
    1750            0 :                 spdm_context->transcript.digest_context_m1m2 = NULL;
    1751            0 :                 return LIBSPDM_STATUS_CRYPTO_ERROR;
    1752              :             }
    1753              :         }
    1754              : 
    1755           52 :         result = libspdm_hash_update (spdm_context->connection_info.algorithm.base_hash_algo,
    1756              :                                       spdm_context->transcript.digest_context_m1m2, message,
    1757              :                                       message_size);
    1758           52 :         if (!result) {
    1759            0 :             libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    1760              :                                spdm_context->transcript.digest_context_m1m2);
    1761            0 :             spdm_context->transcript.digest_context_m1m2 = NULL;
    1762            0 :             return LIBSPDM_STATUS_CRYPTO_ERROR;
    1763              :         }
    1764              : 
    1765           52 :         return LIBSPDM_STATUS_SUCCESS;
    1766              :     }
    1767              : #endif
    1768              : }
    1769              : 
    1770         2847 : libspdm_return_t libspdm_append_message_mut_b(libspdm_context_t *spdm_context, const void *message,
    1771              :                                               size_t message_size)
    1772              : {
    1773              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    1774              :     return libspdm_append_managed_buffer(&spdm_context->transcript.message_mut_b,
    1775              :                                          message, message_size);
    1776              : #else
    1777              :     {
    1778              :         bool result;
    1779              : 
    1780         2847 :         if (spdm_context->transcript.digest_context_mut_m1m2 == NULL) {
    1781           32 :             spdm_context->transcript.digest_context_mut_m1m2 = libspdm_hash_new (
    1782              :                 spdm_context->connection_info.algorithm.base_hash_algo);
    1783           32 :             if (spdm_context->transcript.digest_context_mut_m1m2 == NULL) {
    1784            0 :                 return LIBSPDM_STATUS_CRYPTO_ERROR;
    1785              :             }
    1786           32 :             result = libspdm_hash_init (spdm_context->connection_info.algorithm.base_hash_algo,
    1787              :                                         spdm_context->transcript.digest_context_mut_m1m2);
    1788           32 :             if (!result) {
    1789            0 :                 libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    1790              :                                    spdm_context->transcript.digest_context_mut_m1m2);
    1791            0 :                 spdm_context->transcript.digest_context_mut_m1m2 = NULL;
    1792            0 :                 return LIBSPDM_STATUS_CRYPTO_ERROR;
    1793              :             }
    1794           32 :             if ((spdm_context->connection_info.version >> SPDM_VERSION_NUMBER_SHIFT_BIT) >
    1795              :                 SPDM_MESSAGE_VERSION_11) {
    1796              : 
    1797              :                 /* Need append VCA since 1.2 script */
    1798            5 :                 result = libspdm_hash_update (
    1799              :                     spdm_context->connection_info.algorithm.base_hash_algo,
    1800              :                     spdm_context->transcript.digest_context_mut_m1m2,
    1801            5 :                     libspdm_get_managed_buffer(&spdm_context->transcript.message_a),
    1802            5 :                     libspdm_get_managed_buffer_size(&spdm_context->transcript.
    1803              :                                                     message_a));
    1804            5 :                 if (!result) {
    1805            0 :                     libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    1806              :                                        spdm_context->transcript.digest_context_mut_m1m2);
    1807            0 :                     spdm_context->transcript.digest_context_mut_m1m2 = NULL;
    1808            0 :                     return LIBSPDM_STATUS_CRYPTO_ERROR;
    1809              :                 }
    1810              :             }
    1811              :         }
    1812              : 
    1813         2847 :         result = libspdm_hash_update (spdm_context->connection_info.algorithm.base_hash_algo,
    1814              :                                       spdm_context->transcript.digest_context_mut_m1m2, message,
    1815              :                                       message_size);
    1816         2847 :         if (!result) {
    1817            0 :             libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    1818              :                                spdm_context->transcript.digest_context_mut_m1m2);
    1819            0 :             spdm_context->transcript.digest_context_mut_m1m2 = NULL;
    1820            0 :             return LIBSPDM_STATUS_CRYPTO_ERROR;
    1821              :         }
    1822              : 
    1823         2847 :         return LIBSPDM_STATUS_SUCCESS;
    1824              :     }
    1825              : #endif
    1826              : }
    1827              : 
    1828           10 : libspdm_return_t libspdm_append_message_mut_c(libspdm_context_t *spdm_context, const void *message,
    1829              :                                               size_t message_size)
    1830              : {
    1831              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    1832              :     return libspdm_append_managed_buffer(&spdm_context->transcript.message_mut_c,
    1833              :                                          message, message_size);
    1834              : #else
    1835              :     {
    1836              :         bool result;
    1837              : 
    1838           10 :         if (spdm_context->transcript.digest_context_mut_m1m2 == NULL) {
    1839            7 :             spdm_context->transcript.digest_context_mut_m1m2 = libspdm_hash_new (
    1840              :                 spdm_context->connection_info.algorithm.base_hash_algo);
    1841            7 :             if (spdm_context->transcript.digest_context_mut_m1m2 == NULL) {
    1842            0 :                 return LIBSPDM_STATUS_CRYPTO_ERROR;
    1843              :             }
    1844            7 :             result = libspdm_hash_init (spdm_context->connection_info.algorithm.base_hash_algo,
    1845              :                                         spdm_context->transcript.digest_context_mut_m1m2);
    1846            7 :             if (!result) {
    1847            0 :                 libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    1848              :                                    spdm_context->transcript.digest_context_mut_m1m2);
    1849            0 :                 spdm_context->transcript.digest_context_mut_m1m2 = NULL;
    1850            0 :                 return LIBSPDM_STATUS_CRYPTO_ERROR;
    1851              :             }
    1852            7 :             if ((spdm_context->connection_info.version >> SPDM_VERSION_NUMBER_SHIFT_BIT) >
    1853              :                 SPDM_MESSAGE_VERSION_11) {
    1854              : 
    1855              :                 /* Need append VCA since 1.2 script */
    1856            2 :                 result = libspdm_hash_update (
    1857              :                     spdm_context->connection_info.algorithm.base_hash_algo,
    1858              :                     spdm_context->transcript.digest_context_mut_m1m2,
    1859            2 :                     libspdm_get_managed_buffer(&spdm_context->transcript.message_a),
    1860            2 :                     libspdm_get_managed_buffer_size(&spdm_context->transcript.
    1861              :                                                     message_a));
    1862            2 :                 if (!result) {
    1863            0 :                     libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    1864              :                                        spdm_context->transcript.digest_context_mut_m1m2);
    1865            0 :                     spdm_context->transcript.digest_context_mut_m1m2 = NULL;
    1866            0 :                     return LIBSPDM_STATUS_CRYPTO_ERROR;
    1867              :                 }
    1868              :             }
    1869              :         }
    1870              : 
    1871           10 :         result = libspdm_hash_update (spdm_context->connection_info.algorithm.base_hash_algo,
    1872              :                                       spdm_context->transcript.digest_context_mut_m1m2, message,
    1873              :                                       message_size);
    1874           10 :         if (!result) {
    1875            0 :             libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    1876              :                                spdm_context->transcript.digest_context_mut_m1m2);
    1877            0 :             spdm_context->transcript.digest_context_mut_m1m2 = NULL;
    1878            0 :             return LIBSPDM_STATUS_CRYPTO_ERROR;
    1879              :         }
    1880              : 
    1881           10 :         return LIBSPDM_STATUS_SUCCESS;
    1882              :     }
    1883              : #endif
    1884              : }
    1885              : 
    1886          722 : libspdm_return_t libspdm_append_message_m(libspdm_context_t *spdm_context, void *session_info,
    1887              :                                           const void *message, size_t message_size)
    1888              : {
    1889              :     libspdm_session_info_t *spdm_session_info;
    1890              : 
    1891          722 :     spdm_session_info = session_info;
    1892              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    1893              :     if (spdm_session_info == NULL) {
    1894              :         return libspdm_append_managed_buffer(&spdm_context->transcript.message_m,
    1895              :                                              message, message_size);
    1896              :     } else {
    1897              :         return libspdm_append_managed_buffer(&spdm_session_info->session_transcript.message_m,
    1898              :                                              message, message_size);
    1899              :     }
    1900              : #else
    1901              :     {
    1902              :         bool result;
    1903              : 
    1904          722 :         if (spdm_session_info == NULL) {
    1905          718 :             if (spdm_context->transcript.digest_context_l1l2 == NULL) {
    1906           62 :                 spdm_context->transcript.digest_context_l1l2 = libspdm_hash_new (
    1907              :                     spdm_context->connection_info.algorithm.base_hash_algo);
    1908           62 :                 if (spdm_context->transcript.digest_context_l1l2 == NULL) {
    1909            0 :                     return LIBSPDM_STATUS_CRYPTO_ERROR;
    1910              :                 }
    1911           62 :                 result = libspdm_hash_init (spdm_context->connection_info.algorithm.base_hash_algo,
    1912              :                                             spdm_context->transcript.digest_context_l1l2);
    1913           62 :                 if (!result) {
    1914            0 :                     libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    1915              :                                        spdm_context->transcript.digest_context_l1l2);
    1916            0 :                     spdm_context->transcript.digest_context_l1l2 = NULL;
    1917            0 :                     return LIBSPDM_STATUS_CRYPTO_ERROR;
    1918              :                 }
    1919           62 :                 if ((spdm_context->connection_info.version >> SPDM_VERSION_NUMBER_SHIFT_BIT) >
    1920              :                     SPDM_MESSAGE_VERSION_11) {
    1921              : 
    1922              :                     /* Need append VCA since 1.2 script */
    1923           13 :                     result = libspdm_hash_update (
    1924              :                         spdm_context->connection_info.algorithm.base_hash_algo,
    1925              :                         spdm_context->transcript.digest_context_l1l2,
    1926           13 :                         libspdm_get_managed_buffer(
    1927           13 :                             &spdm_context->transcript.message_a),
    1928           13 :                         libspdm_get_managed_buffer_size(&spdm_context->transcript.
    1929              :                                                         message_a));
    1930           13 :                     if (!result) {
    1931            0 :                         libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    1932              :                                            spdm_context->transcript.digest_context_l1l2);
    1933            0 :                         spdm_context->transcript.digest_context_l1l2 = NULL;
    1934            0 :                         return LIBSPDM_STATUS_CRYPTO_ERROR;
    1935              :                     }
    1936              :                 }
    1937              :             }
    1938          718 :             result = libspdm_hash_update (spdm_context->connection_info.algorithm.base_hash_algo,
    1939              :                                           spdm_context->transcript.digest_context_l1l2, message,
    1940              :                                           message_size);
    1941          718 :             if (!result) {
    1942            0 :                 libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    1943              :                                    spdm_context->transcript.digest_context_l1l2);
    1944            0 :                 spdm_context->transcript.digest_context_l1l2 = NULL;
    1945            0 :                 return LIBSPDM_STATUS_CRYPTO_ERROR;
    1946              :             }
    1947              :         } else {
    1948            4 :             if (spdm_session_info->session_transcript.digest_context_l1l2 == NULL) {
    1949            2 :                 spdm_session_info->session_transcript.digest_context_l1l2 = libspdm_hash_new (
    1950              :                     spdm_context->connection_info.algorithm.base_hash_algo);
    1951            2 :                 if (spdm_session_info->session_transcript.digest_context_l1l2 == NULL) {
    1952            0 :                     return LIBSPDM_STATUS_CRYPTO_ERROR;
    1953              :                 }
    1954            2 :                 result = libspdm_hash_init (spdm_context->connection_info.algorithm.base_hash_algo,
    1955              :                                             spdm_session_info->session_transcript.digest_context_l1l2);
    1956            2 :                 if (!result) {
    1957            0 :                     libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    1958              :                                        spdm_session_info->session_transcript.digest_context_l1l2);
    1959            0 :                     spdm_session_info->session_transcript.digest_context_l1l2 = NULL;
    1960            0 :                     return LIBSPDM_STATUS_CRYPTO_ERROR;
    1961              :                 }
    1962            2 :                 if ((spdm_context->connection_info.version >> SPDM_VERSION_NUMBER_SHIFT_BIT) >
    1963              :                     SPDM_MESSAGE_VERSION_11) {
    1964              : 
    1965              :                     /* Need append VCA since 1.2 script*/
    1966              : 
    1967            0 :                     result = libspdm_hash_update (
    1968              :                         spdm_context->connection_info.algorithm.base_hash_algo,
    1969              :                         spdm_session_info->session_transcript.digest_context_l1l2,
    1970            0 :                         libspdm_get_managed_buffer(
    1971            0 :                             &spdm_context->transcript.message_a),
    1972            0 :                         libspdm_get_managed_buffer_size(&spdm_context->transcript.
    1973              :                                                         message_a));
    1974            0 :                     if (!result) {
    1975            0 :                         libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    1976              :                                            spdm_session_info->session_transcript.digest_context_l1l2);
    1977            0 :                         spdm_session_info->session_transcript.digest_context_l1l2 = NULL;
    1978            0 :                         return LIBSPDM_STATUS_CRYPTO_ERROR;
    1979              :                     }
    1980              :                 }
    1981              :             }
    1982            4 :             result = libspdm_hash_update (spdm_context->connection_info.algorithm.base_hash_algo,
    1983              :                                           spdm_session_info->session_transcript.digest_context_l1l2,
    1984              :                                           message, message_size);
    1985            4 :             if (!result) {
    1986            0 :                 libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    1987              :                                    spdm_session_info->session_transcript.digest_context_l1l2);
    1988            0 :                 spdm_session_info->session_transcript.digest_context_l1l2 = NULL;
    1989            0 :                 return LIBSPDM_STATUS_CRYPTO_ERROR;
    1990              :             }
    1991              :         }
    1992              : 
    1993          722 :         return LIBSPDM_STATUS_SUCCESS;
    1994              :     }
    1995              : #endif
    1996              : }
    1997              : 
    1998          299 : libspdm_return_t libspdm_append_message_k(libspdm_context_t *spdm_context,
    1999              :                                           void *session_info,
    2000              :                                           bool is_requester, const void *message,
    2001              :                                           size_t message_size)
    2002              : {
    2003              :     libspdm_session_info_t *spdm_session_info;
    2004              : 
    2005          299 :     spdm_session_info = session_info;
    2006              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    2007              :     return libspdm_append_managed_buffer(
    2008              :         &spdm_session_info->session_transcript.message_k, message,
    2009              :         message_size);
    2010              : #else
    2011              :     {
    2012              :         uint8_t *cert_chain_buffer;
    2013              :         size_t cert_chain_buffer_size;
    2014              :         bool result;
    2015              :         uint8_t cert_chain_buffer_hash[LIBSPDM_MAX_HASH_SIZE];
    2016              :         uint32_t hash_size;
    2017              :         uint8_t slot_id;
    2018              : 
    2019          299 :         hash_size = libspdm_get_hash_size(spdm_context->connection_info.algorithm.base_hash_algo);
    2020              : 
    2021          299 :         if (spdm_session_info->session_transcript.digest_context_th == NULL) {
    2022          155 :             if (!spdm_session_info->use_psk) {
    2023           90 :                 if (is_requester) {
    2024           59 :                     slot_id = spdm_context->connection_info.peer_used_cert_chain_slot_id;
    2025           59 :                     LIBSPDM_ASSERT((slot_id < SPDM_MAX_SLOT_COUNT) || (slot_id == 0xFF));
    2026           59 :                     if (slot_id == 0xFF) {
    2027            2 :                         result = libspdm_get_peer_public_key_buffer(
    2028              :                             spdm_context, (const void **)&cert_chain_buffer,
    2029              :                             &cert_chain_buffer_size);
    2030            2 :                         if (!result) {
    2031            0 :                             return LIBSPDM_STATUS_INVALID_STATE_PEER;
    2032              :                         }
    2033              : 
    2034            2 :                         result = libspdm_hash_all(
    2035              :                             spdm_context->connection_info.algorithm.base_hash_algo,
    2036              :                             cert_chain_buffer, cert_chain_buffer_size,
    2037              :                             cert_chain_buffer_hash);
    2038            2 :                         if (!result) {
    2039            0 :                             return LIBSPDM_STATUS_CRYPTO_ERROR;
    2040              :                         }
    2041              :                     } else {
    2042           57 :                         LIBSPDM_ASSERT(
    2043              :                             hash_size ==
    2044              :                             spdm_context->connection_info
    2045              :                             .peer_used_cert_chain[slot_id].buffer_hash_size);
    2046              : 
    2047           57 :                         libspdm_copy_mem(cert_chain_buffer_hash,
    2048              :                                          sizeof(cert_chain_buffer_hash),
    2049              :                                          spdm_context->connection_info
    2050           57 :                                          .peer_used_cert_chain[slot_id].buffer_hash,
    2051              :                                          hash_size);
    2052              :                     }
    2053              :                 } else {
    2054           31 :                     slot_id = spdm_context->connection_info.local_used_cert_chain_slot_id;
    2055           31 :                     LIBSPDM_ASSERT((slot_id < SPDM_MAX_SLOT_COUNT) || (slot_id == 0xFF));
    2056           31 :                     if (slot_id == 0xFF) {
    2057            2 :                         result = libspdm_get_local_public_key_buffer(
    2058              :                             spdm_context, (const void **)&cert_chain_buffer,
    2059              :                             &cert_chain_buffer_size);
    2060              :                     } else {
    2061           29 :                         result = libspdm_get_local_cert_chain_buffer(
    2062              :                             spdm_context, (const void **)&cert_chain_buffer,
    2063              :                             &cert_chain_buffer_size);
    2064              :                     }
    2065           31 :                     if (!result) {
    2066            0 :                         return LIBSPDM_STATUS_INVALID_STATE_LOCAL;
    2067              :                     }
    2068              : 
    2069           31 :                     result = libspdm_hash_all(
    2070              :                         spdm_context->connection_info.algorithm.base_hash_algo,
    2071              :                         cert_chain_buffer, cert_chain_buffer_size,
    2072              :                         cert_chain_buffer_hash);
    2073           31 :                     if (!result) {
    2074            0 :                         return LIBSPDM_STATUS_CRYPTO_ERROR;
    2075              :                     }
    2076              :                 }
    2077              :             }
    2078              :         }
    2079              : 
    2080              : 
    2081              :         /* prepare digest_context_th*/
    2082              : 
    2083          299 :         if (spdm_session_info->session_transcript.digest_context_th == NULL) {
    2084          155 :             spdm_session_info->session_transcript.digest_context_th = libspdm_hash_new (
    2085              :                 spdm_context->connection_info.algorithm.base_hash_algo);
    2086          155 :             if (spdm_session_info->session_transcript.digest_context_th == NULL) {
    2087            0 :                 return LIBSPDM_STATUS_CRYPTO_ERROR;
    2088              :             }
    2089          155 :             result = libspdm_hash_init (spdm_context->connection_info.algorithm.base_hash_algo,
    2090              :                                         spdm_session_info->session_transcript.digest_context_th);
    2091          155 :             if (!result) {
    2092            0 :                 libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    2093              :                                    spdm_session_info->session_transcript.digest_context_th);
    2094            0 :                 return LIBSPDM_STATUS_CRYPTO_ERROR;
    2095              :             }
    2096          155 :             result = libspdm_hash_update (spdm_context->connection_info.algorithm.base_hash_algo,
    2097              :                                           spdm_session_info->session_transcript.digest_context_th,
    2098          155 :                                           libspdm_get_managed_buffer(&spdm_context->transcript.
    2099              :                                                                      message_a),
    2100              :                                           libspdm_get_managed_buffer_size(
    2101          155 :                                               &spdm_context->transcript.message_a));
    2102          155 :             if (!result) {
    2103            0 :                 libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    2104              :                                    spdm_session_info->session_transcript.digest_context_th);
    2105            0 :                 return LIBSPDM_STATUS_CRYPTO_ERROR;
    2106              :             }
    2107          155 :             if (!spdm_session_info->use_psk) {
    2108           90 :                 if (spdm_context->connection_info.multi_key_conn_rsp) {
    2109            0 :                     result = libspdm_hash_update (
    2110              :                         spdm_context->connection_info.algorithm.base_hash_algo,
    2111              :                         spdm_session_info->session_transcript.digest_context_th,
    2112            0 :                         libspdm_get_managed_buffer(&spdm_context->transcript.message_d),
    2113            0 :                         libspdm_get_managed_buffer_size(&spdm_context->transcript.message_d));
    2114            0 :                     if (!result) {
    2115            0 :                         libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    2116              :                                            spdm_session_info->session_transcript.digest_context_th);
    2117            0 :                         return LIBSPDM_STATUS_CRYPTO_ERROR;
    2118              :                     }
    2119              :                 }
    2120              : 
    2121           90 :                 result = libspdm_hash_update (
    2122              :                     spdm_context->connection_info.algorithm.base_hash_algo,
    2123              :                     spdm_session_info->session_transcript.digest_context_th,
    2124              :                     cert_chain_buffer_hash, hash_size);
    2125           90 :                 if (!result) {
    2126            0 :                     libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    2127              :                                        spdm_session_info->session_transcript.digest_context_th);
    2128            0 :                     return LIBSPDM_STATUS_CRYPTO_ERROR;
    2129              :                 }
    2130              :             }
    2131              :         }
    2132          299 :         result = libspdm_hash_update (spdm_context->connection_info.algorithm.base_hash_algo,
    2133              :                                       spdm_session_info->session_transcript.digest_context_th,
    2134              :                                       message,
    2135              :                                       message_size);
    2136          299 :         if (!result) {
    2137            0 :             libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    2138              :                                spdm_session_info->session_transcript.digest_context_th);
    2139            0 :             return LIBSPDM_STATUS_CRYPTO_ERROR;
    2140              :         }
    2141          299 :         return LIBSPDM_STATUS_SUCCESS;
    2142              :     }
    2143              : #endif
    2144              : }
    2145              : 
    2146            4 : libspdm_return_t libspdm_append_message_encap_d(libspdm_context_t *spdm_context,
    2147              :                                                 void *session_info,
    2148              :                                                 bool is_requester, const void *message,
    2149              :                                                 size_t message_size)
    2150              : {
    2151              :     libspdm_session_info_t *spdm_session_info;
    2152              : 
    2153            4 :     spdm_session_info = session_info;
    2154              :     /* Only the first message EncapD in current session counts  */
    2155            4 :     if (libspdm_get_managed_buffer_size(&spdm_session_info->session_transcript.message_encap_d) !=
    2156              :         0) {
    2157            0 :         return LIBSPDM_STATUS_SUCCESS;
    2158              :     }
    2159            4 :     return libspdm_append_managed_buffer(
    2160            4 :         &spdm_session_info->session_transcript.message_encap_d, message,
    2161              :         message_size);
    2162              : }
    2163              : 
    2164          253 : libspdm_return_t libspdm_append_message_f(libspdm_context_t *spdm_context,
    2165              :                                           void *session_info,
    2166              :                                           bool is_requester, const void *message,
    2167              :                                           size_t message_size)
    2168              : {
    2169              :     libspdm_session_info_t *spdm_session_info;
    2170              : 
    2171          253 :     spdm_session_info = session_info;
    2172              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    2173              :     return libspdm_append_managed_buffer(
    2174              :         &spdm_session_info->session_transcript.message_f, message,
    2175              :         message_size);
    2176              : #else
    2177              :     {
    2178              :         const uint8_t *mut_cert_chain_buffer;
    2179              :         size_t mut_cert_chain_buffer_size;
    2180              :         bool result;
    2181              :         uint8_t mut_cert_chain_buffer_hash[LIBSPDM_MAX_HASH_SIZE];
    2182              :         uint32_t hash_size;
    2183              :         libspdm_return_t status;
    2184              :         uint8_t slot_id;
    2185              : 
    2186          253 :         hash_size = libspdm_get_hash_size(spdm_context->connection_info.algorithm.base_hash_algo);
    2187              : 
    2188          253 :         if (!spdm_session_info->session_transcript.message_f_initialized) {
    2189              :             /* digest_context_th might be NULL in unit test, where message_k is hardcoded. */
    2190           96 :             if (spdm_session_info->session_transcript.digest_context_th == NULL) {
    2191              :                 status =
    2192           95 :                     libspdm_append_message_k (spdm_context, session_info, is_requester, NULL, 0);
    2193           95 :                 if (LIBSPDM_STATUS_IS_ERROR(status)) {
    2194            0 :                     return status;
    2195              :                 }
    2196              :             }
    2197              : 
    2198           96 :             if (!spdm_session_info->use_psk && (spdm_session_info->mut_auth_requested != 0)) {
    2199           16 :                 if (is_requester) {
    2200            5 :                     slot_id = spdm_context->connection_info.local_used_cert_chain_slot_id;
    2201            5 :                     LIBSPDM_ASSERT((slot_id < SPDM_MAX_SLOT_COUNT) || (slot_id == 0xFF));
    2202            5 :                     if (slot_id == 0xFF) {
    2203            0 :                         result = libspdm_get_local_public_key_buffer(
    2204              :                             spdm_context,
    2205              :                             (const void **)&mut_cert_chain_buffer,
    2206              :                             &mut_cert_chain_buffer_size);
    2207              :                     } else {
    2208            5 :                         result = libspdm_get_local_cert_chain_buffer(
    2209              :                             spdm_context,
    2210              :                             (const void **)&mut_cert_chain_buffer,
    2211              :                             &mut_cert_chain_buffer_size);
    2212              :                     }
    2213            5 :                     if (!result) {
    2214            0 :                         return LIBSPDM_STATUS_INVALID_STATE_LOCAL;
    2215              :                     }
    2216              : 
    2217            5 :                     result = libspdm_hash_all(
    2218              :                         spdm_context->connection_info.algorithm.base_hash_algo,
    2219              :                         mut_cert_chain_buffer, mut_cert_chain_buffer_size,
    2220              :                         mut_cert_chain_buffer_hash);
    2221            5 :                     if (!result) {
    2222            0 :                         return LIBSPDM_STATUS_CRYPTO_ERROR;
    2223              :                     }
    2224              :                 } else {
    2225           11 :                     slot_id = spdm_context->connection_info.peer_used_cert_chain_slot_id;
    2226           11 :                     LIBSPDM_ASSERT((slot_id < SPDM_MAX_SLOT_COUNT) || (slot_id == 0xFF));
    2227           11 :                     if (slot_id == 0xFF) {
    2228            1 :                         result = libspdm_get_peer_public_key_buffer(
    2229              :                             spdm_context,
    2230              :                             (const void **)&mut_cert_chain_buffer,
    2231              :                             &mut_cert_chain_buffer_size);
    2232            1 :                         if (!result) {
    2233            0 :                             return LIBSPDM_STATUS_INVALID_STATE_PEER;
    2234              :                         }
    2235              : 
    2236            1 :                         result = libspdm_hash_all(
    2237              :                             spdm_context->connection_info.algorithm.base_hash_algo,
    2238              :                             mut_cert_chain_buffer, mut_cert_chain_buffer_size,
    2239              :                             mut_cert_chain_buffer_hash);
    2240            1 :                         if (!result) {
    2241            0 :                             return LIBSPDM_STATUS_CRYPTO_ERROR;
    2242              :                         }
    2243              :                     } else {
    2244           10 :                         LIBSPDM_ASSERT(
    2245              :                             hash_size ==
    2246              :                             spdm_context->connection_info
    2247              :                             .peer_used_cert_chain[slot_id].buffer_hash_size);
    2248              : 
    2249           10 :                         libspdm_copy_mem(mut_cert_chain_buffer_hash,
    2250              :                                          sizeof(mut_cert_chain_buffer_hash),
    2251              :                                          spdm_context->connection_info
    2252           10 :                                          .peer_used_cert_chain[slot_id].buffer_hash,
    2253              :                                          hash_size);
    2254              :                     }
    2255              :                 }
    2256              :             }
    2257              : 
    2258              :             /* It is first time call, backup current message_k context
    2259              :              * this backup will be used in reset_message_f.*/
    2260              : 
    2261           96 :             LIBSPDM_ASSERT (spdm_session_info->session_transcript.digest_context_th != NULL);
    2262           96 :             spdm_session_info->session_transcript.digest_context_th_backup = libspdm_hash_new (
    2263              :                 spdm_context->connection_info.algorithm.base_hash_algo);
    2264           96 :             if (spdm_session_info->session_transcript.digest_context_th_backup == NULL) {
    2265            0 :                 return LIBSPDM_STATUS_CRYPTO_ERROR;
    2266              :             }
    2267           96 :             result = libspdm_hash_duplicate (spdm_context->connection_info.algorithm.base_hash_algo,
    2268           96 :                                              spdm_session_info->session_transcript.digest_context_th,
    2269              :                                              spdm_session_info->session_transcript.digest_context_th_backup);
    2270           96 :             if (!result) {
    2271            0 :                 libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    2272              :                                    spdm_session_info->session_transcript.digest_context_th_backup);
    2273            0 :                 spdm_session_info->session_transcript.digest_context_th_backup = NULL;
    2274            0 :                 return LIBSPDM_STATUS_CRYPTO_ERROR;
    2275              :             }
    2276              :         }
    2277              : 
    2278              : 
    2279              :         /* prepare digest_context_th*/
    2280              : 
    2281          253 :         LIBSPDM_ASSERT (spdm_session_info->session_transcript.digest_context_th != NULL);
    2282          253 :         if (!spdm_session_info->session_transcript.message_f_initialized) {
    2283           96 :             if (!spdm_session_info->use_psk && (spdm_session_info->mut_auth_requested != 0)) {
    2284           16 :                 if (spdm_context->connection_info.multi_key_conn_req) {
    2285            0 :                     result = libspdm_hash_update (
    2286              :                         spdm_context->connection_info.algorithm.base_hash_algo,
    2287              :                         spdm_session_info->session_transcript.digest_context_th,
    2288            0 :                         libspdm_get_managed_buffer(&spdm_session_info->session_transcript.
    2289              :                                                    message_encap_d),
    2290            0 :                         libspdm_get_managed_buffer_size(&spdm_session_info->session_transcript.
    2291              :                                                         message_encap_d));
    2292            0 :                     if (!result) {
    2293            0 :                         libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    2294              :                                            spdm_session_info->session_transcript.digest_context_th);
    2295            0 :                         spdm_session_info->session_transcript.digest_context_th = NULL;
    2296            0 :                         return LIBSPDM_STATUS_CRYPTO_ERROR;
    2297              :                     }
    2298              :                 }
    2299              : 
    2300           16 :                 result = libspdm_hash_update (
    2301              :                     spdm_context->connection_info.algorithm.base_hash_algo,
    2302              :                     spdm_session_info->session_transcript.digest_context_th,
    2303              :                     mut_cert_chain_buffer_hash, hash_size);
    2304           16 :                 if (!result) {
    2305            0 :                     libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    2306              :                                        spdm_session_info->session_transcript.digest_context_th);
    2307            0 :                     spdm_session_info->session_transcript.digest_context_th = NULL;
    2308            0 :                     return LIBSPDM_STATUS_CRYPTO_ERROR;
    2309              :                 }
    2310              :             }
    2311              :         }
    2312          253 :         result = libspdm_hash_update (spdm_context->connection_info.algorithm.base_hash_algo,
    2313              :                                       spdm_session_info->session_transcript.digest_context_th,
    2314              :                                       message,
    2315              :                                       message_size);
    2316          253 :         if (!result) {
    2317            0 :             libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    2318              :                                spdm_session_info->session_transcript.digest_context_th);
    2319            0 :             spdm_session_info->session_transcript.digest_context_th = NULL;
    2320            0 :             return LIBSPDM_STATUS_CRYPTO_ERROR;
    2321              :         }
    2322              : 
    2323          253 :         spdm_session_info->session_transcript.message_f_initialized = true;
    2324          253 :         return LIBSPDM_STATUS_SUCCESS;
    2325              :     }
    2326              : #endif
    2327              : }
    2328              : 
    2329           34 : libspdm_return_t libspdm_append_message_e(libspdm_context_t *spdm_context, void *session_info,
    2330              :                                           const void *message, size_t message_size)
    2331              : {
    2332              :     libspdm_session_info_t *spdm_session_info;
    2333              : 
    2334           34 :     spdm_session_info = session_info;
    2335              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    2336              :     if (spdm_session_info == NULL) {
    2337              :         return libspdm_append_managed_buffer(&spdm_context->transcript.message_e,
    2338              :                                              message, message_size);
    2339              :     } else {
    2340              :         return libspdm_append_managed_buffer(&spdm_session_info->session_transcript.message_e,
    2341              :                                              message, message_size);
    2342              :     }
    2343              : #else
    2344              :     {
    2345              :         bool result;
    2346              : 
    2347           34 :         if (spdm_session_info == NULL) {
    2348           28 :             if (spdm_context->transcript.digest_context_il1il2 == NULL) {
    2349           14 :                 spdm_context->transcript.digest_context_il1il2 = libspdm_hash_new (
    2350              :                     spdm_context->connection_info.algorithm.base_hash_algo);
    2351           14 :                 if (spdm_context->transcript.digest_context_il1il2 == NULL) {
    2352            0 :                     return LIBSPDM_STATUS_CRYPTO_ERROR;
    2353              :                 }
    2354           14 :                 result = libspdm_hash_init (spdm_context->connection_info.algorithm.base_hash_algo,
    2355              :                                             spdm_context->transcript.digest_context_il1il2);
    2356           14 :                 if (!result) {
    2357            0 :                     libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    2358              :                                        spdm_context->transcript.digest_context_il1il2);
    2359            0 :                     spdm_context->transcript.digest_context_il1il2 = NULL;
    2360            0 :                     return LIBSPDM_STATUS_CRYPTO_ERROR;
    2361              :                 }
    2362              : 
    2363           14 :                 result = libspdm_hash_update (
    2364              :                     spdm_context->connection_info.algorithm.base_hash_algo,
    2365              :                     spdm_context->transcript.digest_context_il1il2,
    2366           14 :                     libspdm_get_managed_buffer(&spdm_context->transcript.message_a),
    2367           14 :                     libspdm_get_managed_buffer_size(&spdm_context->transcript.message_a));
    2368              : 
    2369           14 :                 if (!result) {
    2370            0 :                     libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    2371              :                                        spdm_context->transcript.digest_context_il1il2);
    2372            0 :                     spdm_context->transcript.digest_context_il1il2 = NULL;
    2373            0 :                     return LIBSPDM_STATUS_CRYPTO_ERROR;
    2374              :                 }
    2375              :             }
    2376           28 :             result = libspdm_hash_update (spdm_context->connection_info.algorithm.base_hash_algo,
    2377              :                                           spdm_context->transcript.digest_context_il1il2, message,
    2378              :                                           message_size);
    2379           28 :             if (!result) {
    2380            0 :                 libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    2381              :                                    spdm_context->transcript.digest_context_il1il2);
    2382            0 :                 spdm_context->transcript.digest_context_il1il2 = NULL;
    2383            0 :                 return LIBSPDM_STATUS_CRYPTO_ERROR;
    2384              :             }
    2385              :         } else {
    2386            6 :             if (spdm_session_info->session_transcript.digest_context_il1il2 == NULL) {
    2387            3 :                 spdm_session_info->session_transcript.digest_context_il1il2 = libspdm_hash_new (
    2388              :                     spdm_context->connection_info.algorithm.base_hash_algo);
    2389            3 :                 if (spdm_session_info->session_transcript.digest_context_il1il2 == NULL) {
    2390            0 :                     return LIBSPDM_STATUS_CRYPTO_ERROR;
    2391              :                 }
    2392            3 :                 result = libspdm_hash_init (spdm_context->connection_info.algorithm.base_hash_algo,
    2393              :                                             spdm_session_info->session_transcript.digest_context_il1il2);
    2394            3 :                 if (!result) {
    2395            0 :                     libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    2396              :                                        spdm_session_info->session_transcript.digest_context_il1il2);
    2397            0 :                     spdm_session_info->session_transcript.digest_context_il1il2 = NULL;
    2398            0 :                     return LIBSPDM_STATUS_CRYPTO_ERROR;
    2399              :                 }
    2400              : 
    2401            3 :                 result = libspdm_hash_update (
    2402              :                     spdm_context->connection_info.algorithm.base_hash_algo,
    2403              :                     spdm_session_info->session_transcript.digest_context_il1il2,
    2404            3 :                     libspdm_get_managed_buffer(&spdm_context->transcript.message_a),
    2405            3 :                     libspdm_get_managed_buffer_size(&spdm_context->transcript.message_a));
    2406              : 
    2407            3 :                 if (!result) {
    2408            0 :                     libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    2409              :                                        spdm_session_info->session_transcript.digest_context_il1il2);
    2410            0 :                     spdm_session_info->session_transcript.digest_context_il1il2 = NULL;
    2411            0 :                     return LIBSPDM_STATUS_CRYPTO_ERROR;
    2412              :                 }
    2413              :             }
    2414            6 :             result = libspdm_hash_update (spdm_context->connection_info.algorithm.base_hash_algo,
    2415              :                                           spdm_session_info->session_transcript.digest_context_il1il2,
    2416              :                                           message, message_size);
    2417            6 :             if (!result) {
    2418            0 :                 libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    2419              :                                    spdm_session_info->session_transcript.digest_context_il1il2);
    2420            0 :                 spdm_session_info->session_transcript.digest_context_il1il2 = NULL;
    2421            0 :                 return LIBSPDM_STATUS_CRYPTO_ERROR;
    2422              :             }
    2423              :         }
    2424              : 
    2425           34 :         return LIBSPDM_STATUS_SUCCESS;
    2426              :     }
    2427              : #endif
    2428              : }
    2429              : 
    2430           24 : libspdm_return_t libspdm_append_message_encap_e(libspdm_context_t *spdm_context, void *session_info,
    2431              :                                                 const void *message, size_t message_size)
    2432              : {
    2433              :     libspdm_session_info_t *spdm_session_info;
    2434              : 
    2435           24 :     spdm_session_info = session_info;
    2436              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    2437              :     if (spdm_session_info == NULL) {
    2438              :         return libspdm_append_managed_buffer(&spdm_context->transcript.message_encap_e,
    2439              :                                              message, message_size);
    2440              :     } else {
    2441              :         return libspdm_append_managed_buffer(&spdm_session_info->session_transcript.message_encap_e,
    2442              :                                              message, message_size);
    2443              :     }
    2444              : #else
    2445              :     {
    2446              :         bool result;
    2447              : 
    2448           24 :         if (spdm_session_info == NULL) {
    2449           19 :             if (spdm_context->transcript.digest_context_encap_il1il2 == NULL) {
    2450           12 :                 spdm_context->transcript.digest_context_encap_il1il2 = libspdm_hash_new (
    2451              :                     spdm_context->connection_info.algorithm.base_hash_algo);
    2452           12 :                 if (spdm_context->transcript.digest_context_encap_il1il2 == NULL) {
    2453            0 :                     return LIBSPDM_STATUS_CRYPTO_ERROR;
    2454              :                 }
    2455           12 :                 result = libspdm_hash_init (spdm_context->connection_info.algorithm.base_hash_algo,
    2456              :                                             spdm_context->transcript.digest_context_encap_il1il2);
    2457           12 :                 if (!result) {
    2458            0 :                     libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    2459              :                                        spdm_context->transcript.digest_context_encap_il1il2);
    2460            0 :                     spdm_context->transcript.digest_context_encap_il1il2 = NULL;
    2461            0 :                     return LIBSPDM_STATUS_CRYPTO_ERROR;
    2462              :                 }
    2463              : 
    2464           12 :                 result = libspdm_hash_update (
    2465              :                     spdm_context->connection_info.algorithm.base_hash_algo,
    2466              :                     spdm_context->transcript.digest_context_encap_il1il2,
    2467           12 :                     libspdm_get_managed_buffer(&spdm_context->transcript.message_a),
    2468           12 :                     libspdm_get_managed_buffer_size(&spdm_context->transcript.message_a));
    2469              : 
    2470           12 :                 if (!result) {
    2471            0 :                     libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    2472              :                                        spdm_context->transcript.digest_context_encap_il1il2);
    2473            0 :                     spdm_context->transcript.digest_context_encap_il1il2 = NULL;
    2474            0 :                     return LIBSPDM_STATUS_CRYPTO_ERROR;
    2475              :                 }
    2476              :             }
    2477           19 :             result = libspdm_hash_update (spdm_context->connection_info.algorithm.base_hash_algo,
    2478              :                                           spdm_context->transcript.digest_context_encap_il1il2,
    2479              :                                           message,
    2480              :                                           message_size);
    2481           19 :             if (!result) {
    2482            0 :                 libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    2483              :                                    spdm_context->transcript.digest_context_encap_il1il2);
    2484            0 :                 spdm_context->transcript.digest_context_encap_il1il2 = NULL;
    2485            0 :                 return LIBSPDM_STATUS_CRYPTO_ERROR;
    2486              :             }
    2487              :         } else {
    2488            5 :             if (spdm_session_info->session_transcript.digest_context_encap_il1il2 == NULL) {
    2489            3 :                 spdm_session_info->session_transcript.digest_context_encap_il1il2 =
    2490            3 :                     libspdm_hash_new (spdm_context->connection_info.algorithm.base_hash_algo);
    2491            3 :                 if (spdm_session_info->session_transcript.digest_context_encap_il1il2 == NULL) {
    2492            0 :                     return LIBSPDM_STATUS_CRYPTO_ERROR;
    2493              :                 }
    2494            3 :                 result = libspdm_hash_init (spdm_context->connection_info.algorithm.base_hash_algo,
    2495              :                                             spdm_session_info->session_transcript.digest_context_encap_il1il2);
    2496            3 :                 if (!result) {
    2497            0 :                     libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    2498              :                                        spdm_session_info->session_transcript.digest_context_encap_il1il2);
    2499            0 :                     spdm_session_info->session_transcript.digest_context_encap_il1il2 = NULL;
    2500            0 :                     return LIBSPDM_STATUS_CRYPTO_ERROR;
    2501              :                 }
    2502              : 
    2503            3 :                 result = libspdm_hash_update (
    2504              :                     spdm_context->connection_info.algorithm.base_hash_algo,
    2505              :                     spdm_session_info->session_transcript.digest_context_encap_il1il2,
    2506            3 :                     libspdm_get_managed_buffer(&spdm_context->transcript.message_a),
    2507            3 :                     libspdm_get_managed_buffer_size(&spdm_context->transcript.message_a));
    2508              : 
    2509            3 :                 if (!result) {
    2510            0 :                     libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    2511              :                                        spdm_session_info->session_transcript.digest_context_encap_il1il2);
    2512            0 :                     spdm_session_info->session_transcript.digest_context_encap_il1il2 = NULL;
    2513            0 :                     return LIBSPDM_STATUS_CRYPTO_ERROR;
    2514              :                 }
    2515              :             }
    2516            5 :             result = libspdm_hash_update (spdm_context->connection_info.algorithm.base_hash_algo,
    2517              :                                           spdm_session_info->session_transcript.digest_context_encap_il1il2,
    2518              :                                           message, message_size);
    2519            5 :             if (!result) {
    2520            0 :                 libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
    2521              :                                    spdm_session_info->session_transcript.digest_context_encap_il1il2);
    2522            0 :                 spdm_session_info->session_transcript.digest_context_encap_il1il2 = NULL;
    2523            0 :                 return LIBSPDM_STATUS_CRYPTO_ERROR;
    2524              :             }
    2525              :         }
    2526              : 
    2527           24 :         return LIBSPDM_STATUS_SUCCESS;
    2528              :     }
    2529              : #endif
    2530              : }
    2531              : /**
    2532              :  * This function returns if a given version is supported based upon the GET_VERSION/VERSION.
    2533              :  *
    2534              :  * @param  spdm_context                  A pointer to the SPDM context.
    2535              :  * @param  version                      The SPDM version.
    2536              :  *
    2537              :  * @retval true  the version is supported.
    2538              :  * @retval false the version is not supported.
    2539              :  **/
    2540            0 : bool libspdm_is_version_supported(const libspdm_context_t *spdm_context, uint8_t version)
    2541              : {
    2542            0 :     if (version == (spdm_context->connection_info.version >> SPDM_VERSION_NUMBER_SHIFT_BIT)) {
    2543            0 :         return true;
    2544              :     }
    2545              : 
    2546            0 :     return false;
    2547              : }
    2548              : 
    2549              : /**
    2550              :  * This function returns connection version negotiated by GET_VERSION/VERSION.
    2551              :  *
    2552              :  * @param  spdm_context                  A pointer to the SPDM context.
    2553              :  *
    2554              :  * @return the connection version.
    2555              :  **/
    2556       273528 : uint8_t libspdm_get_connection_version(const libspdm_context_t *spdm_context)
    2557              : {
    2558       273528 :     return (uint8_t)(spdm_context->connection_info.version >> SPDM_VERSION_NUMBER_SHIFT_BIT);
    2559              : }
    2560              : 
    2561              : /**
    2562              :  * This function returns if a capabilities flag is supported in current SPDM connection.
    2563              :  *
    2564              :  * @param  spdm_context                  A pointer to the SPDM context.
    2565              :  * @param  is_requester                  Is the function called from a requester.
    2566              :  * @param  requester_capabilities_flag    The requester capabilities flag to be checked
    2567              :  * @param  responder_capabilities_flag    The responder capabilities flag to be checked
    2568              :  *
    2569              :  * @retval true  the capabilities flag is supported.
    2570              :  * @retval false the capabilities flag is not supported.
    2571              :  **/
    2572        76860 : bool libspdm_is_capabilities_flag_supported(const libspdm_context_t *spdm_context,
    2573              :                                             bool is_requester,
    2574              :                                             uint32_t requester_capabilities_flag,
    2575              :                                             uint32_t responder_capabilities_flag)
    2576              : {
    2577              :     uint32_t negotiated_requester_capabilities_flag;
    2578              :     uint32_t negotiated_responder_capabilities_flag;
    2579              : 
    2580        76860 :     if (is_requester) {
    2581        72395 :         negotiated_requester_capabilities_flag = spdm_context->local_context.capability.flags;
    2582        72395 :         negotiated_responder_capabilities_flag = spdm_context->connection_info.capability.flags;
    2583              :     } else {
    2584         4465 :         negotiated_requester_capabilities_flag = spdm_context->connection_info.capability.flags;
    2585         4465 :         negotiated_responder_capabilities_flag = spdm_context->local_context.capability.flags;
    2586              :     }
    2587              : 
    2588        76860 :     if (((requester_capabilities_flag == 0) ||
    2589        73187 :          ((negotiated_requester_capabilities_flag &
    2590        71841 :            requester_capabilities_flag) != 0)) &&
    2591        70353 :         ((responder_capabilities_flag == 0) ||
    2592        70353 :          ((negotiated_responder_capabilities_flag &
    2593              :            responder_capabilities_flag) != 0))) {
    2594        70962 :         return true;
    2595              :     } else {
    2596         5898 :         return false;
    2597              :     }
    2598              : }
    2599              : 
    2600              : /**
    2601              :  * This function returns if a capabilities extended flag is supported in current SPDM connection.
    2602              :  *
    2603              :  * @param  spdm_context                     A pointer to the SPDM context.
    2604              :  * @param  is_requester                     Is the function called from a requester.
    2605              :  * @param  requester_capabilities_ext_flag  The requester capabilities extended flag to be checked
    2606              :  * @param  responder_capabilities_ext_flag  The responder capabilities extended flag to be checked
    2607              :  *
    2608              :  * @retval true  the capabilities extended flag is supported.
    2609              :  * @retval false the capabilities extended flag is not supported.
    2610              :  **/
    2611            0 : bool libspdm_is_capabilities_ext_flag_supported(const libspdm_context_t *spdm_context,
    2612              :                                                 bool is_requester,
    2613              :                                                 uint16_t requester_capabilities_ext_flag,
    2614              :                                                 uint16_t responder_capabilities_ext_flag)
    2615              : {
    2616              :     uint16_t negotiated_requester_capabilities_ext_flag;
    2617              :     uint16_t negotiated_responder_capabilities_ext_flag;
    2618              : 
    2619            0 :     if (is_requester) {
    2620            0 :         negotiated_requester_capabilities_ext_flag = spdm_context->local_context.capability.ext_flags;
    2621            0 :         negotiated_responder_capabilities_ext_flag = spdm_context->connection_info.capability.ext_flags;
    2622              :     } else {
    2623            0 :         negotiated_requester_capabilities_ext_flag = spdm_context->connection_info.capability.ext_flags;
    2624            0 :         negotiated_responder_capabilities_ext_flag = spdm_context->local_context.capability.ext_flags;
    2625              :     }
    2626              : 
    2627            0 :     if (((requester_capabilities_ext_flag == 0) ||
    2628              :          ((negotiated_requester_capabilities_ext_flag &
    2629            0 :            requester_capabilities_ext_flag) != 0)) &&
    2630            0 :         ((responder_capabilities_ext_flag == 0) ||
    2631              :          ((negotiated_responder_capabilities_ext_flag &
    2632            0 :            responder_capabilities_ext_flag) != 0))) {
    2633            0 :         return true;
    2634              :     } else {
    2635            0 :         return false;
    2636              :     }
    2637              : }
    2638              : 
    2639           33 : bool libspdm_is_encap_supported(const libspdm_context_t *spdm_context)
    2640              : {
    2641           33 :     if (libspdm_get_connection_version(spdm_context) == SPDM_MESSAGE_VERSION_10) {
    2642            0 :         return false;
    2643           33 :     } else if (libspdm_get_connection_version(spdm_context) == SPDM_MESSAGE_VERSION_12) {
    2644              :         /* ENCAP_CAP was erroneously deprecated in SPDM 1.2.0 and 1.2.1, and MUT_AUTH_CAP
    2645              :          * was used in its place. In SPDM 1.2.2 and later ENCAP_CAP is undeprecated. Since
    2646              :          * UpdateVersionNumber must be ignored when checking interoperability libspdm will check
    2647              :          * if ENCAP_CAP or MUT_AUTH_CAP is set. */
    2648            2 :         const bool is_req_encap_cap_supported = libspdm_is_capabilities_flag_supported(
    2649            2 :             spdm_context, spdm_context->local_context.is_requester,
    2650              :             SPDM_GET_CAPABILITIES_REQUEST_FLAGS_ENCAP_CAP, 0);
    2651            2 :         const bool is_req_mut_auth_cap_supported = libspdm_is_capabilities_flag_supported(
    2652            2 :             spdm_context, spdm_context->local_context.is_requester,
    2653              :             SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MUT_AUTH_CAP, 0);
    2654            2 :         const bool is_rsp_encap_cap_supported = libspdm_is_capabilities_flag_supported(
    2655            2 :             spdm_context, spdm_context->local_context.is_requester,
    2656              :             0, SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_ENCAP_CAP);
    2657            2 :         const bool is_rsp_mut_auth_cap_supported = libspdm_is_capabilities_flag_supported(
    2658            2 :             spdm_context, spdm_context->local_context.is_requester,
    2659              :             0, SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MUT_AUTH_CAP);
    2660              : 
    2661            2 :         return ((is_req_encap_cap_supported || is_req_mut_auth_cap_supported) &&
    2662            0 :                 (is_rsp_encap_cap_supported || is_rsp_mut_auth_cap_supported));
    2663              :     } else {
    2664              :         /* For SPDM 1.1 and 1.3 and later only check ENCAP_CAP. */
    2665           31 :         return libspdm_is_capabilities_flag_supported(
    2666           31 :             spdm_context, spdm_context->local_context.is_requester,
    2667              :             SPDM_GET_CAPABILITIES_REQUEST_FLAGS_ENCAP_CAP,
    2668              :             SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_ENCAP_CAP);
    2669              :     }
    2670              : }
    2671              : 
    2672              : /**
    2673              :  * Register SPDM device input/output functions.
    2674              :  *
    2675              :  * This function must be called after libspdm_init_context, and before any SPDM communication.
    2676              :  *
    2677              :  * @param  spdm_context                  A pointer to the SPDM context.
    2678              :  * @param  send_message                  The function to send an SPDM transport layer message.
    2679              :  * @param  receive_message               The function to receive an SPDM transport layer message.
    2680              :  **/
    2681          109 : void libspdm_register_device_io_func(
    2682              :     void *spdm_context, libspdm_device_send_message_func send_message,
    2683              :     libspdm_device_receive_message_func receive_message)
    2684              : {
    2685              :     libspdm_context_t *context;
    2686              : 
    2687          109 :     context = spdm_context;
    2688          109 :     context->send_message = send_message;
    2689          109 :     context->receive_message = receive_message;
    2690          109 : }
    2691              : 
    2692              : /**
    2693              :  * Register SPDM device buffer management functions.
    2694              :  *
    2695              :  * This function must be called after libspdm_init_context, and before any SPDM communication.
    2696              :  *
    2697              :  * The sender_buffer_size and receiver_buffer_size must be no smaller than
    2698              :  * MAX (non-secure Transport Message Header Size +
    2699              :  *          SPDM_CAPABILITIES.DataTransferSize +
    2700              :  *          max alignment pad size (transport specific),
    2701              :  *      secure Transport Message Header Size +
    2702              :  *          sizeof(spdm_secured_message_a_data_header1_t) +
    2703              :  *          length of sequence_number (transport specific) +
    2704              :  *          sizeof(spdm_secured_message_a_data_header2_t) +
    2705              :  *          sizeof(spdm_secured_message_cipher_header_t) +
    2706              :  *          App Message Header Size (transport specific) +
    2707              :  *          SPDM_CAPABILITIES.DataTransferSize +
    2708              :  *          maximum random data size (transport specific) +
    2709              :  *          AEAD MAC size (16) +
    2710              :  *          max alignment pad size (transport specific)).
    2711              :  *
    2712              :  * Finally, the SPDM_CAPABILITIES.DataTransferSize will be calculated based upon it.
    2713              :  *
    2714              :  *   For MCTP,
    2715              :  *          Transport Message Header Size = sizeof(mctp_message_header_t)
    2716              :  *          length of sequence_number = 2
    2717              :  *          App Message Header Size = sizeof(mctp_message_header_t)
    2718              :  *          maximum random data size = MCTP_MAX_RANDOM_NUMBER_COUNT
    2719              :  *          max alignment pad size = 0
    2720              :  *   For PCI_DOE,
    2721              :  *          Transport Message Header Size = sizeof(pci_doe_data_object_header_t)
    2722              :  *          length of sequence_number = 0
    2723              :  *          App Message Header Size = 0
    2724              :  *          maximum random data size = 0
    2725              :  *          max alignment pad size = 3
    2726              :  *
    2727              :  * @param  spdm_context                  A pointer to the SPDM context.
    2728              :  * @param  sender_buffer_size            Size in bytes of the sender buffer.
    2729              :  * @param  receiver_buffer_size          Size in bytes of the receiver buffer.
    2730              :  * @param  acquire_sender_buffer         The function to acquire transport layer sender buffer.
    2731              :  * @param  release_sender_buffer         The function to release transport layer sender buffer.
    2732              :  * @param  acquire_receiver_buffer       The function to acquire transport layer receiver buffer.
    2733              :  * @param  release_receiver_buffer       The function to release transport layer receiver buffer.
    2734              :  **/
    2735          110 : void libspdm_register_device_buffer_func(
    2736              :     void *spdm_context,
    2737              :     uint32_t sender_buffer_size,
    2738              :     uint32_t receiver_buffer_size,
    2739              :     libspdm_device_acquire_sender_buffer_func acquire_sender_buffer,
    2740              :     libspdm_device_release_sender_buffer_func release_sender_buffer,
    2741              :     libspdm_device_acquire_receiver_buffer_func acquire_receiver_buffer,
    2742              :     libspdm_device_release_receiver_buffer_func release_receiver_buffer)
    2743              : {
    2744              :     libspdm_context_t *context;
    2745              : 
    2746          110 :     context = spdm_context;
    2747          110 :     context->sender_buffer_size = sender_buffer_size;
    2748          110 :     context->receiver_buffer_size = receiver_buffer_size;
    2749          110 :     context->acquire_sender_buffer = acquire_sender_buffer;
    2750          110 :     context->release_sender_buffer = release_sender_buffer;
    2751          110 :     context->acquire_receiver_buffer = acquire_receiver_buffer;
    2752          110 :     context->release_receiver_buffer = release_receiver_buffer;
    2753              : 
    2754          110 :     LIBSPDM_ASSERT (sender_buffer_size >=
    2755              :                     context->local_context.capability.transport_header_size +
    2756              :                     context->local_context.capability.transport_tail_size);
    2757          110 :     sender_buffer_size -= (context->local_context.capability.transport_header_size +
    2758          110 :                            context->local_context.capability.transport_tail_size);
    2759          110 :     LIBSPDM_ASSERT (sender_buffer_size >= SPDM_MIN_DATA_TRANSFER_SIZE_VERSION_12);
    2760          110 :     context->local_context.capability.sender_data_transfer_size = sender_buffer_size;
    2761              : 
    2762          110 :     LIBSPDM_ASSERT(receiver_buffer_size >=
    2763              :                    context->local_context.capability.transport_header_size +
    2764              :                    context->local_context.capability.transport_tail_size);
    2765          110 :     receiver_buffer_size -= (context->local_context.capability.transport_header_size +
    2766          110 :                              context->local_context.capability.transport_tail_size);
    2767          110 :     LIBSPDM_ASSERT (receiver_buffer_size >= SPDM_MIN_DATA_TRANSFER_SIZE_VERSION_12);
    2768          110 :     context->local_context.capability.data_transfer_size = receiver_buffer_size;
    2769          110 : }
    2770              : 
    2771              : /**
    2772              :  * Register SPDM transport layer encode/decode functions for SPDM or APP messages.
    2773              :  *
    2774              :  * This function must be called after libspdm_init_context, and before any SPDM communication.
    2775              :  *
    2776              :  * @param  spdm_context                  A pointer to the SPDM context.
    2777              :  * @param  transport_encode_message       The function to encode an SPDM or APP message to a transport layer message.
    2778              :  * @param  transport_decode_message       The function to decode an SPDM or APP message from a transport layer message.
    2779              :  **/
    2780          111 : void libspdm_register_transport_layer_func(
    2781              :     void *spdm_context,
    2782              :     uint32_t max_spdm_msg_size,
    2783              :     uint32_t transport_header_size,
    2784              :     uint32_t transport_tail_size,
    2785              :     libspdm_transport_encode_message_func transport_encode_message,
    2786              :     libspdm_transport_decode_message_func transport_decode_message)
    2787              : {
    2788              :     libspdm_context_t *context;
    2789              : 
    2790          111 :     context = spdm_context;
    2791              : 
    2792              :     /* fix the data_transfer_size if it is set before */
    2793          111 :     if ((context->local_context.capability.data_transfer_size != 0) &&
    2794            1 :         (context->local_context.capability.data_transfer_size ==
    2795            1 :          context->receiver_buffer_size)) {
    2796            0 :         context->local_context.capability.data_transfer_size =
    2797            0 :             (uint32_t)(context->receiver_buffer_size -
    2798            0 :                        (transport_header_size + transport_tail_size));
    2799              :     }
    2800          111 :     if ((context->local_context.capability.sender_data_transfer_size != 0) &&
    2801            1 :         (context->local_context.capability.sender_data_transfer_size ==
    2802            1 :          context->sender_buffer_size)) {
    2803            0 :         context->local_context.capability.sender_data_transfer_size =
    2804            0 :             (uint32_t)(context->sender_buffer_size -
    2805            0 :                        (transport_header_size + transport_tail_size));
    2806              :     }
    2807              : 
    2808          111 :     context->local_context.capability.max_spdm_msg_size = max_spdm_msg_size;
    2809          111 :     context->local_context.capability.transport_header_size = transport_header_size;
    2810          111 :     context->local_context.capability.transport_tail_size = transport_tail_size;
    2811          111 :     context->transport_encode_message = transport_encode_message;
    2812          111 :     context->transport_decode_message = transport_decode_message;
    2813          111 : }
    2814              : 
    2815              : /**
    2816              :  * Register SPDM certificate verification functions for SPDM GET_CERTIFICATE in requester or responder.
    2817              :  * It is called after GET_CERTIFICATE gets a full certificate chain from peer.
    2818              :  *
    2819              :  * If it is NOT registered, the default verification in SPDM lib will be used. It verifies:
    2820              :  *    1) The integrity of the certificate chain, (Root Cert Hash->Root Cert->Cert Chain), according to X.509.
    2821              :  *  2) The trust anchor, according LIBSPDM_DATA_PEER_PUBLIC_ROOT_CERT or LIBSPDM_DATA_PEER_PUBLIC_CERT_CHAIN.
    2822              :  * If it is registered, SPDM lib will use this function to verify the certificate.
    2823              :  *
    2824              :  * This function must be called after libspdm_init_context, and before any SPDM communication.
    2825              :  *
    2826              :  * @param  context                  A pointer to the SPDM context.
    2827              :  * @param  verify_spdm_cert_chain   The function to verify an SPDM certificate after GET_CERTIFICATE.
    2828              :  **/
    2829            0 : void libspdm_register_verify_spdm_cert_chain_func(
    2830              :     void *spdm_context,
    2831              :     const libspdm_verify_spdm_cert_chain_func verify_spdm_cert_chain)
    2832              : {
    2833              :     libspdm_context_t *context;
    2834              : 
    2835            0 :     context = spdm_context;
    2836            0 :     context->local_context.verify_peer_spdm_cert_chain = verify_spdm_cert_chain;
    2837            0 : }
    2838              : 
    2839              : /**
    2840              :  * Get the size of required scratch buffer.
    2841              :  *
    2842              :  * The SPDM Integrator must call libspdm_get_sizeof_required_scratch_buffer to get the size,
    2843              :  * then allocate enough scratch buffer and call libspdm_set_scratch_buffer().
    2844              :  *
    2845              :  * @param  context                  A pointer to the SPDM context.
    2846              :  *
    2847              :  * @return the size of required scratch buffer.
    2848              :  **/
    2849          114 : size_t libspdm_get_sizeof_required_scratch_buffer (void *spdm_context)
    2850              : {
    2851              :     libspdm_context_t *context;
    2852              :     size_t scratch_buffer_size;
    2853              : 
    2854          114 :     context = spdm_context;
    2855          114 :     LIBSPDM_ASSERT (context->local_context.capability.max_spdm_msg_size != 0);
    2856              : 
    2857          114 :     scratch_buffer_size = libspdm_get_scratch_buffer_capacity(context);
    2858          114 :     return scratch_buffer_size;
    2859              : }
    2860              : 
    2861              : /**
    2862              :  * Set the scratch buffer.
    2863              :  *
    2864              :  * This function must be called after libspdm_init_context, and before any SPDM communication.
    2865              :  *
    2866              :  * @param  context                  A pointer to the SPDM context.
    2867              :  * @param  scratch_buffer           Buffer address of the scratch buffer.
    2868              :  * @param  scratch_buffer_size      Size of the scratch buffer.
    2869              :  *
    2870              :  **/
    2871          114 : void libspdm_set_scratch_buffer (
    2872              :     void *spdm_context,
    2873              :     void *scratch_buffer,
    2874              :     size_t scratch_buffer_size)
    2875              : {
    2876              :     libspdm_context_t *context;
    2877              : 
    2878          114 :     context = spdm_context;
    2879          114 :     LIBSPDM_ASSERT (context->local_context.capability.max_spdm_msg_size != 0);
    2880          114 :     LIBSPDM_ASSERT (scratch_buffer_size >= libspdm_get_scratch_buffer_capacity(spdm_context));
    2881          114 :     context->scratch_buffer = scratch_buffer;
    2882          114 :     context->scratch_buffer_size = scratch_buffer_size;
    2883          114 :     context->last_spdm_request = (uint8_t *)scratch_buffer +
    2884          114 :                                  libspdm_get_scratch_buffer_last_spdm_request_offset(spdm_context);
    2885              : #if LIBSPDM_RESPOND_IF_READY_SUPPORT
    2886          114 :     context->cache_spdm_request = (uint8_t *)scratch_buffer +
    2887          114 :                                   libspdm_get_scratch_buffer_cache_spdm_request_offset(spdm_context);
    2888              : #endif
    2889          114 : }
    2890              : 
    2891              : /**
    2892              :  * Get the scratch buffer.
    2893              :  *
    2894              :  * @param  context                  A pointer to the SPDM context.
    2895              :  * @param  scratch_buffer           Buffer address of the scratch buffer.
    2896              :  * @param  scratch_buffer_size      Size of the scratch buffer.
    2897              :  *
    2898              :  **/
    2899       136708 : void libspdm_get_scratch_buffer (
    2900              :     void *spdm_context,
    2901              :     void **scratch_buffer,
    2902              :     size_t *scratch_buffer_size)
    2903              : {
    2904              :     libspdm_context_t *context;
    2905              : 
    2906       136708 :     context = spdm_context;
    2907       136708 :     LIBSPDM_ASSERT (context->scratch_buffer != NULL);
    2908       136708 :     LIBSPDM_ASSERT (context->scratch_buffer_size >=
    2909              :                     libspdm_get_scratch_buffer_capacity(spdm_context));
    2910       136708 :     *scratch_buffer = context->scratch_buffer;
    2911       136708 :     *scratch_buffer_size = context->scratch_buffer_size;
    2912              :     /* need to remove last 2 sections, because they are for libspdm internal state track. */
    2913       136708 :     *scratch_buffer_size -= libspdm_get_scratch_buffer_last_spdm_request_capacity(spdm_context);
    2914              : #if LIBSPDM_RESPOND_IF_READY_SUPPORT
    2915       136708 :     *scratch_buffer_size -= libspdm_get_scratch_buffer_cache_spdm_request_capacity(spdm_context);
    2916              : #endif
    2917       136708 : }
    2918              : 
    2919         2600 : libspdm_return_t libspdm_acquire_sender_buffer (
    2920              :     libspdm_context_t *spdm_context, size_t *max_msg_size, void **msg_buf_ptr)
    2921              : {
    2922              :     libspdm_return_t status;
    2923              : 
    2924         2600 :     LIBSPDM_ASSERT (spdm_context->sender_buffer == NULL);
    2925         2600 :     LIBSPDM_ASSERT (spdm_context->sender_buffer_size != 0);
    2926         2600 :     status = spdm_context->acquire_sender_buffer (spdm_context, msg_buf_ptr);
    2927         2600 :     if (status != LIBSPDM_STATUS_SUCCESS) {
    2928            7 :         return status;
    2929              :     }
    2930         2593 :     spdm_context->sender_buffer = *msg_buf_ptr;
    2931         2593 :     *max_msg_size = spdm_context->sender_buffer_size;
    2932              :     #if LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP
    2933              :     /* it return scratch buffer, because the requester need build message there.*/
    2934         5186 :     *msg_buf_ptr = (uint8_t *)spdm_context->scratch_buffer +
    2935         2593 :                    libspdm_get_scratch_buffer_large_sender_receiver_offset(spdm_context);
    2936         2593 :     *max_msg_size = libspdm_get_scratch_buffer_large_sender_receiver_capacity(spdm_context);
    2937              :     #endif
    2938         2593 :     return LIBSPDM_STATUS_SUCCESS;
    2939              : }
    2940              : 
    2941         2593 : void libspdm_release_sender_buffer (libspdm_context_t *spdm_context)
    2942              : {
    2943         2593 :     LIBSPDM_ASSERT(spdm_context->sender_buffer != NULL);
    2944         2593 :     LIBSPDM_ASSERT(spdm_context->sender_buffer_size != 0);
    2945              : 
    2946         2593 :     spdm_context->release_sender_buffer (spdm_context, spdm_context->sender_buffer);
    2947         2593 :     spdm_context->sender_buffer = NULL;
    2948         2593 : }
    2949              : 
    2950              : /**
    2951              :  * Get the sender buffer.
    2952              :  *
    2953              :  * @param  context                  A pointer to the SPDM context.
    2954              :  * @param  receiver_buffer            Buffer address of the sender buffer.
    2955              :  * @param  receiver_buffer_size       Size of the sender buffer.
    2956              :  *
    2957              :  **/
    2958        68204 : void libspdm_get_sender_buffer (
    2959              :     libspdm_context_t *spdm_context,
    2960              :     void **sender_buffer,
    2961              :     size_t *sender_buffer_size)
    2962              : {
    2963        68204 :     *sender_buffer = spdm_context->sender_buffer;
    2964        68204 :     *sender_buffer_size = spdm_context->sender_buffer_size;
    2965        68204 : }
    2966              : 
    2967         2554 : libspdm_return_t libspdm_acquire_receiver_buffer (
    2968              :     libspdm_context_t *spdm_context, size_t *max_msg_size, void **msg_buf_ptr)
    2969              : {
    2970              :     libspdm_return_t status;
    2971              : 
    2972         2554 :     LIBSPDM_ASSERT (spdm_context->receiver_buffer == NULL);
    2973         2554 :     LIBSPDM_ASSERT (spdm_context->receiver_buffer_size != 0);
    2974         2554 :     status = spdm_context->acquire_receiver_buffer (spdm_context, msg_buf_ptr);
    2975         2554 :     if (status != LIBSPDM_STATUS_SUCCESS) {
    2976            7 :         return status;
    2977              :     }
    2978         2547 :     spdm_context->receiver_buffer = *msg_buf_ptr;
    2979         2547 :     *max_msg_size = spdm_context->receiver_buffer_size;
    2980              :     #if LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP
    2981              :     /* it return scratch buffer, because the requester need build message there.*/
    2982         5094 :     *msg_buf_ptr = (uint8_t *)spdm_context->scratch_buffer +
    2983         2547 :                    libspdm_get_scratch_buffer_large_sender_receiver_offset(spdm_context);
    2984         2547 :     *max_msg_size = libspdm_get_scratch_buffer_large_sender_receiver_capacity(spdm_context);
    2985              :     #endif
    2986         2547 :     return LIBSPDM_STATUS_SUCCESS;
    2987              : }
    2988              : 
    2989         2547 : void libspdm_release_receiver_buffer (libspdm_context_t *spdm_context)
    2990              : {
    2991         2547 :     LIBSPDM_ASSERT(spdm_context->receiver_buffer != NULL);
    2992         2547 :     LIBSPDM_ASSERT(spdm_context->receiver_buffer_size != 0);
    2993              : 
    2994         2547 :     spdm_context->release_receiver_buffer (spdm_context, spdm_context->receiver_buffer);
    2995         2547 :     spdm_context->receiver_buffer = NULL;
    2996         2547 : }
    2997              : 
    2998              : /**
    2999              :  * Get the receiver buffer.
    3000              :  *
    3001              :  * @param  context                  A pointer to the SPDM context.
    3002              :  * @param  receiver_buffer            Buffer address of the receiver buffer.
    3003              :  * @param  receiver_buffer_size       Size of the receiver buffer.
    3004              :  *
    3005              :  **/
    3006            0 : void libspdm_get_receiver_buffer (
    3007              :     libspdm_context_t *spdm_context,
    3008              :     void **receiver_buffer,
    3009              :     size_t *receiver_buffer_size)
    3010              : {
    3011            0 :     *receiver_buffer = spdm_context->receiver_buffer;
    3012            0 :     *receiver_buffer_size = spdm_context->receiver_buffer_size;
    3013            0 : }
    3014              : 
    3015              : /**
    3016              :  * Get the last SPDM error struct of an SPDM context.
    3017              :  *
    3018              :  * @param  spdm_context                  A pointer to the SPDM context.
    3019              :  * @param  last_spdm_error                Last SPDM error struct of an SPDM context.
    3020              :  */
    3021            0 : void libspdm_get_last_spdm_error_struct(void *spdm_context, libspdm_error_struct_t *last_spdm_error)
    3022              : {
    3023              :     libspdm_context_t *context;
    3024              : 
    3025            0 :     context = spdm_context;
    3026            0 :     libspdm_copy_mem(last_spdm_error, sizeof(libspdm_error_struct_t),
    3027            0 :                      &context->last_spdm_error,sizeof(libspdm_error_struct_t));
    3028            0 : }
    3029              : 
    3030              : /**
    3031              :  * Set the last SPDM error struct of an SPDM context.
    3032              :  *
    3033              :  * @param  spdm_context                  A pointer to the SPDM context.
    3034              :  * @param  last_spdm_error                Last SPDM error struct of an SPDM context.
    3035              :  */
    3036        68302 : void libspdm_set_last_spdm_error_struct(void *spdm_context, libspdm_error_struct_t *last_spdm_error)
    3037              : {
    3038              :     libspdm_context_t *context;
    3039              : 
    3040        68302 :     context = spdm_context;
    3041        68302 :     libspdm_copy_mem(&context->last_spdm_error, sizeof(context->last_spdm_error),
    3042              :                      last_spdm_error, sizeof(libspdm_error_struct_t));
    3043        68302 : }
    3044              : 
    3045              : #if LIBSPDM_FIPS_MODE
    3046            0 : libspdm_return_t libspdm_init_fips_selftest_context(void *fips_selftest_context)
    3047              : {
    3048              :     libspdm_fips_selftest_context_t *context;
    3049            0 :     LIBSPDM_ASSERT(fips_selftest_context != NULL);
    3050              : 
    3051            0 :     context = fips_selftest_context;
    3052              : 
    3053              :     /*No tested for every used algo*/
    3054            0 :     context->tested_algo = 0;
    3055              :     /*self_test result is false for every used algo*/
    3056            0 :     context->self_test_result = 0;
    3057              : 
    3058            0 :     return LIBSPDM_STATUS_SUCCESS;
    3059              : }
    3060              : 
    3061              : /**
    3062              :  * Return the size in bytes of the fips_selftest_context.
    3063              :  *
    3064              :  * @return the size in bytes of the fips_selftest_context.
    3065              :  **/
    3066            0 : size_t libspdm_get_fips_selftest_context_size(void)
    3067              : {
    3068              :     size_t size;
    3069              : 
    3070            0 :     size = sizeof(libspdm_fips_selftest_context_t);
    3071            0 :     return size;
    3072              : }
    3073              : 
    3074              : /**
    3075              :  * import fips_selftest_context to spdm_context;
    3076              :  *
    3077              :  * @param[in,out]  spdm_context                A pointer to the spdm_context.
    3078              :  * @param[in]      fips_selftest_context       A pointer to the fips_selftest_context.
    3079              :  * @param[in]      fips_selftest_context_size  The size of fips_selftest_context.
    3080              :  *
    3081              :  * @retval true   import fips_selftest_context successful.
    3082              :  * @retval false  spdm_context or fips_selftest_context is null.
    3083              :  */
    3084            0 : bool libspdm_import_fips_selftest_context_to_spdm_context(void *spdm_context,
    3085              :                                                           void *fips_selftest_context,
    3086              :                                                           size_t fips_selftest_context_size)
    3087              : {
    3088              :     libspdm_fips_selftest_context_t *libspdm_fips_selftest_context;
    3089              :     libspdm_context_t *libspdm_context;
    3090              : 
    3091            0 :     libspdm_context = spdm_context;
    3092            0 :     libspdm_fips_selftest_context = fips_selftest_context;
    3093              : 
    3094            0 :     if ((libspdm_context == NULL) || (libspdm_fips_selftest_context == NULL)) {
    3095            0 :         return false;
    3096              :     }
    3097            0 :     if (fips_selftest_context_size != sizeof(libspdm_fips_selftest_context_t)) {
    3098            0 :         return false;
    3099              :     }
    3100              : 
    3101            0 :     libspdm_copy_mem(&(libspdm_context->fips_selftest_context),
    3102              :                      sizeof(libspdm_fips_selftest_context_t),
    3103              :                      libspdm_fips_selftest_context, sizeof(libspdm_fips_selftest_context_t));
    3104            0 :     return true;
    3105              : }
    3106              : 
    3107              : /**
    3108              :  * export fips_selftest_context from spdm_context;
    3109              :  *
    3110              :  * @param[in]          spdm_context                A pointer to the spdm_context.
    3111              :  * @param[in,out]      fips_selftest_context       A pointer to the fips_selftest_context.
    3112              :  * @param[in]          fips_selftest_context_size  The size of fips_selftest_context.
    3113              :  *
    3114              :  * @retval true   export fips_selftest_context successful.
    3115              :  * @retval false  spdm_context or fips_selftest_context is null.
    3116              :  */
    3117            0 : bool libspdm_export_fips_selftest_context_from_spdm_context(void *spdm_context,
    3118              :                                                             void *fips_selftest_context,
    3119              :                                                             size_t fips_selftest_context_size)
    3120              : {
    3121              :     libspdm_fips_selftest_context_t *libspdm_fips_selftest_context;
    3122              :     libspdm_context_t *libspdm_context;
    3123              : 
    3124            0 :     libspdm_context = spdm_context;
    3125            0 :     libspdm_fips_selftest_context = fips_selftest_context;
    3126              : 
    3127            0 :     if ((libspdm_context == NULL) || (libspdm_fips_selftest_context == NULL)) {
    3128            0 :         return false;
    3129              :     }
    3130            0 :     if (fips_selftest_context_size != sizeof(libspdm_fips_selftest_context_t)) {
    3131            0 :         return false;
    3132              :     }
    3133              : 
    3134            0 :     libspdm_copy_mem(libspdm_fips_selftest_context,
    3135              :                      sizeof(libspdm_fips_selftest_context_t),
    3136            0 :                      &(libspdm_context->fips_selftest_context),
    3137              :                      sizeof(libspdm_fips_selftest_context_t));
    3138            0 :     return true;
    3139              : }
    3140              : 
    3141              : #endif /* LIBSPDM_FIPS_MODE */
    3142              : 
    3143          117 : libspdm_return_t libspdm_init_context_with_secured_context(void *spdm_context,
    3144              :                                                            void **secured_contexts,
    3145              :                                                            size_t num_secured_contexts)
    3146              : {
    3147              :     libspdm_context_t *context;
    3148              :     size_t index;
    3149              : 
    3150          117 :     LIBSPDM_ASSERT(spdm_context != NULL);
    3151          117 :     LIBSPDM_ASSERT(secured_contexts != NULL);
    3152          117 :     LIBSPDM_ASSERT(num_secured_contexts == LIBSPDM_MAX_SESSION_COUNT);
    3153              : 
    3154          117 :     context = spdm_context;
    3155          117 :     libspdm_zero_mem(context, sizeof(libspdm_context_t));
    3156          117 :     context->version = LIBSPDM_CONTEXT_STRUCT_VERSION;
    3157          117 :     context->transcript.message_a.max_buffer_size =
    3158              :         sizeof(context->transcript.message_a.buffer);
    3159          117 :     context->transcript.message_d.max_buffer_size =
    3160              :         sizeof(context->transcript.message_d.buffer);
    3161              : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
    3162              :     context->transcript.message_b.max_buffer_size =
    3163              :         sizeof(context->transcript.message_b.buffer);
    3164              :     context->transcript.message_c.max_buffer_size =
    3165              :         sizeof(context->transcript.message_c.buffer);
    3166              :     context->transcript.message_mut_b.max_buffer_size =
    3167              :         sizeof(context->transcript.message_mut_b.buffer);
    3168              :     context->transcript.message_mut_c.max_buffer_size =
    3169              :         sizeof(context->transcript.message_mut_c.buffer);
    3170              :     context->transcript.message_m.max_buffer_size =
    3171              :         sizeof(context->transcript.message_m.buffer);
    3172              :     context->transcript.message_e.max_buffer_size =
    3173              :         sizeof(context->transcript.message_e.buffer);
    3174              :     context->transcript.message_encap_e.max_buffer_size =
    3175              :         sizeof(context->transcript.message_encap_e.buffer);
    3176              : #endif
    3177          117 :     context->response_state = LIBSPDM_RESPONSE_STATE_NORMAL;
    3178          117 :     context->local_context.version.spdm_version_count = SPDM_MAX_VERSION_COUNT;
    3179          117 :     context->local_context.version.spdm_version[0] = SPDM_MESSAGE_VERSION_10 <<
    3180              :                                                      SPDM_VERSION_NUMBER_SHIFT_BIT;
    3181          117 :     context->local_context.version.spdm_version[1] = SPDM_MESSAGE_VERSION_11 <<
    3182              :                                                      SPDM_VERSION_NUMBER_SHIFT_BIT;
    3183          117 :     context->local_context.version.spdm_version[2] = SPDM_MESSAGE_VERSION_12 <<
    3184              :                                                      SPDM_VERSION_NUMBER_SHIFT_BIT;
    3185          117 :     context->local_context.version.spdm_version[3] = SPDM_MESSAGE_VERSION_13 <<
    3186              :                                                      SPDM_VERSION_NUMBER_SHIFT_BIT;
    3187          117 :     context->local_context.version.spdm_version[4] = SPDM_MESSAGE_VERSION_14 <<
    3188              :                                                      SPDM_VERSION_NUMBER_SHIFT_BIT;
    3189          117 :     context->local_context.secured_message_version.spdm_version_count =
    3190              :         SECURED_SPDM_MAX_VERSION_COUNT;
    3191          117 :     context->local_context.secured_message_version.spdm_version[0] =
    3192              :         SECURED_SPDM_VERSION_10 << SPDM_VERSION_NUMBER_SHIFT_BIT;
    3193          117 :     context->local_context.secured_message_version.spdm_version[1] =
    3194              :         SECURED_SPDM_VERSION_11 << SPDM_VERSION_NUMBER_SHIFT_BIT;
    3195          117 :     context->local_context.secured_message_version.spdm_version[2] =
    3196              :         SECURED_SPDM_VERSION_12 << SPDM_VERSION_NUMBER_SHIFT_BIT;
    3197          117 :     context->local_context.capability.st1 = SPDM_ST1_VALUE_US;
    3198              : 
    3199          117 :     context->mut_auth_cert_chain_buffer_size = 0;
    3200              : 
    3201          117 :     context->max_spdm_session_sequence_number = LIBSPDM_MAX_SPDM_SESSION_SEQUENCE_NUMBER;
    3202              : 
    3203          117 :     context->latest_session_id = INVALID_SESSION_ID;
    3204          117 :     context->last_spdm_request_session_id = INVALID_SESSION_ID;
    3205          117 :     context->last_spdm_request_session_id_valid = false;
    3206          117 :     context->last_spdm_request_size = 0;
    3207              : 
    3208              :     /* To be updated in libspdm_register_device_buffer_func */
    3209          117 :     context->local_context.capability.data_transfer_size = 0;
    3210          117 :     context->local_context.capability.sender_data_transfer_size = 0;
    3211          117 :     context->local_context.capability.max_spdm_msg_size = 0;
    3212              : 
    3213          585 :     for (index = 0; index < num_secured_contexts; index++) {
    3214          468 :         if (secured_contexts[index] == NULL) {
    3215            0 :             return LIBSPDM_STATUS_INVALID_PARAMETER;
    3216              :         }
    3217              : 
    3218          468 :         context->session_info[index].secured_message_context = secured_contexts[index];
    3219          468 :         libspdm_secured_message_init_context(
    3220              :             context->session_info[index].secured_message_context);
    3221              :     }
    3222              : 
    3223          117 :     return LIBSPDM_STATUS_SUCCESS;
    3224              : }
    3225              : 
    3226          116 : libspdm_return_t libspdm_init_context(void *spdm_context)
    3227              : {
    3228              :     libspdm_context_t *context;
    3229              :     void *secured_context;
    3230              :     void *secured_contexts[LIBSPDM_MAX_SESSION_COUNT];
    3231              :     size_t secured_context_size;
    3232              :     size_t index;
    3233              : 
    3234          116 :     LIBSPDM_ASSERT(spdm_context != NULL);
    3235              : 
    3236              :     /* libspdm_get_context_size() allocates space for all secured message
    3237              :      * contexts. They are appended to the general SPDM context. */
    3238          116 :     context = spdm_context;
    3239          116 :     secured_context = (void *)((size_t)(context + 1));
    3240          116 :     secured_context_size = libspdm_secured_message_get_context_size();
    3241              : 
    3242          580 :     for (index = 0; index < LIBSPDM_MAX_SESSION_COUNT; index++)
    3243              :     {
    3244          464 :         secured_contexts[index] = (uint8_t *)secured_context + secured_context_size * index;
    3245              :     }
    3246              : 
    3247          116 :     return libspdm_init_context_with_secured_context(spdm_context,
    3248              :                                                      secured_contexts,
    3249              :                                                      LIBSPDM_MAX_SESSION_COUNT);
    3250              : }
    3251              : 
    3252           42 : void libspdm_reset_context(void *spdm_context)
    3253              : {
    3254              :     libspdm_context_t *context;
    3255              :     size_t index;
    3256              : 
    3257           42 :     context = spdm_context;
    3258              : 
    3259              :     /*Clear all info about last connection*/
    3260              : 
    3261              :     /*need clear session info to free context before algo is zeroed.*/
    3262          210 :     for (index = 0; index < LIBSPDM_MAX_SESSION_COUNT; index++)
    3263              :     {
    3264          168 :         libspdm_session_info_init(context,
    3265              :                                   &context->session_info[index],
    3266              :                                   INVALID_SESSION_ID,
    3267              :                                   0,
    3268              :                                   false);
    3269              :     }
    3270              : 
    3271           42 :     context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NOT_STARTED;
    3272           42 :     libspdm_zero_mem(&context->connection_info.version, sizeof(spdm_version_number_t));
    3273           42 :     libspdm_zero_mem(&context->connection_info.capability,
    3274              :                      sizeof(libspdm_device_capability_t));
    3275           42 :     libspdm_zero_mem(&context->connection_info.algorithm, sizeof(libspdm_device_algorithm_t));
    3276           42 :     libspdm_zero_mem(&context->last_spdm_error, sizeof(libspdm_error_struct_t));
    3277           42 :     libspdm_zero_mem(&context->encap_context, sizeof(libspdm_encap_context_t));
    3278           42 :     context->connection_info.local_used_cert_chain_buffer_size = 0;
    3279           42 :     context->connection_info.local_used_cert_chain_buffer = NULL;
    3280           42 :     context->connection_info.multi_key_conn_req = false;
    3281           42 :     context->connection_info.multi_key_conn_rsp = false;
    3282              : #if LIBSPDM_RESPOND_IF_READY_SUPPORT
    3283           42 :     context->cache_spdm_request_size = 0;
    3284              : #endif
    3285           42 :     context->response_state = LIBSPDM_RESPONSE_STATE_NORMAL;
    3286           42 :     context->current_token = 0;
    3287           42 :     context->latest_session_id = INVALID_SESSION_ID;
    3288           42 :     context->last_spdm_request_session_id = INVALID_SESSION_ID;
    3289           42 :     context->last_spdm_request_session_id_valid = false;
    3290           42 :     context->last_spdm_request_size = 0;
    3291           42 :     context->mut_auth_cert_chain_buffer_size = 0;
    3292           42 :     context->current_dhe_session_count = 0;
    3293           42 :     context->current_psk_session_count = 0;
    3294           42 : }
    3295              : 
    3296              : /**
    3297              :  * Free the memory of contexts within the SPDM context.
    3298              :  * These are typically contexts whose memory has been allocated by the cryptography library.
    3299              :  * This function does not free the SPDM context itself.
    3300              :  *
    3301              :  * @param[in]  spdm_context         A pointer to the SPDM context.
    3302              :  *
    3303              :  */
    3304            0 : void libspdm_deinit_context(void *spdm_context)
    3305              : {
    3306              :     uint32_t session_id;
    3307              :     libspdm_context_t *context;
    3308              :     libspdm_session_info_t *session_info;
    3309              : #if !(LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT)
    3310              :     void *pubkey_context;
    3311              :     bool is_requester;
    3312              :     uint8_t slot_index;
    3313              : #endif
    3314              : 
    3315            0 :     context = spdm_context;
    3316              : 
    3317              : #if !(LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT)
    3318            0 :     is_requester = context->local_context.is_requester;
    3319              : 
    3320            0 :     for (slot_index = 0; slot_index < SPDM_MAX_SLOT_COUNT; slot_index++) {
    3321            0 :         pubkey_context = context->connection_info.peer_used_cert_chain[slot_index].
    3322              :                          leaf_cert_public_key;
    3323              : 
    3324            0 :         if (pubkey_context != NULL) {
    3325            0 :             if (is_requester) {
    3326            0 :                 if (context->connection_info.algorithm.pqc_asym_algo != 0) {
    3327            0 :                     libspdm_pqc_asym_free(
    3328              :                         context->connection_info.algorithm.pqc_asym_algo, pubkey_context);
    3329              :                 } else {
    3330            0 :                     libspdm_asym_free(
    3331              :                         context->connection_info.algorithm.base_asym_algo, pubkey_context);
    3332              :                 }
    3333              :             } else {
    3334            0 :                 if (context->connection_info.algorithm.req_pqc_asym_alg != 0) {
    3335            0 :                     libspdm_req_pqc_asym_free(
    3336              :                         context->connection_info.algorithm.req_pqc_asym_alg, pubkey_context);
    3337              :                 } else {
    3338            0 :                     libspdm_req_asym_free(
    3339            0 :                         context->connection_info.algorithm.req_base_asym_alg, pubkey_context);
    3340              :                 }
    3341              :             }
    3342              : 
    3343            0 :             context->connection_info.peer_used_cert_chain[slot_index].leaf_cert_public_key = NULL;
    3344              :         }
    3345              :     }
    3346              : #endif
    3347              : 
    3348            0 :     libspdm_reset_message_a(context);
    3349            0 :     libspdm_reset_message_d(context);
    3350            0 :     libspdm_reset_message_b(context);
    3351            0 :     libspdm_reset_message_c(context);
    3352            0 :     libspdm_reset_message_mut_b(context);
    3353            0 :     libspdm_reset_message_mut_c(context);
    3354            0 :     for (session_id = 0; session_id < LIBSPDM_MAX_SESSION_COUNT; session_id++) {
    3355            0 :         session_info = &context->session_info[session_id];
    3356            0 :         libspdm_reset_message_m(context, session_info);
    3357            0 :         libspdm_reset_message_e(context, session_info);
    3358            0 :         libspdm_reset_message_encap_e(context, session_info);
    3359            0 :         libspdm_reset_message_encap_d(context, session_info);
    3360            0 :         libspdm_reset_message_k(context, session_info);
    3361            0 :         libspdm_reset_message_f(context, session_info);
    3362              :     }
    3363            0 : }
    3364              : 
    3365              : /**
    3366              :  * Return the size in bytes of the SPDM context. This includes all
    3367              :  * secured message context data as well.
    3368              :  *
    3369              :  * For just the SPDM context size, use libspdm_get_context_size_without_secured_context.
    3370              :  *
    3371              :  * @return the size in bytes of the SPDM context and secured message contexts.
    3372              :  **/
    3373          116 : size_t libspdm_get_context_size(void)
    3374              : {
    3375              :     size_t size;
    3376              : 
    3377          116 :     size = sizeof(libspdm_context_t) +
    3378          116 :            libspdm_secured_message_get_context_size() * LIBSPDM_MAX_SESSION_COUNT;
    3379          116 :     LIBSPDM_ASSERT (size == LIBSPDM_CONTEXT_SIZE_ALL);
    3380          116 :     return size;
    3381              : }
    3382              : 
    3383              : /**
    3384              :  * Return the size in bytes of just the SPDM context, without secured message context.
    3385              :  *
    3386              :  * For the complete context size, use libspdm_get_context_size.
    3387              :  *
    3388              :  * @return the size in bytes of the SPDM context.
    3389              :  **/
    3390            1 : size_t libspdm_get_context_size_without_secured_context(void)
    3391              : {
    3392              :     size_t size;
    3393              : 
    3394            1 :     size = sizeof(libspdm_context_t);
    3395            1 :     LIBSPDM_ASSERT (size == LIBSPDM_CONTEXT_SIZE_WITHOUT_SECURED_CONTEXT);
    3396            1 :     return size;
    3397              : }
    3398              : 
    3399              : /**
    3400              :  * Return the SPDMversion field of the version number struct.
    3401              :  *
    3402              :  * @param  ver                Spdm version number struct.
    3403              :  *
    3404              :  * @return the SPDMversion of the version number struct.
    3405              :  **/
    3406          245 : uint8_t libspdm_get_version_from_version_number(const spdm_version_number_t ver)
    3407              : {
    3408          245 :     return (uint8_t)(ver >> SPDM_VERSION_NUMBER_SHIFT_BIT);
    3409              : }
    3410              : 
    3411              : /**
    3412              :  * Sort SPDMversion in descending order.
    3413              :  *
    3414              :  * @param  spdm_context                A pointer to the SPDM context.
    3415              :  * @param  ver_set                    A pointer to the version set.
    3416              :  * @param  ver_num                    Version number.
    3417              :  */
    3418           60 : void libspdm_version_number_sort(spdm_version_number_t *ver_set, size_t ver_num)
    3419              : {
    3420              :     size_t index;
    3421              :     size_t index_sort;
    3422              :     size_t index_max;
    3423              :     spdm_version_number_t version;
    3424              : 
    3425              :     /* Select sort */
    3426           60 :     if (ver_num > 1) {
    3427          135 :         for (index_sort = 0; index_sort < ver_num; index_sort++) {
    3428          103 :             index_max = index_sort;
    3429          230 :             for (index = index_sort + 1; index < ver_num; index++) {
    3430              :                 /* if ver_ser[index] higher than ver_set[index_max] */
    3431          127 :                 if (ver_set[index] > ver_set[index_max]) {
    3432           74 :                     index_max = index;
    3433              :                 }
    3434              :             }
    3435              :             /* swap ver_ser[index_min] and ver_set[index_sort] */
    3436          103 :             version = ver_set[index_sort];
    3437          103 :             ver_set[index_sort] = ver_set[index_max];
    3438          103 :             ver_set[index_max] = version;
    3439              :         }
    3440              :     }
    3441           60 : }
    3442              : 
    3443              : /**
    3444              :  * Negotiate SPDMversion for connection.
    3445              :  * ver_set is the local version set of requester, res_ver_set is the version set of responder.
    3446              :  *
    3447              :  * @param  common_version             A pointer to store the common version.
    3448              :  * @param  req_ver_set                A pointer to the requester version set.
    3449              :  * @param  req_ver_num                Version number of requester.
    3450              :  * @param  res_ver_set                A pointer to the responder version set.
    3451              :  * @param  res_ver_num                Version number of responder.
    3452              :  *
    3453              :  * @retval true                       Negotiation successfully, connect version be saved to common_version.
    3454              :  * @retval false                      Negotiation failed.
    3455              :  */
    3456           30 : bool libspdm_negotiate_connection_version(spdm_version_number_t *common_version,
    3457              :                                           spdm_version_number_t *req_ver_set,
    3458              :                                           size_t req_ver_num,
    3459              :                                           const spdm_version_number_t *res_ver_set,
    3460              :                                           size_t res_ver_num)
    3461              : {
    3462              :     spdm_version_number_t req_version_list[LIBSPDM_MAX_VERSION_COUNT];
    3463              :     spdm_version_number_t res_version_list[LIBSPDM_MAX_VERSION_COUNT];
    3464              :     size_t req_index;
    3465              :     size_t res_index;
    3466              : 
    3467           30 :     if (req_ver_num > LIBSPDM_MAX_VERSION_COUNT || res_ver_num > LIBSPDM_MAX_VERSION_COUNT) {
    3468            0 :         return false;
    3469              :     }
    3470              : 
    3471           30 :     if (req_ver_set == NULL || req_ver_num == 0 || res_ver_set == NULL || res_ver_num == 0) {
    3472            0 :         return false;
    3473              :     }
    3474              : 
    3475           30 :     libspdm_zero_mem(req_version_list, sizeof(spdm_version_number_t) * LIBSPDM_MAX_VERSION_COUNT);
    3476           30 :     libspdm_zero_mem(res_version_list, sizeof(spdm_version_number_t) * LIBSPDM_MAX_VERSION_COUNT);
    3477              : 
    3478           30 :     libspdm_copy_mem(req_version_list, sizeof(spdm_version_number_t) * LIBSPDM_MAX_VERSION_COUNT,
    3479              :                      req_ver_set, sizeof(spdm_version_number_t) * req_ver_num);
    3480           30 :     libspdm_copy_mem(res_version_list, sizeof(spdm_version_number_t) * LIBSPDM_MAX_VERSION_COUNT,
    3481              :                      res_ver_set, sizeof(spdm_version_number_t) * res_ver_num);
    3482              : 
    3483              :     /* Sort SPDMversion in descending order. */
    3484           30 :     libspdm_version_number_sort(req_version_list, req_ver_num);
    3485           30 :     libspdm_version_number_sort(res_version_list, res_ver_num);
    3486              : 
    3487              :     /**
    3488              :      * Find highest same version and make req_index point to it.
    3489              :      * If not found, return false.
    3490              :      **/
    3491           35 :     for (res_index = 0; res_index < res_ver_num; res_index++) {
    3492           67 :         for (req_index = 0; req_index < req_ver_num; req_index++) {
    3493          124 :             if (libspdm_get_version_from_version_number(req_version_list[req_index]) ==
    3494           62 :                 libspdm_get_version_from_version_number(res_version_list[res_index])) {
    3495           29 :                 *common_version = req_version_list[req_index];
    3496           29 :                 return true;
    3497              :             }
    3498              :         }
    3499              :     }
    3500            1 :     return false;
    3501              : }
    3502              : 
    3503              : #if LIBSPDM_EVENT_RECIPIENT_SUPPORT
    3504           20 : void libspdm_register_event_callback(void *context,
    3505              :                                      libspdm_process_event_func process_event_func)
    3506              : {
    3507              :     libspdm_context_t *spdm_context;
    3508              : 
    3509           20 :     spdm_context = context;
    3510           20 :     spdm_context->process_event = process_event_func;
    3511           20 : }
    3512              : #endif /* LIBSPDM_EVENT_RECIPIENT_SUPPORT */
        

Generated by: LCOV version 2.0-1