LCOV - code coverage report
Current view: top level - spdm_transport_storage_lib - libspdm_storage.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 42.0 % 331 139
Test Date: 2026-10-01 20:56:25 Functions: 61.5 % 13 8
Branches: 37.4 % 182 68

             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                 :           0 : static spdm_version_number_t libspdm_storage_get_secured_spdm_version(
      23                 :             :     spdm_version_number_t secured_message_version)
      24                 :             : {
      25                 :           0 :     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                 :           0 : static uint32_t libspdm_storage_get_max_random_number_count(void)
      37                 :             : {
      38                 :           0 :     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                 :           0 : static uint8_t libspdm_storage_get_sequence_number(uint64_t sequence_number,
      55                 :             :                                                    uint8_t *sequence_number_buffer)
      56                 :             : {
      57                 :           0 :     libspdm_copy_mem(sequence_number_buffer, sizeof(uint64_t),
      58                 :             :                      &sequence_number, sizeof(uint64_t));
      59                 :             : 
      60                 :           0 :     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                 :           0 : 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         [ #  # ]:           0 :     if (*message_size < LIBSPDM_STORAGE_SECURED_MESSAGE_DESCRIPTOR_MIN_SIZE) {
     100                 :           0 :         return LIBSPDM_STATUS_INVALID_MSG_SIZE;
     101                 :             :     }
     102                 :             : 
     103                 :           0 :     num_descriptors = ((uint8_t *)(*message))[0];
     104                 :             : 
     105                 :             :     /* Check for invalid message with no descriptors (DSP0286 Table 8) */
     106         [ #  # ]:           0 :     if (num_descriptors == 0) {
     107                 :           0 :         spdm_error.session_id = session_id;
     108                 :           0 :         spdm_error.error_code = SPDM_STORAGE_SECURED_MSG_ENCAPSULATED_STATUS_INVALID_CMD;
     109                 :           0 :         libspdm_set_last_spdm_error_struct(spdm_context, &spdm_error);
     110                 :           0 :         return LIBSPDM_STATUS_INVALID_MSG_FIELD;
     111                 :             :     }
     112                 :             : 
     113                 :             :     /* Currently support handling only a single SPDM descriptor */
     114         [ #  # ]:           0 :     if (num_descriptors > 1) {
     115                 :           0 :         spdm_error.session_id = session_id;
     116                 :           0 :         spdm_error.error_code = SPDM_STORAGE_SECURED_MSG_ENCAPSULATED_STATUS_INVALID_CMD;
     117                 :           0 :         libspdm_set_last_spdm_error_struct(spdm_context, &spdm_error);
     118                 :           0 :         return LIBSPDM_STATUS_UNSUPPORTED_CAP;
     119                 :             :     }
     120                 :             : 
     121                 :           0 :     spdm_storage_descriptor_start = ((uint8_t *)(*message)) + (sizeof(uint8_t) * 3);
     122                 :           0 :     descriptor = (void *)spdm_storage_descriptor_start;
     123                 :             : 
     124         [ #  # ]:           0 :     for (int i = 0; i < num_descriptors; ++i) {
     125         [ #  # ]:           0 :         switch(descriptor->desc_type) {
     126                 :           0 :         case SPDM_STORAGE_SECURED_MSG_DESCRIPTOR_SPDM:
     127         [ #  # ]:           0 :             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         [ #  # ]:           0 :             if (LIBSPDM_STORAGE_SECURED_MESSAGE_NUM_DESCRIPTORS_OFFSET > descriptor->offset)
     136                 :           0 :                 return LIBSPDM_STATUS_INVALID_MSG_FIELD;
     137                 :             : 
     138                 :           0 :             spdm_msg_offset = descriptor->offset -
     139                 :             :                               LIBSPDM_STORAGE_SECURED_MESSAGE_NUM_DESCRIPTORS_OFFSET;
     140         [ #  # ]:           0 :             if (spdm_msg_offset > *message_size)
     141                 :           0 :                 return LIBSPDM_STATUS_INVALID_MSG_SIZE;
     142                 :             : 
     143         [ #  # ]:           0 :             if (!is_request_message &&
     144         [ #  # ]:           0 :                 descriptor->status != SPDM_STORAGE_SECURED_MSG_ENCAPSULATED_STATUS_SUCCESS)
     145                 :           0 :                 return LIBSPDM_STATUS_ERROR_PEER;
     146                 :             : 
     147                 :           0 :             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                 :           0 :         descriptor = (void *)(spdm_storage_descriptor_start +
     157                 :           0 :                               (LIBSPDM_STORAGE_SECURED_MESSAGE_DESCRIPTOR_MIN_SIZE * i));
     158                 :             :     }
     159                 :             : 
     160                 :           0 :     *message = ((uint8_t *)*message) + spdm_msg_offset;
     161                 :           0 :     *message_size -= spdm_msg_offset;
     162                 :             : 
     163                 :           0 :     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                 :           0 : 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                 :           0 :     size_t sec_trans_header_size = is_request_message ?
     191         [ #  # ]:           0 :                                    sizeof(libspdm_storage_transport_virtual_header_t): 0;
     192                 :             :     uint8_t* secured_storage_desc_start;
     193                 :             :     uint8_t* secured_storage_desc_end;
     194                 :           0 :     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                 :           0 :     sec_trans_header_size += sizeof(uint8_t) * 4;
     199                 :             : 
     200                 :           0 :     libspdm_zero_mem(*transport_message, *transport_message_size);
     201                 :           0 :     *secured_message = ((uint8_t *)(*transport_message)) + sec_trans_header_size;
     202                 :           0 :     *secured_message_size = *transport_message_size - sec_trans_header_size;
     203                 :             : 
     204                 :           0 :     if (*secured_message_size <
     205         [ #  # ]:           0 :         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                 :           0 :     secured_storage_desc_start = *secured_message + (4 + 2 + 2 + 2 + 2);
     212                 :           0 :     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                 :           0 :     libspdm_copy_mem(secured_storage_desc_end,
     220                 :           0 :                      *secured_message_size - LIBSPDM_STORAGE_SECURED_MESSAGE_DESCRIPTOR_MIN_SIZE,
     221                 :             :                      *message, *message_size);
     222                 :           0 :     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                 :           0 :     libspdm_get_last_spdm_error_struct(spdm_context, &spdm_error);
     227                 :             : 
     228                 :             :     /* Encode Secured Message Storage Descriptor */
     229                 :           0 :     secured_storage_desc_start[0] = num_descriptors;
     230                 :             :     /* 3 reserved bytes before the descriptor begins */
     231                 :           0 :     descriptor = (void *)(secured_storage_desc_start + (sizeof(uint8_t) * 3));
     232                 :           0 :     descriptor->desc_type = SPDM_STORAGE_SECURED_MSG_DESCRIPTOR_SPDM;
     233         [ #  # ]:           0 :     descriptor->status =
     234                 :             :         is_request_message ? 0 : spdm_error.error_code;
     235                 :             : 
     236                 :             :     /* Length of the element this SPDM element  */
     237                 :           0 :     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                 :           0 :     *message = secured_storage_desc_start;
     245                 :           0 :     *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                 :           0 :     descriptor->offset = (4 + 4 + 2 + 2 + 2 + 2 +
     253                 :             :                           LIBSPDM_STORAGE_SECURED_MESSAGE_DESCRIPTOR_MIN_SIZE);
     254                 :             : 
     255                 :           0 :     return LIBSPDM_STATUS_SUCCESS;
     256                 :             : }
     257                 :             : 
     258                 :           2 : 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         [ -  + ]:           2 :     LIBSPDM_ASSERT(transport_message_size >= sizeof(libspdm_storage_transport_virtual_header_t));
     270         [ -  + ]:           2 :     if (transport_message_size <= sizeof(libspdm_storage_transport_virtual_header_t)) {
     271                 :           0 :         return LIBSPDM_STATUS_INVALID_MSG_SIZE;
     272                 :             :     }
     273                 :             : 
     274         [ -  + ]:           2 :     if (transport_message_size == 0) {
     275                 :           0 :         return LIBSPDM_STATUS_INVALID_MSG_SIZE;
     276                 :             :     }
     277                 :             : 
     278                 :           2 :     storage_header = transport_message;
     279         [ -  + ]:           2 :     if (storage_header->security_protocol != SPDM_STORAGE_SECURITY_PROTOCOL_DMTF) {
     280                 :           0 :         return LIBSPDM_STATUS_INVALID_MSG_FIELD;
     281                 :             :     }
     282                 :             : 
     283                 :             : #if __BYTE_ORDER__==__ORDER_BIG_ENDIAN__
     284                 :             :     security_protocol_specific  = libspdm_byte_swap_16(storage_header->security_protocol_specific);
     285                 :             : #else
     286                 :           2 :     security_protocol_specific  = storage_header->security_protocol_specific;
     287                 :             : #endif
     288                 :           2 :     spsp0 = security_protocol_specific & 0xFF;
     289                 :           2 :     spsp1 = security_protocol_specific >> 8;
     290                 :             : 
     291         [ -  + ]:           2 :     if (spsp1 != 0) {
     292                 :           0 :         return LIBSPDM_STATUS_INVALID_MSG_FIELD;
     293                 :             :     }
     294                 :             : 
     295         [ -  + ]:           2 :     if (connection_id) {
     296                 :           0 :         *connection_id = spsp0 & 0x03;
     297                 :             :     }
     298                 :           2 :     spdm_operation = (spsp0 & 0xFC) >> 2;
     299                 :             : 
     300      [ +  -  - ]:           2 :     switch (spdm_operation) {
     301                 :           2 :     case SPDM_STORAGE_OPERATION_CODE_DISCOVERY:
     302                 :             :     case SPDM_STORAGE_OPERATION_CODE_PENDING_INFO:
     303                 :             :     case SPDM_STORAGE_OPERATION_CODE_MESSAGE:
     304         [ +  - ]:           2 :         if (session_id != NULL) {
     305                 :           2 :             *session_id = NULL;
     306                 :             :         }
     307                 :           2 :         *message_size = transport_message_size - sizeof(libspdm_storage_transport_virtual_header_t);
     308                 :           2 :         *message = (uint8_t *)transport_message + sizeof(libspdm_storage_transport_virtual_header_t);
     309                 :           2 :         break;
     310                 :           0 :     case SPDM_STORAGE_OPERATION_CODE_SECURED_MESSAGE:
     311         [ #  # ]:           0 :         LIBSPDM_ASSERT(session_id != NULL);
     312         [ #  # ]:           0 :         if (session_id == NULL) {
     313                 :           0 :             return LIBSPDM_STATUS_INVALID_MSG_FIELD;
     314                 :             :         }
     315         [ #  # ]:           0 :         if (transport_message_size <=
     316                 :             :             sizeof(libspdm_storage_transport_virtual_header_t) + sizeof(uint32_t)) {
     317                 :           0 :             return LIBSPDM_STATUS_INVALID_MSG_SIZE;
     318                 :             :         }
     319                 :           0 :         *session_id = (uint32_t *)((uint8_t *)transport_message +
     320                 :             :                                    sizeof(libspdm_storage_transport_virtual_header_t) +
     321                 :             :                                    LIBSPDM_STORAGE_SECURED_MESSAGE_HEADER_RESERVED_BYTES);
     322                 :           0 :         *message_size = transport_message_size - sizeof(libspdm_storage_transport_virtual_header_t) -
     323                 :             :                         LIBSPDM_STORAGE_SECURED_MESSAGE_HEADER_RESERVED_BYTES;
     324                 :           0 :         *message = (uint8_t *)transport_message + sizeof(libspdm_storage_transport_virtual_header_t) +
     325                 :             :                    LIBSPDM_STORAGE_SECURED_MESSAGE_HEADER_RESERVED_BYTES;
     326                 :           0 :         break;
     327                 :           0 :     default:
     328                 :           0 :         return LIBSPDM_STATUS_UNSUPPORTED_CAP;
     329                 :             :     }
     330                 :             : 
     331                 :           2 :     return LIBSPDM_STATUS_SUCCESS;
     332                 :             : }
     333                 :             : 
     334                 :           1 : libspdm_return_t libspdm_transport_storage_decode_message(
     335                 :             :     void *spdm_context, uint32_t **session_id,
     336                 :             :     bool *is_app_message, bool is_request_message,
     337                 :             :     size_t transport_message_size, void *transport_message,
     338                 :             :     size_t *message_size, void **message)
     339                 :             : {
     340                 :             :     libspdm_return_t status;
     341                 :             :     uint32_t *secured_message_session_id;
     342                 :             :     uint8_t *secured_message;
     343                 :             :     size_t secured_message_size;
     344                 :             :     libspdm_secured_message_callbacks_t spdm_secured_message_callbacks;
     345                 :             :     void *secured_message_context;
     346                 :             :     libspdm_error_struct_t spdm_error;
     347                 :             : 
     348                 :           1 :     spdm_error.error_code = 0;
     349                 :           1 :     spdm_error.session_id = 0;
     350                 :           1 :     libspdm_set_last_spdm_error_struct(spdm_context, &spdm_error);
     351                 :             : 
     352                 :           1 :     spdm_secured_message_callbacks.version =
     353                 :             :         LIBSPDM_SECURED_MESSAGE_CALLBACKS_VERSION;
     354                 :           1 :     spdm_secured_message_callbacks.get_sequence_number =
     355                 :             :         libspdm_storage_get_sequence_number;
     356                 :           1 :     spdm_secured_message_callbacks.get_max_random_number_count =
     357                 :             :         libspdm_storage_get_max_random_number_count;
     358                 :           1 :     spdm_secured_message_callbacks.get_secured_spdm_version =
     359                 :             :         libspdm_storage_get_secured_spdm_version;
     360                 :             : 
     361   [ +  -  -  + ]:           1 :     if ((session_id == NULL) || (is_app_message == NULL)) {
     362                 :           0 :         return LIBSPDM_STATUS_UNSUPPORTED_CAP;
     363                 :             :     }
     364                 :           1 :     *is_app_message = false;
     365                 :             : 
     366                 :           1 :     secured_message_session_id = NULL;
     367                 :             : 
     368         [ -  + ]:           1 :     if (!is_request_message) {
     369                 :             :         /*
     370                 :             :          * Storage response messages are not transport encoded, this is the SPDM
     371                 :             :          * message, and shall be processed as such. Which also means that there
     372                 :             :          * is no way from the response to determine if it's secure or not, instead
     373                 :             :          * use internal state to determine.
     374                 :             :          */
     375                 :             :         /* Expecting a secured message */
     376         [ #  # ]:           0 :         if (*session_id != NULL) {
     377         [ #  # ]:           0 :             if (transport_message_size <
     378                 :             :                 LIBSPDM_STORAGE_SECURED_MESSAGE_HEADER_RESERVED_BYTES + sizeof(uint32_t)) {
     379                 :           0 :                 return LIBSPDM_STATUS_INVALID_MSG_SIZE;
     380                 :             :             }
     381                 :           0 :             **session_id = libspdm_read_uint32(
     382                 :             :                 (const uint8_t *)transport_message +
     383                 :             :                 LIBSPDM_STORAGE_SECURED_MESSAGE_HEADER_RESERVED_BYTES);
     384                 :             : 
     385                 :             :             secured_message_context =
     386                 :           0 :                 libspdm_get_secured_message_context_via_session_id(
     387                 :           0 :                     spdm_context, **session_id);
     388         [ #  # ]:           0 :             if (secured_message_context == NULL) {
     389                 :           0 :                 spdm_error.error_code = SPDM_ERROR_CODE_INVALID_SESSION;
     390                 :           0 :                 spdm_error.session_id = **session_id;
     391                 :           0 :                 libspdm_set_last_spdm_error_struct(spdm_context,
     392                 :             :                                                    &spdm_error);
     393                 :           0 :                 return LIBSPDM_STATUS_UNSUPPORTED_CAP;
     394                 :             :             }
     395                 :             : 
     396                 :             :             /*
     397                 :             :              * Secured message to message
     398                 :             :              *
     399                 :             :              * DSP0286 specifies 4 reserved bytes at the start of a secured
     400                 :             :              * message. Skip that for decoding.
     401                 :             :              */
     402                 :           0 :             status = libspdm_decode_secured_message(
     403                 :           0 :                 secured_message_context, **session_id,
     404                 :             :                 is_request_message,
     405                 :             :                 transport_message_size - LIBSPDM_STORAGE_SECURED_MESSAGE_HEADER_RESERVED_BYTES,
     406                 :             :                 ((uint8_t *)transport_message) +
     407                 :             :                 LIBSPDM_STORAGE_SECURED_MESSAGE_HEADER_RESERVED_BYTES,
     408                 :             :                 message_size, message, &spdm_secured_message_callbacks);
     409                 :             : 
     410         [ #  # ]:           0 :             if (LIBSPDM_STATUS_IS_ERROR(status)) {
     411                 :           0 :                 LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR,
     412                 :             :                                "libspdm_decode_secured_message - %x\n", status));
     413                 :           0 :                 libspdm_secured_message_get_last_spdm_error_struct(
     414                 :             :                     secured_message_context, &spdm_error);
     415                 :           0 :                 libspdm_set_last_spdm_error_struct(spdm_context,
     416                 :             :                                                    &spdm_error);
     417                 :           0 :                 return status;
     418                 :             :             }
     419                 :             : 
     420                 :           0 :             status = libspdm_storage_secured_message_decode(spdm_context, **session_id, message_size,
     421                 :             :                                                             message, is_request_message);
     422         [ #  # ]:           0 :             if (LIBSPDM_STATUS_IS_ERROR(status)) {
     423                 :           0 :                 LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR,
     424                 :             :                                "libspdm_storage_secured_message_decode - %x\n", status));
     425                 :           0 :                 return status;
     426                 :             :             }
     427                 :             : 
     428                 :             :         } else {
     429                 :           0 :             *message_size = transport_message_size;
     430                 :           0 :             *message = transport_message;
     431                 :           0 :             *session_id = NULL;
     432                 :             :         };
     433                 :           0 :         return LIBSPDM_STATUS_SUCCESS;
     434                 :             :     } else {
     435                 :             :         /* Storage requests need to be transport encoded/decoded */
     436                 :           1 :         status = libspdm_storage_decode_message(
     437                 :             :             &secured_message_session_id, 0, transport_message_size,
     438                 :             :             transport_message, &secured_message_size, (void **)&secured_message);
     439                 :             : 
     440         [ -  + ]:           1 :         if (LIBSPDM_STATUS_IS_ERROR(status)) {
     441                 :           0 :             LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR, "transport_decode_message - %x\n", status));
     442                 :           0 :             return status;
     443                 :             :         }
     444                 :             : 
     445         [ -  + ]:           1 :         if (secured_message_session_id != NULL) {
     446                 :           0 :             *session_id = secured_message_session_id;
     447                 :             : 
     448                 :             :             secured_message_context =
     449                 :           0 :                 libspdm_get_secured_message_context_via_session_id(
     450                 :             :                     spdm_context, *secured_message_session_id);
     451         [ #  # ]:           0 :             if (secured_message_context == NULL) {
     452                 :           0 :                 spdm_error.error_code = SPDM_ERROR_CODE_INVALID_SESSION;
     453                 :           0 :                 spdm_error.session_id = *secured_message_session_id;
     454                 :           0 :                 libspdm_set_last_spdm_error_struct(spdm_context,
     455                 :             :                                                    &spdm_error);
     456                 :           0 :                 return LIBSPDM_STATUS_UNSUPPORTED_CAP;
     457                 :             :             }
     458                 :             : 
     459                 :             :             /* Secured message to message*/
     460                 :           0 :             status = libspdm_decode_secured_message(
     461                 :             :                 secured_message_context, *secured_message_session_id,
     462                 :             :                 is_request_message, secured_message_size,
     463                 :             :                 (uint8_t *)secured_message,
     464                 :             :                 message_size, message, &spdm_secured_message_callbacks);
     465         [ #  # ]:           0 :             if (LIBSPDM_STATUS_IS_ERROR(status)) {
     466                 :           0 :                 LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR,
     467                 :             :                                "libspdm_decode_secured_message - %x\n", status));
     468                 :           0 :                 libspdm_secured_message_get_last_spdm_error_struct(
     469                 :             :                     secured_message_context, &spdm_error);
     470                 :           0 :                 libspdm_set_last_spdm_error_struct(spdm_context,
     471                 :             :                                                    &spdm_error);
     472                 :           0 :                 return status;
     473                 :             :             }
     474                 :             : 
     475                 :           0 :             status = libspdm_storage_secured_message_decode(spdm_context, **session_id, message_size,
     476                 :             :                                                             message, is_request_message);
     477         [ #  # ]:           0 :             if (LIBSPDM_STATUS_IS_ERROR(status)) {
     478                 :           0 :                 LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR,
     479                 :             :                                "libspdm_storage_secured_message_decode - %x\n", status));
     480                 :           0 :                 return status;
     481                 :             :             }
     482                 :           0 :             return LIBSPDM_STATUS_SUCCESS;
     483                 :             :         } else {
     484                 :             :             /* get non-secured message*/
     485                 :           1 :             status = libspdm_storage_decode_message(&secured_message_session_id,
     486                 :             :                                                     0,
     487                 :             :                                                     transport_message_size,
     488                 :             :                                                     transport_message,
     489                 :             :                                                     message_size, message);
     490         [ -  + ]:           1 :             if (LIBSPDM_STATUS_IS_ERROR(status)) {
     491                 :           0 :                 LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR, "transport_decode_message - %x\n",
     492                 :             :                                status));
     493                 :           0 :                 return status;
     494                 :             :             }
     495         [ -  + ]:           1 :             LIBSPDM_ASSERT(secured_message_session_id == NULL);
     496                 :           1 :             *session_id = NULL;
     497                 :           1 :             return LIBSPDM_STATUS_SUCCESS;
     498                 :             :         }
     499                 :             :     }
     500                 :             : }
     501                 :             : 
     502                 :           2 : libspdm_return_t libspdm_storage_encode_message(const uint32_t *session_id,
     503                 :             :                                                 uint8_t connection_id,
     504                 :             :                                                 size_t message_size, void *message,
     505                 :             :                                                 size_t *transport_message_size,
     506                 :             :                                                 void **transport_message)
     507                 :             : {
     508                 :             :     uint32_t data32;
     509                 :             :     libspdm_storage_transport_virtual_header_t *storage_header;
     510                 :             : 
     511   [ +  -  +  - ]:           2 :     if (!transport_message_size || *transport_message_size == 0
     512         [ -  + ]:           2 :         || message_size == 0) {
     513                 :           0 :         return LIBSPDM_STATUS_INVALID_MSG_SIZE;
     514                 :             :     }
     515                 :             : 
     516         [ -  + ]:           2 :     LIBSPDM_ASSERT(*transport_message_size >= sizeof(libspdm_storage_transport_virtual_header_t));
     517                 :             : 
     518         [ -  + ]:           2 :     if (*transport_message_size < message_size + sizeof(libspdm_storage_transport_virtual_header_t)) {
     519                 :           0 :         *transport_message_size = message_size + sizeof(libspdm_storage_transport_virtual_header_t);
     520                 :           0 :         return LIBSPDM_STATUS_BUFFER_TOO_SMALL;
     521                 :             :     }
     522                 :             : 
     523   [ +  -  -  + ]:           2 :     if (!message || !transport_message) {
     524                 :           0 :         return LIBSPDM_STATUS_INVALID_MSG_SIZE;
     525                 :             :     }
     526                 :             : 
     527         [ -  + ]:           2 :     if (connection_id & ~0x03) {
     528                 :           0 :         return LIBSPDM_STATUS_INVALID_MSG_FIELD;
     529                 :             :     }
     530                 :             : 
     531                 :           2 :     *transport_message_size = message_size + sizeof(libspdm_storage_transport_virtual_header_t);
     532                 :           2 :     *transport_message = (uint8_t *)message - sizeof(libspdm_storage_transport_virtual_header_t);
     533                 :           2 :     storage_header = *transport_message;
     534                 :             : 
     535                 :           2 :     storage_header->security_protocol = SPDM_STORAGE_SECURITY_PROTOCOL_DMTF;
     536                 :             : 
     537         [ -  + ]:           2 :     if (session_id != NULL) {
     538                 :           0 :         storage_header->security_protocol_specific = SPDM_STORAGE_OPERATION_CODE_SECURED_MESSAGE <<
     539                 :             :                                                      2;
     540                 :           0 :         storage_header->security_protocol_specific |= connection_id &
     541                 :             :                                                       SPDM_STORAGE_MAX_CONNECTION_ID_MASK;
     542                 :           0 :         libspdm_zero_mem(message, LIBSPDM_STORAGE_SECURED_MESSAGE_HEADER_RESERVED_BYTES);
     543                 :           0 :         data32 = libspdm_read_uint32(((const uint8_t *)message +
     544                 :             :                                       LIBSPDM_STORAGE_SECURED_MESSAGE_HEADER_RESERVED_BYTES));
     545         [ #  # ]:           0 :         LIBSPDM_ASSERT(*session_id == data32);
     546         [ #  # ]:           0 :         if (*session_id != data32) {
     547                 :           0 :             return LIBSPDM_STATUS_INVALID_MSG_FIELD;
     548                 :             :         }
     549                 :             :     } else {
     550                 :           2 :         storage_header->security_protocol_specific = SPDM_STORAGE_OPERATION_CODE_MESSAGE << 2;
     551                 :           2 :         storage_header->security_protocol_specific |= connection_id &
     552                 :             :                                                       SPDM_STORAGE_MAX_CONNECTION_ID_MASK;
     553                 :             :     }
     554                 :             : 
     555                 :             : #if __BYTE_ORDER__==__ORDER_BIG_ENDIAN__
     556                 :             :     storage_header->security_protocol_specific = libspdm_byte_swap_16(
     557                 :             :         storage_header->security_protocol_specific);
     558                 :             : #endif
     559                 :             : 
     560                 :           2 :     return LIBSPDM_STATUS_SUCCESS;
     561                 :             : }
     562                 :             : 
     563                 :           3 : libspdm_return_t libspdm_transport_storage_encode_message(
     564                 :             :     void *spdm_context, const uint32_t *session_id,
     565                 :             :     bool is_app_message,
     566                 :             :     bool is_request_message, size_t message_size, void *message,
     567                 :             :     size_t *transport_message_size, void **transport_message)
     568                 :             : {
     569                 :             :     libspdm_return_t status;
     570                 :             :     uint8_t *secured_message;
     571                 :             :     size_t secured_message_size;
     572                 :             :     libspdm_secured_message_callbacks_t spdm_secured_message_callbacks;
     573                 :             :     void *secured_message_context;
     574                 :             : 
     575                 :           3 :     spdm_secured_message_callbacks.version =
     576                 :             :         LIBSPDM_SECURED_MESSAGE_CALLBACKS_VERSION;
     577                 :           3 :     spdm_secured_message_callbacks.get_sequence_number =
     578                 :             :         libspdm_storage_get_sequence_number;
     579                 :           3 :     spdm_secured_message_callbacks.get_max_random_number_count =
     580                 :             :         libspdm_storage_get_max_random_number_count;
     581                 :           3 :     spdm_secured_message_callbacks.get_secured_spdm_version =
     582                 :             :         libspdm_storage_get_secured_spdm_version;
     583                 :             : 
     584         [ -  + ]:           3 :     if (is_app_message) {
     585                 :           0 :         return LIBSPDM_STATUS_UNSUPPORTED_CAP;
     586                 :             :     }
     587                 :             : 
     588   [ +  -  +  - ]:           3 :     if (!transport_message_size || !transport_message
     589         [ +  + ]:           3 :         || *transport_message_size == 0) {
     590                 :           1 :         return LIBSPDM_STATUS_INVALID_MSG_SIZE;
     591                 :             :     }
     592                 :             : 
     593         [ -  + ]:           2 :     if (session_id != NULL) {
     594                 :             :         secured_message_context =
     595                 :           0 :             libspdm_get_secured_message_context_via_session_id(
     596                 :             :                 spdm_context, *session_id);
     597         [ #  # ]:           0 :         if (secured_message_context == NULL) {
     598                 :           0 :             return LIBSPDM_STATUS_UNSUPPORTED_CAP;
     599                 :             :         }
     600                 :             : 
     601                 :             :         /* Message to secured message*/
     602                 :           0 :         status = libspdm_storage_secured_message_encode(
     603                 :             :             spdm_context, &message_size, &message, &secured_message_size, &secured_message,
     604                 :             :             transport_message_size, transport_message, is_request_message);
     605         [ #  # ]:           0 :         if (LIBSPDM_STATUS_IS_ERROR(status)) {
     606                 :           0 :             LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR,
     607                 :             :                            "libspdm_storage_secured_message_encode - %x\n", status));
     608                 :           0 :             return status;
     609                 :             :         }
     610                 :             : 
     611                 :           0 :         status = libspdm_encode_secured_message(
     612                 :             :             secured_message_context, *session_id, is_request_message,
     613                 :             :             message_size, message, &secured_message_size,
     614                 :             :             secured_message, &spdm_secured_message_callbacks);
     615         [ #  # ]:           0 :         if (LIBSPDM_STATUS_IS_ERROR(status)) {
     616                 :           0 :             LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR,
     617                 :             :                            "libspdm_encode_secured_message - %x\n", status));
     618                 :           0 :             return status;
     619                 :             :         }
     620                 :             : 
     621         [ #  # ]:           0 :         if (!is_request_message) {
     622                 :             :             /*
     623                 :             :              * Storage response messages are not transport encoded, instead it
     624                 :             :              * is just the SPDM message response.
     625                 :             :              */
     626                 :           0 :             *transport_message_size = secured_message_size +
     627                 :             :                                       LIBSPDM_STORAGE_SECURED_MESSAGE_HEADER_RESERVED_BYTES;
     628                 :             :             /* Ensure we allow the 4 reserved bytes to be encapsulated */
     629                 :           0 :             *transport_message = secured_message -
     630                 :             :                                  LIBSPDM_STORAGE_SECURED_MESSAGE_HEADER_RESERVED_BYTES;
     631                 :           0 :             return LIBSPDM_STATUS_SUCCESS;
     632                 :             :         }
     633                 :             : 
     634                 :             :         /* secured message to secured storage message*/
     635                 :           0 :         status = libspdm_storage_encode_message(
     636                 :             :             session_id, 0,
     637                 :             :             secured_message_size + LIBSPDM_STORAGE_SECURED_MESSAGE_HEADER_RESERVED_BYTES,
     638                 :           0 :             secured_message - LIBSPDM_STORAGE_SECURED_MESSAGE_HEADER_RESERVED_BYTES,
     639                 :             :             transport_message_size, transport_message);
     640         [ #  # ]:           0 :         if (LIBSPDM_STATUS_IS_ERROR(status)) {
     641                 :           0 :             LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR, "transport_encode_message - %x\n",
     642                 :             :                            status));
     643                 :           0 :             return status;
     644                 :             :         }
     645                 :             :     } else {
     646         [ -  + ]:           2 :         if (!is_request_message) {
     647                 :             :             /*
     648                 :             :              * Storage response messages are not transport encoded, instead it
     649                 :             :              * is just the SPDM message response.
     650                 :             :              */
     651                 :           0 :             *transport_message_size = message_size;
     652                 :           0 :             *transport_message = message;
     653                 :           0 :             return LIBSPDM_STATUS_SUCCESS;
     654                 :             :         }
     655                 :             : 
     656                 :             :         /* SPDM message to normal storage message*/
     657                 :           2 :         status = libspdm_storage_encode_message(NULL, 0,
     658                 :             :                                                 message_size, message,
     659                 :             :                                                 transport_message_size,
     660                 :             :                                                 transport_message);
     661         [ -  + ]:           2 :         if (LIBSPDM_STATUS_IS_ERROR(status)) {
     662                 :           0 :             LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR, "transport_encode_message - %x\n",
     663                 :             :                            status));
     664                 :           0 :             return status;
     665                 :             :         }
     666                 :             :     }
     667                 :             : 
     668                 :           2 :     return LIBSPDM_STATUS_SUCCESS;
     669                 :             : }
     670                 :             : 
     671                 :           6 : libspdm_return_t libspdm_transport_storage_encode_management_cmd(
     672                 :             :     uint8_t cmd_direction, uint8_t transport_operation,
     673                 :             :     uint8_t connection_id, size_t *transport_message_size,
     674                 :             :     size_t *allocation_length, void *transport_message)
     675                 :             : {
     676                 :             :     libspdm_storage_transport_virtual_header_t *storage_header;
     677                 :             : 
     678   [ +  -  +  - ]:           6 :     if (!transport_message_size || !allocation_length
     679         [ +  + ]:           6 :         || *transport_message_size == 0) {
     680                 :           1 :         return LIBSPDM_STATUS_INVALID_MSG_SIZE;
     681                 :             :     }
     682                 :             : 
     683         [ -  + ]:           5 :     if (*transport_message_size < sizeof(libspdm_storage_transport_virtual_header_t)) {
     684                 :           0 :         return LIBSPDM_STATUS_BUFFER_TOO_SMALL;
     685                 :             :     }
     686                 :             : 
     687         [ -  + ]:           5 :     if (connection_id & ~0x03) {
     688                 :           0 :         return LIBSPDM_STATUS_INVALID_MSG_FIELD;
     689                 :             :     }
     690                 :             : 
     691   [ +  +  +  + ]:           5 :     if (!(cmd_direction == LIBSPDM_STORAGE_CMD_DIRECTION_IF_SEND ||
     692                 :             :           cmd_direction == LIBSPDM_STORAGE_CMD_DIRECTION_IF_RECV)) {
     693                 :           1 :         return LIBSPDM_STATUS_INVALID_MSG_FIELD;
     694                 :             :     }
     695                 :             : 
     696      [ +  +  + ]:           4 :     switch (transport_operation) {
     697                 :           2 :     case SPDM_STORAGE_OPERATION_CODE_DISCOVERY:
     698         [ +  - ]:           2 :         if (cmd_direction == LIBSPDM_STORAGE_CMD_DIRECTION_IF_RECV) {
     699                 :           2 :             *allocation_length = sizeof(spdm_storage_discovery_response_t);
     700         [ -  + ]:           2 :             if (*transport_message_size < sizeof(spdm_storage_discovery_response_t)) {
     701                 :           0 :                 return LIBSPDM_STATUS_BUFFER_TOO_SMALL;
     702                 :             :             }
     703                 :             :         }
     704                 :           2 :         break;
     705                 :           1 :     case SPDM_STORAGE_OPERATION_CODE_PENDING_INFO:
     706         [ -  + ]:           1 :         if (cmd_direction == LIBSPDM_STORAGE_CMD_DIRECTION_IF_RECV) {
     707                 :           0 :             *allocation_length = sizeof(spdm_storage_pending_info_response_t);
     708         [ #  # ]:           0 :             if (*transport_message_size < sizeof(spdm_storage_pending_info_response_t)) {
     709                 :           0 :                 return LIBSPDM_STATUS_BUFFER_TOO_SMALL;
     710                 :             :             }
     711                 :             :         }
     712                 :           1 :         break;
     713                 :           1 :     default:
     714                 :           1 :         return LIBSPDM_STATUS_INVALID_MSG_FIELD;
     715                 :             :     }
     716                 :             : 
     717                 :           3 :     *transport_message_size = sizeof(libspdm_storage_transport_virtual_header_t);
     718                 :           3 :     libspdm_zero_mem(transport_message, *transport_message_size);
     719                 :             : 
     720                 :           3 :     storage_header = transport_message;
     721                 :           3 :     storage_header->security_protocol = SPDM_STORAGE_SECURITY_PROTOCOL_DMTF;
     722                 :           3 :     storage_header->security_protocol_specific = transport_operation << 2;
     723                 :           3 :     storage_header->security_protocol_specific |= connection_id &
     724                 :             :                                                   SPDM_STORAGE_MAX_CONNECTION_ID_MASK;
     725                 :             : 
     726                 :             : #if __BYTE_ORDER__==__ORDER_BIG_ENDIAN__
     727                 :             :     storage_header->security_protocol_specific = libspdm_byte_swap_16(
     728                 :             :         storage_header->security_protocol_specific);
     729                 :             : #endif
     730                 :             : 
     731                 :           3 :     return LIBSPDM_STATUS_SUCCESS;
     732                 :             : }
     733                 :             : 
     734                 :           2 : libspdm_return_t libspdm_transport_storage_encode_discovery_response(
     735                 :             :     size_t *transport_message_size,
     736                 :             :     void *transport_message)
     737                 :             : {
     738                 :             :     spdm_storage_discovery_response_t *discovery_response;
     739                 :             : 
     740   [ +  -  +  - ]:           2 :     if (!transport_message || !transport_message_size
     741         [ -  + ]:           2 :         || *transport_message_size == 0) {
     742                 :           0 :         return LIBSPDM_STATUS_INVALID_MSG_SIZE;
     743                 :             :     }
     744                 :             : 
     745         [ +  + ]:           2 :     if (*transport_message_size < sizeof(spdm_storage_discovery_response_t)) {
     746                 :           1 :         return LIBSPDM_STATUS_BUFFER_TOO_SMALL;
     747                 :             :     }
     748                 :             : 
     749                 :           1 :     *transport_message_size = sizeof(spdm_storage_discovery_response_t);
     750                 :           1 :     libspdm_zero_mem(transport_message, *transport_message_size);
     751                 :           1 :     discovery_response = transport_message;
     752                 :             : 
     753                 :           1 :     discovery_response->storage_response_headers.data_length = (uint16_t)*transport_message_size;
     754                 :           1 :     discovery_response->storage_response_headers.storage_binding_version =
     755                 :             :         SPDM_STORAGE_SECURITY_BINDING_VERSION;
     756                 :             :     /* 1 supported connection (0's based) */
     757                 :           1 :     discovery_response->conn_params = 0;
     758                 :           1 :     discovery_response->supported_operations = (1 << SPDM_STORAGE_OPERATION_CODE_DISCOVERY)
     759                 :             :                                                | (1 << SPDM_STORAGE_OPERATION_CODE_PENDING_INFO)
     760                 :             :                                                | (1 << SPDM_STORAGE_OPERATION_CODE_MESSAGE)
     761                 :             :                                                | (1 <<
     762                 :             :                                                   SPDM_STORAGE_OPERATION_CODE_SECURED_MESSAGE);
     763                 :             : 
     764                 :           1 :     return LIBSPDM_STATUS_SUCCESS;
     765                 :             : }
     766                 :             : 
     767                 :           4 : libspdm_return_t libspdm_transport_storage_encode_pending_info_response(
     768                 :             :     size_t *transport_message_size,
     769                 :             :     void *transport_message, bool response_pending,
     770                 :             :     uint32_t pending_response_length)
     771                 :             : {
     772                 :             :     spdm_storage_pending_info_response_t *pending_info_response;
     773                 :             : 
     774   [ +  -  +  + ]:           4 :     if (!transport_message || !transport_message_size
     775         [ -  + ]:           3 :         || *transport_message_size == 0) {
     776                 :           1 :         return LIBSPDM_STATUS_INVALID_MSG_SIZE;
     777                 :             :     }
     778                 :             : 
     779         [ +  + ]:           3 :     if (*transport_message_size < sizeof(spdm_storage_pending_info_response_t)) {
     780                 :           1 :         return LIBSPDM_STATUS_BUFFER_TOO_SMALL;
     781                 :             :     }
     782                 :             : 
     783                 :           2 :     *transport_message_size = sizeof(spdm_storage_pending_info_response_t);
     784                 :           2 :     libspdm_zero_mem(transport_message, *transport_message_size);
     785                 :           2 :     pending_info_response = transport_message;
     786                 :             : 
     787                 :           2 :     pending_info_response->storage_response_headers.data_length = (uint16_t)*transport_message_size;
     788                 :           2 :     pending_info_response->storage_response_headers.storage_binding_version =
     789                 :             :         SPDM_STORAGE_SECURITY_BINDING_VERSION;
     790                 :             : 
     791         [ +  + ]:           2 :     if (response_pending) {
     792                 :           1 :         pending_info_response->pending_info_flag = (1 << 0);
     793                 :           1 :         pending_info_response->response_length = pending_response_length;
     794                 :             :     }
     795                 :             : 
     796                 :           2 :     return LIBSPDM_STATUS_SUCCESS;
     797                 :             : }
     798                 :             : 
     799                 :           1 : libspdm_return_t libspdm_transport_storage_decode_management_cmd(
     800                 :             :     size_t transport_message_size,
     801                 :             :     const void *transport_message,
     802                 :             :     uint8_t *transport_command)
     803                 :             : {
     804                 :             :     const libspdm_storage_transport_virtual_header_t *storage_header;
     805                 :             :     uint16_t security_protocol_specific;
     806                 :             :     uint8_t spsp0, spsp1, spdm_operation;
     807                 :             : 
     808   [ +  -  -  + ]:           1 :     if (!transport_message || transport_message_size == 0) {
     809                 :           0 :         return LIBSPDM_STATUS_INVALID_MSG_SIZE;
     810                 :             :     }
     811                 :             : 
     812         [ -  + ]:           1 :     LIBSPDM_ASSERT(transport_message_size >= sizeof(libspdm_storage_transport_virtual_header_t));
     813                 :             : 
     814         [ -  + ]:           1 :     if (transport_message_size < sizeof(libspdm_storage_transport_virtual_header_t)) {
     815                 :           0 :         return LIBSPDM_STATUS_INVALID_MSG_SIZE;
     816                 :             :     }
     817                 :             : 
     818                 :           1 :     storage_header = transport_message;
     819         [ -  + ]:           1 :     if (storage_header->security_protocol != SPDM_STORAGE_SECURITY_PROTOCOL_DMTF) {
     820                 :           0 :         return LIBSPDM_STATUS_INVALID_MSG_FIELD;
     821                 :             :     }
     822                 :             : 
     823                 :             : #if __BYTE_ORDER__==__ORDER_BIG_ENDIAN__
     824                 :             :     security_protocol_specific = libspdm_byte_swap_16(storage_header->security_protocol_specific);
     825                 :             : #else
     826                 :           1 :     security_protocol_specific = storage_header->security_protocol_specific;
     827                 :             : #endif
     828                 :           1 :     spsp0 = security_protocol_specific & 0xFF;
     829                 :           1 :     spsp1 = security_protocol_specific >> 8;
     830                 :             : 
     831         [ -  + ]:           1 :     if (spsp1 != 0) {
     832                 :           0 :         return LIBSPDM_STATUS_INVALID_MSG_FIELD;
     833                 :             :     }
     834                 :             : 
     835                 :           1 :     spdm_operation = (spsp0 & 0xFC) >> 2;
     836                 :             : 
     837         [ +  - ]:           1 :     switch (spdm_operation) {
     838                 :           1 :     case SPDM_STORAGE_OPERATION_CODE_DISCOVERY:
     839                 :             :     case SPDM_STORAGE_OPERATION_CODE_PENDING_INFO:
     840                 :             :     case SPDM_STORAGE_OPERATION_CODE_MESSAGE:
     841                 :             :     case SPDM_STORAGE_OPERATION_CODE_SECURED_MESSAGE:
     842                 :           1 :         *transport_command = spdm_operation;
     843                 :           1 :         break;
     844                 :           0 :     default:
     845                 :           0 :         *transport_command = 0;
     846                 :           0 :         return LIBSPDM_STATUS_UNSUPPORTED_CAP;
     847                 :             :     }
     848                 :             : 
     849                 :           1 :     return LIBSPDM_STATUS_SUCCESS;
     850                 :             : }
        

Generated by: LCOV version 2.0-1