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.9 % 1681 754
Test Date: 2026-09-13 08:13:44 Functions: 84.6 % 78 66

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

Generated by: LCOV version 2.0-1