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