Line data Source code
1 : /**
2 : * Copyright Notice:
3 : * Copyright 2021-2024 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_test_lib.h"
8 : #include "library/spdm_secured_message_lib.h"
9 :
10 : /**
11 : * Encode a normal message or secured message to a transport message.
12 : *
13 : * @param session_id Indicates if it is a secured message protected via SPDM session.
14 : * If session_id is NULL, it is a normal message.
15 : * If session_id is NOT NULL, it is a secured message.
16 : * @param message_size size in bytes of the message data buffer.
17 : * @param message A pointer to a source buffer to store the message.
18 : * @param transport_message_size size in bytes of the transport message data buffer.
19 : * @param transport_message A pointer to a destination buffer to store the transport message.
20 : *
21 : * @retval RETURN_SUCCESS The message is encoded successfully.
22 : * @retval RETURN_INVALID_PARAMETER The message is NULL or the message_size is zero.
23 : **/
24 : libspdm_return_t libspdm_test_encode_message(const uint32_t *session_id,
25 : bool need_alignment,
26 : size_t message_size,
27 : const void *message,
28 : size_t *transport_message_size,
29 : void **transport_message);
30 :
31 : /**
32 : * Decode a transport message to a normal message or secured message.
33 : *
34 : * @param session_id Indicates if it is a secured message protected via SPDM session.
35 : * If *session_id is NULL, it is a normal message.
36 : * If *session_id is NOT NULL, it is a secured message.
37 : * @param transport_message_size size in bytes of the transport message data buffer.
38 : * @param transport_message A pointer to a source buffer to store the transport message.
39 : * @param message_size size in bytes of the message data buffer.
40 : * @param message A pointer to a destination buffer to store the message.
41 : *
42 : * @retval RETURN_SUCCESS The message is encoded successfully.
43 : * @retval RETURN_INVALID_PARAMETER The message is NULL or the message_size is zero.
44 : **/
45 : libspdm_return_t libspdm_test_decode_message(uint32_t **session_id,
46 : bool need_alignment,
47 : size_t transport_message_size,
48 : const void *transport_message,
49 : size_t *message_size,
50 : void **message);
51 :
52 : /**
53 : * Encode an SPDM or APP message to a transport layer message.
54 : *
55 : * For normal SPDM message, it adds the transport layer wrapper.
56 : * For secured SPDM message, it encrypts a secured message then adds the transport layer wrapper.
57 : * For secured APP message, it encrypts a secured message then adds the transport layer wrapper.
58 : *
59 : * The APP message is encoded to a secured message directly in SPDM session.
60 : * The APP message format is defined by the transport layer.
61 : * Take MCTP as example: APP message == MCTP header (MCTP_MESSAGE_TYPE_SPDM) + SPDM message
62 : *
63 : * @param spdm_context A pointer to the SPDM context.
64 : * @param session_id Indicates if it is a secured message protected via SPDM session.
65 : * If session_id is NULL, it is a normal message.
66 : * If session_id is not NULL, it is a secured message.
67 : * @param is_app_message Indicates if it is an APP message or SPDM message.
68 : * @param is_request_message Indicates if it is a request message.
69 : * @param message_size Size in bytes of the message data buffer.
70 : * @param message A pointer to a source buffer to store the message.
71 : * For normal message, it shall point to the acquired sender buffer.
72 : * For secured message, it shall point to the scratch buffer in spdm_context.
73 : * @param transport_message_size Size in bytes of the transport message data buffer.
74 : * @param transport_message A pointer to a destination buffer to store the transport message.
75 : * On input, it shall be msg_buf_ptr from sender buffer.
76 : * On output, it will point to acquired sender buffer.
77 : *
78 : * @retval RETURN_SUCCESS The message is encoded successfully.
79 : * @retval RETURN_INVALID_PARAMETER The message is NULL or the message_size is zero.
80 : **/
81 136307 : libspdm_return_t libspdm_transport_test_encode_message(
82 : void *spdm_context, const uint32_t *session_id, bool is_app_message,
83 : bool is_request_message, size_t message_size, void *message,
84 : size_t *transport_message_size, void **transport_message)
85 : {
86 : libspdm_return_t status;
87 : void *app_message;
88 : size_t app_message_size;
89 : uint8_t *secured_message;
90 : size_t secured_message_size;
91 : libspdm_secured_message_callbacks_t spdm_secured_message_callbacks;
92 : void *secured_message_context;
93 : size_t transport_header_size;
94 :
95 136307 : spdm_secured_message_callbacks.version =
96 : LIBSPDM_SECURED_MESSAGE_CALLBACKS_VERSION;
97 136307 : spdm_secured_message_callbacks.get_sequence_number =
98 : libspdm_test_get_sequence_number;
99 136307 : spdm_secured_message_callbacks.get_max_random_number_count =
100 : libspdm_test_get_max_random_number_count;
101 136307 : spdm_secured_message_callbacks.get_secured_spdm_version =
102 : libspdm_test_get_secured_spdm_version;
103 :
104 136307 : if (is_app_message && (session_id == NULL)) {
105 0 : return LIBSPDM_STATUS_UNSUPPORTED_CAP;
106 : }
107 :
108 136307 : if (session_id != NULL) {
109 : secured_message_context =
110 466 : libspdm_get_secured_message_context_via_session_id(
111 : spdm_context, *session_id);
112 466 : if (secured_message_context == NULL) {
113 0 : return LIBSPDM_STATUS_UNSUPPORTED_CAP;
114 : }
115 :
116 466 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
117 :
118 466 : if (!is_app_message) {
119 : /* SPDM message to APP message*/
120 466 : app_message = NULL;
121 466 : app_message_size = transport_header_size + message_size + (LIBSPDM_TEST_ALIGNMENT - 1);
122 466 : status = libspdm_test_encode_message(NULL, false, message_size,
123 : message,
124 : &app_message_size,
125 : &app_message);
126 466 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
127 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR,
128 : "transport_encode_message - %xu\n",
129 : status));
130 0 : return status;
131 : }
132 : } else {
133 0 : app_message = (void *)message;
134 0 : app_message_size = message_size;
135 : }
136 : /* APP message to secured message*/
137 466 : secured_message = (uint8_t *)*transport_message + transport_header_size;
138 466 : secured_message_size = *transport_message_size - transport_header_size;
139 466 : status = libspdm_encode_secured_message(
140 : secured_message_context, *session_id, is_request_message,
141 : app_message_size, app_message, &secured_message_size,
142 : secured_message, &spdm_secured_message_callbacks);
143 466 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
144 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR,
145 : "libspdm_encode_secured_message - %xu\n", status));
146 0 : return status;
147 : }
148 :
149 : /* secured message to secured Test message*/
150 466 : status = libspdm_test_encode_message(
151 : session_id, true, secured_message_size, secured_message,
152 : transport_message_size, transport_message);
153 466 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
154 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR, "transport_encode_message - %xu\n",
155 : status));
156 0 : return status;
157 : }
158 : } else {
159 : /* SPDM message to normal Test message*/
160 135841 : status = libspdm_test_encode_message(NULL, true, message_size, message,
161 : transport_message_size,
162 : transport_message);
163 135841 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
164 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR, "transport_encode_message - %xu\n",
165 : status));
166 0 : return status;
167 : }
168 : }
169 :
170 136307 : return LIBSPDM_STATUS_SUCCESS;
171 : }
172 :
173 : /**
174 : * Decode an SPDM or APP message from a transport layer message.
175 : *
176 : * For normal SPDM message, it removes the transport layer wrapper,
177 : * For secured SPDM message, it removes the transport layer wrapper, then decrypts and verifies a secured message.
178 : * For secured APP message, it removes the transport layer wrapper, then decrypts and verifies a secured message.
179 : *
180 : * The APP message is decoded from a secured message directly in SPDM session.
181 : * The APP message format is defined by the transport layer.
182 : * Take MCTP as example: APP message == MCTP header (MCTP_MESSAGE_TYPE_SPDM) + SPDM message
183 : *
184 : * @param spdm_context A pointer to the SPDM context.
185 : * @param session_id Indicates if it is a secured message protected via SPDM session.
186 : * If session_id is NULL, it is a normal message.
187 : * If session_id is not NULL, it is a secured message.
188 : * @param is_app_message Indicates if it is an APP message or SPDM message.
189 : * @param is_request_message Indicates if it is a request message.
190 : * @param transport_message_size Size in bytes of the transport message data buffer.
191 : * @param transport_message A pointer to a source buffer to store the transport message.
192 : * For normal message or secured message, it shall point to acquired receiver buffer.
193 : * @param message_size Size in bytes of the message data buffer.
194 : * @param message A pointer to a destination buffer to store the message.
195 : * On input, it shall point to the scratch buffer in spdm_context.
196 : * On output, for normal message, it will point to the original receiver buffer.
197 : * On output, for secured message, it will point to the scratch buffer in spdm_context.
198 : *
199 : * @retval RETURN_SUCCESS The message is decoded successfully.
200 : * @retval RETURN_INVALID_PARAMETER The message is NULL or the message_size is zero.
201 : * @retval RETURN_UNSUPPORTED The transport_message is unsupported.
202 : **/
203 68236 : libspdm_return_t libspdm_transport_test_decode_message(
204 : void *spdm_context, uint32_t **session_id,
205 : bool *is_app_message, bool is_request_message,
206 : size_t transport_message_size, void *transport_message,
207 : size_t *message_size, void **message)
208 : {
209 : libspdm_return_t status;
210 : uint32_t *secured_message_session_id;
211 : uint8_t *secured_message;
212 : size_t secured_message_size;
213 : uint8_t *app_message;
214 : size_t app_message_size;
215 : libspdm_secured_message_callbacks_t spdm_secured_message_callbacks;
216 : void *secured_message_context;
217 : libspdm_error_struct_t spdm_error;
218 :
219 68236 : spdm_error.error_code = 0;
220 68236 : spdm_error.session_id = 0;
221 68236 : libspdm_set_last_spdm_error_struct(spdm_context, &spdm_error);
222 :
223 68236 : spdm_secured_message_callbacks.version =
224 : LIBSPDM_SECURED_MESSAGE_CALLBACKS_VERSION;
225 68236 : spdm_secured_message_callbacks.get_sequence_number =
226 : libspdm_test_get_sequence_number;
227 68236 : spdm_secured_message_callbacks.get_max_random_number_count =
228 : libspdm_test_get_max_random_number_count;
229 68236 : spdm_secured_message_callbacks.get_secured_spdm_version =
230 : libspdm_test_get_secured_spdm_version;
231 :
232 68236 : if ((session_id == NULL) || (is_app_message == NULL)) {
233 0 : return LIBSPDM_STATUS_UNSUPPORTED_CAP;
234 : }
235 :
236 68236 : secured_message_session_id = NULL;
237 : /* Detect received message*/
238 68236 : status = libspdm_test_decode_message(
239 : &secured_message_session_id, true, transport_message_size,
240 : transport_message, &secured_message_size, (void **)&secured_message);
241 68236 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
242 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR, "transport_decode_message - %xu\n", status));
243 0 : return status;
244 : }
245 :
246 68236 : if (secured_message_session_id != NULL) {
247 328 : *session_id = secured_message_session_id;
248 :
249 : secured_message_context =
250 328 : libspdm_get_secured_message_context_via_session_id(
251 : spdm_context, *secured_message_session_id);
252 328 : if (secured_message_context == NULL) {
253 0 : spdm_error.error_code = SPDM_ERROR_CODE_INVALID_SESSION;
254 0 : spdm_error.session_id = *secured_message_session_id;
255 0 : libspdm_set_last_spdm_error_struct(spdm_context,
256 : &spdm_error);
257 0 : return LIBSPDM_STATUS_UNSUPPORTED_CAP;
258 : }
259 :
260 : /* Secured message to APP message*/
261 328 : app_message = *message;
262 328 : app_message_size = *message_size;
263 328 : status = libspdm_decode_secured_message(
264 : secured_message_context, *secured_message_session_id,
265 : is_request_message, secured_message_size, secured_message,
266 : &app_message_size, (void **)&app_message,
267 : &spdm_secured_message_callbacks);
268 328 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
269 28 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR,
270 : "libspdm_decode_secured_message - %xu\n", status));
271 28 : libspdm_secured_message_get_last_spdm_error_struct(
272 : secured_message_context, &spdm_error);
273 28 : libspdm_set_last_spdm_error_struct(spdm_context,
274 : &spdm_error);
275 28 : return status;
276 : }
277 :
278 : /* APP message to SPDM message.*/
279 300 : status = libspdm_test_decode_message(&secured_message_session_id, false,
280 : app_message_size, app_message,
281 : message_size, message);
282 300 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
283 0 : *is_app_message = true;
284 : /* just return APP message.*/
285 0 : *message = app_message;
286 0 : *message_size = app_message_size;
287 0 : return LIBSPDM_STATUS_SUCCESS;
288 : } else {
289 300 : *is_app_message = false;
290 300 : if (secured_message_session_id == NULL) {
291 300 : return LIBSPDM_STATUS_SUCCESS;
292 : } else {
293 : /* get encapsulated secured message - cannot handle it.*/
294 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR,
295 : "transport_decode_message - expect encapsulated normal but got session (%08x)\n",
296 : *secured_message_session_id));
297 0 : return LIBSPDM_STATUS_UNSUPPORTED_CAP;
298 : }
299 : }
300 : } else {
301 : /* get non-secured message*/
302 67908 : status = libspdm_test_decode_message(&secured_message_session_id, true,
303 : transport_message_size,
304 : transport_message,
305 : message_size, message);
306 67908 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
307 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR, "transport_decode_message - %xu\n",
308 : status));
309 0 : return status;
310 : }
311 67908 : LIBSPDM_ASSERT(secured_message_session_id == NULL);
312 67908 : *session_id = NULL;
313 67908 : *is_app_message = false;
314 67908 : return LIBSPDM_STATUS_SUCCESS;
315 : }
316 : }
|