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

Generated by: LCOV version 2.0-1