Code coverage report for DMTF/libspdm
Current view: top level - library/spdm_transport_tcp_lib - libspdm_tcp_tcp.c (source / functions) Coverage Total Hit
Test: 36148b912f76d231c18d216d6dee5c0858575bb1 Lines: 95.0 % 80 76
Test Date: 2026-10-25 08:40:22 Functions: 100.0 % 8 8
Branches: 83.8 % 37 31

             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_tcp_lib.h"
       8                 :             : #include "internal/libspdm_common_lib.h"
       9                 :             : #include "hal/library/memlib.h"
      10                 :             : #include "industry_standard/spdm_tcp_binding.h"
      11                 :             : 
      12                 :          18 : uint8_t libspdm_tcp_get_sequence_number(uint64_t sequence_number,
      13                 :             :                                         uint8_t *sequence_number_buffer)
      14                 :             : {
      15                 :          18 :     return SPDM_TCP_SEQUENCE_NUMBER_COUNT;
      16                 :             : }
      17                 :             : 
      18                 :          10 : uint32_t libspdm_tcp_get_max_random_number_count(void)
      19                 :             : {
      20                 :          10 :     return SPDM_TCP_MAX_RANDOM_NUMBER_COUNT;
      21                 :             : }
      22                 :             : 
      23                 :          18 : spdm_version_number_t libspdm_tcp_get_secured_spdm_version(
      24                 :             :     spdm_version_number_t secured_message_version)
      25                 :             : {
      26                 :          18 :     return secured_message_version;
      27                 :             : }
      28                 :             : 
      29                 :             : /**
      30                 :             :  * Encode a normal message or secured message to a transport message.
      31                 :             :  *
      32                 :             :  * @param  session_id                    Indicates if it is a secured message protected via SPDM session.
      33                 :             :  *                                     If session_id is NULL, it is a normal message.
      34                 :             :  *                                     If session_id is NOT NULL, it is a secured message.
      35                 :             :  * @param  message_size                  size in bytes of the message data buffer.
      36                 :             :  * @param  message                      A pointer to a source buffer to store the message.
      37                 :             :  * @param  transport_message_size         size in bytes of the transport message data buffer.
      38                 :             :  * @param  transport_message             A pointer to a destination buffer to store the transport message.
      39                 :             :  **/
      40                 :          18 : libspdm_return_t libspdm_tcp_encode_message(const uint32_t *session_id, size_t message_size,
      41                 :             :                                             void *message,
      42                 :             :                                             size_t *transport_message_size,
      43                 :             :                                             void **transport_message)
      44                 :             : {
      45                 :             :     uint32_t data32;
      46                 :             :     spdm_tcp_binding_header_t *tcp_message_header;
      47                 :             : 
      48         [ -  + ]:          18 :     if (message_size > UINT16_MAX) {
      49                 :           0 :         return LIBSPDM_STATUS_BUFFER_FULL;
      50                 :             :     }
      51                 :             : 
      52                 :          18 :     if (*transport_message_size <
      53         [ +  + ]:          18 :         message_size + sizeof(spdm_tcp_binding_header_t)) {
      54                 :           2 :         *transport_message_size = message_size +
      55                 :             :                                   sizeof(spdm_tcp_binding_header_t);
      56                 :           2 :         return LIBSPDM_STATUS_BUFFER_TOO_SMALL;
      57                 :             :     }
      58                 :             : 
      59                 :          16 :     *transport_message_size =
      60                 :          16 :         message_size + sizeof(spdm_tcp_binding_header_t);
      61                 :          16 :     *transport_message = (uint8_t *)message - sizeof(spdm_tcp_binding_header_t);
      62                 :          16 :     tcp_message_header = *transport_message;
      63                 :          16 :     tcp_message_header->payload_length = (uint16_t)message_size;
      64                 :          16 :     tcp_message_header->binding_version = 0x1;
      65                 :             : 
      66         [ +  + ]:          16 :     if (session_id != NULL) {
      67                 :           8 :         tcp_message_header->message_type = SPDM_TCP_MESSAGE_TYPE_IN_SESSION;
      68                 :           8 :         data32 = libspdm_read_uint32((const uint8_t *)message);
      69                 :           8 :         LIBSPDM_ASSERT(*session_id == data32);
      70         [ -  + ]:           8 :         if (*session_id != data32) {
      71                 :           0 :             return LIBSPDM_STATUS_INVALID_MSG_FIELD;
      72                 :             :         }
      73                 :             :     } else {
      74                 :           8 :         tcp_message_header->message_type = SPDM_TCP_MESSAGE_TYPE_OUT_OF_SESSION;
      75                 :             :     }
      76                 :             : 
      77                 :          16 :     return LIBSPDM_STATUS_SUCCESS;
      78                 :             : }
      79                 :             : 
      80                 :             : 
      81                 :             : /**
      82                 :             :  * Decode a transport message to a normal message or secured message.
      83                 :             :  *
      84                 :             :  * @param  session_id                    Indicates if it is a secured message protected via SPDM session.
      85                 :             :  *                                     If *session_id is NULL, it is a normal message.
      86                 :             :  *                                     If *session_id is NOT NULL, it is a secured message.
      87                 :             :  * @param  transport_message_size         size in bytes of the transport message data buffer.
      88                 :             :  * @param  transport_message             A pointer to a source buffer to store the transport message.
      89                 :             :  * @param  message_size                  size in bytes of the message data buffer.
      90                 :             :  * @param  message                      A pointer to a destination buffer to store the message.
      91                 :             :  **/
      92                 :          28 : libspdm_return_t libspdm_tcp_decode_message(uint32_t **session_id,
      93                 :             :                                             size_t transport_message_size,
      94                 :             :                                             void *transport_message,
      95                 :             :                                             size_t *message_size, void **message)
      96                 :             : {
      97                 :             :     const spdm_tcp_binding_header_t *tcp_message_header;
      98                 :             : 
      99                 :          28 :     LIBSPDM_ASSERT(transport_message_size > sizeof(spdm_tcp_binding_header_t));
     100         [ -  + ]:          28 :     if (transport_message_size <= sizeof(spdm_tcp_binding_header_t)) {
     101                 :           0 :         return LIBSPDM_STATUS_INVALID_MSG_SIZE;
     102                 :             :     }
     103                 :             : 
     104                 :          28 :     tcp_message_header = transport_message;
     105                 :             : 
     106      [ +  +  + ]:          28 :     switch (tcp_message_header->message_type) {
     107                 :          16 :     case SPDM_TCP_MESSAGE_TYPE_IN_SESSION:
     108                 :          16 :         LIBSPDM_ASSERT(session_id != NULL);
     109         [ -  + ]:          16 :         if (session_id == NULL) {
     110                 :           0 :             return LIBSPDM_STATUS_INVALID_MSG_FIELD;
     111                 :             :         }
     112         [ +  + ]:          16 :         if (transport_message_size <=
     113                 :             :             sizeof(spdm_tcp_binding_header_t) + sizeof(uint32_t)) {
     114                 :           2 :             return LIBSPDM_STATUS_INVALID_MSG_SIZE;
     115                 :             :         }
     116                 :          14 :         *session_id = (uint32_t *)((uint8_t *)transport_message +
     117                 :             :                                    sizeof(spdm_tcp_binding_header_t));
     118                 :          14 :         break;
     119                 :             : 
     120                 :           8 :     case SPDM_TCP_MESSAGE_TYPE_OUT_OF_SESSION:
     121         [ +  - ]:           8 :         if (session_id != NULL) {
     122                 :           8 :             *session_id = NULL;
     123                 :             :         }
     124                 :           8 :         break;
     125                 :             : 
     126                 :           4 :     default:
     127                 :           4 :         return LIBSPDM_STATUS_UNSUPPORTED_CAP;
     128                 :             :     }
     129                 :             : 
     130                 :          22 :     if (tcp_message_header->payload_length >
     131         [ +  + ]:          22 :         transport_message_size - sizeof(spdm_tcp_binding_header_t)) {
     132                 :           2 :         return LIBSPDM_STATUS_INVALID_MSG_FIELD;
     133                 :             :     }
     134                 :             : 
     135                 :          20 :     *message_size = tcp_message_header->payload_length;
     136                 :          20 :     *message = (uint8_t *)transport_message + sizeof(spdm_tcp_binding_header_t);
     137                 :             : 
     138                 :          20 :     return LIBSPDM_STATUS_SUCCESS;
     139                 :             : }
     140                 :             : 
     141                 :             : 
     142                 :           8 : libspdm_return_t libspdm_tcp_encode_discovery_message(uint8_t message_type,
     143                 :             :                                                       size_t *transport_message_size,
     144                 :             :                                                       void **transport_message)
     145                 :             : {
     146   [ +  +  +  + ]:           8 :     if ((message_type != SPDM_TCP_MESSAGE_TYPE_ROLE_INQUIRY &&
     147                 :             :          (message_type < SPDM_TCP_MESSAGE_TYPE_ERROR_TOO_LARGE ||
     148                 :             :           message_type > SPDM_TCP_MESSAGE_TYPE_ERROR_RESERVED_MAX))){
     149                 :           2 :         return LIBSPDM_STATUS_INVALID_PARAMETER;
     150                 :             :     }
     151                 :             : 
     152         [ +  + ]:           6 :     if (*transport_message_size < sizeof(spdm_tcp_binding_header_t)) {
     153                 :           2 :         *transport_message_size = sizeof(spdm_tcp_binding_header_t);
     154                 :           2 :         return LIBSPDM_STATUS_BUFFER_TOO_SMALL;
     155                 :             :     }
     156                 :             : 
     157                 :           4 :     *transport_message_size = sizeof(spdm_tcp_binding_header_t);
     158                 :           4 :     spdm_tcp_binding_header_t *tcp_header = (spdm_tcp_binding_header_t *)(*transport_message);
     159                 :             : 
     160                 :           4 :     tcp_header->payload_length = 0;
     161                 :           4 :     tcp_header->binding_version = 0x01;
     162                 :           4 :     tcp_header->message_type = message_type;
     163                 :             : 
     164                 :           4 :     return LIBSPDM_STATUS_SUCCESS;
     165                 :             : }
     166                 :             : 
     167                 :             : 
     168                 :          16 : libspdm_return_t libspdm_tcp_decode_discovery_message(size_t transport_message_size,
     169                 :             :                                                       const void *transport_message,
     170                 :             :                                                       uint8_t *message_type)
     171                 :             : {
     172         [ +  + ]:          16 :     if (transport_message_size < sizeof(spdm_tcp_binding_header_t)) {
     173                 :           2 :         return LIBSPDM_STATUS_INVALID_MSG_SIZE;
     174                 :             :     }
     175                 :             : 
     176                 :          14 :     const spdm_tcp_binding_header_t *tcp_header = (const spdm_tcp_binding_header_t *)transport_message;
     177                 :             : 
     178         [ +  + ]:          14 :     if (tcp_header->binding_version != 0x01) {
     179                 :           2 :         return LIBSPDM_STATUS_UNSUPPORTED_CAP;
     180                 :             :     }
     181                 :             : 
     182         [ +  + ]:          12 :     if (tcp_header->payload_length != 0) {
     183                 :           6 :         return LIBSPDM_STATUS_INVALID_MSG_FIELD;
     184                 :             :     }
     185                 :             : 
     186                 :           6 :     uint8_t type = tcp_header->message_type;
     187   [ +  +  +  - ]:           6 :     if (type != SPDM_TCP_MESSAGE_TYPE_ROLE_INQUIRY &&
     188                 :             :         (type < SPDM_TCP_MESSAGE_TYPE_ERROR_TOO_LARGE || type > SPDM_TCP_MESSAGE_TYPE_ERROR_RESERVED_MAX)) {
     189                 :           2 :         return LIBSPDM_STATUS_INVALID_MSG_FIELD;
     190                 :             :     }
     191                 :             : 
     192                 :           4 :     *message_type = type;
     193                 :             : 
     194                 :           4 :     return LIBSPDM_STATUS_SUCCESS;
     195                 :             : }
     196                 :             : 
     197                 :             : 
     198                 :          10 : uint32_t libspdm_transport_tcp_get_header_size(
     199                 :             :     void *spdm_context)
     200                 :             : {
     201                 :          10 :     return sizeof(spdm_tcp_binding_header_t) + sizeof(spdm_secured_message_cipher_header_t);
     202                 :             : }
        

Generated by: LCOV version 2.0-1