Code coverage report for DMTF/libspdm
Current view: top level - library/spdm_requester_lib - libspdm_req_encap_request.c (source / functions) Coverage Total Hit
Test: 36148b912f76d231c18d216d6dee5c0858575bb1 Lines: 94.9 % 234 222
Test Date: 2026-10-25 08:40:22 Functions: 100.0 % 5 5
Branches: 90.8 % 98 89

             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_requester_lib.h"
       8                 :             : 
       9                 :             : #if LIBSPDM_ENABLE_CAPABILITY_ENCAP_CAP
      10                 :             : 
      11                 :          90 : void libspdm_register_get_encap_response_func(void *spdm_context,
      12                 :             :                                               const libspdm_get_encap_response_func
      13                 :             :                                               get_encap_response_func)
      14                 :             : {
      15                 :             :     libspdm_context_t *context;
      16                 :             : 
      17                 :          90 :     context = spdm_context;
      18                 :          90 :     context->get_encap_response_func = (void *)get_encap_response_func;
      19                 :          90 : }
      20                 :             : 
      21                 :             : /**
      22                 :             :  * Return the GET_ENCAP_RESPONSE function via request code.
      23                 :             :  *
      24                 :             :  * @param  request_response_code         The SPDM request code.
      25                 :             :  *
      26                 :             :  * @return GET_ENCAP_RESPONSE function according to the request code.
      27                 :             :  **/
      28                 :             : static libspdm_get_encap_response_func
      29                 :          54 : libspdm_get_encap_response_func_via_request_code(uint8_t request_response_code)
      30                 :             : {
      31                 :             :     typedef struct {
      32                 :             :         uint8_t request_response_code;
      33                 :             :         libspdm_get_encap_response_func get_encap_response_func;
      34                 :             :     } libspdm_get_encap_response_struct_t;
      35                 :             : 
      36                 :             :     size_t index;
      37                 :             : 
      38                 :          54 :     const libspdm_get_encap_response_struct_t get_encap_response_struct[] = {
      39                 :             :         #if LIBSPDM_ENABLE_CAPABILITY_CERT_CAP
      40                 :             :         { SPDM_GET_DIGESTS, libspdm_get_encap_response_digest },
      41                 :             :         { SPDM_GET_CERTIFICATE, libspdm_get_encap_response_certificate },
      42                 :             :         #endif /* LIBSPDM_ENABLE_CAPABILITY_CERT_CAP */
      43                 :             : 
      44                 :             :         #if LIBSPDM_ENABLE_CAPABILITY_MUT_AUTH_CAP
      45                 :             :         #if LIBSPDM_ENABLE_CAPABILITY_CHAL_CAP
      46                 :             :         { SPDM_CHALLENGE, libspdm_get_encap_response_challenge_auth },
      47                 :             :         #endif /* LIBSPDM_ENABLE_CAPABILITY_CHAL_CAP */
      48                 :             :         #endif /* LIBSPDM_ENABLE_CAPABILITY_MUT_AUTH_CAP */
      49                 :             : 
      50                 :             :         #if ((LIBSPDM_ENABLE_CAPABILITY_KEY_EX_CAP) || (LIBSPDM_ENABLE_CAPABILITY_PSK_CAP))
      51                 :             :         { SPDM_KEY_UPDATE, libspdm_get_encap_response_key_update },
      52                 :             :         #endif /* ((LIBSPDM_ENABLE_CAPABILITY_KEY_EX_CAP) || (LIBSPDM_ENABLE_CAPABILITY_PSK_CAP)) */
      53                 :             : 
      54                 :             :         #if LIBSPDM_EVENT_RECIPIENT_SUPPORT
      55                 :             :         { SPDM_SEND_EVENT, libspdm_get_encap_response_event_ack },
      56                 :             :         #endif /* LIBSPDM_EVENT_RECIPIENT_SUPPORT */
      57                 :             : 
      58                 :             :         #if LIBSPDM_ENABLE_CAPABILITY_EVENT_CAP
      59                 :             :         { SPDM_GET_SUPPORTED_EVENT_TYPES, libspdm_get_encap_supported_event_types },
      60                 :             :         { SPDM_SUBSCRIBE_EVENT_TYPES, libspdm_get_encap_subscribe_event_types_ack },
      61                 :             :         #endif /* LIBSPDM_ENABLE_CAPABILITY_EVENT_CAP */
      62                 :             : 
      63                 :             :         #if LIBSPDM_ENABLE_CAPABILITY_ENDPOINT_INFO_CAP
      64                 :             :         { SPDM_GET_ENDPOINT_INFO, libspdm_get_encap_response_endpoint_info },
      65                 :             :         #endif /* LIBSPDM_ENABLE_CAPABILITY_ENDPOINT_INFO_CAP */
      66                 :             :     };
      67                 :             : 
      68         [ +  + ]:         348 :     for (index = 0; index < LIBSPDM_ARRAY_SIZE(get_encap_response_struct); index++) {
      69         [ +  + ]:         314 :         if (request_response_code == get_encap_response_struct[index].request_response_code) {
      70                 :          20 :             return get_encap_response_struct[index].get_encap_response_func;
      71                 :             :         }
      72                 :             :     }
      73                 :          34 :     return NULL;
      74                 :             : }
      75                 :             : 
      76                 :             : /**
      77                 :             :  * This function processes encapsulated request.
      78                 :             :  *
      79                 :             :  * @param  spdm_context         A pointer to the SPDM context.
      80                 :             :  * @param  encap_request_size   Size, in bytes, of the request data buffer.
      81                 :             :  * @param  encap_request        A pointer to a destination buffer to store the request.
      82                 :             :  * @param  encap_response_size  Size, in bytes, of the response data buffer.
      83                 :             :  * @param  encap_response       A pointer to a destination buffer to store the response.
      84                 :             :  **/
      85                 :          54 : static libspdm_return_t libspdm_process_encapsulated_request(libspdm_context_t *spdm_context,
      86                 :             :                                                              libspdm_session_info_t *session_info,
      87                 :             :                                                              size_t encap_request_size,
      88                 :             :                                                              void *encap_request,
      89                 :             :                                                              size_t *encap_response_size,
      90                 :             :                                                              void *encap_response)
      91                 :             : {
      92                 :             :     libspdm_get_encap_response_func get_encap_response_func;
      93                 :             :     spdm_message_header_t *spdm_requester;
      94                 :             : 
      95                 :          54 :     spdm_requester = encap_request;
      96         [ -  + ]:          54 :     if (encap_request_size < sizeof(spdm_message_header_t)) {
      97                 :           0 :         return libspdm_generate_encap_error_response(
      98                 :             :             spdm_context, SPDM_ERROR_CODE_UNSUPPORTED_REQUEST,
      99                 :           0 :             spdm_requester->request_response_code,
     100                 :             :             encap_response_size, encap_response);
     101                 :             :     }
     102                 :             : 
     103                 :          54 :     libspdm_reset_message_buffer_via_encap_request_code(
     104                 :          54 :         spdm_context, session_info, spdm_requester->request_response_code);
     105                 :             : 
     106                 :          54 :     get_encap_response_func = libspdm_get_encap_response_func_via_request_code(
     107                 :          54 :         spdm_requester->request_response_code);
     108         [ +  + ]:          54 :     if (get_encap_response_func == NULL) {
     109                 :          34 :         get_encap_response_func =
     110                 :          34 :             (libspdm_get_encap_response_func)spdm_context->get_encap_response_func;
     111                 :             :     }
     112         [ +  + ]:          54 :     if (get_encap_response_func != NULL) {
     113                 :          26 :         return get_encap_response_func(
     114                 :             :             spdm_context, encap_request_size, encap_request,
     115                 :             :             encap_response_size, encap_response);
     116                 :             :     } else {
     117                 :          28 :         return libspdm_generate_encap_error_response(
     118                 :             :             spdm_context, SPDM_ERROR_CODE_UNEXPECTED_REQUEST,
     119                 :             :             0, encap_response_size, encap_response);
     120                 :             :     }
     121                 :             : }
     122                 :             : 
     123                 :          80 : libspdm_return_t libspdm_encapsulated_request(libspdm_context_t *spdm_context,
     124                 :             :                                               const uint32_t *session_id,
     125                 :             :                                               uint8_t mut_auth_requested,
     126                 :             :                                               uint8_t *req_slot_id_param)
     127                 :             : {
     128                 :             :     libspdm_return_t status;
     129                 :             :     uint8_t *spdm_request;
     130                 :             :     size_t spdm_request_size;
     131                 :             :     spdm_get_encapsulated_request_request_t
     132                 :             :     *spdm_get_encapsulated_request_request;
     133                 :             :     spdm_deliver_encapsulated_response_request_t
     134                 :             :     *spdm_deliver_encapsulated_response_request;
     135                 :             :     uint8_t *spdm_response;
     136                 :             :     size_t spdm_response_size;
     137                 :             :     spdm_encapsulated_request_response_t *libspdm_encapsulated_request_response;
     138                 :             :     spdm_encapsulated_response_ack_response_t
     139                 :             :     *spdm_encapsulated_response_ack_response;
     140                 :             :     libspdm_session_info_t *session_info;
     141                 :             :     uint8_t request_id;
     142                 :             :     void *encapsulated_request;
     143                 :             :     size_t encapsulated_request_size;
     144                 :             :     void *encapsulated_response;
     145                 :             :     size_t encapsulated_response_size;
     146                 :             :     size_t ack_header_size;
     147                 :             : 
     148                 :             :     uint8_t *message;
     149                 :             :     size_t message_size;
     150                 :             :     size_t transport_header_size;
     151                 :             : 
     152                 :             :     #if LIBSPDM_ENABLE_CAPABILITY_CERT_CAP
     153                 :             :     spdm_get_digest_request_t *get_digests;
     154                 :             :     #endif /* LIBSPDM_ENABLE_CAPABILITY_CERT_CAP */
     155                 :             : 
     156         [ +  + ]:          80 :     if (!libspdm_is_encap_supported(spdm_context)) {
     157                 :           2 :         return LIBSPDM_STATUS_UNSUPPORTED_CAP;
     158                 :             :     }
     159                 :             : 
     160         [ +  + ]:          78 :     if (session_id != NULL) {
     161                 :          10 :         session_info = libspdm_get_session_info_via_session_id(spdm_context, *session_id);
     162         [ -  + ]:          10 :         if (session_info == NULL) {
     163                 :           0 :             LIBSPDM_ASSERT(false);
     164                 :           0 :             return LIBSPDM_STATUS_INVALID_STATE_LOCAL;
     165                 :             :         }
     166                 :          10 :         LIBSPDM_ASSERT((mut_auth_requested == 0) ||
     167                 :             :                        (mut_auth_requested ==
     168                 :             :                         SPDM_KEY_EXCHANGE_RESPONSE_MUT_AUTH_REQUESTED_WITH_ENCAP_REQUEST) ||
     169                 :             :                        (mut_auth_requested ==
     170                 :             :                         SPDM_KEY_EXCHANGE_RESPONSE_MUT_AUTH_REQUESTED_WITH_GET_DIGESTS));
     171                 :             :     } else {
     172                 :          68 :         session_info = NULL;
     173                 :          68 :         LIBSPDM_ASSERT(mut_auth_requested == 0);
     174                 :             :     }
     175                 :             : 
     176                 :             : 
     177                 :             :     /* Cache */
     178                 :          78 :     libspdm_reset_message_mut_b(spdm_context);
     179                 :          78 :     libspdm_reset_message_mut_c(spdm_context);
     180                 :             : 
     181         [ +  + ]:          78 :     if (session_id == NULL) {
     182                 :          68 :         spdm_context->last_spdm_request_session_id_valid = false;
     183                 :          68 :         spdm_context->last_spdm_request_session_id = 0;
     184                 :             :     } else {
     185                 :          10 :         spdm_context->last_spdm_request_session_id_valid = true;
     186                 :          10 :         spdm_context->last_spdm_request_session_id = *session_id;
     187                 :             :     }
     188                 :             : 
     189         [ +  + ]:          78 :     if (mut_auth_requested == SPDM_KEY_EXCHANGE_RESPONSE_MUT_AUTH_REQUESTED_WITH_GET_DIGESTS) {
     190                 :             : #if LIBSPDM_ENABLE_CAPABILITY_CERT_CAP
     191                 :           2 :         get_digests = (void *)spdm_context->last_spdm_request;
     192                 :           2 :         get_digests->header.spdm_version = libspdm_get_connection_version (spdm_context);
     193                 :           2 :         get_digests->header.request_response_code = SPDM_GET_DIGESTS;
     194                 :           2 :         get_digests->header.param1 = 0;
     195                 :           2 :         get_digests->header.param2 = 0;
     196                 :           2 :         spdm_context->last_spdm_request_size = sizeof(spdm_get_digest_request_t);
     197                 :           2 :         encapsulated_request = (void *)spdm_context->last_spdm_request;
     198                 :           2 :         encapsulated_request_size = spdm_context->last_spdm_request_size;
     199                 :           2 :         request_id = 0;
     200                 :             : #else /* LIBSPDM_ENABLE_CAPABILITY_CERT_CAP */
     201                 :             :         return LIBSPDM_STATUS_UNSUPPORTED_CAP;
     202                 :             : #endif /* LIBSPDM_ENABLE_CAPABILITY_CERT_CAP */
     203                 :             :     } else {
     204                 :          76 :         transport_header_size = spdm_context->local_context.capability.transport_header_size;
     205                 :          76 :         status = libspdm_acquire_sender_buffer (spdm_context, &message_size, (void **)&message);
     206         [ +  + ]:          76 :         if (LIBSPDM_STATUS_IS_ERROR(status)) {
     207                 :           2 :             return status;
     208                 :             :         }
     209                 :          74 :         LIBSPDM_ASSERT (message_size >= transport_header_size +
     210                 :             :                         spdm_context->local_context.capability.transport_tail_size);
     211                 :          74 :         spdm_request = (void *)(message + transport_header_size);
     212                 :          74 :         spdm_request_size = message_size - transport_header_size -
     213                 :          74 :                             spdm_context->local_context.capability.transport_tail_size;
     214                 :             : 
     215                 :          74 :         spdm_context->crypto_request = true;
     216                 :          74 :         spdm_get_encapsulated_request_request = (void *)spdm_request;
     217                 :          74 :         spdm_get_encapsulated_request_request->header.spdm_version =
     218                 :          74 :             libspdm_get_connection_version (spdm_context);
     219                 :             :         spdm_get_encapsulated_request_request->header
     220                 :          74 :         .request_response_code = SPDM_GET_ENCAPSULATED_REQUEST;
     221                 :          74 :         spdm_get_encapsulated_request_request->header.param1 = 0;
     222                 :          74 :         spdm_get_encapsulated_request_request->header.param2 = 0;
     223                 :          74 :         spdm_request_size = sizeof(spdm_get_encapsulated_request_request_t);
     224                 :          74 :         libspdm_reset_message_buffer_via_request_code
     225                 :             :             (spdm_context, NULL,
     226                 :          74 :             spdm_get_encapsulated_request_request->header.request_response_code);
     227                 :          74 :         status = libspdm_send_spdm_request(spdm_context, session_id, spdm_request_size,
     228                 :             :                                            spdm_request);
     229         [ +  + ]:          74 :         if (LIBSPDM_STATUS_IS_ERROR(status)) {
     230                 :           2 :             libspdm_release_sender_buffer (spdm_context);
     231                 :           2 :             return status;
     232                 :             :         }
     233                 :          72 :         libspdm_release_sender_buffer (spdm_context);
     234                 :          72 :         spdm_get_encapsulated_request_request = (void *)spdm_context->last_spdm_request;
     235                 :             : 
     236                 :             :         /* receive */
     237                 :             : 
     238                 :          72 :         status = libspdm_acquire_receiver_buffer (spdm_context, &message_size, (void **)&message);
     239         [ +  + ]:          72 :         if (LIBSPDM_STATUS_IS_ERROR(status)) {
     240                 :           2 :             return status;
     241                 :             :         }
     242                 :          70 :         LIBSPDM_ASSERT (message_size >= transport_header_size);
     243                 :          70 :         spdm_response = (void *)(message);
     244                 :          70 :         spdm_response_size = message_size;
     245                 :             : 
     246                 :          70 :         status = libspdm_receive_spdm_response(
     247                 :             :             spdm_context, session_id, &spdm_response_size,
     248                 :             :             (void **)&spdm_response);
     249                 :          70 :         libspdm_encapsulated_request_response = (void *)spdm_response;
     250         [ +  + ]:          70 :         if (LIBSPDM_STATUS_IS_ERROR(status)) {
     251                 :           2 :             libspdm_release_receiver_buffer (spdm_context);
     252                 :           2 :             return status;
     253                 :             :         }
     254         [ -  + ]:          68 :         if (spdm_response_size < sizeof(spdm_message_header_t)) {
     255                 :           0 :             libspdm_release_receiver_buffer (spdm_context);
     256                 :           0 :             return LIBSPDM_STATUS_INVALID_MSG_SIZE;
     257                 :             :         }
     258         [ +  + ]:          68 :         if (libspdm_encapsulated_request_response->header.request_response_code == SPDM_ERROR) {
     259                 :           8 :             const uint8_t error_code = libspdm_encapsulated_request_response->header.param1;
     260                 :             : 
     261         [ +  - ]:           8 :             if (mut_auth_requested == 0) {
     262                 :             :                 /* Responder can send NoPendingRequests or UnexpectedRequest if it has no
     263                 :             :                  * encapsulated request for the Requester. */
     264   [ +  +  +  + ]:           8 :                 if ((libspdm_get_connection_version(spdm_context) >= SPDM_MESSAGE_VERSION_13) &&
     265                 :             :                     (error_code == SPDM_ERROR_CODE_NO_PENDING_REQUESTS)) {
     266                 :           2 :                     libspdm_release_receiver_buffer (spdm_context);
     267                 :           2 :                     return LIBSPDM_STATUS_SUCCESS;
     268                 :             :                 }
     269   [ +  +  +  + ]:           6 :                 if ((libspdm_get_connection_version(spdm_context) < SPDM_MESSAGE_VERSION_13) &&
     270                 :             :                     (error_code == SPDM_ERROR_CODE_UNEXPECTED_REQUEST)) {
     271                 :           2 :                     libspdm_release_receiver_buffer (spdm_context);
     272                 :           2 :                     return LIBSPDM_STATUS_SUCCESS;
     273                 :             :                 }
     274                 :             :             }
     275                 :           4 :             status = libspdm_handle_error_response_main(
     276                 :             :                 spdm_context, session_id,
     277                 :             :                 &spdm_response_size, (void **)&spdm_response,
     278                 :             :                 SPDM_GET_ENCAPSULATED_REQUEST, SPDM_ENCAPSULATED_REQUEST);
     279         [ +  + ]:           4 :             if (LIBSPDM_STATUS_IS_ERROR(status)) {
     280                 :           2 :                 libspdm_release_receiver_buffer (spdm_context);
     281                 :           2 :                 return status;
     282                 :             :             }
     283                 :           2 :             libspdm_encapsulated_request_response = (void *)spdm_response;
     284                 :             :         }
     285                 :          62 :         if (libspdm_encapsulated_request_response->header.spdm_version !=
     286         [ +  + ]:          62 :             spdm_get_encapsulated_request_request->header.spdm_version) {
     287                 :           6 :             libspdm_release_receiver_buffer (spdm_context);
     288                 :           6 :             return LIBSPDM_STATUS_INVALID_MSG_FIELD;
     289                 :             :         }
     290                 :             : 
     291         [ +  + ]:          56 :         if (libspdm_encapsulated_request_response->header.request_response_code !=
     292                 :             :             SPDM_ENCAPSULATED_REQUEST) {
     293                 :           2 :             libspdm_release_receiver_buffer (spdm_context);
     294                 :           2 :             return LIBSPDM_STATUS_INVALID_MSG_FIELD;
     295                 :             :         }
     296         [ +  + ]:          54 :         if (spdm_response_size <= sizeof(spdm_encapsulated_request_response_t)) {
     297                 :           2 :             libspdm_release_receiver_buffer (spdm_context);
     298                 :           2 :             return LIBSPDM_STATUS_INVALID_MSG_SIZE;
     299                 :             :         }
     300                 :             : 
     301                 :          52 :         request_id = libspdm_encapsulated_request_response->header.param1;
     302                 :             : 
     303                 :          52 :         encapsulated_request = (void *)(libspdm_encapsulated_request_response + 1);
     304                 :          52 :         encapsulated_request_size =
     305                 :          52 :             spdm_response_size - sizeof(spdm_encapsulated_request_response_t);
     306                 :             : 
     307                 :          52 :         libspdm_copy_mem (spdm_context->last_spdm_request,
     308                 :          52 :                           libspdm_get_scratch_buffer_last_spdm_request_capacity(spdm_context),
     309                 :             :                           encapsulated_request,
     310                 :             :                           encapsulated_request_size);
     311                 :          52 :         spdm_context->last_spdm_request_size = encapsulated_request_size;
     312                 :          52 :         encapsulated_request = (void *)spdm_context->last_spdm_request;
     313                 :             : 
     314                 :          52 :         libspdm_release_receiver_buffer (spdm_context);
     315                 :             :     }
     316                 :             : 
     317                 :             :     while (true) {
     318                 :             :         /* Process request. */
     319                 :          56 :         transport_header_size = spdm_context->local_context.capability.transport_header_size;
     320                 :          56 :         status = libspdm_acquire_sender_buffer (spdm_context, &message_size, (void **)&message);
     321         [ +  + ]:          56 :         if (LIBSPDM_STATUS_IS_ERROR(status)) {
     322                 :           2 :             return status;
     323                 :             :         }
     324                 :          54 :         LIBSPDM_ASSERT (message_size >= transport_header_size +
     325                 :             :                         spdm_context->local_context.capability.transport_tail_size);
     326                 :          54 :         spdm_request = (void *)(message + transport_header_size);
     327                 :          54 :         spdm_request_size = message_size - transport_header_size -
     328                 :          54 :                             spdm_context->local_context.capability.transport_tail_size;
     329                 :             : 
     330                 :          54 :         spdm_context->crypto_request = true;
     331                 :          54 :         spdm_deliver_encapsulated_response_request = (void *)spdm_request;
     332                 :          54 :         spdm_deliver_encapsulated_response_request->header.spdm_version =
     333                 :          54 :             libspdm_get_connection_version (spdm_context);
     334                 :          54 :         spdm_deliver_encapsulated_response_request->header.request_response_code =
     335                 :             :             SPDM_DELIVER_ENCAPSULATED_RESPONSE;
     336                 :          54 :         spdm_deliver_encapsulated_response_request->header.param1 = request_id;
     337                 :          54 :         spdm_deliver_encapsulated_response_request->header.param2 = 0;
     338                 :          54 :         encapsulated_response = (void *)(spdm_deliver_encapsulated_response_request + 1);
     339                 :          54 :         encapsulated_response_size =
     340                 :          54 :             spdm_request_size - sizeof(spdm_deliver_encapsulated_response_request_t);
     341                 :             : 
     342                 :          54 :         status = libspdm_process_encapsulated_request(
     343                 :             :             spdm_context, session_info, encapsulated_request_size,
     344                 :             :             encapsulated_request, &encapsulated_response_size,
     345                 :             :             encapsulated_response);
     346         [ +  + ]:          54 :         if (LIBSPDM_STATUS_IS_ERROR(status)) {
     347                 :           2 :             libspdm_release_sender_buffer (spdm_context);
     348                 :           2 :             return status;
     349                 :             :         }
     350                 :             : 
     351                 :          52 :         spdm_request_size =
     352                 :          52 :             sizeof(spdm_deliver_encapsulated_response_request_t) + encapsulated_response_size;
     353                 :          52 :         status = libspdm_send_spdm_request(
     354                 :             :             spdm_context, session_id, spdm_request_size,
     355                 :             :             spdm_request);
     356         [ +  + ]:          52 :         if (LIBSPDM_STATUS_IS_ERROR(status)) {
     357                 :           2 :             libspdm_release_sender_buffer (spdm_context);
     358                 :           2 :             return status;
     359                 :             :         }
     360                 :          50 :         libspdm_release_sender_buffer (spdm_context);
     361                 :          50 :         spdm_deliver_encapsulated_response_request = (void *)spdm_context->last_spdm_request;
     362                 :             : 
     363                 :             :         /* Receive. */
     364                 :          50 :         status = libspdm_acquire_receiver_buffer (spdm_context, &message_size, (void **)&message);
     365         [ +  + ]:          50 :         if (LIBSPDM_STATUS_IS_ERROR(status)) {
     366                 :           2 :             return status;
     367                 :             :         }
     368                 :          48 :         LIBSPDM_ASSERT (message_size >= transport_header_size);
     369                 :          48 :         spdm_response = (void *)(message);
     370                 :          48 :         spdm_response_size = message_size;
     371                 :             : 
     372                 :          48 :         status = libspdm_receive_spdm_response(
     373                 :             :             spdm_context, session_id, &spdm_response_size,
     374                 :             :             (void **)&spdm_response);
     375                 :          48 :         spdm_encapsulated_response_ack_response = (void *)spdm_response;
     376         [ +  + ]:          48 :         if (LIBSPDM_STATUS_IS_ERROR(status)) {
     377                 :           2 :             libspdm_release_receiver_buffer (spdm_context);
     378                 :           2 :             return status;
     379                 :             :         }
     380         [ -  + ]:          46 :         if (spdm_response_size < sizeof(spdm_message_header_t)) {
     381                 :           0 :             libspdm_release_receiver_buffer (spdm_context);
     382                 :           0 :             return LIBSPDM_STATUS_INVALID_MSG_SIZE;
     383                 :             :         }
     384         [ +  + ]:          46 :         if (spdm_encapsulated_response_ack_response->header.request_response_code == SPDM_ERROR) {
     385                 :           4 :             status = libspdm_handle_error_response_main(
     386                 :             :                 spdm_context, session_id,
     387                 :             :                 &spdm_response_size, (void **)&spdm_response,
     388                 :             :                 SPDM_DELIVER_ENCAPSULATED_RESPONSE,
     389                 :             :                 SPDM_ENCAPSULATED_RESPONSE_ACK);
     390         [ +  + ]:           4 :             if (LIBSPDM_STATUS_IS_ERROR(status)) {
     391                 :           2 :                 libspdm_release_receiver_buffer (spdm_context);
     392                 :           2 :                 return status;
     393                 :             :             }
     394                 :           2 :             spdm_encapsulated_response_ack_response = (void *)spdm_response;
     395         [ +  + ]:          42 :         } else if (spdm_encapsulated_response_ack_response->header.request_response_code !=
     396                 :             :                    SPDM_ENCAPSULATED_RESPONSE_ACK) {
     397                 :           2 :             libspdm_release_receiver_buffer (spdm_context);
     398                 :           2 :             return LIBSPDM_STATUS_INVALID_MSG_FIELD;
     399                 :             :         }
     400                 :          42 :         if (spdm_encapsulated_response_ack_response->header.spdm_version !=
     401         [ +  + ]:          42 :             spdm_deliver_encapsulated_response_request->header.spdm_version) {
     402                 :           2 :             libspdm_release_receiver_buffer (spdm_context);
     403                 :           2 :             return LIBSPDM_STATUS_INVALID_MSG_FIELD;
     404                 :             :         }
     405         [ +  + ]:          40 :         if (spdm_encapsulated_response_ack_response->header.spdm_version >=
     406                 :             :             SPDM_MESSAGE_VERSION_12) {
     407                 :          28 :             ack_header_size = sizeof(spdm_encapsulated_response_ack_response_t);
     408                 :             :         } else {
     409                 :          12 :             ack_header_size = sizeof(spdm_message_header_t);
     410                 :             :         }
     411         [ +  + ]:          40 :         if (spdm_response_size < ack_header_size) {
     412                 :           2 :             libspdm_release_receiver_buffer (spdm_context);
     413                 :           2 :             return LIBSPDM_STATUS_INVALID_MSG_SIZE;
     414                 :             :         }
     415                 :             : 
     416         [ +  + ]:          38 :         if (spdm_encapsulated_response_ack_response->header.spdm_version >=
     417                 :             :             SPDM_MESSAGE_VERSION_12) {
     418                 :          26 :             if (spdm_encapsulated_response_ack_response->ack_request_id !=
     419         [ +  + ]:          26 :                 spdm_deliver_encapsulated_response_request->header.param1) {
     420                 :           2 :                 libspdm_release_receiver_buffer (spdm_context);
     421                 :           2 :                 return LIBSPDM_STATUS_INVALID_MSG_FIELD;
     422                 :             :             }
     423                 :             :         }
     424                 :             : 
     425   [ +  +  +  + ]:          36 :         switch (spdm_encapsulated_response_ack_response->header.param2) {
     426                 :          18 :         case SPDM_ENCAPSULATED_RESPONSE_ACK_RESPONSE_PAYLOAD_TYPE_ABSENT:
     427                 :          18 :             libspdm_release_receiver_buffer (spdm_context);
     428                 :          18 :             return LIBSPDM_STATUS_SUCCESS;
     429                 :           2 :         case SPDM_ENCAPSULATED_RESPONSE_ACK_RESPONSE_PAYLOAD_TYPE_PRESENT:
     430                 :           2 :             break;
     431                 :          14 :         case SPDM_ENCAPSULATED_RESPONSE_ACK_RESPONSE_PAYLOAD_TYPE_REQ_SLOT_NUMBER:
     432         [ +  + ]:          14 :             if (spdm_response_size >= ack_header_size + sizeof(uint8_t)) {
     433   [ +  +  +  - ]:          12 :                 if ((req_slot_id_param != NULL) && (*req_slot_id_param == 0)) {
     434                 :          10 :                     *req_slot_id_param =
     435                 :          10 :                         *((uint8_t *)spdm_encapsulated_response_ack_response + ack_header_size);
     436                 :             :                     /* 0xFF or 0xF slot is not allowed. */
     437         [ +  + ]:          10 :                     if (*req_slot_id_param >= SPDM_MAX_SLOT_COUNT) {
     438                 :           2 :                         libspdm_release_receiver_buffer (spdm_context);
     439                 :           2 :                         return LIBSPDM_STATUS_INVALID_MSG_FIELD;
     440                 :             :                     }
     441                 :             :                     /* The Responder shall not designate a slot that is not provisioned. */
     442                 :           8 :                     if (spdm_context->local_context.local_cert_chain_provision[
     443         [ +  + ]:           8 :                             *req_slot_id_param] == NULL) {
     444                 :           4 :                         libspdm_release_receiver_buffer (spdm_context);
     445                 :           4 :                         return LIBSPDM_STATUS_INVALID_MSG_FIELD;
     446                 :             :                     }
     447                 :             : 
     448         [ +  + ]:           4 :                     if ((spdm_encapsulated_response_ack_response->header.spdm_version >=
     449                 :           2 :                          SPDM_MESSAGE_VERSION_13) &&
     450         [ -  + ]:           2 :                         spdm_context->connection_info.multi_key_conn_req) {
     451                 :           0 :                         if ((spdm_context->local_context.local_key_usage_bit_mask[*req_slot_id_param
     452         [ #  # ]:           0 :                              ] & SPDM_KEY_USAGE_BIT_MASK_KEY_EX_USE) == 0) {
     453                 :           0 :                             libspdm_release_receiver_buffer (spdm_context);
     454                 :           0 :                             return LIBSPDM_STATUS_INVALID_MSG_FIELD;
     455                 :             :                         }
     456                 :             :                     }
     457                 :             :                 }
     458                 :           6 :                 libspdm_release_receiver_buffer (spdm_context);
     459                 :           6 :                 return LIBSPDM_STATUS_SUCCESS;
     460                 :             :             } else {
     461                 :           2 :                 libspdm_release_receiver_buffer (spdm_context);
     462                 :           2 :                 return LIBSPDM_STATUS_INVALID_MSG_SIZE;
     463                 :             :             }
     464                 :             :             break;
     465                 :           2 :         default:
     466                 :           2 :             libspdm_release_receiver_buffer (spdm_context);
     467                 :           2 :             return LIBSPDM_STATUS_INVALID_MSG_FIELD;
     468                 :             :         }
     469                 :           2 :         request_id = spdm_encapsulated_response_ack_response->header.param1;
     470                 :             : 
     471                 :           2 :         encapsulated_request =
     472                 :             :             ((uint8_t *)spdm_encapsulated_response_ack_response + ack_header_size);
     473                 :           2 :         encapsulated_request_size = spdm_response_size - ack_header_size;
     474                 :             : 
     475                 :           2 :         libspdm_copy_mem (spdm_context->last_spdm_request,
     476                 :           2 :                           libspdm_get_scratch_buffer_last_spdm_request_capacity(spdm_context),
     477                 :             :                           encapsulated_request,
     478                 :             :                           encapsulated_request_size);
     479                 :           2 :         spdm_context->last_spdm_request_size = encapsulated_request_size;
     480                 :           2 :         encapsulated_request = (void *)spdm_context->last_spdm_request;
     481                 :             : 
     482                 :           2 :         libspdm_release_receiver_buffer (spdm_context);
     483                 :             :     }
     484                 :             : 
     485                 :             :     return LIBSPDM_STATUS_SUCCESS;
     486                 :             : }
     487                 :             : 
     488                 :          42 : libspdm_return_t libspdm_send_receive_encap_request(void *spdm_context, const uint32_t *session_id)
     489                 :             : {
     490                 :          42 :     return libspdm_encapsulated_request(spdm_context, session_id, 0, NULL);
     491                 :             : }
     492                 :             : 
     493                 :             : #endif /* LIBSPDM_ENABLE_CAPABILITY_ENCAP_CAP */
        

Generated by: LCOV version 2.0-1