Code coverage report for DMTF/libspdm
Current view: top level - library/spdm_transport_storage_lib - libspdm_storage.c (source / functions) Coverage Total Hit
Test: 36148b912f76d231c18d216d6dee5c0858575bb1 Lines: 90.3 % 331 299
Test Date: 2026-10-25 08:40:22 Functions: 100.0 % 13 13
Branches: 79.4 % 170 135

             Branch data     Line data    Source code
       1                 :             : /**
       2                 :             :  *  Copyright Notice:
       3                 :             :  *  Copyright 2025-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 "library/spdm_transport_storage_lib.h"
       8                 :             : #include "industry_standard/spdm_storage_binding.h"
       9                 :             : #include "internal/libspdm_common_lib.h"
      10                 :             : #include "hal/library/debuglib.h"
      11                 :             : #include "hal/library/memlib.h"
      12                 :             : 
      13                 :             : /**
      14                 :             :  * This function translates the negotiated secured_message_version to a DSP0277 version.
      15                 :             :  *
      16                 :             :  * @param  secured_message_version  The version specified in binding specification and
      17                 :             :  *                                  negotiated in KEY_EXCHANGE/KEY_EXCHANGE_RSP.
      18                 :             :  *
      19                 :             :  * @return The DSP0277 version specified in binding specification,
      20                 :             :  *         which is bound to secured_message_version.
      21                 :             :  */
      22                 :          22 : static spdm_version_number_t libspdm_storage_get_secured_spdm_version(
      23                 :             :     spdm_version_number_t secured_message_version)
      24                 :             : {
      25                 :          22 :     return secured_message_version;
      26                 :             : }
      27                 :             : 
      28                 :             : /**
      29                 :             :  * Return max random number count in an SPDM secure message.
      30                 :             :  *
      31                 :             :  * This value is transport layer specific.
      32                 :             :  *
      33                 :             :  * @return Max random number count in an SPDM secured message.
      34                 :             :  *        0 means no random number is required.
      35                 :             :  **/
      36                 :           8 : static uint32_t libspdm_storage_get_max_random_number_count(void)
      37                 :             : {
      38                 :           8 :     return LIBSPDM_STORAGE_MAX_RANDOM_NUMBER_COUNT;
      39                 :             : }
      40                 :             : 
      41                 :             : /**
      42                 :             :  * Get sequence number in an SPDM secure message.
      43                 :             :  *
      44                 :             :  * This value is transport layer specific.
      45                 :             :  *
      46                 :             :  * @param sequence_number        The current sequence number used to encode or decode message.
      47                 :             :  * @param sequence_number_buffer  A buffer to hold the sequence number output used in the secured message.
      48                 :             :  *                             The size in byte of the output buffer shall be 8.
      49                 :             :  *
      50                 :             :  * @return size in byte of the sequence_number_buffer.
      51                 :             :  *        It shall be no greater than 8.
      52                 :             :  *        0 means no sequence number is required.
      53                 :             :  **/
      54                 :          22 : static uint8_t libspdm_storage_get_sequence_number(uint64_t sequence_number,
      55                 :             :                                                    uint8_t *sequence_number_buffer)
      56                 :             : {
      57                 :          22 :     libspdm_copy_mem(sequence_number_buffer, sizeof(uint64_t),
      58                 :             :                      &sequence_number, sizeof(uint64_t));
      59                 :             : 
      60                 :          22 :     return SPDM_STORAGE_SEQUENCE_NUMBER_COUNT;
      61                 :             : }
      62                 :             : 
      63                 :             : /**
      64                 :             :  * Decode, from a decrypted SPDM Secured Storage message, the SPDM Secured Message Descriptor.
      65                 :             :  * This function must only be called after `libspdm_decode_secured_message()` has already
      66                 :             :  * processed the encrypted secured message.
      67                 :             :  *
      68                 :             :  * Limitations:
      69                 :             :  *  - Implementation only supports parsing a single descriptor
      70                 :             :  *  - Only supports processing of SPDM Message Descriptor
      71                 :             :  *
      72                 :             :  * Notes: Encapsulated Error Status shall be set in the response within the Secured descriptor
      73                 :             :  *    message `status` field, if an erroneous or an unsupported message/field is detected.
      74                 :             :  *    To accommodate this, keep track of the error state within the transport layer and append the error
      75                 :             :  *    status when encoding the subsequent response. This is done in `libspdm_transport_storage_encode_message()`
      76                 :             :  *
      77                 :             :  * @param  spdm_context            A pointer to the SPDM context.
      78                 :             :  * @param  session_id              Secured Session ID
      79                 :             :  * @param  message_size            SPDM Message Size.
      80                 :             :  *                                 On output, size of the real SPDM Message.
      81                 :             :  * @param  message                 Decrypted SPDM Message, pointing to the `num descriptors` field of the message.
      82                 :             :  *                                 On output, points the start of the real SPDM Message.
      83                 :             :  * @param  is_request_message      Indicates if it is a request message.
      84                 :             :  *
      85                 :             :  **/
      86                 :          12 : static libspdm_return_t libspdm_storage_secured_message_decode(
      87                 :             :     void *spdm_context, uint32_t session_id, size_t *message_size, void **message,
      88                 :             :     bool is_request_message)
      89                 :             : {
      90                 :             :     uint8_t *spdm_storage_descriptor_start;
      91                 :             :     libspdm_error_struct_t spdm_error;
      92                 :             :     uint32_t spdm_msg_offset;
      93                 :             :     spdm_storage_secured_message_descriptor *descriptor;
      94                 :             :     uint8_t num_descriptors;
      95                 :             : 
      96                 :             :     /* The num descriptors byte and the single supported descriptor are read
      97                 :             :      * below, so the decrypted message must be at least that large before any
      98                 :             :      * field is dereferenced. */
      99         [ +  + ]:          12 :     if (*message_size < LIBSPDM_STORAGE_SECURED_MESSAGE_DESCRIPTOR_MIN_SIZE) {
     100                 :           2 :         return LIBSPDM_STATUS_INVALID_MSG_SIZE;
     101                 :             :     }
     102                 :             : 
     103                 :          10 :     num_descriptors = ((uint8_t *)(*message))[0];
     104                 :             : 
     105                 :             :     /* Check for invalid message with no descriptors (DSP0286 Table 8) */
     106         [ +  + ]:          10 :     if (num_descriptors == 0) {
     107                 :           2 :         spdm_error.session_id = session_id;
     108                 :           2 :         spdm_error.error_code = SPDM_STORAGE_SECURED_MSG_ENCAPSULATED_STATUS_INVALID_CMD;
     109                 :           2 :         libspdm_set_last_spdm_error_struct(spdm_context, &spdm_error);
     110                 :           2 :         return LIBSPDM_STATUS_INVALID_MSG_FIELD;
     111                 :             :     }
     112                 :             : 
     113                 :             :     /* Currently support handling only a single SPDM descriptor */
     114         [ +  + ]:           8 :     if (num_descriptors > 1) {
     115                 :           2 :         spdm_error.session_id = session_id;
     116                 :           2 :         spdm_error.error_code = SPDM_STORAGE_SECURED_MSG_ENCAPSULATED_STATUS_INVALID_CMD;
     117                 :           2 :         libspdm_set_last_spdm_error_struct(spdm_context, &spdm_error);
     118                 :           2 :         return LIBSPDM_STATUS_UNSUPPORTED_CAP;
     119                 :             :     }
     120                 :             : 
     121                 :           6 :     spdm_storage_descriptor_start = ((uint8_t *)(*message)) + (sizeof(uint8_t) * 3);
     122                 :           6 :     descriptor = (void *)spdm_storage_descriptor_start;
     123                 :             : 
     124         [ +  + ]:          10 :     for (int i = 0; i < num_descriptors; ++i) {
     125         [ +  - ]:           6 :         switch(descriptor->desc_type) {
     126                 :           6 :         case SPDM_STORAGE_SECURED_MSG_DESCRIPTOR_SPDM:
     127         [ -  + ]:           6 :             if (descriptor->length > *message_size)
     128                 :           0 :                 return LIBSPDM_STATUS_INVALID_MSG_SIZE;
     129                 :             : 
     130                 :             :             /*
     131                 :             :              * Offset is calculated from the start of the Secured
     132                 :             :              * Message Data Buffer. `message` points to the start
     133                 :             :              * of `num descriptors` within the decoded Secured Message.
     134                 :             :              */
     135         [ -  + ]:           6 :             if (LIBSPDM_STORAGE_SECURED_MESSAGE_NUM_DESCRIPTORS_OFFSET > descriptor->offset)
     136                 :           0 :                 return LIBSPDM_STATUS_INVALID_MSG_FIELD;
     137                 :             : 
     138                 :           6 :             spdm_msg_offset = descriptor->offset -
     139                 :             :                               LIBSPDM_STORAGE_SECURED_MESSAGE_NUM_DESCRIPTORS_OFFSET;
     140         [ -  + ]:           6 :             if (spdm_msg_offset > *message_size)
     141                 :           0 :                 return LIBSPDM_STATUS_INVALID_MSG_SIZE;
     142                 :             : 
     143         [ +  + ]:           6 :             if (!is_request_message &&
     144         [ +  + ]:           4 :                 descriptor->status != SPDM_STORAGE_SECURED_MSG_ENCAPSULATED_STATUS_SUCCESS)
     145                 :           2 :                 return LIBSPDM_STATUS_ERROR_PEER;
     146                 :             : 
     147                 :           4 :             break;
     148                 :           0 :         default:
     149                 :           0 :             spdm_error.session_id = session_id;
     150                 :           0 :             spdm_error.error_code = SPDM_STORAGE_SECURED_MSG_ENCAPSULATED_STATUS_INVALID_CMD;
     151                 :           0 :             libspdm_set_last_spdm_error_struct(spdm_context, &spdm_error);
     152                 :           0 :             return LIBSPDM_STATUS_UNSUPPORTED_CAP;
     153                 :             :         }
     154                 :             : 
     155                 :             :         /* Next descriptor */
     156                 :           4 :         descriptor = (void *)(spdm_storage_descriptor_start +
     157                 :           4 :                               (LIBSPDM_STORAGE_SECURED_MESSAGE_DESCRIPTOR_MIN_SIZE * i));
     158                 :             :     }
     159                 :             : 
     160                 :           4 :     *message = ((uint8_t *)*message) + spdm_msg_offset;
     161                 :           4 :     *message_size -= spdm_msg_offset;
     162                 :             : 
     163                 :           4 :     return LIBSPDM_STATUS_SUCCESS;
     164                 :             : }
     165                 :             : 
     166                 :             : /**
     167                 :             :  * Encode the SPDM Storage Secured Descriptor into an SPDM message. This shall be
     168                 :             :  * followed by a call to `libspdm_encode_secured_message()` to encrypt the
     169                 :             :  * attached command buffer. This appends exactly one descriptor with the
     170                 :             :  * SPDM message type, encapsulating the SPDM message data buffer.
     171                 :             :  *
     172                 :             :  * @param  spdm_context            A pointer to the SPDM context.
     173                 :             :  * @param  message_size            SPDM Message Size.
     174                 :             :  * @param  message                 SPDM Message.
     175                 :             :  * @param  secured_message_size    On output, size in bytes of the secured message to be encrypted.
     176                 :             :  * @param  secured_message         On output, the start of an SPDM Storage secured message, pointing
     177                 :             :  *                                 into the transport message.
     178                 :             :  * @param  transport_message_size  Size in bytes of the transport message buffer.
     179                 :             :  * @param  transport_message       A pointer to a destination buffer to store the transport message.
     180                 :             :  * @param  is_request_message      Indicates if it is a request message.
     181                 :             :  *
     182                 :             :  **/
     183                 :           8 : static libspdm_return_t libspdm_storage_secured_message_encode(
     184                 :             :     void *spdm_context, size_t *message_size, void **message,
     185                 :             :     size_t *secured_message_size, uint8_t **secured_message,
     186                 :             :     size_t *transport_message_size, void **transport_message,
     187                 :             :     bool is_request_message)
     188                 :             : {
     189                 :             :     libspdm_error_struct_t spdm_error;
     190                 :           8 :     size_t sec_trans_header_size = is_request_message ?
     191         [ +  + ]:           8 :                                    sizeof(libspdm_storage_transport_virtual_header_t): 0;
     192                 :             :     uint8_t* secured_storage_desc_start;
     193                 :             :     uint8_t* secured_storage_desc_end;
     194                 :           8 :     uint8_t num_descriptors = 1;
     195                 :             :     spdm_storage_secured_message_descriptor *descriptor;
     196                 :             : 
     197                 :             :     /* DSP0286 Specifies 4 Reserved bytes at the start of a secured message */
     198                 :           8 :     sec_trans_header_size += sizeof(uint8_t) * 4;
     199                 :             : 
     200                 :           8 :     libspdm_zero_mem(*transport_message, *transport_message_size);
     201                 :           8 :     *secured_message = ((uint8_t *)(*transport_message)) + sec_trans_header_size;
     202                 :           8 :     *secured_message_size = *transport_message_size - sec_trans_header_size;
     203                 :             : 
     204                 :           8 :     if (*secured_message_size <
     205         [ -  + ]:           8 :         LIBSPDM_STORAGE_SECURED_MESSAGE_DESCRIPTOR_MIN_SIZE + *message_size) {
     206                 :           0 :         LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR,
     207                 :             :                        "No space in transport message buffer to append storage descriptors"));
     208                 :           0 :         return LIBSPDM_STATUS_INVALID_MSG_SIZE;
     209                 :             :     }
     210                 :             : 
     211                 :           8 :     secured_storage_desc_start = *secured_message + (4 + 2 + 2 + 2 + 2);
     212                 :           8 :     secured_storage_desc_end = secured_storage_desc_start +
     213                 :             :                                LIBSPDM_STORAGE_SECURED_MESSAGE_DESCRIPTOR_MIN_SIZE;
     214                 :             : 
     215                 :             :     /*
     216                 :             :      * Move the secured message within the transport message to allow space for
     217                 :             :      * descriptors and zero the descriptor fields.
     218                 :             :      */
     219                 :           8 :     libspdm_copy_mem(secured_storage_desc_end,
     220                 :           8 :                      *secured_message_size - LIBSPDM_STORAGE_SECURED_MESSAGE_DESCRIPTOR_MIN_SIZE,
     221                 :             :                      *message, *message_size);
     222                 :           8 :     libspdm_zero_mem(secured_storage_desc_start,
     223                 :             :                      LIBSPDM_STORAGE_SECURED_MESSAGE_DESCRIPTOR_MIN_SIZE);
     224                 :             : 
     225                 :             :     /* Retrieve secured session encapsulated error status if any */
     226                 :           8 :     libspdm_get_last_spdm_error_struct(spdm_context, &spdm_error);
     227                 :             : 
     228                 :             :     /* Encode Secured Message Storage Descriptor */
     229                 :           8 :     secured_storage_desc_start[0] = num_descriptors;
     230                 :             :     /* 3 reserved bytes before the descriptor begins */
     231                 :           8 :     descriptor = (void *)(secured_storage_desc_start + (sizeof(uint8_t) * 3));
     232                 :           8 :     descriptor->desc_type = SPDM_STORAGE_SECURED_MSG_DESCRIPTOR_SPDM;
     233         [ +  + ]:           8 :     descriptor->status =
     234                 :             :         is_request_message ? 0 : spdm_error.error_code;
     235                 :             : 
     236                 :             :     /* Length of the element this SPDM element  */
     237                 :           8 :     descriptor->length = (uint32_t)*message_size;
     238                 :             : 
     239                 :             :     /*
     240                 :             :      * The updated `message` means subsequent calls to `libspdm_encode_secured_message()`
     241                 :             :      * also encode this `descriptor` as part of the data buffer as specified
     242                 :             :      * by DSP0286: 158.
     243                 :             :      */
     244                 :           8 :     *message = secured_storage_desc_start;
     245                 :           8 :     *message_size += LIBSPDM_STORAGE_SECURED_MESSAGE_DESCRIPTOR_MIN_SIZE;
     246                 :             : 
     247                 :             :     /*
     248                 :             :      * Only a single descriptor is used, the offset into the secure message data
     249                 :             :      * element is calculated as per Table 7 of DSP0286. That is, from the start of
     250                 :             :      * the SPDM Storage Secured Message Header
     251                 :             :      */
     252                 :           8 :     descriptor->offset = (4 + 4 + 2 + 2 + 2 + 2 +
     253                 :             :                           LIBSPDM_STORAGE_SECURED_MESSAGE_DESCRIPTOR_MIN_SIZE);
     254                 :             : 
     255                 :           8 :     return LIBSPDM_STATUS_SUCCESS;
     256                 :             : }
     257                 :             : 
     258                 :          32 : libspdm_return_t libspdm_storage_decode_message(uint32_t **session_id,
     259                 :             :                                                 uint8_t *connection_id,
     260                 :             :                                                 size_t transport_message_size,
     261                 :             :                                                 void *transport_message,
     262                 :             :                                                 size_t *message_size,
     263                 :             :                                                 void **message)
     264                 :             : {
     265                 :             :     const libspdm_storage_transport_virtual_header_t *storage_header;
     266                 :             :     uint16_t security_protocol_specific;
     267                 :             :     uint8_t spsp0, spsp1, spdm_operation;
     268                 :             : 
     269                 :          32 :     LIBSPDM_ASSERT(transport_message_size >= sizeof(libspdm_storage_transport_virtual_header_t));
     270         [ +  + ]:          32 :     if (transport_message_size <= sizeof(libspdm_storage_transport_virtual_header_t)) {
     271                 :           2 :         return LIBSPDM_STATUS_INVALID_MSG_SIZE;
     272                 :             :     }
     273                 :             : 
     274         [ -  + ]:          30 :     if (transport_message_size == 0) {
     275                 :           0 :         return LIBSPDM_STATUS_INVALID_MSG_SIZE;
     276                 :             :     }
     277                 :             : 
     278                 :          30 :     storage_header = transport_message;
     279         [ +  + ]:          30 :     if (storage_header->security_protocol != SPDM_STORAGE_SECURITY_PROTOCOL_DMTF) {
     280                 :           2 :         return LIBSPDM_STATUS_INVALID_MSG_FIELD;
     281                 :             :     }
     282                 :             : 
     283                 :          28 :     security_protocol_specific  = storage_header->security_protocol_specific;
     284                 :          28 :     spsp0 = security_protocol_specific & 0xFF;
     285                 :          28 :     spsp1 = security_protocol_specific >> 8;
     286                 :             : 
     287         [ +  + ]:          28 :     if (spsp1 != 0) {
     288                 :           2 :         return LIBSPDM_STATUS_INVALID_MSG_FIELD;
     289                 :             :     }
     290                 :             : 
     291         [ +  + ]:          26 :     if (connection_id) {
     292                 :           2 :         *connection_id = spsp0 & 0x03;
     293                 :             :     }
     294                 :          26 :     spdm_operation = (spsp0 & 0xFC) >> 2;
     295                 :             : 
     296      [ +  +  + ]:          26 :     switch (spdm_operation) {
     297                 :          10 :     case SPDM_STORAGE_OPERATION_CODE_DISCOVERY:
     298                 :             :     case SPDM_STORAGE_OPERATION_CODE_PENDING_INFO:
     299                 :             :     case SPDM_STORAGE_OPERATION_CODE_MESSAGE:
     300         [ +  - ]:          10 :         if (session_id != NULL) {
     301                 :          10 :             *session_id = NULL;
     302                 :             :         }
     303                 :          10 :         *message_size = transport_message_size - sizeof(libspdm_storage_transport_virtual_header_t);
     304                 :          10 :         *message = (uint8_t *)transport_message + sizeof(libspdm_storage_transport_virtual_header_t);
     305                 :          10 :         break;
     306                 :          14 :     case SPDM_STORAGE_OPERATION_CODE_SECURED_MESSAGE:
     307                 :          14 :         LIBSPDM_ASSERT(session_id != NULL);
     308         [ -  + ]:          14 :         if (session_id == NULL) {
     309                 :           0 :             return LIBSPDM_STATUS_INVALID_MSG_FIELD;
     310                 :             :         }
     311         [ +  + ]:          14 :         if (transport_message_size <=
     312                 :             :             sizeof(libspdm_storage_transport_virtual_header_t) + sizeof(uint32_t)) {
     313                 :           2 :             return LIBSPDM_STATUS_INVALID_MSG_SIZE;
     314                 :             :         }
     315                 :          12 :         *session_id = (uint32_t *)((uint8_t *)transport_message +
     316                 :             :                                    sizeof(libspdm_storage_transport_virtual_header_t) +
     317                 :             :                                    LIBSPDM_STORAGE_SECURED_MESSAGE_HEADER_RESERVED_BYTES);
     318                 :          12 :         *message_size = transport_message_size - sizeof(libspdm_storage_transport_virtual_header_t) -
     319                 :             :                         LIBSPDM_STORAGE_SECURED_MESSAGE_HEADER_RESERVED_BYTES;
     320                 :          12 :         *message = (uint8_t *)transport_message + sizeof(libspdm_storage_transport_virtual_header_t) +
     321                 :             :                    LIBSPDM_STORAGE_SECURED_MESSAGE_HEADER_RESERVED_BYTES;
     322                 :          12 :         break;
     323                 :           2 :     default:
     324                 :           2 :         return LIBSPDM_STATUS_UNSUPPORTED_CAP;
     325                 :             :     }
     326                 :             : 
     327                 :          22 :     return LIBSPDM_STATUS_SUCCESS;
     328                 :             : }
     329                 :             : 
     330                 :          36 : libspdm_return_t libspdm_transport_storage_decode_message(
     331                 :             :     void *spdm_context, uint32_t **session_id,
     332                 :             :     bool *is_app_message, bool is_request_message,
     333                 :             :     size_t transport_message_size, void *transport_message,
     334                 :             :     size_t *message_size, void **message)
     335                 :             : {
     336                 :             :     libspdm_return_t status;
     337                 :             :     uint32_t *secured_message_session_id;
     338                 :             :     uint8_t *secured_message;
     339                 :             :     size_t secured_message_size;
     340                 :             :     libspdm_secured_message_callbacks_t spdm_secured_message_callbacks;
     341                 :             :     void *secured_message_context;
     342                 :             :     libspdm_error_struct_t spdm_error;
     343                 :             : 
     344                 :          36 :     spdm_error.error_code = 0;
     345                 :          36 :     spdm_error.session_id = 0;
     346                 :          36 :     libspdm_set_last_spdm_error_struct(spdm_context, &spdm_error);
     347                 :             : 
     348                 :          36 :     spdm_secured_message_callbacks.version =
     349                 :             :         LIBSPDM_SECURED_MESSAGE_CALLBACKS_VERSION;
     350                 :          36 :     spdm_secured_message_callbacks.get_sequence_number =
     351                 :             :         libspdm_storage_get_sequence_number;
     352                 :          36 :     spdm_secured_message_callbacks.get_max_random_number_count =
     353                 :             :         libspdm_storage_get_max_random_number_count;
     354                 :          36 :     spdm_secured_message_callbacks.get_secured_spdm_version =
     355                 :             :         libspdm_storage_get_secured_spdm_version;
     356                 :             : 
     357   [ +  -  -  + ]:          36 :     if ((session_id == NULL) || (is_app_message == NULL)) {
     358                 :           0 :         return LIBSPDM_STATUS_UNSUPPORTED_CAP;
     359                 :             :     }
     360                 :          36 :     *is_app_message = false;
     361                 :             : 
     362                 :          36 :     secured_message_session_id = NULL;
     363                 :             : 
     364         [ +  + ]:          36 :     if (!is_request_message) {
     365                 :             :         /*
     366                 :             :          * Storage response messages are not transport encoded, this is the SPDM
     367                 :             :          * message, and shall be processed as such. Which also means that there
     368                 :             :          * is no way from the response to determine if it's secure or not, instead
     369                 :             :          * use internal state to determine.
     370                 :             :          */
     371                 :             :         /* Expecting a secured message */
     372         [ +  + ]:          10 :         if (*session_id != NULL) {
     373         [ +  + ]:           8 :             if (transport_message_size <
     374                 :             :                 LIBSPDM_STORAGE_SECURED_MESSAGE_HEADER_RESERVED_BYTES + sizeof(uint32_t)) {
     375                 :           2 :                 return LIBSPDM_STATUS_INVALID_MSG_SIZE;
     376                 :             :             }
     377                 :           6 :             **session_id = libspdm_read_uint32(
     378                 :             :                 (const uint8_t *)transport_message +
     379                 :             :                 LIBSPDM_STORAGE_SECURED_MESSAGE_HEADER_RESERVED_BYTES);
     380                 :             : 
     381                 :             :             secured_message_context =
     382                 :           6 :                 libspdm_get_secured_message_context_via_session_id(
     383                 :           6 :                     spdm_context, **session_id);
     384         [ +  + ]:           6 :             if (secured_message_context == NULL) {
     385                 :           2 :                 spdm_error.error_code = SPDM_ERROR_CODE_INVALID_SESSION;
     386                 :           2 :                 spdm_error.session_id = **session_id;
     387                 :           2 :                 libspdm_set_last_spdm_error_struct(spdm_context,
     388                 :             :                                                    &spdm_error);
     389                 :           2 :                 return LIBSPDM_STATUS_UNSUPPORTED_CAP;
     390                 :             :             }
     391                 :             : 
     392                 :             :             /*
     393                 :             :              * Secured message to message
     394                 :             :              *
     395                 :             :              * DSP0286 specifies 4 reserved bytes at the start of a secured
     396                 :             :              * message. Skip that for decoding.
     397                 :             :              */
     398                 :           4 :             status = libspdm_decode_secured_message(
     399                 :           4 :                 secured_message_context, **session_id,
     400                 :             :                 is_request_message,
     401                 :             :                 transport_message_size - LIBSPDM_STORAGE_SECURED_MESSAGE_HEADER_RESERVED_BYTES,
     402                 :             :                 ((uint8_t *)transport_message) +
     403                 :             :                 LIBSPDM_STORAGE_SECURED_MESSAGE_HEADER_RESERVED_BYTES,
     404                 :             :                 message_size, message, &spdm_secured_message_callbacks);
     405                 :             : 
     406         [ -  + ]:           4 :             if (LIBSPDM_STATUS_IS_ERROR(status)) {
     407                 :           0 :                 LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR,
     408                 :             :                                "libspdm_decode_secured_message - %x\n", status));
     409                 :           0 :                 libspdm_secured_message_get_last_spdm_error_struct(
     410                 :             :                     secured_message_context, &spdm_error);
     411                 :           0 :                 libspdm_set_last_spdm_error_struct(spdm_context,
     412                 :             :                                                    &spdm_error);
     413                 :           0 :                 return status;
     414                 :             :             }
     415                 :             : 
     416                 :           4 :             status = libspdm_storage_secured_message_decode(spdm_context, **session_id, message_size,
     417                 :             :                                                             message, is_request_message);
     418         [ +  + ]:           4 :             if (LIBSPDM_STATUS_IS_ERROR(status)) {
     419                 :           2 :                 LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR,
     420                 :             :                                "libspdm_storage_secured_message_decode - %x\n", status));
     421                 :           2 :                 return status;
     422                 :             :             }
     423                 :             : 
     424                 :             :         } else {
     425                 :           2 :             *message_size = transport_message_size;
     426                 :           2 :             *message = transport_message;
     427                 :           2 :             *session_id = NULL;
     428                 :             :         };
     429                 :           4 :         return LIBSPDM_STATUS_SUCCESS;
     430                 :             :     } else {
     431                 :             :         /* Storage requests need to be transport encoded/decoded */
     432                 :          26 :         status = libspdm_storage_decode_message(
     433                 :             :             &secured_message_session_id, 0, transport_message_size,
     434                 :             :             transport_message, &secured_message_size, (void **)&secured_message);
     435                 :             : 
     436         [ +  + ]:          26 :         if (LIBSPDM_STATUS_IS_ERROR(status)) {
     437                 :          10 :             LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR, "transport_decode_message - %x\n", status));
     438                 :          10 :             return status;
     439                 :             :         }
     440                 :             : 
     441         [ +  + ]:          16 :         if (secured_message_session_id != NULL) {
     442                 :          12 :             *session_id = secured_message_session_id;
     443                 :             : 
     444                 :             :             secured_message_context =
     445                 :          12 :                 libspdm_get_secured_message_context_via_session_id(
     446                 :             :                     spdm_context, *secured_message_session_id);
     447         [ +  + ]:          12 :             if (secured_message_context == NULL) {
     448                 :           2 :                 spdm_error.error_code = SPDM_ERROR_CODE_INVALID_SESSION;
     449                 :           2 :                 spdm_error.session_id = *secured_message_session_id;
     450                 :           2 :                 libspdm_set_last_spdm_error_struct(spdm_context,
     451                 :             :                                                    &spdm_error);
     452                 :           2 :                 return LIBSPDM_STATUS_UNSUPPORTED_CAP;
     453                 :             :             }
     454                 :             : 
     455                 :             :             /* Secured message to message*/
     456                 :          10 :             status = libspdm_decode_secured_message(
     457                 :             :                 secured_message_context, *secured_message_session_id,
     458                 :             :                 is_request_message, secured_message_size,
     459                 :             :                 (uint8_t *)secured_message,
     460                 :             :                 message_size, message, &spdm_secured_message_callbacks);
     461         [ +  + ]:          10 :             if (LIBSPDM_STATUS_IS_ERROR(status)) {
     462                 :           2 :                 LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR,
     463                 :             :                                "libspdm_decode_secured_message - %x\n", status));
     464                 :           2 :                 libspdm_secured_message_get_last_spdm_error_struct(
     465                 :             :                     secured_message_context, &spdm_error);
     466                 :           2 :                 libspdm_set_last_spdm_error_struct(spdm_context,
     467                 :             :                                                    &spdm_error);
     468                 :           2 :                 return status;
     469                 :             :             }
     470                 :             : 
     471                 :           8 :             status = libspdm_storage_secured_message_decode(spdm_context, **session_id, message_size,
     472                 :             :                                                             message, is_request_message);
     473         [ +  + ]:           8 :             if (LIBSPDM_STATUS_IS_ERROR(status)) {
     474                 :           6 :                 LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR,
     475                 :             :                                "libspdm_storage_secured_message_decode - %x\n", status));
     476                 :           6 :                 return status;
     477                 :             :             }
     478                 :           2 :             return LIBSPDM_STATUS_SUCCESS;
     479                 :             :         } else {
     480                 :             :             /* get non-secured message*/
     481                 :           4 :             status = libspdm_storage_decode_message(&secured_message_session_id,
     482                 :             :                                                     0,
     483                 :             :                                                     transport_message_size,
     484                 :             :                                                     transport_message,
     485                 :             :                                                     message_size, message);
     486         [ -  + ]:           4 :             if (LIBSPDM_STATUS_IS_ERROR(status)) {
     487                 :           0 :                 LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR, "transport_decode_message - %x\n",
     488                 :             :                                status));
     489                 :           0 :                 return status;
     490                 :             :             }
     491                 :           4 :             LIBSPDM_ASSERT(secured_message_session_id == NULL);
     492                 :           4 :             *session_id = NULL;
     493                 :           4 :             return LIBSPDM_STATUS_SUCCESS;
     494                 :             :         }
     495                 :             :     }
     496                 :             : }
     497                 :             : 
     498                 :          16 : libspdm_return_t libspdm_storage_encode_message(const uint32_t *session_id,
     499                 :             :                                                 uint8_t connection_id,
     500                 :             :                                                 size_t message_size, void *message,
     501                 :             :                                                 size_t *transport_message_size,
     502                 :             :                                                 void **transport_message)
     503                 :             : {
     504                 :             :     uint32_t data32;
     505                 :             :     libspdm_storage_transport_virtual_header_t *storage_header;
     506                 :             : 
     507   [ +  -  +  - ]:          16 :     if (!transport_message_size || *transport_message_size == 0
     508         [ -  + ]:          16 :         || message_size == 0) {
     509                 :           0 :         return LIBSPDM_STATUS_INVALID_MSG_SIZE;
     510                 :             :     }
     511                 :             : 
     512                 :          16 :     LIBSPDM_ASSERT(*transport_message_size >= sizeof(libspdm_storage_transport_virtual_header_t));
     513                 :             : 
     514         [ +  + ]:          16 :     if (*transport_message_size < message_size + sizeof(libspdm_storage_transport_virtual_header_t)) {
     515                 :           2 :         *transport_message_size = message_size + sizeof(libspdm_storage_transport_virtual_header_t);
     516                 :           2 :         return LIBSPDM_STATUS_BUFFER_TOO_SMALL;
     517                 :             :     }
     518                 :             : 
     519   [ +  -  -  + ]:          14 :     if (!message || !transport_message) {
     520                 :           0 :         return LIBSPDM_STATUS_INVALID_MSG_SIZE;
     521                 :             :     }
     522                 :             : 
     523         [ +  + ]:          14 :     if (connection_id & ~0x03) {
     524                 :           2 :         return LIBSPDM_STATUS_INVALID_MSG_FIELD;
     525                 :             :     }
     526                 :             : 
     527                 :          12 :     *transport_message_size = message_size + sizeof(libspdm_storage_transport_virtual_header_t);
     528                 :          12 :     *transport_message = (uint8_t *)message - sizeof(libspdm_storage_transport_virtual_header_t);
     529                 :          12 :     storage_header = *transport_message;
     530                 :             : 
     531                 :          12 :     storage_header->security_protocol = SPDM_STORAGE_SECURITY_PROTOCOL_DMTF;
     532                 :             : 
     533         [ +  + ]:          12 :     if (session_id != NULL) {
     534                 :           4 :         storage_header->security_protocol_specific = SPDM_STORAGE_OPERATION_CODE_SECURED_MESSAGE <<
     535                 :             :                                                      2;
     536                 :           4 :         storage_header->security_protocol_specific |= connection_id &
     537                 :             :                                                       SPDM_STORAGE_MAX_CONNECTION_ID_MASK;
     538                 :           4 :         libspdm_zero_mem(message, LIBSPDM_STORAGE_SECURED_MESSAGE_HEADER_RESERVED_BYTES);
     539                 :           4 :         data32 = libspdm_read_uint32(((const uint8_t *)message +
     540                 :             :                                       LIBSPDM_STORAGE_SECURED_MESSAGE_HEADER_RESERVED_BYTES));
     541                 :           4 :         LIBSPDM_ASSERT(*session_id == data32);
     542         [ -  + ]:           4 :         if (*session_id != data32) {
     543                 :           0 :             return LIBSPDM_STATUS_INVALID_MSG_FIELD;
     544                 :             :         }
     545                 :             :     } else {
     546                 :           8 :         storage_header->security_protocol_specific = SPDM_STORAGE_OPERATION_CODE_MESSAGE << 2;
     547                 :           8 :         storage_header->security_protocol_specific |= connection_id &
     548                 :             :                                                       SPDM_STORAGE_MAX_CONNECTION_ID_MASK;
     549                 :             :     }
     550                 :             : 
     551                 :          12 :     return LIBSPDM_STATUS_SUCCESS;
     552                 :             : }
     553                 :             : 
     554                 :          26 : libspdm_return_t libspdm_transport_storage_encode_message(
     555                 :             :     void *spdm_context, const uint32_t *session_id,
     556                 :             :     bool is_app_message,
     557                 :             :     bool is_request_message, size_t message_size, void *message,
     558                 :             :     size_t *transport_message_size, void **transport_message)
     559                 :             : {
     560                 :             :     libspdm_return_t status;
     561                 :             :     uint8_t *secured_message;
     562                 :             :     size_t secured_message_size;
     563                 :             :     libspdm_secured_message_callbacks_t spdm_secured_message_callbacks;
     564                 :             :     void *secured_message_context;
     565                 :             : 
     566                 :          26 :     spdm_secured_message_callbacks.version =
     567                 :             :         LIBSPDM_SECURED_MESSAGE_CALLBACKS_VERSION;
     568                 :          26 :     spdm_secured_message_callbacks.get_sequence_number =
     569                 :             :         libspdm_storage_get_sequence_number;
     570                 :          26 :     spdm_secured_message_callbacks.get_max_random_number_count =
     571                 :             :         libspdm_storage_get_max_random_number_count;
     572                 :          26 :     spdm_secured_message_callbacks.get_secured_spdm_version =
     573                 :             :         libspdm_storage_get_secured_spdm_version;
     574                 :             : 
     575         [ +  + ]:          26 :     if (is_app_message) {
     576                 :           2 :         return LIBSPDM_STATUS_UNSUPPORTED_CAP;
     577                 :             :     }
     578                 :             : 
     579   [ +  -  +  - ]:          24 :     if (!transport_message_size || !transport_message
     580         [ +  + ]:          24 :         || *transport_message_size == 0) {
     581                 :           4 :         return LIBSPDM_STATUS_INVALID_MSG_SIZE;
     582                 :             :     }
     583                 :             : 
     584         [ +  + ]:          20 :     if (session_id != NULL) {
     585                 :             :         secured_message_context =
     586                 :          10 :             libspdm_get_secured_message_context_via_session_id(
     587                 :             :                 spdm_context, *session_id);
     588         [ +  + ]:          10 :         if (secured_message_context == NULL) {
     589                 :           2 :             return LIBSPDM_STATUS_UNSUPPORTED_CAP;
     590                 :             :         }
     591                 :             : 
     592                 :             :         /* Message to secured message*/
     593                 :           8 :         status = libspdm_storage_secured_message_encode(
     594                 :             :             spdm_context, &message_size, &message, &secured_message_size, &secured_message,
     595                 :             :             transport_message_size, transport_message, is_request_message);
     596         [ -  + ]:           8 :         if (LIBSPDM_STATUS_IS_ERROR(status)) {
     597                 :           0 :             LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR,
     598                 :             :                            "libspdm_storage_secured_message_encode - %x\n", status));
     599                 :           0 :             return status;
     600                 :             :         }
     601                 :             : 
     602                 :           8 :         status = libspdm_encode_secured_message(
     603                 :             :             secured_message_context, *session_id, is_request_message,
     604                 :             :             message_size, message, &secured_message_size,
     605                 :             :             secured_message, &spdm_secured_message_callbacks);
     606         [ -  + ]:           8 :         if (LIBSPDM_STATUS_IS_ERROR(status)) {
     607                 :           0 :             LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR,
     608                 :             :                            "libspdm_encode_secured_message - %x\n", status));
     609                 :           0 :             return status;
     610                 :             :         }
     611                 :             : 
     612         [ +  + ]:           8 :         if (!is_request_message) {
     613                 :             :             /*
     614                 :             :              * Storage response messages are not transport encoded, instead it
     615                 :             :              * is just the SPDM message response.
     616                 :             :              */
     617                 :           4 :             *transport_message_size = secured_message_size +
     618                 :             :                                       LIBSPDM_STORAGE_SECURED_MESSAGE_HEADER_RESERVED_BYTES;
     619                 :             :             /* Ensure we allow the 4 reserved bytes to be encapsulated */
     620                 :           4 :             *transport_message = secured_message -
     621                 :             :                                  LIBSPDM_STORAGE_SECURED_MESSAGE_HEADER_RESERVED_BYTES;
     622                 :           4 :             return LIBSPDM_STATUS_SUCCESS;
     623                 :             :         }
     624                 :             : 
     625                 :             :         /* secured message to secured storage message*/
     626                 :           4 :         status = libspdm_storage_encode_message(
     627                 :             :             session_id, 0,
     628                 :             :             secured_message_size + LIBSPDM_STORAGE_SECURED_MESSAGE_HEADER_RESERVED_BYTES,
     629                 :           4 :             secured_message - LIBSPDM_STORAGE_SECURED_MESSAGE_HEADER_RESERVED_BYTES,
     630                 :             :             transport_message_size, transport_message);
     631         [ -  + ]:           4 :         if (LIBSPDM_STATUS_IS_ERROR(status)) {
     632                 :           0 :             LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR, "transport_encode_message - %x\n",
     633                 :             :                            status));
     634                 :           0 :             return status;
     635                 :             :         }
     636                 :             :     } else {
     637         [ +  + ]:          10 :         if (!is_request_message) {
     638                 :             :             /*
     639                 :             :              * Storage response messages are not transport encoded, instead it
     640                 :             :              * is just the SPDM message response.
     641                 :             :              */
     642                 :           2 :             *transport_message_size = message_size;
     643                 :           2 :             *transport_message = message;
     644                 :           2 :             return LIBSPDM_STATUS_SUCCESS;
     645                 :             :         }
     646                 :             : 
     647                 :             :         /* SPDM message to normal storage message*/
     648                 :           8 :         status = libspdm_storage_encode_message(NULL, 0,
     649                 :             :                                                 message_size, message,
     650                 :             :                                                 transport_message_size,
     651                 :             :                                                 transport_message);
     652         [ +  + ]:           8 :         if (LIBSPDM_STATUS_IS_ERROR(status)) {
     653                 :           2 :             LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR, "transport_encode_message - %x\n",
     654                 :             :                            status));
     655                 :           2 :             return status;
     656                 :             :         }
     657                 :             :     }
     658                 :             : 
     659                 :          10 :     return LIBSPDM_STATUS_SUCCESS;
     660                 :             : }
     661                 :             : 
     662                 :          26 : libspdm_return_t libspdm_transport_storage_encode_management_cmd(
     663                 :             :     uint8_t cmd_direction, uint8_t transport_operation,
     664                 :             :     uint8_t connection_id, size_t *transport_message_size,
     665                 :             :     size_t *allocation_length, void *transport_message)
     666                 :             : {
     667                 :             :     libspdm_storage_transport_virtual_header_t *storage_header;
     668                 :             : 
     669   [ +  -  +  - ]:          26 :     if (!transport_message_size || !allocation_length
     670         [ +  + ]:          26 :         || *transport_message_size == 0) {
     671                 :           2 :         return LIBSPDM_STATUS_INVALID_MSG_SIZE;
     672                 :             :     }
     673                 :             : 
     674         [ +  + ]:          24 :     if (*transport_message_size < sizeof(libspdm_storage_transport_virtual_header_t)) {
     675                 :           2 :         return LIBSPDM_STATUS_BUFFER_TOO_SMALL;
     676                 :             :     }
     677                 :             : 
     678         [ +  + ]:          22 :     if (connection_id & ~0x03) {
     679                 :           2 :         return LIBSPDM_STATUS_INVALID_MSG_FIELD;
     680                 :             :     }
     681                 :             : 
     682   [ +  +  +  + ]:          20 :     if (!(cmd_direction == LIBSPDM_STORAGE_CMD_DIRECTION_IF_SEND ||
     683                 :             :           cmd_direction == LIBSPDM_STORAGE_CMD_DIRECTION_IF_RECV)) {
     684                 :           4 :         return LIBSPDM_STATUS_INVALID_MSG_FIELD;
     685                 :             :     }
     686                 :             : 
     687      [ +  +  + ]:          16 :     switch (transport_operation) {
     688                 :           8 :     case SPDM_STORAGE_OPERATION_CODE_DISCOVERY:
     689         [ +  - ]:           8 :         if (cmd_direction == LIBSPDM_STORAGE_CMD_DIRECTION_IF_RECV) {
     690                 :           8 :             *allocation_length = sizeof(spdm_storage_discovery_response_t);
     691         [ +  + ]:           8 :             if (*transport_message_size < sizeof(spdm_storage_discovery_response_t)) {
     692                 :           2 :                 return LIBSPDM_STATUS_BUFFER_TOO_SMALL;
     693                 :             :             }
     694                 :             :         }
     695                 :           6 :         break;
     696                 :           4 :     case SPDM_STORAGE_OPERATION_CODE_PENDING_INFO:
     697         [ +  + ]:           4 :         if (cmd_direction == LIBSPDM_STORAGE_CMD_DIRECTION_IF_RECV) {
     698                 :           2 :             *allocation_length = sizeof(spdm_storage_pending_info_response_t);
     699         [ -  + ]:           2 :             if (*transport_message_size < sizeof(spdm_storage_pending_info_response_t)) {
     700                 :           0 :                 return LIBSPDM_STATUS_BUFFER_TOO_SMALL;
     701                 :             :             }
     702                 :             :         }
     703                 :           4 :         break;
     704                 :           4 :     default:
     705                 :           4 :         return LIBSPDM_STATUS_INVALID_MSG_FIELD;
     706                 :             :     }
     707                 :             : 
     708                 :          10 :     *transport_message_size = sizeof(libspdm_storage_transport_virtual_header_t);
     709                 :          10 :     libspdm_zero_mem(transport_message, *transport_message_size);
     710                 :             : 
     711                 :          10 :     storage_header = transport_message;
     712                 :          10 :     storage_header->security_protocol = SPDM_STORAGE_SECURITY_PROTOCOL_DMTF;
     713                 :          10 :     storage_header->security_protocol_specific = transport_operation << 2;
     714                 :          10 :     storage_header->security_protocol_specific |= connection_id &
     715                 :             :                                                   SPDM_STORAGE_MAX_CONNECTION_ID_MASK;
     716                 :             : 
     717                 :          10 :     return LIBSPDM_STATUS_SUCCESS;
     718                 :             : }
     719                 :             : 
     720                 :           8 : libspdm_return_t libspdm_transport_storage_encode_discovery_response(
     721                 :             :     size_t *transport_message_size,
     722                 :             :     void *transport_message)
     723                 :             : {
     724                 :             :     spdm_storage_discovery_response_t *discovery_response;
     725                 :             : 
     726   [ +  -  +  - ]:           8 :     if (!transport_message || !transport_message_size
     727         [ -  + ]:           8 :         || *transport_message_size == 0) {
     728                 :           0 :         return LIBSPDM_STATUS_INVALID_MSG_SIZE;
     729                 :             :     }
     730                 :             : 
     731         [ +  + ]:           8 :     if (*transport_message_size < sizeof(spdm_storage_discovery_response_t)) {
     732                 :           4 :         return LIBSPDM_STATUS_BUFFER_TOO_SMALL;
     733                 :             :     }
     734                 :             : 
     735                 :           4 :     *transport_message_size = sizeof(spdm_storage_discovery_response_t);
     736                 :           4 :     libspdm_zero_mem(transport_message, *transport_message_size);
     737                 :           4 :     discovery_response = transport_message;
     738                 :             : 
     739                 :           4 :     discovery_response->storage_response_headers.data_length = (uint16_t)*transport_message_size;
     740                 :           4 :     discovery_response->storage_response_headers.storage_binding_version =
     741                 :             :         SPDM_STORAGE_SECURITY_BINDING_VERSION;
     742                 :             :     /* 1 supported connection (0's based) */
     743                 :           4 :     discovery_response->conn_params = 0;
     744                 :           4 :     discovery_response->supported_operations = (1 << SPDM_STORAGE_OPERATION_CODE_DISCOVERY)
     745                 :             :                                                | (1 << SPDM_STORAGE_OPERATION_CODE_PENDING_INFO)
     746                 :             :                                                | (1 << SPDM_STORAGE_OPERATION_CODE_MESSAGE)
     747                 :             :                                                | (1 <<
     748                 :             :                                                   SPDM_STORAGE_OPERATION_CODE_SECURED_MESSAGE);
     749                 :             : 
     750                 :           4 :     return LIBSPDM_STATUS_SUCCESS;
     751                 :             : }
     752                 :             : 
     753                 :          14 : libspdm_return_t libspdm_transport_storage_encode_pending_info_response(
     754                 :             :     size_t *transport_message_size,
     755                 :             :     void *transport_message, bool response_pending,
     756                 :             :     uint32_t pending_response_length)
     757                 :             : {
     758                 :             :     spdm_storage_pending_info_response_t *pending_info_response;
     759                 :             : 
     760   [ +  -  +  + ]:          14 :     if (!transport_message || !transport_message_size
     761         [ -  + ]:          12 :         || *transport_message_size == 0) {
     762                 :           2 :         return LIBSPDM_STATUS_INVALID_MSG_SIZE;
     763                 :             :     }
     764                 :             : 
     765         [ +  + ]:          12 :     if (*transport_message_size < sizeof(spdm_storage_pending_info_response_t)) {
     766                 :           4 :         return LIBSPDM_STATUS_BUFFER_TOO_SMALL;
     767                 :             :     }
     768                 :             : 
     769                 :           8 :     *transport_message_size = sizeof(spdm_storage_pending_info_response_t);
     770                 :           8 :     libspdm_zero_mem(transport_message, *transport_message_size);
     771                 :           8 :     pending_info_response = transport_message;
     772                 :             : 
     773                 :           8 :     pending_info_response->storage_response_headers.data_length = (uint16_t)*transport_message_size;
     774                 :           8 :     pending_info_response->storage_response_headers.storage_binding_version =
     775                 :             :         SPDM_STORAGE_SECURITY_BINDING_VERSION;
     776                 :             : 
     777         [ +  + ]:           8 :     if (response_pending) {
     778                 :           4 :         pending_info_response->pending_info_flag = (1 << 0);
     779                 :           4 :         pending_info_response->response_length = pending_response_length;
     780                 :             :     }
     781                 :             : 
     782                 :           8 :     return LIBSPDM_STATUS_SUCCESS;
     783                 :             : }
     784                 :             : 
     785                 :          10 : libspdm_return_t libspdm_transport_storage_decode_management_cmd(
     786                 :             :     size_t transport_message_size,
     787                 :             :     const void *transport_message,
     788                 :             :     uint8_t *transport_command)
     789                 :             : {
     790                 :             :     const libspdm_storage_transport_virtual_header_t *storage_header;
     791                 :             :     uint16_t security_protocol_specific;
     792                 :             :     uint8_t spsp0, spsp1, spdm_operation;
     793                 :             : 
     794   [ +  -  -  + ]:          10 :     if (!transport_message || transport_message_size == 0) {
     795                 :           0 :         return LIBSPDM_STATUS_INVALID_MSG_SIZE;
     796                 :             :     }
     797                 :             : 
     798                 :          10 :     LIBSPDM_ASSERT(transport_message_size >= sizeof(libspdm_storage_transport_virtual_header_t));
     799                 :             : 
     800         [ -  + ]:          10 :     if (transport_message_size < sizeof(libspdm_storage_transport_virtual_header_t)) {
     801                 :           0 :         return LIBSPDM_STATUS_INVALID_MSG_SIZE;
     802                 :             :     }
     803                 :             : 
     804                 :          10 :     storage_header = transport_message;
     805         [ +  + ]:          10 :     if (storage_header->security_protocol != SPDM_STORAGE_SECURITY_PROTOCOL_DMTF) {
     806                 :           2 :         return LIBSPDM_STATUS_INVALID_MSG_FIELD;
     807                 :             :     }
     808                 :             : 
     809                 :           8 :     security_protocol_specific = storage_header->security_protocol_specific;
     810                 :           8 :     spsp0 = security_protocol_specific & 0xFF;
     811                 :           8 :     spsp1 = security_protocol_specific >> 8;
     812                 :             : 
     813         [ +  + ]:           8 :     if (spsp1 != 0) {
     814                 :           2 :         return LIBSPDM_STATUS_INVALID_MSG_FIELD;
     815                 :             :     }
     816                 :             : 
     817                 :           6 :     spdm_operation = (spsp0 & 0xFC) >> 2;
     818                 :             : 
     819         [ +  + ]:           6 :     switch (spdm_operation) {
     820                 :           4 :     case SPDM_STORAGE_OPERATION_CODE_DISCOVERY:
     821                 :             :     case SPDM_STORAGE_OPERATION_CODE_PENDING_INFO:
     822                 :             :     case SPDM_STORAGE_OPERATION_CODE_MESSAGE:
     823                 :             :     case SPDM_STORAGE_OPERATION_CODE_SECURED_MESSAGE:
     824                 :           4 :         *transport_command = spdm_operation;
     825                 :           4 :         break;
     826                 :           2 :     default:
     827                 :           2 :         *transport_command = 0;
     828                 :           2 :         return LIBSPDM_STATUS_UNSUPPORTED_CAP;
     829                 :             :     }
     830                 :             : 
     831                 :           4 :     return LIBSPDM_STATUS_SUCCESS;
     832                 :             : }
        

Generated by: LCOV version 2.0-1