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