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