LCOV - code coverage report
Current view: top level - spdm_common_lib - libspdm_com_context_data_session.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 82.4 % 148 122
Test Date: 2026-10-01 20:56:25 Functions: 90.9 % 11 10
Branches: 79.5 % 78 62

             Branch data     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_secured_message_lib.h"
       8                 :             : 
       9                 :        1270 : void libspdm_session_info_init(libspdm_context_t *spdm_context,
      10                 :             :                                libspdm_session_info_t *session_info,
      11                 :             :                                uint32_t session_id, spdm_version_number_t secured_message_version,
      12                 :             :                                bool use_psk)
      13                 :             : {
      14                 :             :     libspdm_session_type_t session_type;
      15                 :             :     uint32_t capabilities_flag;
      16                 :             : 
      17         [ +  + ]:        1270 :     if (session_id != INVALID_SESSION_ID) {
      18         [ +  + ]:         639 :         if (use_psk) {
      19   [ +  +  -  + ]:         454 :             LIBSPDM_ASSERT((spdm_context->max_psk_session_count == 0) ||
      20                 :             :                            (spdm_context->current_psk_session_count <
      21                 :             :                             spdm_context->max_psk_session_count));
      22                 :         454 :             spdm_context->current_psk_session_count++;
      23                 :             :         } else {
      24   [ +  +  -  + ]:         185 :             LIBSPDM_ASSERT((spdm_context->max_dhe_session_count == 0) ||
      25                 :             :                            (spdm_context->current_dhe_session_count <
      26                 :             :                             spdm_context->max_dhe_session_count));
      27                 :         185 :             spdm_context->current_dhe_session_count++;
      28                 :             :         }
      29                 :             :     } else {
      30         [ +  + ]:         631 :         if (use_psk) {
      31         [ +  - ]:          75 :             if (spdm_context->current_psk_session_count > 0) {
      32                 :          75 :                 spdm_context->current_psk_session_count--;
      33                 :             :             }
      34                 :             :         } else {
      35         [ +  + ]:         556 :             if (spdm_context->current_dhe_session_count > 0) {
      36                 :         116 :                 spdm_context->current_dhe_session_count--;
      37                 :             :             }
      38                 :             :         }
      39                 :             :     }
      40                 :             : 
      41                 :        1270 :     capabilities_flag = spdm_context->connection_info.capability.flags &
      42                 :        1270 :                         spdm_context->local_context.capability.flags;
      43   [ +  +  +  - ]:        1270 :     switch (capabilities_flag &
      44                 :             :             (SPDM_GET_CAPABILITIES_REQUEST_FLAGS_ENCRYPT_CAP |
      45                 :             :              SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MAC_CAP)) {
      46                 :         567 :     case 0:
      47                 :         567 :         session_type = LIBSPDM_SESSION_TYPE_NONE;
      48                 :         567 :         break;
      49                 :         503 :     case (SPDM_GET_CAPABILITIES_REQUEST_FLAGS_ENCRYPT_CAP |
      50                 :             :           SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MAC_CAP):
      51                 :         503 :         session_type = LIBSPDM_SESSION_TYPE_ENC_MAC;
      52                 :         503 :         break;
      53                 :         200 :     case SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MAC_CAP:
      54                 :         200 :         session_type = LIBSPDM_SESSION_TYPE_MAC_ONLY;
      55                 :         200 :         break;
      56                 :           0 :     default:
      57                 :           0 :         LIBSPDM_ASSERT(false);
      58                 :           0 :         session_type = LIBSPDM_SESSION_TYPE_MAX;
      59                 :           0 :         break;
      60                 :             :     }
      61                 :             : 
      62                 :             : #if !(LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT)
      63         [ +  + ]:        1270 :     if (session_info->session_transcript.digest_context_th != NULL) {
      64                 :         162 :         libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
      65                 :             :                            session_info->session_transcript.digest_context_th);
      66                 :         162 :         session_info->session_transcript.digest_context_th = NULL;
      67                 :             :     }
      68         [ +  + ]:        1270 :     if (session_info->session_transcript.digest_context_th_backup != NULL) {
      69                 :          76 :         libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
      70                 :             :                            session_info->session_transcript.digest_context_th_backup);
      71                 :          76 :         session_info->session_transcript.digest_context_th_backup = NULL;
      72                 :             :     }
      73         [ -  + ]:        1270 :     if (session_info->session_transcript.digest_context_l1l2 != NULL) {
      74                 :           0 :         libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
      75                 :             :                            session_info->session_transcript.digest_context_l1l2);
      76                 :           0 :         session_info->session_transcript.digest_context_l1l2 = NULL;
      77                 :             :     }
      78         [ -  + ]:        1270 :     if (session_info->session_transcript.digest_context_il1il2 != NULL) {
      79                 :           0 :         libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
      80                 :             :                            session_info->session_transcript.digest_context_il1il2);
      81                 :           0 :         session_info->session_transcript.digest_context_il1il2 = NULL;
      82                 :             :     }
      83         [ +  + ]:        1270 :     if (session_info->session_transcript.digest_context_encap_il1il2 != NULL) {
      84                 :           1 :         libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
      85                 :             :                            session_info->session_transcript.digest_context_encap_il1il2);
      86                 :           1 :         session_info->session_transcript.digest_context_encap_il1il2 = NULL;
      87                 :             :     }
      88                 :             : #endif
      89                 :             : 
      90                 :        1270 :     libspdm_zero_mem (&(session_info->last_key_update_request), sizeof(spdm_key_update_request_t));
      91                 :        1270 :     libspdm_zero_mem(session_info, offsetof(libspdm_session_info_t, secured_message_context));
      92                 :             :     /* The fields below follow secured_message_context, so they are not covered by the zeroing
      93                 :             :      * above and would otherwise retain values from a previous use of this session slot. */
      94                 :        1270 :     session_info->local_used_cert_chain_slot_id = 0;
      95                 :        1270 :     session_info->peer_used_cert_chain_slot_id = 0;
      96                 :             : #if LIBSPDM_ENABLE_CAPABILITY_ENCAP_CAP
      97                 :        1270 :     libspdm_zero_mem(&session_info->encap_context, sizeof(libspdm_encap_context_t));
      98                 :             : #endif /* LIBSPDM_ENABLE_CAPABILITY_ENCAP_CAP */
      99                 :        1270 :     libspdm_secured_message_init_context(session_info->secured_message_context);
     100                 :        1270 :     session_info->session_id = session_id;
     101                 :        1270 :     session_info->use_psk = use_psk;
     102                 :        1270 :     libspdm_secured_message_set_use_psk(session_info->secured_message_context, use_psk);
     103                 :        1270 :     libspdm_secured_message_set_session_type(session_info->secured_message_context, session_type);
     104                 :             : 
     105                 :             :     /* DSP0277 1.2 explicitly specifies a little-endian sequence number. 1.0 and 1.1 leave it up to
     106                 :             :      * the Integrator to specify. */
     107         [ +  + ]:        1270 :     if ((secured_message_version >> SPDM_VERSION_NUMBER_SHIFT_BIT) >= SECURED_SPDM_VERSION_12) {
     108                 :          21 :         libspdm_secured_message_set_sequence_number_endian(
     109                 :             :             session_info->secured_message_context,
     110                 :             :             LIBSPDM_DATA_SESSION_SEQ_NUM_ENC_LITTLE_DEC_LITTLE);
     111                 :             :     } else {
     112                 :        1249 :         libspdm_secured_message_set_sequence_number_endian(session_info->secured_message_context,
     113                 :        1249 :                                                            spdm_context->sequence_number_endian);
     114                 :             :     }
     115                 :             : 
     116                 :        1270 :     libspdm_secured_message_set_max_spdm_session_sequence_number(
     117                 :             :         session_info->secured_message_context, spdm_context->max_spdm_session_sequence_number);
     118                 :        1270 :     libspdm_secured_message_set_algorithms(
     119                 :             :         session_info->secured_message_context,
     120                 :        1270 :         spdm_context->connection_info.version,
     121                 :             :         secured_message_version,
     122                 :             :         spdm_context->connection_info.algorithm.base_hash_algo,
     123                 :        1270 :         spdm_context->connection_info.algorithm.dhe_named_group,
     124                 :             :         spdm_context->connection_info.algorithm.kem_alg,
     125                 :        1270 :         spdm_context->connection_info.algorithm.aead_cipher_suite,
     126                 :        1270 :         spdm_context->connection_info.algorithm.key_schedule);
     127                 :        1270 :     session_info->session_transcript.message_encap_d.max_buffer_size =
     128                 :             :         sizeof(session_info->session_transcript.message_encap_d.buffer);
     129                 :             : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
     130                 :             :     session_info->session_transcript.message_k.max_buffer_size =
     131                 :             :         sizeof(session_info->session_transcript.message_k.buffer);
     132                 :             :     session_info->session_transcript.message_f.max_buffer_size =
     133                 :             :         sizeof(session_info->session_transcript.message_f.buffer);
     134                 :             :     session_info->session_transcript.message_m.max_buffer_size =
     135                 :             :         sizeof(session_info->session_transcript.message_m.buffer);
     136                 :             :     session_info->session_transcript.message_e.max_buffer_size =
     137                 :             :         sizeof(session_info->session_transcript.message_e.buffer);
     138                 :             :     session_info->session_transcript.message_encap_e.max_buffer_size =
     139                 :             :         sizeof(session_info->session_transcript.message_encap_e.buffer);
     140                 :             : #endif
     141                 :        1270 : }
     142                 :             : 
     143                 :             : #if LIBSPDM_ENABLE_CAPABILITY_PSK_CAP
     144                 :          94 : void libspdm_session_info_set_psk_hint(libspdm_session_info_t *session_info,
     145                 :             :                                        const void *psk_hint,
     146                 :             :                                        size_t psk_hint_size)
     147                 :             : {
     148                 :          94 :     libspdm_secured_message_set_psk_hint(
     149                 :             :         session_info->secured_message_context,
     150                 :             :         psk_hint,
     151                 :             :         psk_hint_size);
     152                 :          94 : }
     153                 :             : #endif /* LIBSPDM_ENABLE_CAPABILITY_PSK_CAP */
     154                 :             : 
     155                 :        2179 : void *libspdm_get_session_info_via_session_id(void *spdm_context, uint32_t session_id)
     156                 :             : {
     157                 :             :     libspdm_context_t *context;
     158                 :             :     libspdm_session_info_t *session_info;
     159                 :             :     size_t index;
     160                 :             : 
     161         [ +  + ]:        2179 :     if (session_id == INVALID_SESSION_ID) {
     162                 :           1 :         LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR,
     163                 :             :                        "libspdm_get_session_info_via_session_id - Invalid session_id\n"));
     164                 :           1 :         return NULL;
     165                 :             :     }
     166                 :             : 
     167                 :        2178 :     context = spdm_context;
     168                 :             : 
     169                 :        2178 :     session_info = (libspdm_session_info_t *)context->session_info;
     170         [ +  + ]:        2235 :     for (index = 0; index < LIBSPDM_MAX_SESSION_COUNT; index++) {
     171         [ +  + ]:        2223 :         if (session_info[index].session_id == session_id) {
     172                 :        2166 :             return &session_info[index];
     173                 :             :         }
     174                 :             :     }
     175                 :             : 
     176                 :          12 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR,
     177                 :             :                    "libspdm_get_session_info_via_session_id - not found session_id\n"));
     178                 :          12 :     return NULL;
     179                 :             : }
     180                 :             : 
     181                 :             : #if LIBSPDM_ENABLE_CAPABILITY_ENCAP_CAP
     182                 :         271 : libspdm_encap_context_t *libspdm_get_encap_context(libspdm_context_t *spdm_context,
     183                 :             :                                                    const uint32_t *session_id)
     184                 :             : {
     185                 :             :     libspdm_session_info_t *session_info;
     186                 :             : 
     187         [ +  + ]:         271 :     if (session_id == NULL) {
     188                 :         194 :         return &spdm_context->encap_context;
     189                 :             :     }
     190                 :             : 
     191                 :          77 :     session_info = libspdm_get_session_info_via_session_id(spdm_context, *session_id);
     192         [ +  + ]:          77 :     if (session_info == NULL) {
     193                 :           4 :         return NULL;
     194                 :             :     }
     195                 :             : 
     196                 :          73 :     return &session_info->encap_context;
     197                 :             : }
     198                 :             : 
     199                 :         283 : const uint32_t *libspdm_get_encap_session_id_via_last_request(libspdm_context_t *spdm_context)
     200                 :             : {
     201         [ +  + ]:         283 :     if (spdm_context->last_spdm_request_session_id_valid) {
     202                 :          57 :         return &spdm_context->last_spdm_request_session_id;
     203                 :             :     }
     204                 :             : 
     205                 :             : #if LIBSPDM_ENABLE_CAPABILITY_MUT_AUTH_CAP
     206                 :             :     /* When both endpoints have set HANDSHAKE_IN_THE_CLEAR_CAP the session-based mutual
     207                 :             :      * authentication flow is conducted outside of a session. The flow is still tracked in the
     208                 :             :      * session's encapsulated context, so resolve it from the session that is handshaking. The
     209                 :             :      * flow type is checked so that this does not capture a general flow that legitimately
     210                 :             :      * runs outside of a session. */
     211   [ +  +  +  + ]:         298 :     if ((spdm_context->latest_session_id != INVALID_SESSION_ID) &&
     212                 :          72 :         libspdm_is_capabilities_flag_supported(
     213                 :             :             spdm_context, false,
     214                 :             :             SPDM_GET_CAPABILITIES_REQUEST_FLAGS_HANDSHAKE_IN_THE_CLEAR_CAP,
     215                 :             :             SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_HANDSHAKE_IN_THE_CLEAR_CAP)) {
     216                 :             :         libspdm_session_info_t *session_info;
     217                 :             : 
     218                 :          12 :         session_info = libspdm_get_session_info_via_session_id(spdm_context,
     219                 :             :                                                                spdm_context->latest_session_id);
     220         [ +  - ]:          12 :         if ((session_info != NULL) &&
     221         [ +  - ]:          12 :             (session_info->encap_context.flow_type == LIBSPDM_ENCAP_FLOW_SESS_MUT_AUTH)) {
     222                 :          12 :             return &spdm_context->latest_session_id;
     223                 :             :         }
     224                 :             :     }
     225                 :             : #endif /* LIBSPDM_ENABLE_CAPABILITY_MUT_AUTH_CAP */
     226                 :             : 
     227                 :         214 :     return NULL;
     228                 :             : }
     229                 :             : 
     230                 :         196 : libspdm_encap_context_t *libspdm_get_encap_context_via_last_request(libspdm_context_t *spdm_context)
     231                 :             : {
     232                 :             :     libspdm_encap_context_t *encap_context;
     233                 :             : 
     234                 :         196 :     encap_context = libspdm_get_encap_context(
     235                 :             :         spdm_context, libspdm_get_encap_session_id_via_last_request(spdm_context));
     236                 :             : 
     237                 :             :     /* The session that the request arrived on is necessarily valid. */
     238         [ -  + ]:         196 :     LIBSPDM_ASSERT(encap_context != NULL);
     239                 :             : 
     240                 :         196 :     return encap_context;
     241                 :             : }
     242                 :             : #endif /* LIBSPDM_ENABLE_CAPABILITY_ENCAP_CAP */
     243                 :             : 
     244                 :        1003 : void *libspdm_get_secured_message_context_via_session_id(void *spdm_context, uint32_t session_id)
     245                 :             : {
     246                 :             :     libspdm_session_info_t *session_info;
     247                 :             : 
     248                 :        1003 :     session_info = libspdm_get_session_info_via_session_id(spdm_context, session_id);
     249         [ +  + ]:        1003 :     if (session_info == NULL) {
     250                 :           1 :         return NULL;
     251                 :             :     } else {
     252                 :        1002 :         return session_info->secured_message_context;
     253                 :             :     }
     254                 :             : }
     255                 :             : 
     256                 :           0 : void *libspdm_get_secured_message_context_via_session_info(void *spdm_session_info)
     257                 :             : {
     258                 :             :     libspdm_session_info_t *session_info;
     259                 :             : 
     260                 :           0 :     session_info = spdm_session_info;
     261         [ #  # ]:           0 :     if (session_info == NULL) {
     262                 :           0 :         return NULL;
     263                 :             :     } else {
     264                 :           0 :         return session_info->secured_message_context;
     265                 :             :     }
     266                 :             : }
     267                 :             : 
     268                 :         123 : uint32_t libspdm_generate_session_id(uint16_t req_session_id, uint16_t rsp_session_id)
     269                 :             : {
     270                 :             :     uint32_t session_id;
     271                 :         123 :     session_id = ((uint32_t)rsp_session_id << 16) | req_session_id;
     272                 :         123 :     return session_id;
     273                 :             : }
     274                 :             : 
     275                 :         123 : libspdm_session_info_t *libspdm_assign_session_id(libspdm_context_t *spdm_context,
     276                 :             :                                                   uint32_t session_id,
     277                 :             :                                                   spdm_version_number_t secured_message_version,
     278                 :             :                                                   bool use_psk)
     279                 :             : {
     280                 :             :     libspdm_session_info_t *session_info;
     281                 :             :     size_t index;
     282                 :             : 
     283         [ -  + ]:         123 :     if (session_id == INVALID_SESSION_ID) {
     284                 :           0 :         LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR, "libspdm_assign_session_id - Invalid session_id\n"));
     285                 :           0 :         LIBSPDM_ASSERT(false);
     286                 :           0 :         return NULL;
     287                 :             :     }
     288                 :             : 
     289                 :         123 :     session_info = spdm_context->session_info;
     290                 :             : 
     291         [ +  + ]:         615 :     for (index = 0; index < LIBSPDM_MAX_SESSION_COUNT; index++) {
     292         [ -  + ]:         492 :         if (session_info[index].session_id == session_id) {
     293                 :           0 :             LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR,
     294                 :             :                            "libspdm_assign_session_id - Duplicated session_id\n"));
     295                 :           0 :             LIBSPDM_ASSERT(false);
     296                 :           0 :             return NULL;
     297                 :             :         }
     298                 :             :     }
     299                 :             : 
     300         [ +  - ]:         179 :     for (index = 0; index < LIBSPDM_MAX_SESSION_COUNT; index++) {
     301         [ +  + ]:         179 :         if (session_info[index].session_id == INVALID_SESSION_ID) {
     302                 :         123 :             libspdm_session_info_init(spdm_context,
     303                 :         123 :                                       &session_info[index], session_id, secured_message_version,
     304                 :             :                                       use_psk);
     305                 :         123 :             spdm_context->latest_session_id = session_id;
     306                 :         123 :             return &session_info[index];
     307                 :             :         }
     308                 :             :     }
     309                 :             : 
     310                 :           0 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR, "libspdm_assign_session_id - MAX session_id\n"));
     311                 :           0 :     return NULL;
     312                 :             : }
     313                 :             : 
     314                 :         166 : void libspdm_free_session_id(libspdm_context_t *spdm_context, uint32_t session_id)
     315                 :             : {
     316                 :             :     libspdm_session_info_t *session_info;
     317                 :             :     size_t index;
     318                 :             : 
     319         [ -  + ]:         166 :     if (session_id == INVALID_SESSION_ID) {
     320                 :           0 :         LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR, "libspdm_free_session_id - Invalid session_id\n"));
     321                 :           0 :         LIBSPDM_ASSERT(false);
     322                 :           0 :         return;
     323                 :             :     }
     324                 :             : 
     325         [ +  + ]:         166 :     if (spdm_context->latest_session_id == session_id) {
     326                 :          78 :         spdm_context->latest_session_id = INVALID_SESSION_ID;
     327                 :             :     }
     328                 :             : 
     329                 :         166 :     session_info = spdm_context->session_info;
     330         [ +  - ]:         187 :     for (index = 0; index < LIBSPDM_MAX_SESSION_COUNT; index++) {
     331         [ +  + ]:         187 :         if (session_info[index].session_id == session_id) {
     332                 :         166 :             libspdm_session_info_init(spdm_context,
     333                 :         166 :                                       &session_info[index],
     334                 :             :                                       INVALID_SESSION_ID, 0,
     335                 :         166 :                                       session_info[index].use_psk);
     336                 :         166 :             return;
     337                 :             :         }
     338                 :             :     }
     339                 :             : 
     340                 :           0 :     LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR, "libspdm_free_session_id - MAX session_id\n"));
     341                 :           0 :     LIBSPDM_ASSERT(false);
     342                 :             : }
        

Generated by: LCOV version 2.0-1