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 "library/spdm_secured_message_lib.h"
9 : : #include "hal/library/debuglib.h"
10 : : #include "industry_standard/spdm_tcp_binding.h"
11 : :
12 : : /**
13 : : * Encode a normal message or secured message to a transport message.
14 : : *
15 : : * @param session_id Indicates if it is a secured message protected via SPDM session.
16 : : * If session_id is NULL, it is a normal message.
17 : : * If session_id is NOT NULL, it is a secured message.
18 : : * @param message_size size in bytes of the message data buffer.
19 : : * @param message A pointer to a source buffer to store the message.
20 : : * @param transport_message_size size in bytes of the transport message data buffer.
21 : : * @param transport_message A pointer to a destination buffer to store the transport message.
22 : : **/
23 : : libspdm_return_t libspdm_tcp_encode_message(const uint32_t *session_id, size_t message_size,
24 : : void *message,
25 : : size_t *transport_message_size,
26 : : void **transport_message);
27 : :
28 : : /**
29 : : * Decode a transport message to a normal message or secured message.
30 : : *
31 : : * @param session_id Indicates if it is a secured message protected via SPDM session.
32 : : * If *session_id is NULL, it is a normal message.
33 : : * If *session_id is NOT NULL, it is a secured message.
34 : : * @param transport_message_size size in bytes of the transport message data buffer.
35 : : * @param transport_message A pointer to a source buffer to store the transport message.
36 : : * @param message_size size in bytes of the message data buffer.
37 : : * @param message A pointer to a destination buffer to store the message.
38 : : **/
39 : : libspdm_return_t libspdm_tcp_decode_message(uint32_t **session_id,
40 : : size_t transport_message_size,
41 : : void *transport_message,
42 : : size_t *message_size,
43 : : void **message);
44 : :
45 : 1 : libspdm_return_t libspdm_transport_tcp_encode_message(
46 : : void *spdm_context, const uint32_t *session_id, bool is_app_message,
47 : : bool is_requester, size_t message_size, void *message,
48 : : size_t *transport_message_size, void **transport_message)
49 : : {
50 : : libspdm_return_t status;
51 : : void *app_message;
52 : : size_t app_message_size;
53 : : uint8_t *secured_message;
54 : : size_t secured_message_size;
55 : : libspdm_secured_message_callbacks_t spdm_secured_message_callbacks;
56 : : void *secured_message_context;
57 : : size_t app_transport_header_size;
58 : : size_t secure_transport_header_size;
59 : :
60 : 1 : spdm_secured_message_callbacks.version =
61 : : LIBSPDM_SECURED_MESSAGE_CALLBACKS_VERSION;
62 : 1 : spdm_secured_message_callbacks.get_sequence_number =
63 : : libspdm_tcp_get_sequence_number;
64 : 1 : spdm_secured_message_callbacks.get_max_random_number_count =
65 : : libspdm_tcp_get_max_random_number_count;
66 : 1 : spdm_secured_message_callbacks.get_secured_spdm_version =
67 : : libspdm_tcp_get_secured_spdm_version;
68 : :
69 [ - + - - ]: 1 : if (is_app_message && (session_id == NULL)) {
70 : 0 : return LIBSPDM_STATUS_UNSUPPORTED_CAP;
71 : : }
72 : :
73 [ - + ]: 1 : if (session_id != NULL) {
74 : : secured_message_context =
75 : 0 : libspdm_get_secured_message_context_via_session_id(
76 : : spdm_context, *session_id);
77 [ # # ]: 0 : if (secured_message_context == NULL) {
78 : 0 : return LIBSPDM_STATUS_UNSUPPORTED_CAP;
79 : : }
80 : :
81 : 0 : app_transport_header_size = sizeof(spdm_tcp_binding_header_t);
82 : :
83 [ # # ]: 0 : if (!is_app_message) {
84 : : /* SPDM message to APP message*/
85 : 0 : app_message = NULL;
86 : 0 : app_message_size = app_transport_header_size + message_size;
87 : 0 : status = libspdm_tcp_encode_message(NULL, message_size,
88 : : message,
89 : : &app_message_size,
90 : : &app_message);
91 [ # # ]: 0 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
92 : 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR, "transport_encode_message - %x\n", status));
93 : 0 : return status;
94 : : }
95 : : } else {
96 : 0 : app_message = (void *)message;
97 : 0 : app_message_size = message_size;
98 : : }
99 : : /* APP message to secured message*/
100 : 0 : secure_transport_header_size = libspdm_transport_tcp_get_header_size(spdm_context);
101 : 0 : secured_message = (uint8_t *)*transport_message + secure_transport_header_size;
102 : 0 : secured_message_size = *transport_message_size - secure_transport_header_size;
103 : 0 : status = libspdm_encode_secured_message(
104 : : secured_message_context, *session_id, is_requester,
105 : : app_message_size, app_message, &secured_message_size,
106 : : secured_message, &spdm_secured_message_callbacks);
107 [ # # ]: 0 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
108 : 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR, "libspdm_encode_secured_message - %x\n", status));
109 : 0 : return status;
110 : : }
111 : :
112 : : /* secured message to secured TCP message*/
113 : 0 : status = libspdm_tcp_encode_message(
114 : : session_id, secured_message_size, secured_message,
115 : : transport_message_size, transport_message);
116 [ # # ]: 0 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
117 : 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR, "transport_encode_message - %x\n", status));
118 : 0 : return status;
119 : : }
120 : : } else {
121 : : /* SPDM message to normal TCP message*/
122 : 1 : status = libspdm_tcp_encode_message(NULL, message_size, message,
123 : : transport_message_size,
124 : : transport_message);
125 [ - + ]: 1 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
126 : 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR, "transport_encode_message - %x\n", status));
127 : 0 : return status;
128 : : }
129 : : }
130 : :
131 : 1 : return LIBSPDM_STATUS_SUCCESS;
132 : : }
133 : :
134 : 1 : libspdm_return_t libspdm_transport_tcp_decode_message(
135 : : void *spdm_context, uint32_t **session_id,
136 : : bool *is_app_message, bool is_requester,
137 : : size_t transport_message_size, void *transport_message,
138 : : size_t *message_size, void **message)
139 : : {
140 : : libspdm_return_t status;
141 : : uint32_t *secured_message_session_id;
142 : : uint8_t *secured_message;
143 : : size_t secured_message_size;
144 : : uint8_t *app_message;
145 : : size_t app_message_size;
146 : : libspdm_secured_message_callbacks_t spdm_secured_message_callbacks;
147 : : void *secured_message_context;
148 : : libspdm_error_struct_t spdm_error;
149 : :
150 : 1 : spdm_error.error_code = 0;
151 : 1 : spdm_error.session_id = 0;
152 [ + - ]: 1 : if (spdm_context) {
153 : 1 : libspdm_set_last_spdm_error_struct(spdm_context, &spdm_error);
154 : : }
155 : :
156 : 1 : spdm_secured_message_callbacks.version =
157 : : LIBSPDM_SECURED_MESSAGE_CALLBACKS_VERSION;
158 : 1 : spdm_secured_message_callbacks.get_sequence_number =
159 : : libspdm_tcp_get_sequence_number;
160 : 1 : spdm_secured_message_callbacks.get_max_random_number_count =
161 : : libspdm_tcp_get_max_random_number_count;
162 : 1 : spdm_secured_message_callbacks.get_secured_spdm_version =
163 : : libspdm_tcp_get_secured_spdm_version;
164 : :
165 [ - + - - ]: 1 : if ((session_id == NULL) || (is_app_message == NULL)) {
166 : 1 : return LIBSPDM_STATUS_UNSUPPORTED_CAP;
167 : : }
168 : :
169 : 0 : secured_message_session_id = NULL;
170 : : /* Detect received message*/
171 : 0 : status = libspdm_tcp_decode_message(
172 : : &secured_message_session_id, transport_message_size,
173 : : transport_message, &secured_message_size, (void **)&secured_message);
174 [ # # ]: 0 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
175 : 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR, "transport_decode_message - %x\n", status));
176 : 0 : return status;
177 : : }
178 : :
179 [ # # ]: 0 : if (secured_message_session_id != NULL) {
180 : 0 : *session_id = secured_message_session_id;
181 : :
182 : : secured_message_context =
183 : 0 : libspdm_get_secured_message_context_via_session_id(
184 : : spdm_context, *secured_message_session_id);
185 [ # # ]: 0 : if (secured_message_context == NULL) {
186 : 0 : spdm_error.error_code = SPDM_ERROR_CODE_INVALID_SESSION;
187 : 0 : spdm_error.session_id = *secured_message_session_id;
188 : 0 : libspdm_set_last_spdm_error_struct(spdm_context,
189 : : &spdm_error);
190 : 0 : return LIBSPDM_STATUS_UNSUPPORTED_CAP;
191 : : }
192 : :
193 : : /* Secured message to APP message*/
194 : 0 : app_message = *message;
195 : 0 : app_message_size = *message_size;
196 : 0 : status = libspdm_decode_secured_message(
197 : : secured_message_context, *secured_message_session_id,
198 : : is_requester, secured_message_size, secured_message,
199 : : &app_message_size, (void **)&app_message,
200 : : &spdm_secured_message_callbacks);
201 [ # # ]: 0 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
202 : 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR, "libspdm_decode_secured_message - %x\n", status));
203 : 0 : libspdm_secured_message_get_last_spdm_error_struct(
204 : : secured_message_context, &spdm_error);
205 : 0 : libspdm_set_last_spdm_error_struct(spdm_context,
206 : : &spdm_error);
207 : 0 : return status;
208 : : }
209 : :
210 : : /* APP message to SPDM message.*/
211 : 0 : status = libspdm_tcp_decode_message(&secured_message_session_id,
212 : : app_message_size, app_message,
213 : : message_size, message);
214 [ # # ]: 0 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
215 : 0 : *is_app_message = true;
216 : : /* just return APP message.*/
217 : 0 : *message = app_message;
218 : 0 : *message_size = app_message_size;
219 : 0 : return LIBSPDM_STATUS_SUCCESS;
220 : : } else {
221 : 0 : *is_app_message = false;
222 [ # # ]: 0 : if (secured_message_session_id == NULL) {
223 : 0 : return LIBSPDM_STATUS_SUCCESS;
224 : : } else {
225 : : /* get encapsulated secured message - cannot handle it.*/
226 : 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR,
227 : : "transport_decode_message - expect encapsulated normal but got session (%08x)\n",
228 : : *secured_message_session_id));
229 : 0 : return LIBSPDM_STATUS_UNSUPPORTED_CAP;
230 : : }
231 : : }
232 : : } else {
233 : : /* get non-secured message*/
234 : 0 : status = libspdm_tcp_decode_message(&secured_message_session_id,
235 : : transport_message_size,
236 : : transport_message,
237 : : message_size, message);
238 [ # # ]: 0 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
239 : 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR, "transport_decode_message - %x\n", status));
240 : 0 : return status;
241 : : }
242 [ # # ]: 0 : LIBSPDM_ASSERT(secured_message_session_id == NULL);
243 : 0 : *session_id = NULL;
244 : 0 : *is_app_message = false;
245 : 0 : return LIBSPDM_STATUS_SUCCESS;
246 : : }
247 : : }
|