Line data Source code
1 : /**
2 : * Copyright Notice:
3 : * Copyright 2021-2025 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 "internal/libspdm_common_lib.h"
8 : #include "internal/libspdm_secured_message_lib.h"
9 : #include "internal/libspdm_fips_lib.h"
10 :
11 : #if LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP
12 : /* first section */
13 68138 : uint32_t libspdm_get_scratch_buffer_secure_message_offset(libspdm_context_t *spdm_context) {
14 68138 : return 0;
15 : }
16 :
17 420019 : uint32_t libspdm_get_scratch_buffer_secure_message_capacity(libspdm_context_t *spdm_context) {
18 420019 : return spdm_context->local_context.capability.max_spdm_msg_size +
19 840038 : spdm_context->local_context.capability.transport_header_size +
20 420019 : spdm_context->local_context.capability.transport_tail_size;
21 : }
22 :
23 : /* second section */
24 39 : uint32_t libspdm_get_scratch_buffer_large_message_offset(libspdm_context_t *spdm_context) {
25 39 : return libspdm_get_scratch_buffer_secure_message_capacity(spdm_context);
26 : }
27 :
28 351865 : uint32_t libspdm_get_scratch_buffer_large_message_capacity(libspdm_context_t *spdm_context) {
29 351865 : return spdm_context->local_context.capability.max_spdm_msg_size;
30 : }
31 : #endif
32 :
33 : /* third section */
34 201992 : uint32_t libspdm_get_scratch_buffer_sender_receiver_offset(libspdm_context_t *spdm_context) {
35 201992 : return 0 +
36 : #if LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP
37 : libspdm_get_scratch_buffer_secure_message_capacity(spdm_context) +
38 201992 : libspdm_get_scratch_buffer_large_message_capacity(spdm_context) +
39 : #endif
40 : 0;
41 : }
42 :
43 283665 : uint32_t libspdm_get_scratch_buffer_sender_receiver_capacity(libspdm_context_t *spdm_context) {
44 283665 : return spdm_context->local_context.capability.max_spdm_msg_size +
45 567330 : spdm_context->local_context.capability.transport_header_size +
46 283665 : spdm_context->local_context.capability.transport_tail_size;
47 : }
48 :
49 : #if LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP
50 : /* fourth section */
51 12782 : uint32_t libspdm_get_scratch_buffer_large_sender_receiver_offset(libspdm_context_t *spdm_context) {
52 12782 : return libspdm_get_scratch_buffer_secure_message_capacity(spdm_context) +
53 25564 : libspdm_get_scratch_buffer_large_message_capacity(spdm_context) +
54 12782 : libspdm_get_scratch_buffer_sender_receiver_capacity(spdm_context);
55 : }
56 :
57 147292 : uint32_t libspdm_get_scratch_buffer_large_sender_receiver_capacity(libspdm_context_t *spdm_context)
58 : {
59 147292 : return spdm_context->local_context.capability.max_spdm_msg_size +
60 294584 : spdm_context->local_context.capability.transport_header_size +
61 147292 : spdm_context->local_context.capability.transport_tail_size;
62 : }
63 : #endif
64 :
65 : /* fifth section */
66 106 : uint32_t libspdm_get_scratch_buffer_last_spdm_request_offset(libspdm_context_t *spdm_context) {
67 106 : return 0 +
68 : #if LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP
69 106 : libspdm_get_scratch_buffer_secure_message_capacity(spdm_context) +
70 106 : libspdm_get_scratch_buffer_large_message_capacity(spdm_context) +
71 : #endif
72 106 : libspdm_get_scratch_buffer_sender_receiver_capacity(spdm_context) +
73 : #if LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP
74 106 : libspdm_get_scratch_buffer_large_sender_receiver_capacity(spdm_context) +
75 : #endif
76 : 0;
77 : }
78 :
79 276173 : uint32_t libspdm_get_scratch_buffer_last_spdm_request_capacity(libspdm_context_t *spdm_context) {
80 276173 : return spdm_context->local_context.capability.max_spdm_msg_size;
81 : }
82 :
83 : #if LIBSPDM_RESPOND_IF_READY_SUPPORT
84 : /* sixth section */
85 106 : uint32_t libspdm_get_scratch_buffer_cache_spdm_request_offset(libspdm_context_t *spdm_context) {
86 106 : return 0 +
87 : #if LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP
88 106 : libspdm_get_scratch_buffer_secure_message_capacity(spdm_context) +
89 106 : libspdm_get_scratch_buffer_large_message_capacity(spdm_context) +
90 : #endif
91 106 : libspdm_get_scratch_buffer_sender_receiver_capacity(spdm_context) +
92 : #if LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP
93 106 : libspdm_get_scratch_buffer_large_sender_receiver_capacity(spdm_context) +
94 : #endif
95 106 : libspdm_get_scratch_buffer_last_spdm_request_capacity(spdm_context) +
96 : 0;
97 : }
98 :
99 273525 : uint32_t libspdm_get_scratch_buffer_cache_spdm_request_capacity(libspdm_context_t *spdm_context) {
100 273525 : return spdm_context->local_context.capability.max_spdm_msg_size;
101 : }
102 : #endif
103 :
104 : /* combination */
105 136856 : uint32_t libspdm_get_scratch_buffer_capacity(libspdm_context_t *spdm_context) {
106 136856 : return 0 +
107 : #if LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP
108 136856 : libspdm_get_scratch_buffer_secure_message_capacity(spdm_context) +
109 136856 : libspdm_get_scratch_buffer_large_message_capacity(spdm_context) +
110 : #endif
111 136856 : libspdm_get_scratch_buffer_sender_receiver_capacity(spdm_context) +
112 : #if LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP
113 136856 : libspdm_get_scratch_buffer_large_sender_receiver_capacity(spdm_context) +
114 : #endif
115 136856 : libspdm_get_scratch_buffer_last_spdm_request_capacity(spdm_context) +
116 : #if LIBSPDM_RESPOND_IF_READY_SUPPORT
117 136856 : libspdm_get_scratch_buffer_cache_spdm_request_capacity(spdm_context) +
118 : #endif
119 : 0;
120 : }
121 :
122 : /**
123 : * Returns if an SPDM data_type requires session info.
124 : *
125 : * @param data_type SPDM data type.
126 : *
127 : * @retval true session info is required.
128 : * @retval false session info is not required.
129 : **/
130 61 : static bool need_session_info_for_data(libspdm_data_type_t data_type)
131 : {
132 61 : switch (data_type) {
133 0 : case LIBSPDM_DATA_SESSION_USE_PSK:
134 : case LIBSPDM_DATA_SESSION_MUT_AUTH_REQUESTED:
135 : case LIBSPDM_DATA_SESSION_END_SESSION_ATTRIBUTES:
136 : case LIBSPDM_DATA_SESSION_POLICY:
137 : case LIBSPDM_DATA_SESSION_SEQUENCE_NUMBER_RSP_DIR:
138 : case LIBSPDM_DATA_SESSION_SEQUENCE_NUMBER_REQ_DIR:
139 : case LIBSPDM_DATA_SESSION_SEQUENCE_NUMBER_ENDIAN:
140 0 : return true;
141 61 : default:
142 61 : return false;
143 : }
144 : }
145 :
146 : /**
147 : * Set an SPDM context data.
148 : *
149 : * @param spdm_context A pointer to the SPDM context.
150 : * @param data_type Type of the SPDM context data.
151 : * @param parameter Type specific parameter of the SPDM context data.
152 : * @param data A pointer to the SPDM context data.
153 : * @param data_size size in bytes of the SPDM context data.
154 : *
155 : * @retval RETURN_SUCCESS The SPDM context data is set successfully.
156 : * @retval RETURN_INVALID_PARAMETER The data is NULL or the data_type is zero.
157 : * @retval RETURN_UNSUPPORTED The data_type is unsupported.
158 : * @retval RETURN_ACCESS_DENIED The data_type cannot be set.
159 : * @retval RETURN_NOT_READY data is not ready to set.
160 : **/
161 19 : libspdm_return_t libspdm_set_data(void *spdm_context, libspdm_data_type_t data_type,
162 : const libspdm_data_parameter_t *parameter, const void *data,
163 : size_t data_size)
164 : {
165 : libspdm_context_t *context;
166 : uint32_t session_id;
167 : uint32_t data32;
168 : libspdm_session_info_t *session_info;
169 : uint8_t slot_id;
170 : uint8_t mut_auth_requested;
171 : uint8_t root_cert_index;
172 : uint16_t data16;
173 : #if !(LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT) && LIBSPDM_CERT_PARSE_SUPPORT
174 : bool status;
175 : const uint8_t *cert_buffer;
176 : size_t cert_buffer_size;
177 : #endif
178 :
179 19 : if (spdm_context == NULL || data == NULL || data_type >= LIBSPDM_DATA_MAX) {
180 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
181 : }
182 :
183 19 : context = spdm_context;
184 :
185 19 : if (need_session_info_for_data(data_type)) {
186 0 : if (parameter->location != LIBSPDM_DATA_LOCATION_SESSION) {
187 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
188 : }
189 0 : session_id = libspdm_read_uint32(parameter->additional_data);
190 0 : session_info = libspdm_get_session_info_via_session_id(context, session_id);
191 0 : if (session_info == NULL) {
192 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
193 : }
194 : } else {
195 19 : session_info = NULL;
196 : }
197 :
198 19 : switch (data_type) {
199 0 : case LIBSPDM_DATA_SPDM_VERSION:
200 0 : LIBSPDM_ASSERT (data_size <= sizeof(spdm_version_number_t) * SPDM_MAX_VERSION_COUNT);
201 0 : if (parameter->location == LIBSPDM_DATA_LOCATION_CONNECTION) {
202 : /* Only have one connected version */
203 0 : LIBSPDM_ASSERT (data_size == sizeof(spdm_version_number_t));
204 0 : libspdm_copy_mem(&(context->connection_info.version),
205 : sizeof(context->connection_info.version),
206 : data,
207 : sizeof(spdm_version_number_t));
208 0 : } else if (parameter->location == LIBSPDM_DATA_LOCATION_LOCAL) {
209 0 : context->local_context.version.spdm_version_count =
210 0 : (uint8_t)(data_size / sizeof(spdm_version_number_t));
211 0 : libspdm_copy_mem(context->local_context.version.spdm_version,
212 : sizeof(context->local_context.version.spdm_version),
213 : data,
214 0 : context->local_context.version.spdm_version_count *
215 : sizeof(spdm_version_number_t));
216 : } else {
217 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
218 : }
219 0 : break;
220 0 : case LIBSPDM_DATA_SECURED_MESSAGE_VERSION:
221 0 : LIBSPDM_ASSERT (data_size <=
222 : sizeof(spdm_version_number_t) * SECURED_SPDM_MAX_VERSION_COUNT);
223 0 : if (parameter->location == LIBSPDM_DATA_LOCATION_CONNECTION) {
224 : /* Only have one connected version */
225 0 : LIBSPDM_ASSERT (data_size == sizeof(spdm_version_number_t));
226 0 : libspdm_copy_mem(&(context->connection_info.secured_message_version),
227 : sizeof(context->connection_info.secured_message_version),
228 : data,
229 : sizeof(spdm_version_number_t));
230 0 : } else if (parameter->location == LIBSPDM_DATA_LOCATION_LOCAL) {
231 : context->local_context.secured_message_version
232 0 : .spdm_version_count = (uint8_t)(data_size / sizeof(spdm_version_number_t));
233 0 : libspdm_copy_mem(context->local_context
234 0 : .secured_message_version.spdm_version,
235 : sizeof(context->local_context
236 : .secured_message_version.spdm_version),
237 : data,
238 0 : context->local_context.secured_message_version.
239 : spdm_version_count * sizeof(spdm_version_number_t));
240 : } else {
241 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
242 : }
243 0 : break;
244 0 : case LIBSPDM_DATA_CAPABILITY_FLAGS:
245 0 : if (data_size != sizeof(uint32_t)) {
246 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
247 : }
248 :
249 0 : data32 = libspdm_read_uint32((const uint8_t *)data);
250 :
251 0 : if (parameter->location == LIBSPDM_DATA_LOCATION_LOCAL) {
252 : #if !(LIBSPDM_ENABLE_CAPABILITY_CERT_CAP)
253 : LIBSPDM_ASSERT((data32 & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP) == 0);
254 : #endif /* !LIBSPDM_ENABLE_CAPABILITY_CERT_CAP */
255 :
256 : #if !(LIBSPDM_ENABLE_CAPABILITY_CHAL_CAP)
257 : LIBSPDM_ASSERT((data32 & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHAL_CAP) == 0);
258 : #endif /* !LIBSPDM_ENABLE_CAPABILITY_CHAL_CAP */
259 :
260 : #if !(LIBSPDM_ENABLE_CAPABILITY_MEAS_CAP)
261 : LIBSPDM_ASSERT((data32 & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP) == 0);
262 : #endif /* !LIBSPDM_ENABLE_CAPABILITY_MEAS_CAP */
263 :
264 : #if !(LIBSPDM_ENABLE_CAPABILITY_MEL_CAP)
265 : LIBSPDM_ASSERT((data32 & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEL_CAP) == 0);
266 : #endif /* !LIBSPDM_ENABLE_CAPABILITY_MEL_CAP */
267 :
268 : #if !(LIBSPDM_ENABLE_CAPABILITY_KEY_EX_CAP)
269 : LIBSPDM_ASSERT((data32 & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_KEY_EX_CAP) == 0);
270 : #endif /* !LIBSPDM_ENABLE_CAPABILITY_KEY_EX_CAP */
271 :
272 : #if !(LIBSPDM_ENABLE_CAPABILITY_PSK_CAP)
273 : LIBSPDM_ASSERT((data32 & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_PSK_CAP) == 0);
274 : #endif /* !LIBSPDM_ENABLE_CAPABILITY_PSK_CAP */
275 :
276 : #if !(LIBSPDM_ENABLE_CAPABILITY_ENDPOINT_INFO_CAP)
277 : LIBSPDM_ASSERT((data32 & SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_EP_INFO_CAP) == 0);
278 : #endif /* !LIBSPDM_ENABLE_CAPABILITY_ENDPOINT_INFO_CAP */
279 :
280 0 : context->local_context.capability.flags = data32;
281 0 : } else if (parameter->location == LIBSPDM_DATA_LOCATION_CONNECTION) {
282 0 : context->connection_info.capability.flags = data32;
283 : } else {
284 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
285 : }
286 0 : break;
287 0 : case LIBSPDM_DATA_CAPABILITY_CT_EXPONENT:
288 0 : if (data_size != sizeof(uint8_t)) {
289 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
290 : }
291 0 : if (parameter->location == LIBSPDM_DATA_LOCATION_CONNECTION) {
292 0 : context->connection_info.capability.ct_exponent = *(const uint8_t *)data;
293 0 : } else if (parameter->location == LIBSPDM_DATA_LOCATION_LOCAL) {
294 0 : context->local_context.capability.ct_exponent = *(const uint8_t *)data;
295 : } else {
296 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
297 : }
298 0 : break;
299 0 : case LIBSPDM_DATA_CAPABILITY_RTT_US:
300 0 : if (data_size != sizeof(uint64_t)) {
301 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
302 : }
303 0 : if (parameter->location != LIBSPDM_DATA_LOCATION_LOCAL) {
304 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
305 : }
306 0 : context->local_context.capability.rtt = libspdm_read_uint64((const uint8_t *)data);
307 0 : break;
308 0 : case LIBSPDM_DATA_CAPABILITY_MAX_SPDM_MSG_SIZE:
309 0 : if (data_size != sizeof(uint32_t)) {
310 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
311 : }
312 : /* The local max_spdm_msg_size is set by libspdm_register_transport_layer_func.
313 : * Only the connection's max_spdm_msg_size is settable here. */
314 0 : if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
315 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
316 : }
317 0 : data32 = libspdm_read_uint32((const uint8_t *)data);
318 0 : LIBSPDM_ASSERT (data32 >= SPDM_MIN_DATA_TRANSFER_SIZE_VERSION_12);
319 0 : context->connection_info.capability.max_spdm_msg_size = data32;
320 0 : break;
321 0 : case LIBSPDM_DATA_MEASUREMENT_SPEC:
322 0 : if (data_size != sizeof(uint8_t)) {
323 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
324 : }
325 0 : if (parameter->location == LIBSPDM_DATA_LOCATION_CONNECTION) {
326 0 : context->connection_info.algorithm.measurement_spec = *(const uint8_t *)data;
327 0 : } else if (parameter->location == LIBSPDM_DATA_LOCATION_LOCAL) {
328 0 : context->local_context.algorithm.measurement_spec = *(const uint8_t *)data;
329 : } else {
330 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
331 : }
332 0 : break;
333 0 : case LIBSPDM_DATA_MEASUREMENT_HASH_ALGO:
334 0 : if (data_size != sizeof(uint32_t)) {
335 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
336 : }
337 0 : data32 = libspdm_read_uint32((const uint8_t *)data);
338 0 : if (parameter->location == LIBSPDM_DATA_LOCATION_CONNECTION) {
339 0 : context->connection_info.algorithm.measurement_hash_algo = data32;
340 0 : } else if (parameter->location == LIBSPDM_DATA_LOCATION_LOCAL) {
341 0 : context->local_context.algorithm.measurement_hash_algo = data32;
342 : } else {
343 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
344 : }
345 0 : break;
346 0 : case LIBSPDM_DATA_BASE_ASYM_ALGO:
347 0 : if (data_size != sizeof(uint32_t)) {
348 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
349 : }
350 0 : data32 = libspdm_read_uint32((const uint8_t *)data);
351 0 : if (parameter->location == LIBSPDM_DATA_LOCATION_CONNECTION) {
352 0 : context->connection_info.algorithm.base_asym_algo = data32;
353 0 : } else if (parameter->location == LIBSPDM_DATA_LOCATION_LOCAL) {
354 0 : context->local_context.algorithm.base_asym_algo = data32;
355 : } else {
356 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
357 : }
358 0 : break;
359 0 : case LIBSPDM_DATA_BASE_HASH_ALGO:
360 0 : if (data_size != sizeof(uint32_t)) {
361 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
362 : }
363 0 : data32 = libspdm_read_uint32((const uint8_t *)data);
364 0 : if (parameter->location == LIBSPDM_DATA_LOCATION_CONNECTION) {
365 0 : context->connection_info.algorithm.base_hash_algo = data32;
366 0 : } else if (parameter->location == LIBSPDM_DATA_LOCATION_LOCAL) {
367 0 : context->local_context.algorithm.base_hash_algo = data32;
368 : } else {
369 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
370 : }
371 0 : break;
372 0 : case LIBSPDM_DATA_DHE_NAME_GROUP:
373 0 : if (data_size != sizeof(uint16_t)) {
374 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
375 : }
376 0 : data16 = libspdm_read_uint16((const uint8_t *)data);
377 0 : if (parameter->location == LIBSPDM_DATA_LOCATION_CONNECTION) {
378 0 : context->connection_info.algorithm.dhe_named_group = data16;
379 0 : } else if (parameter->location == LIBSPDM_DATA_LOCATION_LOCAL) {
380 0 : context->local_context.algorithm.dhe_named_group = data16;
381 : } else {
382 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
383 : }
384 0 : break;
385 0 : case LIBSPDM_DATA_AEAD_CIPHER_SUITE:
386 0 : if (data_size != sizeof(uint16_t)) {
387 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
388 : }
389 0 : data16 = libspdm_read_uint16((const uint8_t *)data);
390 0 : if (parameter->location == LIBSPDM_DATA_LOCATION_CONNECTION) {
391 0 : context->connection_info.algorithm.aead_cipher_suite = data16;
392 0 : } else if (parameter->location == LIBSPDM_DATA_LOCATION_LOCAL) {
393 0 : context->local_context.algorithm.aead_cipher_suite = data16;
394 : } else {
395 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
396 : }
397 0 : break;
398 0 : case LIBSPDM_DATA_REQ_BASE_ASYM_ALG:
399 0 : if (data_size != sizeof(uint16_t)) {
400 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
401 : }
402 0 : data16 = libspdm_read_uint16((const uint8_t *)data);
403 0 : if (parameter->location == LIBSPDM_DATA_LOCATION_CONNECTION) {
404 0 : context->connection_info.algorithm.req_base_asym_alg = data16;
405 0 : } else if (parameter->location == LIBSPDM_DATA_LOCATION_LOCAL) {
406 0 : context->local_context.algorithm.req_base_asym_alg = data16;
407 : } else {
408 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
409 : }
410 0 : break;
411 0 : case LIBSPDM_DATA_KEY_SCHEDULE:
412 0 : if (data_size != sizeof(uint16_t)) {
413 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
414 : }
415 0 : data16 = libspdm_read_uint16((const uint8_t *)data);
416 0 : if (parameter->location == LIBSPDM_DATA_LOCATION_CONNECTION) {
417 0 : context->connection_info.algorithm.key_schedule = data16;
418 0 : } else if (parameter->location == LIBSPDM_DATA_LOCATION_LOCAL) {
419 0 : context->local_context.algorithm.key_schedule = data16;
420 : } else {
421 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
422 : }
423 0 : break;
424 0 : case LIBSPDM_DATA_OTHER_PARAMS_SUPPORT:
425 0 : if (data_size != sizeof(uint8_t)) {
426 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
427 : }
428 0 : if (parameter->location == LIBSPDM_DATA_LOCATION_CONNECTION) {
429 0 : context->connection_info.algorithm.other_params_support = *(const uint8_t *)data;
430 0 : } else if (parameter->location == LIBSPDM_DATA_LOCATION_LOCAL) {
431 0 : context->local_context.algorithm.other_params_support = *(const uint8_t *)data;
432 : } else {
433 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
434 : }
435 0 : break;
436 0 : case LIBSPDM_DATA_MEL_SPEC:
437 0 : if (data_size != sizeof(uint8_t)) {
438 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
439 : }
440 0 : if (parameter->location == LIBSPDM_DATA_LOCATION_CONNECTION) {
441 0 : context->connection_info.algorithm.mel_spec = *(const uint8_t *)data;
442 0 : } else if (parameter->location == LIBSPDM_DATA_LOCATION_LOCAL) {
443 0 : context->local_context.algorithm.mel_spec = *(const uint8_t *)data;
444 : } else {
445 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
446 : }
447 0 : break;
448 0 : case LIBSPDM_DATA_PQC_ASYM_ALGO:
449 0 : if (data_size != sizeof(uint32_t)) {
450 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
451 : }
452 0 : data32 = libspdm_read_uint32((const uint8_t *)data);
453 0 : if (parameter->location == LIBSPDM_DATA_LOCATION_CONNECTION) {
454 0 : context->connection_info.algorithm.pqc_asym_algo = data32;
455 0 : } else if (parameter->location == LIBSPDM_DATA_LOCATION_LOCAL) {
456 0 : context->local_context.algorithm.pqc_asym_algo = data32;
457 : } else {
458 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
459 : }
460 0 : break;
461 0 : case LIBSPDM_DATA_REQ_PQC_ASYM_ALG:
462 0 : if (data_size != sizeof(uint32_t)) {
463 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
464 : }
465 0 : data32 = libspdm_read_uint32((const uint8_t *)data);
466 0 : if (parameter->location == LIBSPDM_DATA_LOCATION_CONNECTION) {
467 0 : context->connection_info.algorithm.req_pqc_asym_alg = data32;
468 0 : } else if (parameter->location == LIBSPDM_DATA_LOCATION_LOCAL) {
469 0 : context->local_context.algorithm.req_pqc_asym_alg = data32;
470 : } else {
471 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
472 : }
473 0 : break;
474 0 : case LIBSPDM_DATA_KEM_ALG:
475 0 : if (data_size != sizeof(uint32_t)) {
476 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
477 : }
478 0 : data32 = libspdm_read_uint32((const uint8_t *)data);
479 0 : if (parameter->location == LIBSPDM_DATA_LOCATION_CONNECTION) {
480 0 : context->connection_info.algorithm.kem_alg = data32;
481 0 : } else if (parameter->location == LIBSPDM_DATA_LOCATION_LOCAL) {
482 0 : context->local_context.algorithm.kem_alg = data32;
483 : } else {
484 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
485 : }
486 0 : break;
487 0 : case LIBSPDM_DATA_ALGO_PRIORITY_PQC_FIRST:
488 0 : if (data_size != sizeof(bool)) {
489 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
490 : }
491 0 : if (parameter->location == LIBSPDM_DATA_LOCATION_LOCAL) {
492 0 : context->local_context.algorithm.pqc_first = *(const bool *)data;
493 : } else {
494 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
495 : }
496 0 : break;
497 0 : case LIBSPDM_DATA_CONNECTION_STATE:
498 0 : if (data_size != sizeof(libspdm_connection_state_t)) {
499 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
500 : }
501 0 : if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
502 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
503 : }
504 0 : context->connection_info.connection_state = libspdm_read_uint32((const uint8_t *)data);
505 0 : break;
506 0 : case LIBSPDM_DATA_RESPONSE_STATE:
507 0 : if (data_size != sizeof(libspdm_response_state_t)) {
508 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
509 : }
510 0 : context->response_state = libspdm_read_uint32((const uint8_t *)data);
511 0 : break;
512 2 : case LIBSPDM_DATA_PEER_PUBLIC_ROOT_CERT:
513 2 : if (parameter->location != LIBSPDM_DATA_LOCATION_LOCAL) {
514 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
515 : }
516 2 : root_cert_index = 0;
517 11 : while (context->local_context.peer_root_cert_provision[root_cert_index] != NULL) {
518 10 : root_cert_index++;
519 10 : if (root_cert_index >= LIBSPDM_MAX_ROOT_CERT_SUPPORT) {
520 1 : return LIBSPDM_STATUS_BUFFER_FULL;
521 : }
522 : }
523 1 : context->local_context.peer_root_cert_provision_size[root_cert_index] = data_size;
524 1 : context->local_context.peer_root_cert_provision[root_cert_index] = data;
525 1 : break;
526 0 : case LIBSPDM_DATA_LOCAL_PUBLIC_CERT_CHAIN:
527 0 : if (parameter->location != LIBSPDM_DATA_LOCATION_LOCAL) {
528 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
529 : }
530 0 : slot_id = parameter->additional_data[0];
531 0 : if (slot_id >= SPDM_MAX_SLOT_COUNT) {
532 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
533 : }
534 0 : context->local_context.local_cert_chain_provision_size[slot_id] = data_size;
535 0 : context->local_context.local_cert_chain_provision[slot_id] = data;
536 0 : break;
537 0 : case LIBSPDM_DATA_LOCAL_SUPPORTED_SLOT_MASK:
538 0 : if (parameter->location != LIBSPDM_DATA_LOCATION_LOCAL) {
539 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
540 : }
541 0 : if (data_size != sizeof(uint8_t)) {
542 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
543 : }
544 0 : context->local_context.local_supported_slot_mask = *(const uint8_t *)data;
545 0 : break;
546 0 : case LIBSPDM_DATA_LOCAL_KEY_PAIR_ID:
547 0 : if (parameter->location != LIBSPDM_DATA_LOCATION_LOCAL) {
548 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
549 : }
550 0 : slot_id = parameter->additional_data[0];
551 0 : if (slot_id >= SPDM_MAX_SLOT_COUNT) {
552 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
553 : }
554 0 : if (data_size != sizeof(spdm_key_pair_id_t)) {
555 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
556 : }
557 0 : context->local_context.local_key_pair_id[slot_id] = *(const spdm_key_pair_id_t *)data;
558 0 : break;
559 0 : case LIBSPDM_DATA_LOCAL_CERT_INFO:
560 0 : if (parameter->location != LIBSPDM_DATA_LOCATION_LOCAL) {
561 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
562 : }
563 0 : slot_id = parameter->additional_data[0];
564 0 : if (slot_id >= SPDM_MAX_SLOT_COUNT) {
565 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
566 : }
567 0 : if (data_size != sizeof(spdm_certificate_info_t)) {
568 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
569 : }
570 0 : context->local_context.local_cert_info[slot_id] = *(const spdm_certificate_info_t *)data;
571 0 : break;
572 0 : case LIBSPDM_DATA_LOCAL_KEY_USAGE_BIT_MASK:
573 0 : if (parameter->location != LIBSPDM_DATA_LOCATION_LOCAL) {
574 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
575 : }
576 0 : slot_id = parameter->additional_data[0];
577 0 : if (slot_id >= SPDM_MAX_SLOT_COUNT) {
578 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
579 : }
580 0 : if (data_size != sizeof(spdm_key_usage_bit_mask_t)) {
581 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
582 : }
583 0 : context->local_context.local_key_usage_bit_mask[slot_id] =
584 0 : libspdm_read_uint16((const uint8_t *)data);
585 0 : break;
586 3 : case LIBSPDM_DATA_PEER_USED_CERT_CHAIN_BUFFER:
587 3 : if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
588 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
589 : }
590 3 : slot_id = parameter->additional_data[0];
591 3 : if (slot_id >= SPDM_MAX_SLOT_COUNT) {
592 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
593 : }
594 3 : if (data_size > LIBSPDM_MAX_CERT_CHAIN_SIZE) {
595 0 : return LIBSPDM_STATUS_BUFFER_FULL;
596 : }
597 3 : context->connection_info.peer_used_cert_chain_slot_id = slot_id;
598 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
599 : context->connection_info.peer_used_cert_chain[slot_id].buffer_size = data_size;
600 : libspdm_copy_mem(context->connection_info.peer_used_cert_chain[slot_id].buffer,
601 : sizeof(context->connection_info.peer_used_cert_chain[slot_id].buffer),
602 : data, data_size);
603 : #else
604 : #if LIBSPDM_CERT_PARSE_SUPPORT
605 3 : status = libspdm_hash_all(
606 : context->connection_info.algorithm.base_hash_algo,
607 : data, data_size,
608 3 : context->connection_info.peer_used_cert_chain[slot_id].buffer_hash);
609 3 : if (!status) {
610 0 : return LIBSPDM_STATUS_CRYPTO_ERROR;
611 : }
612 :
613 6 : context->connection_info.peer_used_cert_chain[slot_id].buffer_hash_size =
614 3 : libspdm_get_hash_size(context->connection_info.algorithm.base_hash_algo);
615 :
616 : /*process the SPDM cert header and hash*/
617 3 : data = (const uint8_t *)data + sizeof(spdm_cert_chain_t) +
618 3 : libspdm_get_hash_size(context->connection_info.algorithm.base_hash_algo);
619 3 : data_size = data_size -
620 : (sizeof(spdm_cert_chain_t) +
621 3 : libspdm_get_hash_size(context->connection_info.algorithm.base_hash_algo));
622 :
623 : /* Get leaf cert from cert chain */
624 3 : status = libspdm_x509_get_cert_from_cert_chain(data, data_size, -1,
625 : &cert_buffer, &cert_buffer_size);
626 3 : if (!status) {
627 0 : return LIBSPDM_STATUS_CRYPTO_ERROR;
628 : }
629 :
630 3 : status = false;
631 : #if (LIBSPDM_RSA_SSA_SUPPORT) || (LIBSPDM_RSA_PSS_SUPPORT)
632 3 : if (!status) {
633 3 : status = libspdm_rsa_get_public_key_from_x509(
634 : cert_buffer, cert_buffer_size,
635 3 : &context->connection_info.peer_used_cert_chain[slot_id].leaf_cert_public_key);
636 : }
637 : #endif
638 : #if LIBSPDM_ECDSA_SUPPORT
639 3 : if (!status) {
640 3 : status = libspdm_ec_get_public_key_from_x509(
641 : cert_buffer, cert_buffer_size,
642 3 : &context->connection_info.peer_used_cert_chain[slot_id].leaf_cert_public_key);
643 : }
644 : #endif
645 : #if (LIBSPDM_EDDSA_ED25519_SUPPORT) || (LIBSPDM_EDDSA_ED448_SUPPORT)
646 : if (!status) {
647 : status = libspdm_ecd_get_public_key_from_x509(
648 : cert_buffer, cert_buffer_size,
649 : &context->connection_info.peer_used_cert_chain[slot_id].leaf_cert_public_key);
650 : }
651 : #endif
652 : #if LIBSPDM_SM2_DSA_SUPPORT
653 : if (!status) {
654 : status = libspdm_sm2_get_public_key_from_x509(
655 : cert_buffer, cert_buffer_size,
656 : &context->connection_info.peer_used_cert_chain[slot_id].leaf_cert_public_key);
657 : }
658 : #endif
659 3 : if (!status) {
660 0 : return LIBSPDM_STATUS_INVALID_CERT;
661 : }
662 : #else
663 : LIBSPDM_ASSERT (false);
664 : #endif /* LIBSPDM_CERT_PARSE_SUPPORT */
665 : #endif /* LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT */
666 3 : break;
667 0 : case LIBSPDM_DATA_PEER_PUBLIC_KEY:
668 0 : if (parameter->location != LIBSPDM_DATA_LOCATION_LOCAL) {
669 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
670 : }
671 0 : context->local_context.peer_public_key_provision_size = data_size;
672 0 : context->local_context.peer_public_key_provision = data;
673 0 : break;
674 0 : case LIBSPDM_DATA_LOCAL_PUBLIC_KEY:
675 0 : if (parameter->location != LIBSPDM_DATA_LOCATION_LOCAL) {
676 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
677 : }
678 0 : context->local_context.local_public_key_provision_size = data_size;
679 0 : context->local_context.local_public_key_provision = data;
680 0 : break;
681 0 : case LIBSPDM_DATA_BASIC_MUT_AUTH_REQUESTED:
682 0 : if (data_size != sizeof(bool)) {
683 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
684 : }
685 0 : if (parameter->location != LIBSPDM_DATA_LOCATION_LOCAL) {
686 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
687 : }
688 0 : mut_auth_requested = *(const uint8_t *)data;
689 0 : if (((mut_auth_requested != 0) && (mut_auth_requested != 1))) {
690 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
691 : }
692 0 : context->local_context.basic_mut_auth_requested = mut_auth_requested;
693 0 : context->encap_context.request_id = 0;
694 0 : slot_id = parameter->additional_data[0];
695 0 : if ((slot_id >= SPDM_MAX_SLOT_COUNT) && (slot_id != 0xFF)) {
696 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
697 : }
698 0 : context->encap_context.req_slot_id = slot_id;
699 :
700 : #if LIBSPDM_DEBUG_PRINT_ENABLE
701 0 : if (mut_auth_requested) {
702 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO,
703 : "Basic mutual authentication is a deprecated feature.\n"));
704 : }
705 : #endif /* LIBSPDM_DEBUG_PRINT_ENABLE */
706 0 : break;
707 0 : case LIBSPDM_DATA_MUT_AUTH_REQUESTED:
708 0 : if (data_size != sizeof(uint8_t)) {
709 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
710 : }
711 0 : if (parameter->location != LIBSPDM_DATA_LOCATION_LOCAL) {
712 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
713 : }
714 0 : mut_auth_requested = *(const uint8_t *)data;
715 0 : if (((mut_auth_requested != 0) &&
716 : (mut_auth_requested !=
717 0 : SPDM_KEY_EXCHANGE_RESPONSE_MUT_AUTH_REQUESTED) &&
718 : (mut_auth_requested !=
719 0 : SPDM_KEY_EXCHANGE_RESPONSE_MUT_AUTH_REQUESTED_WITH_ENCAP_REQUEST) &&
720 : (mut_auth_requested !=
721 : SPDM_KEY_EXCHANGE_RESPONSE_MUT_AUTH_REQUESTED_WITH_GET_DIGESTS))) {
722 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
723 : }
724 0 : context->local_context.mut_auth_requested = mut_auth_requested;
725 0 : context->encap_context.request_id = 0;
726 0 : slot_id = parameter->additional_data[0];
727 0 : if ((slot_id >= SPDM_MAX_SLOT_COUNT) && (slot_id != 0xFF)) {
728 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
729 : }
730 0 : context->encap_context.req_slot_id = slot_id;
731 0 : break;
732 0 : case LIBSPDM_DATA_MANDATORY_MUT_AUTH:
733 0 : if (data_size != sizeof(bool)) {
734 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
735 : }
736 0 : if (parameter->location != LIBSPDM_DATA_LOCATION_LOCAL) {
737 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
738 : }
739 0 : context->local_context.mandatory_mut_auth = *(const bool *)data;
740 0 : break;
741 0 : case LIBSPDM_DATA_HEARTBEAT_PERIOD:
742 0 : if (data_size != sizeof(uint8_t)) {
743 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
744 : }
745 0 : if (parameter->location != LIBSPDM_DATA_LOCATION_LOCAL) {
746 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
747 : }
748 0 : context->local_context.heartbeat_period = *(const uint8_t *)data;
749 0 : break;
750 4 : case LIBSPDM_DATA_APP_CONTEXT_DATA:
751 4 : if (data_size != sizeof(void *) || *(void *const *)data == NULL) {
752 2 : return LIBSPDM_STATUS_INVALID_PARAMETER;
753 : }
754 2 : context->app_context_data_ptr = *(void *const *)data;
755 2 : break;
756 0 : case LIBSPDM_DATA_HANDLE_ERROR_RETURN_POLICY:
757 0 : if (data_size != sizeof(uint8_t)) {
758 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
759 : }
760 0 : context->handle_error_return_policy = *(const uint8_t *)data;
761 0 : break;
762 0 : case LIBSPDM_DATA_VCA_CACHE:
763 0 : if (data_size > sizeof(context->transcript.message_a.buffer)) {
764 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
765 : }
766 0 : context->transcript.message_a.buffer_size = data_size;
767 0 : libspdm_copy_mem(context->transcript.message_a.buffer,
768 : sizeof(context->transcript.message_a.buffer),
769 : data, data_size);
770 0 : break;
771 0 : case LIBSPDM_DATA_IS_REQUESTER:
772 0 : if (data_size != sizeof(bool)) {
773 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
774 : }
775 0 : if (parameter->location != LIBSPDM_DATA_LOCATION_LOCAL) {
776 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
777 : }
778 0 : context->local_context.is_requester = *(const bool *)data;
779 0 : break;
780 0 : case LIBSPDM_DATA_REQUEST_RETRY_TIMES:
781 0 : if (data_size != sizeof(uint8_t)) {
782 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
783 : }
784 0 : context->retry_times = *(const uint8_t *)data;
785 0 : break;
786 0 : case LIBSPDM_DATA_REQUEST_RETRY_DELAY_TIME:
787 0 : if (data_size != sizeof(uint64_t)) {
788 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
789 : }
790 0 : context->retry_delay_time = *(const uint64_t *)data;
791 0 : break;
792 5 : case LIBSPDM_DATA_MAX_DHE_SESSION_COUNT:
793 5 : if (data_size != sizeof(uint32_t)) {
794 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
795 : }
796 5 : if (*(const uint32_t *)data > LIBSPDM_MAX_SESSION_COUNT - context->max_psk_session_count) {
797 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
798 : }
799 5 : context->max_dhe_session_count = *(const uint32_t *)data;
800 5 : break;
801 5 : case LIBSPDM_DATA_MAX_PSK_SESSION_COUNT:
802 5 : if (data_size != sizeof(uint32_t)) {
803 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
804 : }
805 5 : if (*(const uint32_t *)data > LIBSPDM_MAX_SESSION_COUNT - context->max_dhe_session_count) {
806 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
807 : }
808 5 : context->max_psk_session_count = *(const uint32_t *)data;
809 5 : break;
810 0 : case LIBSPDM_DATA_MAX_SPDM_SESSION_SEQUENCE_NUMBER:
811 0 : if (data_size != sizeof(uint64_t)) {
812 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
813 : }
814 0 : context->max_spdm_session_sequence_number = *(const uint64_t *)data;
815 0 : if (context->max_spdm_session_sequence_number == 0) {
816 0 : context->max_spdm_session_sequence_number = LIBSPDM_MAX_SPDM_SESSION_SEQUENCE_NUMBER;
817 : }
818 0 : break;
819 0 : case LIBSPDM_DATA_SPDM_VERSION_10_11_VERIFY_SIGNATURE_ENDIAN:
820 0 : if (data_size != sizeof(uint8_t)) {
821 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
822 : }
823 0 : if (*(const uint8_t*)data != LIBSPDM_SPDM_10_11_VERIFY_SIGNATURE_ENDIAN_BIG_ONLY &&
824 0 : *(const uint8_t*)data != LIBSPDM_SPDM_10_11_VERIFY_SIGNATURE_ENDIAN_LITTLE_ONLY &&
825 0 : *(const uint8_t*)data != LIBSPDM_SPDM_10_11_VERIFY_SIGNATURE_ENDIAN_BIG_OR_LITTLE) {
826 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
827 : }
828 0 : context->spdm_10_11_verify_signature_endian = *(const uint8_t*)data;
829 0 : break;
830 0 : case LIBSPDM_DATA_SEQUENCE_NUMBER_ENDIAN:
831 0 : if (data_size != sizeof(uint8_t)) {
832 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
833 : }
834 0 : context->sequence_number_endian = *(const uint8_t *)data;
835 0 : break;
836 0 : case LIBSPDM_DATA_MULTI_KEY_CONN_REQ:
837 0 : if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
838 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
839 : }
840 0 : if (data_size != sizeof(bool)) {
841 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
842 : }
843 0 : context->connection_info.multi_key_conn_req = *(const bool *)data;
844 0 : break;
845 0 : case LIBSPDM_DATA_MULTI_KEY_CONN_RSP:
846 0 : if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
847 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
848 : }
849 0 : if (data_size != sizeof(bool)) {
850 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
851 : }
852 0 : context->connection_info.multi_key_conn_rsp = *(const bool *)data;
853 0 : break;
854 0 : case LIBSPDM_DATA_TOTAL_KEY_PAIRS:
855 0 : if (data_size != sizeof(uint8_t)) {
856 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
857 : }
858 0 : if (parameter->location != LIBSPDM_DATA_LOCATION_LOCAL) {
859 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
860 : }
861 0 : context->local_context.total_key_pairs = *(const uint8_t *)data;
862 0 : break;
863 0 : default:
864 0 : return LIBSPDM_STATUS_UNSUPPORTED_CAP;
865 : break;
866 : }
867 :
868 16 : return LIBSPDM_STATUS_SUCCESS;
869 : }
870 :
871 : /**
872 : * Get an SPDM context data.
873 : *
874 : * @param spdm_context A pointer to the SPDM context.
875 : * @param data_type Type of the SPDM context data.
876 : * @param parameter Type specific parameter of the SPDM context data.
877 : * @param data A pointer to the SPDM context data.
878 : * @param data_size size in bytes of the SPDM context data.
879 : * On input, it means the size in bytes of data buffer.
880 : * On output, it means the size in bytes of copied data buffer if RETURN_SUCCESS,
881 : * and means the size in bytes of desired data buffer if RETURN_BUFFER_TOO_SMALL.
882 : *
883 : * @retval RETURN_SUCCESS The SPDM context data is set successfully.
884 : * @retval RETURN_INVALID_PARAMETER The data_size is NULL or the data is NULL and *data_size is not zero.
885 : * @retval RETURN_UNSUPPORTED The data_type is unsupported.
886 : * @retval RETURN_NOT_FOUND The data_type cannot be found.
887 : * @retval RETURN_NOT_READY The data is not ready to return.
888 : * @retval RETURN_BUFFER_TOO_SMALL The buffer is too small to hold the data.
889 : **/
890 42 : libspdm_return_t libspdm_get_data(void *spdm_context, libspdm_data_type_t data_type,
891 : const libspdm_data_parameter_t *parameter,
892 : void *data, size_t *data_size)
893 : {
894 : libspdm_context_t *context;
895 42 : libspdm_secured_message_context_t *secured_context = NULL;
896 : size_t target_data_size;
897 : void *target_data;
898 : uint32_t session_id;
899 : libspdm_session_info_t *session_info;
900 : size_t digest_size;
901 : size_t digest_count;
902 : uint8_t slot_id;
903 : size_t index;
904 :
905 42 : if (spdm_context == NULL || data == NULL || data_size == NULL ||
906 : data_type >= LIBSPDM_DATA_MAX) {
907 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
908 : }
909 :
910 42 : context = spdm_context;
911 :
912 42 : if (data_type == LIBSPDM_DATA_SESSION_END_SESSION_ATTRIBUTES) {
913 : /* end_session_attributes is present in both a session context as well as an
914 : * spdm context. */
915 0 : session_id = libspdm_read_uint32(parameter->additional_data);
916 0 : session_info = libspdm_get_session_info_via_session_id(context, session_id);
917 42 : } else if (need_session_info_for_data(data_type)) {
918 0 : if (parameter->location != LIBSPDM_DATA_LOCATION_SESSION) {
919 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
920 : }
921 0 : session_id = libspdm_read_uint32(parameter->additional_data);
922 0 : session_info = libspdm_get_session_info_via_session_id(context, session_id);
923 0 : if (session_info == NULL) {
924 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
925 : }
926 0 : secured_context = session_info->secured_message_context;
927 : } else {
928 42 : session_info = NULL;
929 : }
930 :
931 42 : switch (data_type) {
932 0 : case LIBSPDM_DATA_SPDM_VERSION:
933 0 : if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
934 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
935 : }
936 0 : target_data_size = sizeof(spdm_version_number_t);
937 0 : target_data = &(context->connection_info.version);
938 0 : break;
939 0 : case LIBSPDM_DATA_SECURED_MESSAGE_VERSION:
940 0 : if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
941 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
942 : }
943 0 : target_data_size = sizeof(spdm_version_number_t);
944 0 : target_data = &(context->connection_info.secured_message_version);
945 0 : break;
946 0 : case LIBSPDM_DATA_CAPABILITY_FLAGS:
947 0 : target_data_size = sizeof(uint32_t);
948 0 : if (parameter->location == LIBSPDM_DATA_LOCATION_CONNECTION) {
949 0 : target_data = &context->connection_info.capability.flags;
950 0 : } else if (parameter->location == LIBSPDM_DATA_LOCATION_LOCAL) {
951 0 : target_data = &context->local_context.capability.flags;
952 : } else {
953 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
954 : }
955 0 : break;
956 0 : case LIBSPDM_DATA_CAPABILITY_CT_EXPONENT:
957 0 : target_data_size = sizeof(uint8_t);
958 0 : if (parameter->location == LIBSPDM_DATA_LOCATION_CONNECTION) {
959 0 : target_data = &context->connection_info.capability.ct_exponent;
960 0 : } else if (parameter->location == LIBSPDM_DATA_LOCATION_LOCAL) {
961 0 : target_data = &context->local_context.capability.ct_exponent;
962 : } else {
963 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
964 : }
965 0 : break;
966 0 : case LIBSPDM_DATA_CAPABILITY_DATA_TRANSFER_SIZE:
967 0 : target_data_size = sizeof(uint32_t);
968 0 : if (parameter->location == LIBSPDM_DATA_LOCATION_CONNECTION) {
969 0 : target_data = &context->connection_info.capability.data_transfer_size;
970 0 : } else if (parameter->location == LIBSPDM_DATA_LOCATION_LOCAL) {
971 0 : target_data = &context->local_context.capability.data_transfer_size;
972 : } else {
973 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
974 : }
975 0 : break;
976 0 : case LIBSPDM_DATA_CAPABILITY_MAX_SPDM_MSG_SIZE:
977 0 : target_data_size = sizeof(uint32_t);
978 0 : if (parameter->location == LIBSPDM_DATA_LOCATION_CONNECTION) {
979 0 : target_data = &context->connection_info.capability.max_spdm_msg_size;
980 0 : } else if (parameter->location == LIBSPDM_DATA_LOCATION_LOCAL) {
981 0 : target_data = &context->local_context.capability.max_spdm_msg_size;
982 : } else {
983 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
984 : }
985 0 : break;
986 0 : case LIBSPDM_DATA_CAPABILITY_SENDER_DATA_TRANSFER_SIZE:
987 0 : target_data_size = sizeof(uint32_t);
988 0 : if (parameter->location == LIBSPDM_DATA_LOCATION_CONNECTION) {
989 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
990 0 : } else if (parameter->location == LIBSPDM_DATA_LOCATION_LOCAL) {
991 0 : target_data = &context->local_context.capability.sender_data_transfer_size;
992 : } else {
993 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
994 : }
995 0 : break;
996 0 : case LIBSPDM_DATA_MEASUREMENT_SPEC:
997 0 : if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
998 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
999 : }
1000 0 : target_data_size = sizeof(uint8_t);
1001 0 : target_data = &context->connection_info.algorithm.measurement_spec;
1002 0 : break;
1003 0 : case LIBSPDM_DATA_MEASUREMENT_HASH_ALGO:
1004 0 : if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
1005 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
1006 : }
1007 0 : target_data_size = sizeof(uint32_t);
1008 0 : target_data = &context->connection_info.algorithm.measurement_hash_algo;
1009 0 : break;
1010 0 : case LIBSPDM_DATA_BASE_ASYM_ALGO:
1011 0 : if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
1012 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
1013 : }
1014 0 : target_data_size = sizeof(uint32_t);
1015 0 : target_data = &context->connection_info.algorithm.base_asym_algo;
1016 0 : break;
1017 0 : case LIBSPDM_DATA_BASE_HASH_ALGO:
1018 0 : if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
1019 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
1020 : }
1021 0 : target_data_size = sizeof(uint32_t);
1022 0 : target_data = &context->connection_info.algorithm.base_hash_algo;
1023 0 : break;
1024 0 : case LIBSPDM_DATA_DHE_NAME_GROUP:
1025 0 : if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
1026 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
1027 : }
1028 0 : target_data_size = sizeof(uint16_t);
1029 0 : target_data = &context->connection_info.algorithm.dhe_named_group;
1030 0 : break;
1031 0 : case LIBSPDM_DATA_AEAD_CIPHER_SUITE:
1032 0 : if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
1033 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
1034 : }
1035 0 : target_data_size = sizeof(uint16_t);
1036 0 : target_data = &context->connection_info.algorithm.aead_cipher_suite;
1037 0 : break;
1038 0 : case LIBSPDM_DATA_REQ_BASE_ASYM_ALG:
1039 0 : if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
1040 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
1041 : }
1042 0 : target_data_size = sizeof(uint16_t);
1043 0 : target_data = &context->connection_info.algorithm.req_base_asym_alg;
1044 0 : break;
1045 0 : case LIBSPDM_DATA_KEY_SCHEDULE:
1046 0 : if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
1047 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
1048 : }
1049 0 : target_data_size = sizeof(uint16_t);
1050 0 : target_data = &context->connection_info.algorithm.key_schedule;
1051 0 : break;
1052 0 : case LIBSPDM_DATA_OTHER_PARAMS_SUPPORT:
1053 0 : if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
1054 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
1055 : }
1056 0 : target_data_size = sizeof(uint8_t);
1057 0 : target_data = &context->connection_info.algorithm.other_params_support;
1058 0 : break;
1059 0 : case LIBSPDM_DATA_MEL_SPEC:
1060 0 : if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
1061 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
1062 : }
1063 0 : target_data_size = sizeof(uint8_t);
1064 0 : target_data = &context->connection_info.algorithm.mel_spec;
1065 0 : break;
1066 0 : case LIBSPDM_DATA_PQC_ASYM_ALGO:
1067 0 : if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
1068 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
1069 : }
1070 0 : target_data_size = sizeof(uint32_t);
1071 0 : target_data = &context->connection_info.algorithm.pqc_asym_algo;
1072 0 : break;
1073 0 : case LIBSPDM_DATA_REQ_PQC_ASYM_ALG:
1074 0 : if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
1075 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
1076 : }
1077 0 : target_data_size = sizeof(uint32_t);
1078 0 : target_data = &context->connection_info.algorithm.req_pqc_asym_alg;
1079 0 : break;
1080 0 : case LIBSPDM_DATA_KEM_ALG:
1081 0 : if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
1082 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
1083 : }
1084 0 : target_data_size = sizeof(uint32_t);
1085 0 : target_data = &context->connection_info.algorithm.kem_alg;
1086 0 : break;
1087 0 : case LIBSPDM_DATA_CONNECTION_STATE:
1088 0 : if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
1089 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
1090 : }
1091 0 : target_data_size = sizeof(libspdm_connection_state_t);
1092 0 : target_data = &context->connection_info.connection_state;
1093 0 : break;
1094 0 : case LIBSPDM_DATA_RESPONSE_STATE:
1095 0 : target_data_size = sizeof(libspdm_response_state_t);
1096 0 : target_data = &context->response_state;
1097 0 : break;
1098 5 : case LIBSPDM_DATA_PEER_PROVISIONED_SLOT_MASK:
1099 5 : if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
1100 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
1101 : }
1102 5 : target_data_size = sizeof(uint8_t);
1103 5 : target_data = &context->connection_info.peer_provisioned_slot_mask;
1104 5 : break;
1105 0 : case LIBSPDM_DATA_PEER_SUPPORTED_SLOT_MASK:
1106 0 : if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
1107 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
1108 : }
1109 0 : target_data_size = sizeof(uint8_t);
1110 0 : target_data = &context->connection_info.peer_supported_slot_mask;
1111 0 : break;
1112 5 : case LIBSPDM_DATA_PEER_TOTAL_DIGEST_BUFFER:
1113 5 : if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
1114 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
1115 : }
1116 5 : digest_count = 0;
1117 45 : for (index = 0; index < SPDM_MAX_SLOT_COUNT; index++) {
1118 40 : if (context->connection_info.peer_provisioned_slot_mask & (1 << index)) {
1119 12 : digest_count++;
1120 : }
1121 : }
1122 5 : digest_size = libspdm_get_hash_size(context->connection_info.algorithm.base_hash_algo);
1123 5 : target_data_size = digest_size * digest_count;
1124 5 : target_data = context->connection_info.peer_total_digest_buffer;
1125 5 : break;
1126 0 : case LIBSPDM_DATA_PEER_KEY_PAIR_ID:
1127 0 : if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
1128 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
1129 : }
1130 0 : slot_id = parameter->additional_data[0];
1131 0 : if (slot_id >= SPDM_MAX_SLOT_COUNT) {
1132 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
1133 : }
1134 0 : target_data_size = sizeof(spdm_key_pair_id_t);
1135 0 : target_data = &context->connection_info.peer_key_pair_id[slot_id];
1136 0 : break;
1137 0 : case LIBSPDM_DATA_PEER_CERT_INFO:
1138 0 : if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
1139 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
1140 : }
1141 0 : slot_id = parameter->additional_data[0];
1142 0 : if (slot_id >= SPDM_MAX_SLOT_COUNT) {
1143 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
1144 : }
1145 0 : target_data_size = sizeof(spdm_certificate_info_t);
1146 0 : target_data = &context->connection_info.peer_cert_info[slot_id];
1147 0 : break;
1148 0 : case LIBSPDM_DATA_PEER_KEY_USAGE_BIT_MASK:
1149 0 : if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
1150 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
1151 : }
1152 0 : slot_id = parameter->additional_data[0];
1153 0 : if (slot_id >= SPDM_MAX_SLOT_COUNT) {
1154 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
1155 : }
1156 0 : target_data_size = sizeof(spdm_key_usage_bit_mask_t);
1157 0 : target_data = &context->connection_info.peer_key_usage_bit_mask[slot_id];
1158 0 : break;
1159 0 : case LIBSPDM_DATA_SESSION_USE_PSK:
1160 0 : target_data_size = sizeof(bool);
1161 0 : target_data = &session_info->use_psk;
1162 0 : break;
1163 0 : case LIBSPDM_DATA_SESSION_MUT_AUTH_REQUESTED:
1164 0 : target_data_size = sizeof(uint8_t);
1165 0 : target_data = &session_info->mut_auth_requested;
1166 0 : break;
1167 0 : case LIBSPDM_DATA_SESSION_END_SESSION_ATTRIBUTES:
1168 0 : if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
1169 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
1170 : }
1171 0 : target_data_size = sizeof(uint8_t);
1172 0 : if (session_info == NULL) {
1173 0 : target_data = &context->connection_info.end_session_attributes;
1174 : } else {
1175 0 : target_data = &session_info->end_session_attributes;
1176 : }
1177 0 : break;
1178 0 : case LIBSPDM_DATA_SESSION_POLICY:
1179 0 : target_data_size = sizeof(uint8_t);
1180 0 : target_data = &session_info->session_policy;
1181 0 : break;
1182 6 : case LIBSPDM_DATA_APP_CONTEXT_DATA:
1183 6 : target_data_size = sizeof(void *);
1184 6 : target_data = &context->app_context_data_ptr;
1185 6 : break;
1186 0 : case LIBSPDM_DATA_HANDLE_ERROR_RETURN_POLICY:
1187 0 : target_data_size = sizeof(uint8_t);
1188 0 : target_data = &context->handle_error_return_policy;
1189 0 : break;
1190 0 : case LIBSPDM_DATA_MAX_DHE_SESSION_COUNT:
1191 0 : target_data_size = sizeof(uint32_t);
1192 0 : target_data = &context->max_dhe_session_count;
1193 0 : break;
1194 0 : case LIBSPDM_DATA_MAX_PSK_SESSION_COUNT:
1195 0 : target_data_size = sizeof(uint32_t);
1196 0 : target_data = &context->max_psk_session_count;
1197 0 : break;
1198 0 : case LIBSPDM_DATA_SESSION_SEQUENCE_NUMBER_REQ_DIR:
1199 0 : target_data_size = sizeof(uint64_t);
1200 0 : target_data = &secured_context->application_secret.request_data_sequence_number;
1201 0 : break;
1202 0 : case LIBSPDM_DATA_SESSION_SEQUENCE_NUMBER_RSP_DIR:
1203 0 : target_data_size = sizeof(uint64_t);
1204 0 : target_data = &secured_context->application_secret.response_data_sequence_number;
1205 0 : break;
1206 0 : case LIBSPDM_DATA_MAX_SPDM_SESSION_SEQUENCE_NUMBER:
1207 0 : target_data_size = sizeof(uint64_t);
1208 0 : target_data = &context->max_spdm_session_sequence_number;
1209 0 : break;
1210 0 : case LIBSPDM_DATA_VCA_CACHE:
1211 0 : target_data_size = context->transcript.message_a.buffer_size;
1212 0 : target_data = context->transcript.message_a.buffer;
1213 0 : break;
1214 0 : case LIBSPDM_DATA_REQUEST_AND_SIZE:
1215 0 : target_data_size = context->last_spdm_request_size;
1216 0 : target_data = context->last_spdm_request;
1217 0 : break;
1218 0 : case LIBSPDM_DATA_SPDM_VERSION_10_11_VERIFY_SIGNATURE_ENDIAN:
1219 0 : target_data_size = sizeof(uint8_t);
1220 0 : target_data = &context->spdm_10_11_verify_signature_endian;
1221 0 : break;
1222 0 : case LIBSPDM_DATA_SEQUENCE_NUMBER_ENDIAN:
1223 0 : target_data_size = sizeof(uint8_t);
1224 0 : target_data = &context->sequence_number_endian;
1225 0 : break;
1226 0 : case LIBSPDM_DATA_SESSION_SEQUENCE_NUMBER_ENDIAN:
1227 0 : target_data_size = sizeof(uint8_t);
1228 0 : target_data = &secured_context->sequence_number_endian;
1229 0 : break;
1230 0 : case LIBSPDM_DATA_MULTI_KEY_CONN_REQ:
1231 0 : if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
1232 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
1233 : }
1234 0 : target_data_size = sizeof(bool);
1235 0 : target_data = &context->connection_info.multi_key_conn_req;
1236 0 : break;
1237 0 : case LIBSPDM_DATA_MULTI_KEY_CONN_RSP:
1238 0 : if (parameter->location != LIBSPDM_DATA_LOCATION_CONNECTION) {
1239 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
1240 : }
1241 0 : target_data_size = sizeof(bool);
1242 0 : target_data = &context->connection_info.multi_key_conn_rsp;
1243 0 : break;
1244 26 : case LIBSPDM_DATA_TOTAL_KEY_PAIRS:
1245 26 : if (parameter->location != LIBSPDM_DATA_LOCATION_LOCAL) {
1246 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
1247 : }
1248 26 : target_data_size = sizeof(uint8_t);
1249 26 : target_data = &context->local_context.total_key_pairs;
1250 26 : break;
1251 0 : default:
1252 0 : return LIBSPDM_STATUS_UNSUPPORTED_CAP;
1253 : break;
1254 : }
1255 :
1256 42 : if (*data_size < target_data_size) {
1257 1 : *data_size = target_data_size;
1258 1 : return LIBSPDM_STATUS_BUFFER_TOO_SMALL;
1259 : }
1260 41 : libspdm_copy_mem(data, *data_size, target_data, target_data_size);
1261 41 : *data_size = target_data_size;
1262 :
1263 41 : return LIBSPDM_STATUS_SUCCESS;
1264 : }
1265 :
1266 : #if LIBSPDM_CHECK_SPDM_CONTEXT
1267 3 : bool libspdm_check_context (void *spdm_context)
1268 : {
1269 : libspdm_context_t *context;
1270 : size_t index;
1271 :
1272 3 : context = spdm_context;
1273 :
1274 3 : if (context->local_context.capability.data_transfer_size <
1275 : SPDM_MIN_DATA_TRANSFER_SIZE_VERSION_12) {
1276 1 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR,
1277 : "data_transfer_size must be greater than or equal "
1278 : "to SPDM_MIN_DATA_TRANSFER_SIZE (%d).\n",
1279 : SPDM_MIN_DATA_TRANSFER_SIZE_VERSION_12));
1280 1 : return false;
1281 : }
1282 :
1283 2 : if (context->local_context.capability.max_spdm_msg_size <
1284 2 : context->local_context.capability.data_transfer_size) {
1285 1 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR,
1286 : "max_spdm_msg_size (%d) must be greater than or "
1287 : "equal to data_transfer_size (%d).\n",
1288 : context->local_context.capability.max_spdm_msg_size,
1289 : context->local_context.capability.data_transfer_size));
1290 1 : return false;
1291 : }
1292 :
1293 1 : if (context->local_context.capability.sender_data_transfer_size <
1294 : SPDM_MIN_DATA_TRANSFER_SIZE_VERSION_12) {
1295 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR,
1296 : "sender_data_transfer_size must be greater than or equal "
1297 : "to %d.\n", SPDM_MIN_DATA_TRANSFER_SIZE_VERSION_12));
1298 0 : return false;
1299 : }
1300 :
1301 1 : if (context->local_context.capability.max_spdm_msg_size <
1302 1 : context->local_context.capability.sender_data_transfer_size) {
1303 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR,
1304 : "max_spdm_msg_size (%d) must be greater than or "
1305 : "equal to sender_data_transfer_size (%d).\n",
1306 : context->local_context.capability.max_spdm_msg_size,
1307 : context->local_context.capability.sender_data_transfer_size));
1308 0 : return false;
1309 : }
1310 :
1311 1 : if (((context->local_context.capability.flags &
1312 0 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHUNK_CAP) != 0) &&
1313 0 : (context->local_context.capability.max_spdm_msg_size != 0)) {
1314 0 : for (index = 0; index < SPDM_MAX_SLOT_COUNT; index++) {
1315 0 : if ((context->local_context.local_cert_chain_provision_size[index] != 0) &&
1316 0 : (context->local_context.local_cert_chain_provision_size[index] +
1317 : sizeof(spdm_certificate_response_t) >
1318 0 : context->local_context.capability.max_spdm_msg_size)) {
1319 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR,
1320 : "max_spdm_msg_size (%d) must be greater than or "
1321 : "equal to local_cert_chain_provision_size[%zu] (%zu).\n",
1322 : context->local_context.capability.max_spdm_msg_size, index,
1323 : context->local_context.local_cert_chain_provision_size[index]));
1324 0 : return false;
1325 : }
1326 : }
1327 : }
1328 :
1329 1 : return true;
1330 : }
1331 : #endif /* LIBSPDM_CHECK_CONTEXT */
1332 :
1333 : /**
1334 : * Reset message A cache in SPDM context.
1335 : *
1336 : * @param spdm_context A pointer to the SPDM context.
1337 : **/
1338 673 : void libspdm_reset_message_a(libspdm_context_t *spdm_context)
1339 : {
1340 673 : libspdm_reset_managed_buffer(&spdm_context->transcript.message_a);
1341 673 : }
1342 :
1343 : /**
1344 : * Reset message D cache in SPDM context.
1345 : *
1346 : * @param spdm_context A pointer to the SPDM context.
1347 : **/
1348 51 : void libspdm_reset_message_d(libspdm_context_t *spdm_context)
1349 : {
1350 51 : libspdm_reset_managed_buffer(&spdm_context->transcript.message_d);
1351 51 : }
1352 :
1353 : /**
1354 : * Reset message B cache in SPDM context.
1355 : *
1356 : * @param spdm_context A pointer to the SPDM context.
1357 : **/
1358 998 : void libspdm_reset_message_b(libspdm_context_t *spdm_context)
1359 : {
1360 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
1361 : libspdm_reset_managed_buffer(&spdm_context->transcript.message_b);
1362 : #else
1363 998 : if (spdm_context->transcript.digest_context_m1m2 != NULL) {
1364 182 : libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
1365 : spdm_context->transcript.digest_context_m1m2);
1366 182 : spdm_context->transcript.digest_context_m1m2 = NULL;
1367 : }
1368 : #endif
1369 998 : }
1370 :
1371 : /**
1372 : * Reset message C cache in SPDM context.
1373 : *
1374 : * @param spdm_context A pointer to the SPDM context.
1375 : **/
1376 586 : void libspdm_reset_message_c(libspdm_context_t *spdm_context)
1377 : {
1378 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
1379 : libspdm_reset_managed_buffer(&spdm_context->transcript.message_c);
1380 : #else
1381 586 : if (spdm_context->transcript.digest_context_m1m2 != NULL) {
1382 0 : libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
1383 : spdm_context->transcript.digest_context_m1m2);
1384 0 : spdm_context->transcript.digest_context_m1m2 = NULL;
1385 : }
1386 : #endif
1387 586 : }
1388 :
1389 : /**
1390 : * Reset message MutB cache in SPDM context.
1391 : *
1392 : * @param spdm_context A pointer to the SPDM context.
1393 : **/
1394 472 : void libspdm_reset_message_mut_b(libspdm_context_t *spdm_context)
1395 : {
1396 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
1397 : libspdm_reset_managed_buffer(&spdm_context->transcript.message_mut_b);
1398 : #else
1399 472 : if (spdm_context->transcript.digest_context_mut_m1m2 != NULL) {
1400 26 : libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
1401 : spdm_context->transcript.digest_context_mut_m1m2);
1402 26 : spdm_context->transcript.digest_context_mut_m1m2 = NULL;
1403 : }
1404 : #endif
1405 472 : }
1406 :
1407 : /**
1408 : * Reset message MutC cache in SPDM context.
1409 : *
1410 : * @param spdm_context A pointer to the SPDM context.
1411 : **/
1412 457 : void libspdm_reset_message_mut_c(libspdm_context_t *spdm_context)
1413 : {
1414 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
1415 : libspdm_reset_managed_buffer(&spdm_context->transcript.message_mut_c);
1416 : #else
1417 457 : if (spdm_context->transcript.digest_context_mut_m1m2 != NULL) {
1418 0 : libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
1419 : spdm_context->transcript.digest_context_mut_m1m2);
1420 0 : spdm_context->transcript.digest_context_mut_m1m2 = NULL;
1421 : }
1422 : #endif
1423 457 : }
1424 :
1425 : /**
1426 : * Reset message M cache in SPDM context.
1427 : * If session_info is NULL, this function will use M cache of SPDM context,
1428 : * else will use M cache of SPDM session context.
1429 : *
1430 : * @param spdm_context A pointer to the SPDM context.
1431 : * @param session_info A pointer to the SPDM session context.
1432 : **/
1433 4138 : void libspdm_reset_message_m(libspdm_context_t *spdm_context, void *session_info)
1434 : {
1435 : libspdm_session_info_t *spdm_session_info;
1436 :
1437 4138 : spdm_session_info = session_info;
1438 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
1439 : if (spdm_session_info == NULL) {
1440 : libspdm_reset_managed_buffer(&spdm_context->transcript.message_m);
1441 : } else {
1442 : libspdm_reset_managed_buffer(&spdm_session_info->session_transcript.message_m);
1443 : }
1444 : #else
1445 4138 : if (spdm_session_info == NULL) {
1446 3865 : if (spdm_context->transcript.digest_context_l1l2 != NULL) {
1447 62 : libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
1448 : spdm_context->transcript.digest_context_l1l2);
1449 62 : spdm_context->transcript.digest_context_l1l2 = NULL;
1450 : }
1451 : } else {
1452 273 : if (spdm_session_info->session_transcript.digest_context_l1l2 != NULL) {
1453 2 : libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
1454 : spdm_session_info->session_transcript.digest_context_l1l2);
1455 2 : spdm_session_info->session_transcript.digest_context_l1l2 = NULL;
1456 : }
1457 : }
1458 : #endif
1459 4138 : }
1460 :
1461 : /**
1462 : * Reset message K cache in SPDM context.
1463 : *
1464 : * @param spdm_context A pointer to the SPDM context.
1465 : * @param spdm_session_info A pointer to the SPDM session context.
1466 : **/
1467 0 : void libspdm_reset_message_k(libspdm_context_t *spdm_context, void *session_info)
1468 : {
1469 : libspdm_session_info_t *spdm_session_info;
1470 :
1471 0 : spdm_session_info = session_info;
1472 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
1473 : libspdm_reset_managed_buffer(&spdm_session_info->session_transcript.message_k);
1474 : #else
1475 : {
1476 0 : if (spdm_session_info->session_transcript.digest_context_th != NULL) {
1477 0 : libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
1478 : spdm_session_info->session_transcript.digest_context_th);
1479 0 : spdm_session_info->session_transcript.digest_context_th = NULL;
1480 : }
1481 0 : if (spdm_session_info->session_transcript.digest_context_th_backup != NULL) {
1482 0 : libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
1483 : spdm_session_info->session_transcript.digest_context_th_backup);
1484 0 : spdm_session_info->session_transcript.digest_context_th_backup = NULL;
1485 : }
1486 : }
1487 : #endif
1488 0 : }
1489 :
1490 : /**
1491 : * Reset message EncapD cache in SPDM context.
1492 : *
1493 : * @param spdm_context A pointer to the SPDM context.
1494 : * @param spdm_session_info A pointer to the SPDM session context.
1495 : **/
1496 6 : void libspdm_reset_message_encap_d(libspdm_context_t *spdm_context, void *session_info)
1497 : {
1498 : libspdm_session_info_t *spdm_session_info;
1499 :
1500 6 : spdm_session_info = session_info;
1501 6 : libspdm_reset_managed_buffer(&spdm_session_info->session_transcript.message_encap_d);
1502 6 : }
1503 :
1504 : /**
1505 : * Reset message F cache in SPDM context.
1506 : *
1507 : * @param spdm_context A pointer to the SPDM context.
1508 : * @param spdm_session_info A pointer to the SPDM session context.
1509 : **/
1510 21 : void libspdm_reset_message_f(libspdm_context_t *spdm_context, void *session_info)
1511 : {
1512 : libspdm_session_info_t *spdm_session_info;
1513 :
1514 21 : spdm_session_info = session_info;
1515 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
1516 : libspdm_reset_managed_buffer(&spdm_session_info->session_transcript.message_f);
1517 : #else
1518 : {
1519 21 : if (spdm_session_info->session_transcript.digest_context_th != NULL) {
1520 21 : libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
1521 : spdm_session_info->session_transcript.digest_context_th);
1522 21 : spdm_session_info->session_transcript.digest_context_th =
1523 21 : spdm_session_info->session_transcript.digest_context_th_backup;
1524 21 : spdm_session_info->session_transcript.digest_context_th_backup = NULL;
1525 : }
1526 21 : spdm_session_info->session_transcript.message_f_initialized = false;
1527 : }
1528 : #endif
1529 21 : }
1530 :
1531 : /**
1532 : * Reset message E cache in SPDM context.
1533 : * If session_info is NULL, this function will use E cache of SPDM context,
1534 : * else will use E cache of SPDM session context.
1535 : *
1536 : * @param spdm_context A pointer to the SPDM context.
1537 : * @param spdm_session_info A pointer to the SPDM session context.
1538 : **/
1539 143 : void libspdm_reset_message_e(libspdm_context_t *spdm_context, void *session_info)
1540 : {
1541 : libspdm_session_info_t *spdm_session_info;
1542 :
1543 143 : spdm_session_info = session_info;
1544 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
1545 : if (spdm_session_info == NULL) {
1546 : libspdm_reset_managed_buffer(&spdm_context->transcript.message_e);
1547 : } else {
1548 : libspdm_reset_managed_buffer(&spdm_session_info->session_transcript.message_e);
1549 : }
1550 : #else
1551 143 : if (spdm_session_info == NULL) {
1552 135 : if (spdm_context->transcript.digest_context_il1il2 != NULL) {
1553 14 : libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
1554 : spdm_context->transcript.digest_context_il1il2);
1555 14 : spdm_context->transcript.digest_context_il1il2 = NULL;
1556 : }
1557 : } else {
1558 8 : if (spdm_session_info->session_transcript.digest_context_il1il2 != NULL) {
1559 3 : libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
1560 : spdm_session_info->session_transcript.digest_context_il1il2);
1561 3 : spdm_session_info->session_transcript.digest_context_il1il2 = NULL;
1562 : }
1563 : }
1564 : #endif
1565 143 : }
1566 :
1567 : /**
1568 : * Reset message encap E cache in SPDM context.
1569 : * If session_info is NULL, this function will use encap E cache of SPDM context,
1570 : * else will use encap E cache of SPDM session context.
1571 : *
1572 : * @param spdm_context A pointer to the SPDM context.
1573 : * @param spdm_session_info A pointer to the SPDM session context.
1574 : **/
1575 102 : void libspdm_reset_message_encap_e(libspdm_context_t *spdm_context, void *session_info)
1576 : {
1577 : libspdm_session_info_t *spdm_session_info;
1578 :
1579 102 : spdm_session_info = session_info;
1580 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
1581 : if (spdm_session_info == NULL) {
1582 : libspdm_reset_managed_buffer(&spdm_context->transcript.message_encap_e);
1583 : } else {
1584 : libspdm_reset_managed_buffer(&spdm_session_info->session_transcript.message_encap_e);
1585 : }
1586 : #else
1587 102 : if (spdm_session_info == NULL) {
1588 95 : if (spdm_context->transcript.digest_context_encap_il1il2 != NULL) {
1589 12 : libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
1590 : spdm_context->transcript.digest_context_encap_il1il2);
1591 12 : spdm_context->transcript.digest_context_encap_il1il2 = NULL;
1592 : }
1593 : } else {
1594 7 : if (spdm_session_info->session_transcript.digest_context_encap_il1il2 != NULL) {
1595 2 : libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
1596 : spdm_session_info->session_transcript.digest_context_encap_il1il2);
1597 2 : spdm_session_info->session_transcript.digest_context_encap_il1il2 = NULL;
1598 : }
1599 : }
1600 : #endif
1601 102 : }
1602 :
1603 : /**
1604 : * Reset message buffer in SPDM context according to request code.
1605 : *
1606 : * @param spdm_context A pointer to the SPDM context.
1607 : * @param spdm_session_info A pointer to the SPDM session context.
1608 : * @param spdm_request The SPDM request code.
1609 : */
1610 4274 : void libspdm_reset_message_buffer_via_request_code(void *context, void *session_info,
1611 : uint8_t request_code)
1612 : {
1613 : libspdm_context_t *spdm_context;
1614 :
1615 4274 : spdm_context = context;
1616 : /**
1617 : * Any request other than SPDM_GET_MEASUREMENTS resets L1/L2
1618 : */
1619 4274 : if (request_code != SPDM_GET_MEASUREMENTS) {
1620 3849 : libspdm_reset_message_m(spdm_context, session_info);
1621 : }
1622 : /**
1623 : * If the Requester issued GET_MEASUREMENTS or KEY_EXCHANGE or FINISH or PSK_EXCHANGE
1624 : * or PSK_FINISH or KEY_UPDATE or HEARTBEAT or GET_ENCAPSULATED_REQUEST or DELIVER_ENCAPSULATED_RESPONSE
1625 : * or END_SESSION request(s) or SPDM_GET_MEASUREMENT_EXTENSION_LOG and skipped CHALLENGE completion, M1 and M2 are reset to null.
1626 : */
1627 4274 : switch (request_code)
1628 : {
1629 875 : case SPDM_KEY_EXCHANGE:
1630 : case SPDM_GET_MEASUREMENTS:
1631 : case SPDM_FINISH:
1632 : case SPDM_PSK_EXCHANGE:
1633 : case SPDM_PSK_FINISH:
1634 : case SPDM_KEY_UPDATE:
1635 : case SPDM_HEARTBEAT:
1636 : case SPDM_GET_ENCAPSULATED_REQUEST:
1637 : case SPDM_END_SESSION:
1638 : case SPDM_GET_MEASUREMENT_EXTENSION_LOG:
1639 875 : if (spdm_context->connection_info.connection_state <
1640 : LIBSPDM_CONNECTION_STATE_AUTHENTICATED) {
1641 433 : libspdm_reset_message_b(spdm_context);
1642 433 : libspdm_reset_message_c(spdm_context);
1643 433 : libspdm_reset_message_mut_b(spdm_context);
1644 433 : libspdm_reset_message_mut_c(spdm_context);
1645 : }
1646 875 : break;
1647 5 : case SPDM_DELIVER_ENCAPSULATED_RESPONSE:
1648 5 : if (spdm_context->connection_info.connection_state <
1649 : LIBSPDM_CONNECTION_STATE_AUTHENTICATED) {
1650 5 : libspdm_reset_message_b(spdm_context);
1651 5 : libspdm_reset_message_c(spdm_context);
1652 : }
1653 5 : break;
1654 59 : case SPDM_GET_DIGESTS:
1655 59 : libspdm_reset_message_b(spdm_context);
1656 59 : break;
1657 56 : case SPDM_GET_ENDPOINT_INFO:
1658 56 : libspdm_reset_message_e(spdm_context, session_info);
1659 56 : libspdm_reset_message_encap_e(spdm_context, session_info);
1660 56 : break;
1661 3279 : default:
1662 3279 : break;
1663 : }
1664 4274 : }
1665 : /**
1666 : * Append message A cache in SPDM context.
1667 : *
1668 : * @param spdm_context A pointer to the SPDM context.
1669 : * @param message message buffer.
1670 : * @param message_size size in bytes of message buffer.
1671 : *
1672 : * @return RETURN_SUCCESS message is appended.
1673 : * @return RETURN_OUT_OF_RESOURCES message is not appended because the internal cache is full.
1674 : **/
1675 169 : libspdm_return_t libspdm_append_message_a(libspdm_context_t *spdm_context, const void *message,
1676 : size_t message_size)
1677 : {
1678 169 : return libspdm_append_managed_buffer(&spdm_context->transcript.message_a,
1679 : message, message_size);
1680 : }
1681 :
1682 : /**
1683 : * Append message D cache in SPDM context.
1684 : *
1685 : * @param spdm_context A pointer to the SPDM context.
1686 : * @param message Message buffer.
1687 : * @param message_size Size in bytes of message buffer.
1688 : *
1689 : * @return RETURN_SUCCESS message is appended.
1690 : * @return RETURN_OUT_OF_RESOURCES message is not appended because the internal cache is full.
1691 : **/
1692 7 : libspdm_return_t libspdm_append_message_d(libspdm_context_t *spdm_context, const void *message,
1693 : size_t message_size)
1694 : {
1695 : /* Only the first message D after VCA in connection counts */
1696 7 : if (libspdm_get_managed_buffer_size(&spdm_context->transcript.message_d) != 0) {
1697 1 : return LIBSPDM_STATUS_SUCCESS;
1698 : }
1699 6 : return libspdm_append_managed_buffer(&spdm_context->transcript.message_d,
1700 : message, message_size);
1701 : }
1702 :
1703 : /**
1704 : * Append message B cache in SPDM context.
1705 : *
1706 : * @param spdm_context A pointer to the SPDM context.
1707 : * @param message message buffer.
1708 : * @param message_size size in bytes of message buffer.
1709 : *
1710 : * @return RETURN_SUCCESS message is appended.
1711 : * @return RETURN_OUT_OF_RESOURCES message is not appended because the internal cache is full.
1712 : **/
1713 5932 : libspdm_return_t libspdm_append_message_b(libspdm_context_t *spdm_context, const void *message,
1714 : size_t message_size)
1715 : {
1716 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
1717 : return libspdm_append_managed_buffer(&spdm_context->transcript.message_b,
1718 : message, message_size);
1719 : #else
1720 : {
1721 : bool result;
1722 :
1723 5932 : if (spdm_context->transcript.digest_context_m1m2 == NULL) {
1724 162 : spdm_context->transcript.digest_context_m1m2 = libspdm_hash_new (
1725 : spdm_context->connection_info.algorithm.base_hash_algo);
1726 162 : if (spdm_context->transcript.digest_context_m1m2 == NULL) {
1727 0 : return LIBSPDM_STATUS_CRYPTO_ERROR;
1728 : }
1729 162 : result = libspdm_hash_init (spdm_context->connection_info.algorithm.base_hash_algo,
1730 : spdm_context->transcript.digest_context_m1m2);
1731 162 : if (!result) {
1732 0 : libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
1733 : spdm_context->transcript.digest_context_m1m2);
1734 0 : spdm_context->transcript.digest_context_m1m2 = NULL;
1735 0 : return LIBSPDM_STATUS_CRYPTO_ERROR;
1736 : }
1737 162 : result = libspdm_hash_update (spdm_context->connection_info.algorithm.base_hash_algo,
1738 : spdm_context->transcript.digest_context_m1m2,
1739 162 : libspdm_get_managed_buffer(&spdm_context->transcript.
1740 : message_a),
1741 162 : libspdm_get_managed_buffer_size(&spdm_context->transcript.
1742 : message_a));
1743 162 : if (!result) {
1744 0 : libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
1745 : spdm_context->transcript.digest_context_m1m2);
1746 0 : spdm_context->transcript.digest_context_m1m2 = NULL;
1747 0 : return LIBSPDM_STATUS_CRYPTO_ERROR;
1748 : }
1749 : }
1750 :
1751 5932 : result = libspdm_hash_update (spdm_context->connection_info.algorithm.base_hash_algo,
1752 : spdm_context->transcript.digest_context_m1m2, message,
1753 : message_size);
1754 5932 : if (!result) {
1755 0 : libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
1756 : spdm_context->transcript.digest_context_m1m2);
1757 0 : spdm_context->transcript.digest_context_m1m2 = NULL;
1758 0 : return LIBSPDM_STATUS_CRYPTO_ERROR;
1759 : }
1760 :
1761 5932 : return LIBSPDM_STATUS_SUCCESS;
1762 : }
1763 : #endif
1764 : }
1765 :
1766 : /**
1767 : * Append message C cache in SPDM context.
1768 : *
1769 : * @param spdm_context A pointer to the SPDM context.
1770 : * @param message message buffer.
1771 : * @param message_size size in bytes of message buffer.
1772 : *
1773 : * @return RETURN_SUCCESS message is appended.
1774 : * @return RETURN_OUT_OF_RESOURCES message is not appended because the internal cache is full.
1775 : **/
1776 50 : libspdm_return_t libspdm_append_message_c(libspdm_context_t *spdm_context, const void *message,
1777 : size_t message_size)
1778 : {
1779 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
1780 : return libspdm_append_managed_buffer(&spdm_context->transcript.message_c,
1781 : message, message_size);
1782 : #else
1783 : {
1784 : bool result;
1785 :
1786 50 : if (spdm_context->transcript.digest_context_m1m2 == NULL) {
1787 24 : spdm_context->transcript.digest_context_m1m2 = libspdm_hash_new (
1788 : spdm_context->connection_info.algorithm.base_hash_algo);
1789 24 : if (spdm_context->transcript.digest_context_m1m2 == NULL) {
1790 0 : return LIBSPDM_STATUS_CRYPTO_ERROR;
1791 : }
1792 24 : result = libspdm_hash_init (spdm_context->connection_info.algorithm.base_hash_algo,
1793 : spdm_context->transcript.digest_context_m1m2);
1794 24 : if (!result) {
1795 0 : libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
1796 : spdm_context->transcript.digest_context_m1m2);
1797 0 : spdm_context->transcript.digest_context_m1m2 = NULL;
1798 0 : return LIBSPDM_STATUS_CRYPTO_ERROR;
1799 : }
1800 24 : result = libspdm_hash_update (spdm_context->connection_info.algorithm.base_hash_algo,
1801 : spdm_context->transcript.digest_context_m1m2,
1802 24 : libspdm_get_managed_buffer(&spdm_context->transcript.
1803 : message_a),
1804 24 : libspdm_get_managed_buffer_size(&spdm_context->transcript.
1805 : message_a));
1806 24 : if (!result) {
1807 0 : libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
1808 : spdm_context->transcript.digest_context_m1m2);
1809 0 : spdm_context->transcript.digest_context_m1m2 = NULL;
1810 0 : return LIBSPDM_STATUS_CRYPTO_ERROR;
1811 : }
1812 : }
1813 :
1814 50 : result = libspdm_hash_update (spdm_context->connection_info.algorithm.base_hash_algo,
1815 : spdm_context->transcript.digest_context_m1m2, message,
1816 : message_size);
1817 50 : if (!result) {
1818 0 : libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
1819 : spdm_context->transcript.digest_context_m1m2);
1820 0 : spdm_context->transcript.digest_context_m1m2 = NULL;
1821 0 : return LIBSPDM_STATUS_CRYPTO_ERROR;
1822 : }
1823 :
1824 50 : return LIBSPDM_STATUS_SUCCESS;
1825 : }
1826 : #endif
1827 : }
1828 :
1829 : /**
1830 : * Append message MutB cache in SPDM context.
1831 : *
1832 : * @param spdm_context A pointer to the SPDM context.
1833 : * @param message message buffer.
1834 : * @param message_size size in bytes of message buffer.
1835 : *
1836 : * @return RETURN_SUCCESS message is appended.
1837 : * @return RETURN_OUT_OF_RESOURCES message is not appended because the internal cache is full.
1838 : **/
1839 2833 : libspdm_return_t libspdm_append_message_mut_b(libspdm_context_t *spdm_context, const void *message,
1840 : size_t message_size)
1841 : {
1842 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
1843 : return libspdm_append_managed_buffer(&spdm_context->transcript.message_mut_b,
1844 : message, message_size);
1845 : #else
1846 : {
1847 : bool result;
1848 :
1849 2833 : if (spdm_context->transcript.digest_context_mut_m1m2 == NULL) {
1850 25 : spdm_context->transcript.digest_context_mut_m1m2 = libspdm_hash_new (
1851 : spdm_context->connection_info.algorithm.base_hash_algo);
1852 25 : if (spdm_context->transcript.digest_context_mut_m1m2 == NULL) {
1853 0 : return LIBSPDM_STATUS_CRYPTO_ERROR;
1854 : }
1855 25 : result = libspdm_hash_init (spdm_context->connection_info.algorithm.base_hash_algo,
1856 : spdm_context->transcript.digest_context_mut_m1m2);
1857 25 : if (!result) {
1858 0 : libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
1859 : spdm_context->transcript.digest_context_mut_m1m2);
1860 0 : spdm_context->transcript.digest_context_mut_m1m2 = NULL;
1861 0 : return LIBSPDM_STATUS_CRYPTO_ERROR;
1862 : }
1863 25 : if ((spdm_context->connection_info.version >> SPDM_VERSION_NUMBER_SHIFT_BIT) >
1864 : SPDM_MESSAGE_VERSION_11) {
1865 :
1866 : /* Need append VCA since 1.2 script */
1867 5 : result = libspdm_hash_update (
1868 : spdm_context->connection_info.algorithm.base_hash_algo,
1869 : spdm_context->transcript.digest_context_mut_m1m2,
1870 5 : libspdm_get_managed_buffer(&spdm_context->transcript.message_a),
1871 5 : libspdm_get_managed_buffer_size(&spdm_context->transcript.
1872 : message_a));
1873 5 : if (!result) {
1874 0 : libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
1875 : spdm_context->transcript.digest_context_mut_m1m2);
1876 0 : spdm_context->transcript.digest_context_mut_m1m2 = NULL;
1877 0 : return LIBSPDM_STATUS_CRYPTO_ERROR;
1878 : }
1879 : }
1880 : }
1881 :
1882 2833 : result = libspdm_hash_update (spdm_context->connection_info.algorithm.base_hash_algo,
1883 : spdm_context->transcript.digest_context_mut_m1m2, message,
1884 : message_size);
1885 2833 : if (!result) {
1886 0 : libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
1887 : spdm_context->transcript.digest_context_mut_m1m2);
1888 0 : spdm_context->transcript.digest_context_mut_m1m2 = NULL;
1889 0 : return LIBSPDM_STATUS_CRYPTO_ERROR;
1890 : }
1891 :
1892 2833 : return LIBSPDM_STATUS_SUCCESS;
1893 : }
1894 : #endif
1895 : }
1896 :
1897 : /**
1898 : * Append message MutC cache in SPDM context.
1899 : *
1900 : * @param spdm_context A pointer to the SPDM context.
1901 : * @param message message buffer.
1902 : * @param message_size size in bytes of message buffer.
1903 : *
1904 : * @return RETURN_SUCCESS message is appended.
1905 : * @return RETURN_OUT_OF_RESOURCES message is not appended because the internal cache is full.
1906 : **/
1907 10 : libspdm_return_t libspdm_append_message_mut_c(libspdm_context_t *spdm_context, const void *message,
1908 : size_t message_size)
1909 : {
1910 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
1911 : return libspdm_append_managed_buffer(&spdm_context->transcript.message_mut_c,
1912 : message, message_size);
1913 : #else
1914 : {
1915 : bool result;
1916 :
1917 10 : if (spdm_context->transcript.digest_context_mut_m1m2 == NULL) {
1918 7 : spdm_context->transcript.digest_context_mut_m1m2 = libspdm_hash_new (
1919 : spdm_context->connection_info.algorithm.base_hash_algo);
1920 7 : if (spdm_context->transcript.digest_context_mut_m1m2 == NULL) {
1921 0 : return LIBSPDM_STATUS_CRYPTO_ERROR;
1922 : }
1923 7 : result = libspdm_hash_init (spdm_context->connection_info.algorithm.base_hash_algo,
1924 : spdm_context->transcript.digest_context_mut_m1m2);
1925 7 : if (!result) {
1926 0 : libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
1927 : spdm_context->transcript.digest_context_mut_m1m2);
1928 0 : spdm_context->transcript.digest_context_mut_m1m2 = NULL;
1929 0 : return LIBSPDM_STATUS_CRYPTO_ERROR;
1930 : }
1931 7 : if ((spdm_context->connection_info.version >> SPDM_VERSION_NUMBER_SHIFT_BIT) >
1932 : SPDM_MESSAGE_VERSION_11) {
1933 :
1934 : /* Need append VCA since 1.2 script */
1935 2 : result = libspdm_hash_update (
1936 : spdm_context->connection_info.algorithm.base_hash_algo,
1937 : spdm_context->transcript.digest_context_mut_m1m2,
1938 2 : libspdm_get_managed_buffer(&spdm_context->transcript.message_a),
1939 2 : libspdm_get_managed_buffer_size(&spdm_context->transcript.
1940 : message_a));
1941 2 : if (!result) {
1942 0 : libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
1943 : spdm_context->transcript.digest_context_mut_m1m2);
1944 0 : spdm_context->transcript.digest_context_mut_m1m2 = NULL;
1945 0 : return LIBSPDM_STATUS_CRYPTO_ERROR;
1946 : }
1947 : }
1948 : }
1949 :
1950 10 : result = libspdm_hash_update (spdm_context->connection_info.algorithm.base_hash_algo,
1951 : spdm_context->transcript.digest_context_mut_m1m2, message,
1952 : message_size);
1953 10 : if (!result) {
1954 0 : libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
1955 : spdm_context->transcript.digest_context_mut_m1m2);
1956 0 : spdm_context->transcript.digest_context_mut_m1m2 = NULL;
1957 0 : return LIBSPDM_STATUS_CRYPTO_ERROR;
1958 : }
1959 :
1960 10 : return LIBSPDM_STATUS_SUCCESS;
1961 : }
1962 : #endif
1963 : }
1964 :
1965 : /**
1966 : * Append message M cache in SPDM context.
1967 : * If session_info is NULL, this function will use M cache of SPDM context,
1968 : * else will use M cache of SPDM session context.
1969 : *
1970 : * @param spdm_context A pointer to the SPDM context.
1971 : * @param session_info A pointer to the SPDM session context.
1972 : * @param message message buffer.
1973 : * @param message_size size in bytes of message buffer.
1974 : *
1975 : * @return RETURN_SUCCESS message is appended.
1976 : * @return RETURN_OUT_OF_RESOURCES message is not appended because the internal cache is full.
1977 : **/
1978 722 : libspdm_return_t libspdm_append_message_m(libspdm_context_t *spdm_context, void *session_info,
1979 : const void *message, size_t message_size)
1980 : {
1981 : libspdm_session_info_t *spdm_session_info;
1982 :
1983 722 : spdm_session_info = session_info;
1984 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
1985 : if (spdm_session_info == NULL) {
1986 : return libspdm_append_managed_buffer(&spdm_context->transcript.message_m,
1987 : message, message_size);
1988 : } else {
1989 : return libspdm_append_managed_buffer(&spdm_session_info->session_transcript.message_m,
1990 : message, message_size);
1991 : }
1992 : #else
1993 : {
1994 : bool result;
1995 :
1996 722 : if (spdm_session_info == NULL) {
1997 718 : if (spdm_context->transcript.digest_context_l1l2 == NULL) {
1998 62 : spdm_context->transcript.digest_context_l1l2 = libspdm_hash_new (
1999 : spdm_context->connection_info.algorithm.base_hash_algo);
2000 62 : if (spdm_context->transcript.digest_context_l1l2 == NULL) {
2001 0 : return LIBSPDM_STATUS_CRYPTO_ERROR;
2002 : }
2003 62 : result = libspdm_hash_init (spdm_context->connection_info.algorithm.base_hash_algo,
2004 : spdm_context->transcript.digest_context_l1l2);
2005 62 : if (!result) {
2006 0 : libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
2007 : spdm_context->transcript.digest_context_l1l2);
2008 0 : spdm_context->transcript.digest_context_l1l2 = NULL;
2009 0 : return LIBSPDM_STATUS_CRYPTO_ERROR;
2010 : }
2011 62 : if ((spdm_context->connection_info.version >> SPDM_VERSION_NUMBER_SHIFT_BIT) >
2012 : SPDM_MESSAGE_VERSION_11) {
2013 :
2014 : /* Need append VCA since 1.2 script */
2015 13 : result = libspdm_hash_update (
2016 : spdm_context->connection_info.algorithm.base_hash_algo,
2017 : spdm_context->transcript.digest_context_l1l2,
2018 13 : libspdm_get_managed_buffer(
2019 13 : &spdm_context->transcript.message_a),
2020 13 : libspdm_get_managed_buffer_size(&spdm_context->transcript.
2021 : message_a));
2022 13 : if (!result) {
2023 0 : libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
2024 : spdm_context->transcript.digest_context_l1l2);
2025 0 : spdm_context->transcript.digest_context_l1l2 = NULL;
2026 0 : return LIBSPDM_STATUS_CRYPTO_ERROR;
2027 : }
2028 : }
2029 : }
2030 718 : result = libspdm_hash_update (spdm_context->connection_info.algorithm.base_hash_algo,
2031 : spdm_context->transcript.digest_context_l1l2, message,
2032 : message_size);
2033 718 : if (!result) {
2034 0 : libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
2035 : spdm_context->transcript.digest_context_l1l2);
2036 0 : spdm_context->transcript.digest_context_l1l2 = NULL;
2037 0 : return LIBSPDM_STATUS_CRYPTO_ERROR;
2038 : }
2039 : } else {
2040 4 : if (spdm_session_info->session_transcript.digest_context_l1l2 == NULL) {
2041 2 : spdm_session_info->session_transcript.digest_context_l1l2 = libspdm_hash_new (
2042 : spdm_context->connection_info.algorithm.base_hash_algo);
2043 2 : if (spdm_session_info->session_transcript.digest_context_l1l2 == NULL) {
2044 0 : return LIBSPDM_STATUS_CRYPTO_ERROR;
2045 : }
2046 2 : result = libspdm_hash_init (spdm_context->connection_info.algorithm.base_hash_algo,
2047 : spdm_session_info->session_transcript.digest_context_l1l2);
2048 2 : if (!result) {
2049 0 : libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
2050 : spdm_session_info->session_transcript.digest_context_l1l2);
2051 0 : spdm_session_info->session_transcript.digest_context_l1l2 = NULL;
2052 0 : return LIBSPDM_STATUS_CRYPTO_ERROR;
2053 : }
2054 2 : if ((spdm_context->connection_info.version >> SPDM_VERSION_NUMBER_SHIFT_BIT) >
2055 : SPDM_MESSAGE_VERSION_11) {
2056 :
2057 : /* Need append VCA since 1.2 script*/
2058 :
2059 0 : result = libspdm_hash_update (
2060 : spdm_context->connection_info.algorithm.base_hash_algo,
2061 : spdm_session_info->session_transcript.digest_context_l1l2,
2062 0 : libspdm_get_managed_buffer(
2063 0 : &spdm_context->transcript.message_a),
2064 0 : libspdm_get_managed_buffer_size(&spdm_context->transcript.
2065 : message_a));
2066 0 : if (!result) {
2067 0 : libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
2068 : spdm_session_info->session_transcript.digest_context_l1l2);
2069 0 : spdm_session_info->session_transcript.digest_context_l1l2 = NULL;
2070 0 : return LIBSPDM_STATUS_CRYPTO_ERROR;
2071 : }
2072 : }
2073 : }
2074 4 : result = libspdm_hash_update (spdm_context->connection_info.algorithm.base_hash_algo,
2075 : spdm_session_info->session_transcript.digest_context_l1l2,
2076 : message, message_size);
2077 4 : if (!result) {
2078 0 : libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
2079 : spdm_session_info->session_transcript.digest_context_l1l2);
2080 0 : spdm_session_info->session_transcript.digest_context_l1l2 = NULL;
2081 0 : return LIBSPDM_STATUS_CRYPTO_ERROR;
2082 : }
2083 : }
2084 :
2085 722 : return LIBSPDM_STATUS_SUCCESS;
2086 : }
2087 : #endif
2088 : }
2089 :
2090 : /**
2091 : * Append message K cache in SPDM context.
2092 : *
2093 : * @param spdm_context A pointer to the SPDM context.
2094 : * @param spdm_session_info A pointer to the SPDM session context.
2095 : * @param is_requester Indicate of the key generation for a requester or a responder.
2096 : * @param message message buffer.
2097 : * @param message_size size in bytes of message buffer.
2098 : *
2099 : * @return RETURN_SUCCESS message is appended.
2100 : * @return RETURN_OUT_OF_RESOURCES message is not appended because the internal cache is full.
2101 : **/
2102 296 : libspdm_return_t libspdm_append_message_k(libspdm_context_t *spdm_context,
2103 : void *session_info,
2104 : bool is_requester, const void *message,
2105 : size_t message_size)
2106 : {
2107 : libspdm_session_info_t *spdm_session_info;
2108 :
2109 296 : spdm_session_info = session_info;
2110 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
2111 : return libspdm_append_managed_buffer(
2112 : &spdm_session_info->session_transcript.message_k, message,
2113 : message_size);
2114 : #else
2115 : {
2116 : uint8_t *cert_chain_buffer;
2117 : size_t cert_chain_buffer_size;
2118 : bool result;
2119 : uint8_t cert_chain_buffer_hash[LIBSPDM_MAX_HASH_SIZE];
2120 : uint32_t hash_size;
2121 : uint8_t slot_id;
2122 :
2123 296 : hash_size = libspdm_get_hash_size(spdm_context->connection_info.algorithm.base_hash_algo);
2124 :
2125 296 : if (spdm_session_info->session_transcript.digest_context_th == NULL) {
2126 154 : if (!spdm_session_info->use_psk) {
2127 90 : if (is_requester) {
2128 59 : slot_id = spdm_context->connection_info.peer_used_cert_chain_slot_id;
2129 59 : LIBSPDM_ASSERT((slot_id < SPDM_MAX_SLOT_COUNT) || (slot_id == 0xFF));
2130 59 : if (slot_id == 0xFF) {
2131 2 : result = libspdm_get_peer_public_key_buffer(
2132 : spdm_context, (const void **)&cert_chain_buffer,
2133 : &cert_chain_buffer_size);
2134 2 : if (!result) {
2135 0 : return LIBSPDM_STATUS_INVALID_STATE_PEER;
2136 : }
2137 :
2138 2 : result = libspdm_hash_all(
2139 : spdm_context->connection_info.algorithm.base_hash_algo,
2140 : cert_chain_buffer, cert_chain_buffer_size,
2141 : cert_chain_buffer_hash);
2142 2 : if (!result) {
2143 0 : return LIBSPDM_STATUS_CRYPTO_ERROR;
2144 : }
2145 : } else {
2146 57 : LIBSPDM_ASSERT(
2147 : hash_size ==
2148 : spdm_context->connection_info
2149 : .peer_used_cert_chain[slot_id].buffer_hash_size);
2150 :
2151 57 : libspdm_copy_mem(cert_chain_buffer_hash,
2152 : sizeof(cert_chain_buffer_hash),
2153 : spdm_context->connection_info
2154 57 : .peer_used_cert_chain[slot_id].buffer_hash,
2155 : hash_size);
2156 : }
2157 : } else {
2158 31 : slot_id = spdm_context->connection_info.local_used_cert_chain_slot_id;
2159 31 : LIBSPDM_ASSERT((slot_id < SPDM_MAX_SLOT_COUNT) || (slot_id == 0xFF));
2160 31 : if (slot_id == 0xFF) {
2161 2 : result = libspdm_get_local_public_key_buffer(
2162 : spdm_context, (const void **)&cert_chain_buffer,
2163 : &cert_chain_buffer_size);
2164 : } else {
2165 29 : result = libspdm_get_local_cert_chain_buffer(
2166 : spdm_context, (const void **)&cert_chain_buffer,
2167 : &cert_chain_buffer_size);
2168 : }
2169 31 : if (!result) {
2170 0 : return LIBSPDM_STATUS_INVALID_STATE_LOCAL;
2171 : }
2172 :
2173 31 : result = libspdm_hash_all(
2174 : spdm_context->connection_info.algorithm.base_hash_algo,
2175 : cert_chain_buffer, cert_chain_buffer_size,
2176 : cert_chain_buffer_hash);
2177 31 : if (!result) {
2178 0 : return LIBSPDM_STATUS_CRYPTO_ERROR;
2179 : }
2180 : }
2181 : }
2182 : }
2183 :
2184 :
2185 : /* prepare digest_context_th*/
2186 :
2187 296 : if (spdm_session_info->session_transcript.digest_context_th == NULL) {
2188 154 : spdm_session_info->session_transcript.digest_context_th = libspdm_hash_new (
2189 : spdm_context->connection_info.algorithm.base_hash_algo);
2190 154 : if (spdm_session_info->session_transcript.digest_context_th == NULL) {
2191 0 : return LIBSPDM_STATUS_CRYPTO_ERROR;
2192 : }
2193 154 : result = libspdm_hash_init (spdm_context->connection_info.algorithm.base_hash_algo,
2194 : spdm_session_info->session_transcript.digest_context_th);
2195 154 : if (!result) {
2196 0 : libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
2197 : spdm_session_info->session_transcript.digest_context_th);
2198 0 : return LIBSPDM_STATUS_CRYPTO_ERROR;
2199 : }
2200 154 : result = libspdm_hash_update (spdm_context->connection_info.algorithm.base_hash_algo,
2201 : spdm_session_info->session_transcript.digest_context_th,
2202 154 : libspdm_get_managed_buffer(&spdm_context->transcript.
2203 : message_a),
2204 : libspdm_get_managed_buffer_size(
2205 154 : &spdm_context->transcript.message_a));
2206 154 : if (!result) {
2207 0 : libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
2208 : spdm_session_info->session_transcript.digest_context_th);
2209 0 : return LIBSPDM_STATUS_CRYPTO_ERROR;
2210 : }
2211 154 : if (!spdm_session_info->use_psk) {
2212 90 : if (spdm_context->connection_info.multi_key_conn_rsp) {
2213 0 : result = libspdm_hash_update (
2214 : spdm_context->connection_info.algorithm.base_hash_algo,
2215 : spdm_session_info->session_transcript.digest_context_th,
2216 0 : libspdm_get_managed_buffer(&spdm_context->transcript.message_d),
2217 0 : libspdm_get_managed_buffer_size(&spdm_context->transcript.message_d));
2218 0 : if (!result) {
2219 0 : libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
2220 : spdm_session_info->session_transcript.digest_context_th);
2221 0 : return LIBSPDM_STATUS_CRYPTO_ERROR;
2222 : }
2223 : }
2224 :
2225 90 : result = libspdm_hash_update (
2226 : spdm_context->connection_info.algorithm.base_hash_algo,
2227 : spdm_session_info->session_transcript.digest_context_th,
2228 : cert_chain_buffer_hash, hash_size);
2229 90 : if (!result) {
2230 0 : libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
2231 : spdm_session_info->session_transcript.digest_context_th);
2232 0 : return LIBSPDM_STATUS_CRYPTO_ERROR;
2233 : }
2234 : }
2235 : }
2236 296 : result = libspdm_hash_update (spdm_context->connection_info.algorithm.base_hash_algo,
2237 : spdm_session_info->session_transcript.digest_context_th,
2238 : message,
2239 : message_size);
2240 296 : if (!result) {
2241 0 : libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
2242 : spdm_session_info->session_transcript.digest_context_th);
2243 0 : return LIBSPDM_STATUS_CRYPTO_ERROR;
2244 : }
2245 296 : return LIBSPDM_STATUS_SUCCESS;
2246 : }
2247 : #endif
2248 : }
2249 :
2250 : /**
2251 : * Append message EncapD cache in SPDM context.
2252 : *
2253 : * @param spdm_context A pointer to the SPDM context.
2254 : * @param spdm_session_info A pointer to the SPDM session context.
2255 : * @param is_requester Indicate of the key generation for a requester or a responder.
2256 : * @param message Message buffer.
2257 : * @param message_size Size in bytes of message buffer.
2258 : *
2259 : * @return RETURN_SUCCESS message is appended.
2260 : * @return RETURN_OUT_OF_RESOURCES message is not appended because the internal cache is full.
2261 : **/
2262 4 : libspdm_return_t libspdm_append_message_encap_d(libspdm_context_t *spdm_context,
2263 : void *session_info,
2264 : bool is_requester, const void *message,
2265 : size_t message_size)
2266 : {
2267 : libspdm_session_info_t *spdm_session_info;
2268 :
2269 4 : spdm_session_info = session_info;
2270 : /* Only the first message EncapD in current session counts */
2271 4 : if (libspdm_get_managed_buffer_size(&spdm_session_info->session_transcript.message_encap_d) !=
2272 : 0) {
2273 0 : return LIBSPDM_STATUS_SUCCESS;
2274 : }
2275 4 : return libspdm_append_managed_buffer(
2276 4 : &spdm_session_info->session_transcript.message_encap_d, message,
2277 : message_size);
2278 : }
2279 :
2280 : /**
2281 : * Append message F cache in SPDM context.
2282 : *
2283 : * @param spdm_context A pointer to the SPDM context.
2284 : * @param spdm_session_info A pointer to the SPDM session context.
2285 : * @param is_requester Indicate of the key generation for a requester or a responder.
2286 : * @param message message buffer.
2287 : * @param message_size size in bytes of message buffer.
2288 : *
2289 : * @return RETURN_SUCCESS message is appended.
2290 : * @return RETURN_OUT_OF_RESOURCES message is not appended because the internal cache is full.
2291 : **/
2292 253 : libspdm_return_t libspdm_append_message_f(libspdm_context_t *spdm_context,
2293 : void *session_info,
2294 : bool is_requester, const void *message,
2295 : size_t message_size)
2296 : {
2297 : libspdm_session_info_t *spdm_session_info;
2298 :
2299 253 : spdm_session_info = session_info;
2300 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
2301 : return libspdm_append_managed_buffer(
2302 : &spdm_session_info->session_transcript.message_f, message,
2303 : message_size);
2304 : #else
2305 : {
2306 : const uint8_t *mut_cert_chain_buffer;
2307 : size_t mut_cert_chain_buffer_size;
2308 : bool result;
2309 : uint8_t mut_cert_chain_buffer_hash[LIBSPDM_MAX_HASH_SIZE];
2310 : uint32_t hash_size;
2311 : libspdm_return_t status;
2312 : uint8_t slot_id;
2313 :
2314 253 : hash_size = libspdm_get_hash_size(spdm_context->connection_info.algorithm.base_hash_algo);
2315 :
2316 253 : if (!spdm_session_info->session_transcript.message_f_initialized) {
2317 : /* digest_context_th might be NULL in unit test, where message_k is hardcoded. */
2318 96 : if (spdm_session_info->session_transcript.digest_context_th == NULL) {
2319 : status =
2320 95 : libspdm_append_message_k (spdm_context, session_info, is_requester, NULL, 0);
2321 95 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
2322 0 : return status;
2323 : }
2324 : }
2325 :
2326 96 : if (!spdm_session_info->use_psk && (spdm_session_info->mut_auth_requested != 0)) {
2327 16 : if (is_requester) {
2328 5 : slot_id = spdm_context->connection_info.local_used_cert_chain_slot_id;
2329 5 : LIBSPDM_ASSERT((slot_id < SPDM_MAX_SLOT_COUNT) || (slot_id == 0xFF));
2330 5 : if (slot_id == 0xFF) {
2331 0 : result = libspdm_get_local_public_key_buffer(
2332 : spdm_context,
2333 : (const void **)&mut_cert_chain_buffer,
2334 : &mut_cert_chain_buffer_size);
2335 : } else {
2336 5 : result = libspdm_get_local_cert_chain_buffer(
2337 : spdm_context,
2338 : (const void **)&mut_cert_chain_buffer,
2339 : &mut_cert_chain_buffer_size);
2340 : }
2341 5 : if (!result) {
2342 0 : return LIBSPDM_STATUS_INVALID_STATE_LOCAL;
2343 : }
2344 :
2345 5 : result = libspdm_hash_all(
2346 : spdm_context->connection_info.algorithm.base_hash_algo,
2347 : mut_cert_chain_buffer, mut_cert_chain_buffer_size,
2348 : mut_cert_chain_buffer_hash);
2349 5 : if (!result) {
2350 0 : return LIBSPDM_STATUS_CRYPTO_ERROR;
2351 : }
2352 : } else {
2353 11 : slot_id = spdm_context->connection_info.peer_used_cert_chain_slot_id;
2354 11 : LIBSPDM_ASSERT((slot_id < SPDM_MAX_SLOT_COUNT) || (slot_id == 0xFF));
2355 11 : if (slot_id == 0xFF) {
2356 1 : result = libspdm_get_peer_public_key_buffer(
2357 : spdm_context,
2358 : (const void **)&mut_cert_chain_buffer,
2359 : &mut_cert_chain_buffer_size);
2360 1 : if (!result) {
2361 0 : return LIBSPDM_STATUS_INVALID_STATE_PEER;
2362 : }
2363 :
2364 1 : result = libspdm_hash_all(
2365 : spdm_context->connection_info.algorithm.base_hash_algo,
2366 : mut_cert_chain_buffer, mut_cert_chain_buffer_size,
2367 : mut_cert_chain_buffer_hash);
2368 1 : if (!result) {
2369 0 : return LIBSPDM_STATUS_CRYPTO_ERROR;
2370 : }
2371 : } else {
2372 10 : LIBSPDM_ASSERT(
2373 : hash_size ==
2374 : spdm_context->connection_info
2375 : .peer_used_cert_chain[slot_id].buffer_hash_size);
2376 :
2377 10 : libspdm_copy_mem(mut_cert_chain_buffer_hash,
2378 : sizeof(mut_cert_chain_buffer_hash),
2379 : spdm_context->connection_info
2380 10 : .peer_used_cert_chain[slot_id].buffer_hash,
2381 : hash_size);
2382 : }
2383 : }
2384 : }
2385 :
2386 : /* It is first time call, backup current message_k context
2387 : * this backup will be used in reset_message_f.*/
2388 :
2389 96 : LIBSPDM_ASSERT (spdm_session_info->session_transcript.digest_context_th != NULL);
2390 96 : spdm_session_info->session_transcript.digest_context_th_backup = libspdm_hash_new (
2391 : spdm_context->connection_info.algorithm.base_hash_algo);
2392 96 : if (spdm_session_info->session_transcript.digest_context_th_backup == NULL) {
2393 0 : return LIBSPDM_STATUS_CRYPTO_ERROR;
2394 : }
2395 96 : result = libspdm_hash_duplicate (spdm_context->connection_info.algorithm.base_hash_algo,
2396 96 : spdm_session_info->session_transcript.digest_context_th,
2397 : spdm_session_info->session_transcript.digest_context_th_backup);
2398 96 : if (!result) {
2399 0 : libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
2400 : spdm_session_info->session_transcript.digest_context_th_backup);
2401 0 : spdm_session_info->session_transcript.digest_context_th_backup = NULL;
2402 0 : return LIBSPDM_STATUS_CRYPTO_ERROR;
2403 : }
2404 : }
2405 :
2406 :
2407 : /* prepare digest_context_th*/
2408 :
2409 253 : LIBSPDM_ASSERT (spdm_session_info->session_transcript.digest_context_th != NULL);
2410 253 : if (!spdm_session_info->session_transcript.message_f_initialized) {
2411 96 : if (!spdm_session_info->use_psk && (spdm_session_info->mut_auth_requested != 0)) {
2412 16 : if (spdm_context->connection_info.multi_key_conn_req) {
2413 0 : result = libspdm_hash_update (
2414 : spdm_context->connection_info.algorithm.base_hash_algo,
2415 : spdm_session_info->session_transcript.digest_context_th,
2416 0 : libspdm_get_managed_buffer(&spdm_session_info->session_transcript.
2417 : message_encap_d),
2418 0 : libspdm_get_managed_buffer_size(&spdm_session_info->session_transcript.
2419 : message_encap_d));
2420 0 : if (!result) {
2421 0 : libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
2422 : spdm_session_info->session_transcript.digest_context_th);
2423 0 : spdm_session_info->session_transcript.digest_context_th = NULL;
2424 0 : return LIBSPDM_STATUS_CRYPTO_ERROR;
2425 : }
2426 : }
2427 :
2428 16 : result = libspdm_hash_update (
2429 : spdm_context->connection_info.algorithm.base_hash_algo,
2430 : spdm_session_info->session_transcript.digest_context_th,
2431 : mut_cert_chain_buffer_hash, hash_size);
2432 16 : if (!result) {
2433 0 : libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
2434 : spdm_session_info->session_transcript.digest_context_th);
2435 0 : spdm_session_info->session_transcript.digest_context_th = NULL;
2436 0 : return LIBSPDM_STATUS_CRYPTO_ERROR;
2437 : }
2438 : }
2439 : }
2440 253 : result = libspdm_hash_update (spdm_context->connection_info.algorithm.base_hash_algo,
2441 : spdm_session_info->session_transcript.digest_context_th,
2442 : message,
2443 : message_size);
2444 253 : if (!result) {
2445 0 : libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
2446 : spdm_session_info->session_transcript.digest_context_th);
2447 0 : spdm_session_info->session_transcript.digest_context_th = NULL;
2448 0 : return LIBSPDM_STATUS_CRYPTO_ERROR;
2449 : }
2450 :
2451 253 : spdm_session_info->session_transcript.message_f_initialized = true;
2452 253 : return LIBSPDM_STATUS_SUCCESS;
2453 : }
2454 : #endif
2455 : }
2456 :
2457 : /**
2458 : * Append message E cache in SPDM context.
2459 : * If session_info is NULL, this function will use E cache of SPDM context,
2460 : * else will use E cache of SPDM session context.
2461 : *
2462 : * @param spdm_context A pointer to the SPDM context.
2463 : * @param session_info A pointer to the SPDM session context.
2464 : * @param message message buffer.
2465 : * @param message_size size in bytes of message buffer.
2466 : *
2467 : * @return RETURN_SUCCESS message is appended.
2468 : * @return RETURN_OUT_OF_RESOURCES message is not appended because the internal cache is full.
2469 : **/
2470 34 : libspdm_return_t libspdm_append_message_e(libspdm_context_t *spdm_context, void *session_info,
2471 : const void *message, size_t message_size)
2472 : {
2473 : libspdm_session_info_t *spdm_session_info;
2474 :
2475 34 : spdm_session_info = session_info;
2476 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
2477 : if (spdm_session_info == NULL) {
2478 : return libspdm_append_managed_buffer(&spdm_context->transcript.message_e,
2479 : message, message_size);
2480 : } else {
2481 : return libspdm_append_managed_buffer(&spdm_session_info->session_transcript.message_e,
2482 : message, message_size);
2483 : }
2484 : #else
2485 : {
2486 : bool result;
2487 :
2488 34 : if (spdm_session_info == NULL) {
2489 28 : if (spdm_context->transcript.digest_context_il1il2 == NULL) {
2490 14 : spdm_context->transcript.digest_context_il1il2 = libspdm_hash_new (
2491 : spdm_context->connection_info.algorithm.base_hash_algo);
2492 14 : if (spdm_context->transcript.digest_context_il1il2 == NULL) {
2493 0 : return LIBSPDM_STATUS_CRYPTO_ERROR;
2494 : }
2495 14 : result = libspdm_hash_init (spdm_context->connection_info.algorithm.base_hash_algo,
2496 : spdm_context->transcript.digest_context_il1il2);
2497 14 : if (!result) {
2498 0 : libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
2499 : spdm_context->transcript.digest_context_il1il2);
2500 0 : spdm_context->transcript.digest_context_il1il2 = NULL;
2501 0 : return LIBSPDM_STATUS_CRYPTO_ERROR;
2502 : }
2503 :
2504 14 : result = libspdm_hash_update (
2505 : spdm_context->connection_info.algorithm.base_hash_algo,
2506 : spdm_context->transcript.digest_context_il1il2,
2507 14 : libspdm_get_managed_buffer(&spdm_context->transcript.message_a),
2508 14 : libspdm_get_managed_buffer_size(&spdm_context->transcript.message_a));
2509 :
2510 14 : if (!result) {
2511 0 : libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
2512 : spdm_context->transcript.digest_context_il1il2);
2513 0 : spdm_context->transcript.digest_context_il1il2 = NULL;
2514 0 : return LIBSPDM_STATUS_CRYPTO_ERROR;
2515 : }
2516 : }
2517 28 : result = libspdm_hash_update (spdm_context->connection_info.algorithm.base_hash_algo,
2518 : spdm_context->transcript.digest_context_il1il2, message,
2519 : message_size);
2520 28 : if (!result) {
2521 0 : libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
2522 : spdm_context->transcript.digest_context_il1il2);
2523 0 : spdm_context->transcript.digest_context_il1il2 = NULL;
2524 0 : return LIBSPDM_STATUS_CRYPTO_ERROR;
2525 : }
2526 : } else {
2527 6 : if (spdm_session_info->session_transcript.digest_context_il1il2 == NULL) {
2528 3 : spdm_session_info->session_transcript.digest_context_il1il2 = libspdm_hash_new (
2529 : spdm_context->connection_info.algorithm.base_hash_algo);
2530 3 : if (spdm_session_info->session_transcript.digest_context_il1il2 == NULL) {
2531 0 : return LIBSPDM_STATUS_CRYPTO_ERROR;
2532 : }
2533 3 : result = libspdm_hash_init (spdm_context->connection_info.algorithm.base_hash_algo,
2534 : spdm_session_info->session_transcript.digest_context_il1il2);
2535 3 : if (!result) {
2536 0 : libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
2537 : spdm_session_info->session_transcript.digest_context_il1il2);
2538 0 : spdm_session_info->session_transcript.digest_context_il1il2 = NULL;
2539 0 : return LIBSPDM_STATUS_CRYPTO_ERROR;
2540 : }
2541 :
2542 3 : result = libspdm_hash_update (
2543 : spdm_context->connection_info.algorithm.base_hash_algo,
2544 : spdm_session_info->session_transcript.digest_context_il1il2,
2545 3 : libspdm_get_managed_buffer(&spdm_context->transcript.message_a),
2546 3 : libspdm_get_managed_buffer_size(&spdm_context->transcript.message_a));
2547 :
2548 3 : if (!result) {
2549 0 : libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
2550 : spdm_session_info->session_transcript.digest_context_il1il2);
2551 0 : spdm_session_info->session_transcript.digest_context_il1il2 = NULL;
2552 0 : return LIBSPDM_STATUS_CRYPTO_ERROR;
2553 : }
2554 : }
2555 6 : result = libspdm_hash_update (spdm_context->connection_info.algorithm.base_hash_algo,
2556 : spdm_session_info->session_transcript.digest_context_il1il2,
2557 : message, message_size);
2558 6 : if (!result) {
2559 0 : libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
2560 : spdm_session_info->session_transcript.digest_context_il1il2);
2561 0 : spdm_session_info->session_transcript.digest_context_il1il2 = NULL;
2562 0 : return LIBSPDM_STATUS_CRYPTO_ERROR;
2563 : }
2564 : }
2565 :
2566 34 : return LIBSPDM_STATUS_SUCCESS;
2567 : }
2568 : #endif
2569 : }
2570 :
2571 : /**
2572 : * Append message encap E cache in SPDM context.
2573 : * If session_info is NULL, this function will use encap E cache of SPDM context,
2574 : * else will use encap E cache of SPDM session context.
2575 : *
2576 : * @param spdm_context A pointer to the SPDM context.
2577 : * @param session_info A pointer to the SPDM session context.
2578 : * @param message message buffer.
2579 : * @param message_size size in bytes of message buffer.
2580 : *
2581 : * @return RETURN_SUCCESS message is appended.
2582 : * @return RETURN_OUT_OF_RESOURCES message is not appended because the internal cache is full.
2583 : **/
2584 24 : libspdm_return_t libspdm_append_message_encap_e(libspdm_context_t *spdm_context, void *session_info,
2585 : const void *message, size_t message_size)
2586 : {
2587 : libspdm_session_info_t *spdm_session_info;
2588 :
2589 24 : spdm_session_info = session_info;
2590 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
2591 : if (spdm_session_info == NULL) {
2592 : return libspdm_append_managed_buffer(&spdm_context->transcript.message_encap_e,
2593 : message, message_size);
2594 : } else {
2595 : return libspdm_append_managed_buffer(&spdm_session_info->session_transcript.message_encap_e,
2596 : message, message_size);
2597 : }
2598 : #else
2599 : {
2600 : bool result;
2601 :
2602 24 : if (spdm_session_info == NULL) {
2603 19 : if (spdm_context->transcript.digest_context_encap_il1il2 == NULL) {
2604 12 : spdm_context->transcript.digest_context_encap_il1il2 = libspdm_hash_new (
2605 : spdm_context->connection_info.algorithm.base_hash_algo);
2606 12 : if (spdm_context->transcript.digest_context_encap_il1il2 == NULL) {
2607 0 : return LIBSPDM_STATUS_CRYPTO_ERROR;
2608 : }
2609 12 : result = libspdm_hash_init (spdm_context->connection_info.algorithm.base_hash_algo,
2610 : spdm_context->transcript.digest_context_encap_il1il2);
2611 12 : if (!result) {
2612 0 : libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
2613 : spdm_context->transcript.digest_context_encap_il1il2);
2614 0 : spdm_context->transcript.digest_context_encap_il1il2 = NULL;
2615 0 : return LIBSPDM_STATUS_CRYPTO_ERROR;
2616 : }
2617 :
2618 12 : result = libspdm_hash_update (
2619 : spdm_context->connection_info.algorithm.base_hash_algo,
2620 : spdm_context->transcript.digest_context_encap_il1il2,
2621 12 : libspdm_get_managed_buffer(&spdm_context->transcript.message_a),
2622 12 : libspdm_get_managed_buffer_size(&spdm_context->transcript.message_a));
2623 :
2624 12 : if (!result) {
2625 0 : libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
2626 : spdm_context->transcript.digest_context_encap_il1il2);
2627 0 : spdm_context->transcript.digest_context_encap_il1il2 = NULL;
2628 0 : return LIBSPDM_STATUS_CRYPTO_ERROR;
2629 : }
2630 : }
2631 19 : result = libspdm_hash_update (spdm_context->connection_info.algorithm.base_hash_algo,
2632 : spdm_context->transcript.digest_context_encap_il1il2,
2633 : message,
2634 : message_size);
2635 19 : if (!result) {
2636 0 : libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
2637 : spdm_context->transcript.digest_context_encap_il1il2);
2638 0 : spdm_context->transcript.digest_context_encap_il1il2 = NULL;
2639 0 : return LIBSPDM_STATUS_CRYPTO_ERROR;
2640 : }
2641 : } else {
2642 5 : if (spdm_session_info->session_transcript.digest_context_encap_il1il2 == NULL) {
2643 3 : spdm_session_info->session_transcript.digest_context_encap_il1il2 =
2644 3 : libspdm_hash_new (spdm_context->connection_info.algorithm.base_hash_algo);
2645 3 : if (spdm_session_info->session_transcript.digest_context_encap_il1il2 == NULL) {
2646 0 : return LIBSPDM_STATUS_CRYPTO_ERROR;
2647 : }
2648 3 : result = libspdm_hash_init (spdm_context->connection_info.algorithm.base_hash_algo,
2649 : spdm_session_info->session_transcript.digest_context_encap_il1il2);
2650 3 : if (!result) {
2651 0 : libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
2652 : spdm_session_info->session_transcript.digest_context_encap_il1il2);
2653 0 : spdm_session_info->session_transcript.digest_context_encap_il1il2 = NULL;
2654 0 : return LIBSPDM_STATUS_CRYPTO_ERROR;
2655 : }
2656 :
2657 3 : result = libspdm_hash_update (
2658 : spdm_context->connection_info.algorithm.base_hash_algo,
2659 : spdm_session_info->session_transcript.digest_context_encap_il1il2,
2660 3 : libspdm_get_managed_buffer(&spdm_context->transcript.message_a),
2661 3 : libspdm_get_managed_buffer_size(&spdm_context->transcript.message_a));
2662 :
2663 3 : if (!result) {
2664 0 : libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
2665 : spdm_session_info->session_transcript.digest_context_encap_il1il2);
2666 0 : spdm_session_info->session_transcript.digest_context_encap_il1il2 = NULL;
2667 0 : return LIBSPDM_STATUS_CRYPTO_ERROR;
2668 : }
2669 : }
2670 5 : result = libspdm_hash_update (spdm_context->connection_info.algorithm.base_hash_algo,
2671 : spdm_session_info->session_transcript.digest_context_encap_il1il2,
2672 : message, message_size);
2673 5 : if (!result) {
2674 0 : libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
2675 : spdm_session_info->session_transcript.digest_context_encap_il1il2);
2676 0 : spdm_session_info->session_transcript.digest_context_encap_il1il2 = NULL;
2677 0 : return LIBSPDM_STATUS_CRYPTO_ERROR;
2678 : }
2679 : }
2680 :
2681 24 : return LIBSPDM_STATUS_SUCCESS;
2682 : }
2683 : #endif
2684 : }
2685 : /**
2686 : * This function returns if a given version is supported based upon the GET_VERSION/VERSION.
2687 : *
2688 : * @param spdm_context A pointer to the SPDM context.
2689 : * @param version The SPDM version.
2690 : *
2691 : * @retval true the version is supported.
2692 : * @retval false the version is not supported.
2693 : **/
2694 0 : bool libspdm_is_version_supported(const libspdm_context_t *spdm_context, uint8_t version)
2695 : {
2696 0 : if (version == (spdm_context->connection_info.version >> SPDM_VERSION_NUMBER_SHIFT_BIT)) {
2697 0 : return true;
2698 : }
2699 :
2700 0 : return false;
2701 : }
2702 :
2703 : /**
2704 : * This function returns connection version negotiated by GET_VERSION/VERSION.
2705 : *
2706 : * @param spdm_context A pointer to the SPDM context.
2707 : *
2708 : * @return the connection version.
2709 : **/
2710 141884 : uint8_t libspdm_get_connection_version(const libspdm_context_t *spdm_context)
2711 : {
2712 141884 : return (uint8_t)(spdm_context->connection_info.version >> SPDM_VERSION_NUMBER_SHIFT_BIT);
2713 : }
2714 :
2715 : /**
2716 : * This function returns if a capabilities flag is supported in current SPDM connection.
2717 : *
2718 : * @param spdm_context A pointer to the SPDM context.
2719 : * @param is_requester Is the function called from a requester.
2720 : * @param requester_capabilities_flag The requester capabilities flag to be checked
2721 : * @param responder_capabilities_flag The responder capabilities flag to be checked
2722 : *
2723 : * @retval true the capabilities flag is supported.
2724 : * @retval false the capabilities flag is not supported.
2725 : **/
2726 76715 : bool libspdm_is_capabilities_flag_supported(const libspdm_context_t *spdm_context,
2727 : bool is_requester,
2728 : uint32_t requester_capabilities_flag,
2729 : uint32_t responder_capabilities_flag)
2730 : {
2731 : uint32_t negotiated_requester_capabilities_flag;
2732 : uint32_t negotiated_responder_capabilities_flag;
2733 :
2734 76715 : if (is_requester) {
2735 72305 : negotiated_requester_capabilities_flag = spdm_context->local_context.capability.flags;
2736 72305 : negotiated_responder_capabilities_flag = spdm_context->connection_info.capability.flags;
2737 : } else {
2738 4410 : negotiated_requester_capabilities_flag = spdm_context->connection_info.capability.flags;
2739 4410 : negotiated_responder_capabilities_flag = spdm_context->local_context.capability.flags;
2740 : }
2741 :
2742 76715 : if (((requester_capabilities_flag == 0) ||
2743 73083 : ((negotiated_requester_capabilities_flag &
2744 71733 : requester_capabilities_flag) != 0)) &&
2745 70276 : ((responder_capabilities_flag == 0) ||
2746 70276 : ((negotiated_responder_capabilities_flag &
2747 : responder_capabilities_flag) != 0))) {
2748 70868 : return true;
2749 : } else {
2750 5847 : return false;
2751 : }
2752 : }
2753 :
2754 33 : bool libspdm_is_encap_supported(const libspdm_context_t *spdm_context)
2755 : {
2756 33 : if (libspdm_get_connection_version(spdm_context) == SPDM_MESSAGE_VERSION_10) {
2757 0 : return false;
2758 33 : } else if (libspdm_get_connection_version(spdm_context) == SPDM_MESSAGE_VERSION_12) {
2759 : /* ENCAP_CAP was erroneously deprecated in SPDM 1.2.0 and 1.2.1, and MUT_AUTH_CAP
2760 : * was used in its place. In SPDM 1.2.2 and later ENCAP_CAP is undeprecated. Since
2761 : * UpdateVersionNumber must be ignored when checking interoperability libspdm will check
2762 : * if ENCAP_CAP or MUT_AUTH_CAP is set. */
2763 2 : const bool is_req_encap_cap_supported = libspdm_is_capabilities_flag_supported(
2764 2 : spdm_context, spdm_context->local_context.is_requester,
2765 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_ENCAP_CAP, 0);
2766 2 : const bool is_req_mut_auth_cap_supported = libspdm_is_capabilities_flag_supported(
2767 2 : spdm_context, spdm_context->local_context.is_requester,
2768 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MUT_AUTH_CAP, 0);
2769 2 : const bool is_rsp_encap_cap_supported = libspdm_is_capabilities_flag_supported(
2770 2 : spdm_context, spdm_context->local_context.is_requester,
2771 : 0, SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_ENCAP_CAP);
2772 2 : const bool is_rsp_mut_auth_cap_supported = libspdm_is_capabilities_flag_supported(
2773 2 : spdm_context, spdm_context->local_context.is_requester,
2774 : 0, SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MUT_AUTH_CAP);
2775 :
2776 2 : return ((is_req_encap_cap_supported || is_req_mut_auth_cap_supported) &&
2777 0 : (is_rsp_encap_cap_supported || is_rsp_mut_auth_cap_supported));
2778 : } else {
2779 : /* For SPDM 1.1 and 1.3 and later only check ENCAP_CAP. */
2780 31 : return libspdm_is_capabilities_flag_supported(
2781 31 : spdm_context, spdm_context->local_context.is_requester,
2782 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_ENCAP_CAP,
2783 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_ENCAP_CAP);
2784 : }
2785 : }
2786 :
2787 : /**
2788 : * Register SPDM device input/output functions.
2789 : *
2790 : * This function must be called after libspdm_init_context, and before any SPDM communication.
2791 : *
2792 : * @param spdm_context A pointer to the SPDM context.
2793 : * @param send_message The function to send an SPDM transport layer message.
2794 : * @param receive_message The function to receive an SPDM transport layer message.
2795 : **/
2796 101 : void libspdm_register_device_io_func(
2797 : void *spdm_context, libspdm_device_send_message_func send_message,
2798 : libspdm_device_receive_message_func receive_message)
2799 : {
2800 : libspdm_context_t *context;
2801 :
2802 101 : context = spdm_context;
2803 101 : context->send_message = send_message;
2804 101 : context->receive_message = receive_message;
2805 101 : }
2806 :
2807 : /**
2808 : * Register SPDM device buffer management functions.
2809 : *
2810 : * This function must be called after libspdm_init_context, and before any SPDM communication.
2811 : *
2812 : * The sender_buffer_size and receiver_buffer_size must be no smaller than
2813 : * MAX (non-secure Transport Message Header Size +
2814 : * SPDM_CAPABILITIES.DataTransferSize +
2815 : * max alignment pad size (transport specific),
2816 : * secure Transport Message Header Size +
2817 : * sizeof(spdm_secured_message_a_data_header1_t) +
2818 : * length of sequence_number (transport specific) +
2819 : * sizeof(spdm_secured_message_a_data_header2_t) +
2820 : * sizeof(spdm_secured_message_cipher_header_t) +
2821 : * App Message Header Size (transport specific) +
2822 : * SPDM_CAPABILITIES.DataTransferSize +
2823 : * maximum random data size (transport specific) +
2824 : * AEAD MAC size (16) +
2825 : * max alignment pad size (transport specific)).
2826 : *
2827 : * Finally, the SPDM_CAPABILITIES.DataTransferSize will be calculated based upon it.
2828 : *
2829 : * For MCTP,
2830 : * Transport Message Header Size = sizeof(mctp_message_header_t)
2831 : * length of sequence_number = 2
2832 : * App Message Header Size = sizeof(mctp_message_header_t)
2833 : * maximum random data size = MCTP_MAX_RANDOM_NUMBER_COUNT
2834 : * max alignment pad size = 0
2835 : * For PCI_DOE,
2836 : * Transport Message Header Size = sizeof(pci_doe_data_object_header_t)
2837 : * length of sequence_number = 0
2838 : * App Message Header Size = 0
2839 : * maximum random data size = 0
2840 : * max alignment pad size = 3
2841 : *
2842 : * @param spdm_context A pointer to the SPDM context.
2843 : * @param sender_buffer_size Size in bytes of the sender buffer.
2844 : * @param receiver_buffer_size Size in bytes of the receiver buffer.
2845 : * @param acquire_sender_buffer The function to acquire transport layer sender buffer.
2846 : * @param release_sender_buffer The function to release transport layer sender buffer.
2847 : * @param acquire_receiver_buffer The function to acquire transport layer receiver buffer.
2848 : * @param release_receiver_buffer The function to release transport layer receiver buffer.
2849 : **/
2850 102 : void libspdm_register_device_buffer_func(
2851 : void *spdm_context,
2852 : uint32_t sender_buffer_size,
2853 : uint32_t receiver_buffer_size,
2854 : libspdm_device_acquire_sender_buffer_func acquire_sender_buffer,
2855 : libspdm_device_release_sender_buffer_func release_sender_buffer,
2856 : libspdm_device_acquire_receiver_buffer_func acquire_receiver_buffer,
2857 : libspdm_device_release_receiver_buffer_func release_receiver_buffer)
2858 : {
2859 : libspdm_context_t *context;
2860 :
2861 102 : context = spdm_context;
2862 102 : context->sender_buffer_size = sender_buffer_size;
2863 102 : context->receiver_buffer_size = receiver_buffer_size;
2864 102 : context->acquire_sender_buffer = acquire_sender_buffer;
2865 102 : context->release_sender_buffer = release_sender_buffer;
2866 102 : context->acquire_receiver_buffer = acquire_receiver_buffer;
2867 102 : context->release_receiver_buffer = release_receiver_buffer;
2868 :
2869 102 : LIBSPDM_ASSERT (sender_buffer_size >=
2870 : context->local_context.capability.transport_header_size +
2871 : context->local_context.capability.transport_tail_size);
2872 102 : sender_buffer_size -= (context->local_context.capability.transport_header_size +
2873 102 : context->local_context.capability.transport_tail_size);
2874 102 : LIBSPDM_ASSERT (sender_buffer_size >= SPDM_MIN_DATA_TRANSFER_SIZE_VERSION_12);
2875 102 : context->local_context.capability.sender_data_transfer_size = sender_buffer_size;
2876 :
2877 102 : LIBSPDM_ASSERT(receiver_buffer_size >=
2878 : context->local_context.capability.transport_header_size +
2879 : context->local_context.capability.transport_tail_size);
2880 102 : receiver_buffer_size -= (context->local_context.capability.transport_header_size +
2881 102 : context->local_context.capability.transport_tail_size);
2882 102 : LIBSPDM_ASSERT (receiver_buffer_size >= SPDM_MIN_DATA_TRANSFER_SIZE_VERSION_12);
2883 102 : context->local_context.capability.data_transfer_size = receiver_buffer_size;
2884 102 : }
2885 :
2886 : /**
2887 : * Register SPDM transport layer encode/decode functions for SPDM or APP messages.
2888 : *
2889 : * This function must be called after libspdm_init_context, and before any SPDM communication.
2890 : *
2891 : * @param spdm_context A pointer to the SPDM context.
2892 : * @param transport_encode_message The function to encode an SPDM or APP message to a transport layer message.
2893 : * @param transport_decode_message The function to decode an SPDM or APP message from a transport layer message.
2894 : **/
2895 103 : void libspdm_register_transport_layer_func(
2896 : void *spdm_context,
2897 : uint32_t max_spdm_msg_size,
2898 : uint32_t transport_header_size,
2899 : uint32_t transport_tail_size,
2900 : libspdm_transport_encode_message_func transport_encode_message,
2901 : libspdm_transport_decode_message_func transport_decode_message)
2902 : {
2903 : libspdm_context_t *context;
2904 :
2905 103 : context = spdm_context;
2906 :
2907 : /* fix the data_transfer_size if it is set before */
2908 103 : if ((context->local_context.capability.data_transfer_size != 0) &&
2909 1 : (context->local_context.capability.data_transfer_size ==
2910 1 : context->receiver_buffer_size)) {
2911 0 : context->local_context.capability.data_transfer_size =
2912 0 : (uint32_t)(context->receiver_buffer_size -
2913 0 : (transport_header_size + transport_tail_size));
2914 : }
2915 103 : if ((context->local_context.capability.sender_data_transfer_size != 0) &&
2916 1 : (context->local_context.capability.sender_data_transfer_size ==
2917 1 : context->sender_buffer_size)) {
2918 0 : context->local_context.capability.sender_data_transfer_size =
2919 0 : (uint32_t)(context->sender_buffer_size -
2920 0 : (transport_header_size + transport_tail_size));
2921 : }
2922 :
2923 103 : context->local_context.capability.max_spdm_msg_size = max_spdm_msg_size;
2924 103 : context->local_context.capability.transport_header_size = transport_header_size;
2925 103 : context->local_context.capability.transport_tail_size = transport_tail_size;
2926 103 : context->transport_encode_message = transport_encode_message;
2927 103 : context->transport_decode_message = transport_decode_message;
2928 103 : }
2929 :
2930 : /**
2931 : * Register SPDM certificate verification functions for SPDM GET_CERTIFICATE in requester or responder.
2932 : * It is called after GET_CERTIFICATE gets a full certificate chain from peer.
2933 : *
2934 : * If it is NOT registered, the default verification in SPDM lib will be used. It verifies:
2935 : * 1) The integrity of the certificate chain, (Root Cert Hash->Root Cert->Cert Chain), according to X.509.
2936 : * 2) The trust anchor, according LIBSPDM_DATA_PEER_PUBLIC_ROOT_CERT or LIBSPDM_DATA_PEER_PUBLIC_CERT_CHAIN.
2937 : * If it is registered, SPDM lib will use this function to verify the certificate.
2938 : *
2939 : * This function must be called after libspdm_init_context, and before any SPDM communication.
2940 : *
2941 : * @param context A pointer to the SPDM context.
2942 : * @param verify_spdm_cert_chain The function to verify an SPDM certificate after GET_CERTIFICATE.
2943 : **/
2944 0 : void libspdm_register_verify_spdm_cert_chain_func(
2945 : void *spdm_context,
2946 : const libspdm_verify_spdm_cert_chain_func verify_spdm_cert_chain)
2947 : {
2948 : libspdm_context_t *context;
2949 :
2950 0 : context = spdm_context;
2951 0 : context->local_context.verify_peer_spdm_cert_chain = verify_spdm_cert_chain;
2952 0 : }
2953 :
2954 : /**
2955 : * Get the size of required scratch buffer.
2956 : *
2957 : * The SPDM Integrator must call libspdm_get_sizeof_required_scratch_buffer to get the size,
2958 : * then allocate enough scratch buffer and call libspdm_set_scratch_buffer().
2959 : *
2960 : * @param context A pointer to the SPDM context.
2961 : *
2962 : * @return the size of required scratch buffer.
2963 : **/
2964 106 : size_t libspdm_get_sizeof_required_scratch_buffer (void *spdm_context)
2965 : {
2966 : libspdm_context_t *context;
2967 : size_t scratch_buffer_size;
2968 :
2969 106 : context = spdm_context;
2970 106 : LIBSPDM_ASSERT (context->local_context.capability.max_spdm_msg_size != 0);
2971 :
2972 106 : scratch_buffer_size = libspdm_get_scratch_buffer_capacity(context);
2973 106 : return scratch_buffer_size;
2974 : }
2975 :
2976 : /**
2977 : * Set the scratch buffer.
2978 : *
2979 : * This function must be called after libspdm_init_context, and before any SPDM communication.
2980 : *
2981 : * @param context A pointer to the SPDM context.
2982 : * @param scratch_buffer Buffer address of the scratch buffer.
2983 : * @param scratch_buffer_size Size of the scratch buffer.
2984 : *
2985 : **/
2986 106 : void libspdm_set_scratch_buffer (
2987 : void *spdm_context,
2988 : void *scratch_buffer,
2989 : size_t scratch_buffer_size)
2990 : {
2991 : libspdm_context_t *context;
2992 :
2993 106 : context = spdm_context;
2994 106 : LIBSPDM_ASSERT (context->local_context.capability.max_spdm_msg_size != 0);
2995 106 : LIBSPDM_ASSERT (scratch_buffer_size >= libspdm_get_scratch_buffer_capacity(spdm_context));
2996 106 : context->scratch_buffer = scratch_buffer;
2997 106 : context->scratch_buffer_size = scratch_buffer_size;
2998 106 : context->last_spdm_request = (uint8_t *)scratch_buffer +
2999 106 : libspdm_get_scratch_buffer_last_spdm_request_offset(spdm_context);
3000 : #if LIBSPDM_RESPOND_IF_READY_SUPPORT
3001 106 : context->cache_spdm_request = (uint8_t *)scratch_buffer +
3002 106 : libspdm_get_scratch_buffer_cache_spdm_request_offset(spdm_context);
3003 : #endif
3004 106 : }
3005 :
3006 : /**
3007 : * Get the scratch buffer.
3008 : *
3009 : * @param context A pointer to the SPDM context.
3010 : * @param scratch_buffer Buffer address of the scratch buffer.
3011 : * @param scratch_buffer_size Size of the scratch buffer.
3012 : *
3013 : **/
3014 136644 : void libspdm_get_scratch_buffer (
3015 : void *spdm_context,
3016 : void **scratch_buffer,
3017 : size_t *scratch_buffer_size)
3018 : {
3019 : libspdm_context_t *context;
3020 :
3021 136644 : context = spdm_context;
3022 136644 : LIBSPDM_ASSERT (context->scratch_buffer != NULL);
3023 136644 : LIBSPDM_ASSERT (context->scratch_buffer_size >=
3024 : libspdm_get_scratch_buffer_capacity(spdm_context));
3025 136644 : *scratch_buffer = context->scratch_buffer;
3026 136644 : *scratch_buffer_size = context->scratch_buffer_size;
3027 : /* need to remove last 2 sections, because they are for libspdm internal state track. */
3028 136644 : *scratch_buffer_size -= libspdm_get_scratch_buffer_last_spdm_request_capacity(spdm_context);
3029 : #if LIBSPDM_RESPOND_IF_READY_SUPPORT
3030 136644 : *scratch_buffer_size -= libspdm_get_scratch_buffer_cache_spdm_request_capacity(spdm_context);
3031 : #endif
3032 136644 : }
3033 :
3034 : /**
3035 : * Acquire a device sender buffer for transport layer message.
3036 : *
3037 : * @param context A pointer to the SPDM context.
3038 : * @param msg_buf_ptr A pointer to a sender buffer.
3039 : *
3040 : * @retval RETURN_SUCCESS The sender buffer is acquired.
3041 : **/
3042 2582 : libspdm_return_t libspdm_acquire_sender_buffer (
3043 : libspdm_context_t *spdm_context, size_t *max_msg_size, void **msg_buf_ptr)
3044 : {
3045 : libspdm_return_t status;
3046 :
3047 2582 : LIBSPDM_ASSERT (spdm_context->sender_buffer == NULL);
3048 2582 : LIBSPDM_ASSERT (spdm_context->sender_buffer_size != 0);
3049 2582 : status = spdm_context->acquire_sender_buffer (spdm_context, msg_buf_ptr);
3050 2582 : if (status != LIBSPDM_STATUS_SUCCESS) {
3051 6 : return status;
3052 : }
3053 2576 : spdm_context->sender_buffer = *msg_buf_ptr;
3054 2576 : *max_msg_size = spdm_context->sender_buffer_size;
3055 : #if LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP
3056 : /* it return scratch buffer, because the requester need build message there.*/
3057 5152 : *msg_buf_ptr = (uint8_t *)spdm_context->scratch_buffer +
3058 2576 : libspdm_get_scratch_buffer_large_sender_receiver_offset(spdm_context);
3059 2576 : *max_msg_size = libspdm_get_scratch_buffer_large_sender_receiver_capacity(spdm_context);
3060 : #endif
3061 2576 : return LIBSPDM_STATUS_SUCCESS;
3062 : }
3063 :
3064 : /**
3065 : * Release a device sender buffer for transport layer message.
3066 : *
3067 : * @param context A pointer to the SPDM context.
3068 : *
3069 : * @retval RETURN_SUCCESS The sender buffer is Released.
3070 : **/
3071 2576 : void libspdm_release_sender_buffer (libspdm_context_t *spdm_context)
3072 : {
3073 2576 : LIBSPDM_ASSERT(spdm_context->sender_buffer != NULL);
3074 2576 : LIBSPDM_ASSERT(spdm_context->sender_buffer_size != 0);
3075 :
3076 2576 : spdm_context->release_sender_buffer (spdm_context, spdm_context->sender_buffer);
3077 2576 : spdm_context->sender_buffer = NULL;
3078 2576 : }
3079 :
3080 : /**
3081 : * Get the sender buffer.
3082 : *
3083 : * @param context A pointer to the SPDM context.
3084 : * @param receiver_buffer Buffer address of the sender buffer.
3085 : * @param receiver_buffer_size Size of the sender buffer.
3086 : *
3087 : **/
3088 68177 : void libspdm_get_sender_buffer (
3089 : libspdm_context_t *spdm_context,
3090 : void **sender_buffer,
3091 : size_t *sender_buffer_size)
3092 : {
3093 68177 : *sender_buffer = spdm_context->sender_buffer;
3094 68177 : *sender_buffer_size = spdm_context->sender_buffer_size;
3095 68177 : }
3096 :
3097 : /**
3098 : * Acquire a device receiver buffer for transport layer message.
3099 : *
3100 : * @param context A pointer to the SPDM context.
3101 : * @param max_msg_size size in bytes of the maximum size of receiver buffer.
3102 : * @param msg_buf_pt A pointer to a receiver buffer.
3103 : *
3104 : * @retval RETURN_SUCCESS The receiver buffer is acquired.
3105 : **/
3106 2538 : libspdm_return_t libspdm_acquire_receiver_buffer (
3107 : libspdm_context_t *spdm_context, size_t *max_msg_size, void **msg_buf_ptr)
3108 : {
3109 : libspdm_return_t status;
3110 :
3111 2538 : LIBSPDM_ASSERT (spdm_context->receiver_buffer == NULL);
3112 2538 : LIBSPDM_ASSERT (spdm_context->receiver_buffer_size != 0);
3113 2538 : status = spdm_context->acquire_receiver_buffer (spdm_context, msg_buf_ptr);
3114 2538 : if (status != LIBSPDM_STATUS_SUCCESS) {
3115 6 : return status;
3116 : }
3117 2532 : spdm_context->receiver_buffer = *msg_buf_ptr;
3118 2532 : *max_msg_size = spdm_context->receiver_buffer_size;
3119 : #if LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP
3120 : /* it return scratch buffer, because the requester need build message there.*/
3121 5064 : *msg_buf_ptr = (uint8_t *)spdm_context->scratch_buffer +
3122 2532 : libspdm_get_scratch_buffer_large_sender_receiver_offset(spdm_context);
3123 2532 : *max_msg_size = libspdm_get_scratch_buffer_large_sender_receiver_capacity(spdm_context);
3124 : #endif
3125 2532 : return LIBSPDM_STATUS_SUCCESS;
3126 : }
3127 :
3128 : /**
3129 : * Release a device receiver buffer for transport layer message.
3130 : *
3131 : * @param context A pointer to the SPDM context.
3132 : *
3133 : * @retval RETURN_SUCCESS The receiver buffer is Released.
3134 : **/
3135 2532 : void libspdm_release_receiver_buffer (libspdm_context_t *spdm_context)
3136 : {
3137 2532 : LIBSPDM_ASSERT(spdm_context->receiver_buffer != NULL);
3138 2532 : LIBSPDM_ASSERT(spdm_context->receiver_buffer_size != 0);
3139 :
3140 2532 : spdm_context->release_receiver_buffer (spdm_context, spdm_context->receiver_buffer);
3141 2532 : spdm_context->receiver_buffer = NULL;
3142 2532 : }
3143 :
3144 : /**
3145 : * Get the receiver buffer.
3146 : *
3147 : * @param context A pointer to the SPDM context.
3148 : * @param receiver_buffer Buffer address of the receiver buffer.
3149 : * @param receiver_buffer_size Size of the receiver buffer.
3150 : *
3151 : **/
3152 0 : void libspdm_get_receiver_buffer (
3153 : libspdm_context_t *spdm_context,
3154 : void **receiver_buffer,
3155 : size_t *receiver_buffer_size)
3156 : {
3157 0 : *receiver_buffer = spdm_context->receiver_buffer;
3158 0 : *receiver_buffer_size = spdm_context->receiver_buffer_size;
3159 0 : }
3160 :
3161 : /**
3162 : * Get the last SPDM error struct of an SPDM context.
3163 : *
3164 : * @param spdm_context A pointer to the SPDM context.
3165 : * @param last_spdm_error Last SPDM error struct of an SPDM context.
3166 : */
3167 0 : void libspdm_get_last_spdm_error_struct(void *spdm_context, libspdm_error_struct_t *last_spdm_error)
3168 : {
3169 : libspdm_context_t *context;
3170 :
3171 0 : context = spdm_context;
3172 0 : libspdm_copy_mem(last_spdm_error, sizeof(libspdm_error_struct_t),
3173 0 : &context->last_spdm_error,sizeof(libspdm_error_struct_t));
3174 0 : }
3175 :
3176 : /**
3177 : * Set the last SPDM error struct of an SPDM context.
3178 : *
3179 : * @param spdm_context A pointer to the SPDM context.
3180 : * @param last_spdm_error Last SPDM error struct of an SPDM context.
3181 : */
3182 68272 : void libspdm_set_last_spdm_error_struct(void *spdm_context, libspdm_error_struct_t *last_spdm_error)
3183 : {
3184 : libspdm_context_t *context;
3185 :
3186 68272 : context = spdm_context;
3187 68272 : libspdm_copy_mem(&context->last_spdm_error, sizeof(context->last_spdm_error),
3188 : last_spdm_error, sizeof(libspdm_error_struct_t));
3189 68272 : }
3190 :
3191 : #if LIBSPDM_FIPS_MODE
3192 : /**
3193 : * Initialize an libspdm_fips_selftest_context.
3194 : *
3195 : * @param fips_selftest_context A pointer to the fips_selftest_context.
3196 : *
3197 : * @retval RETURN_SUCCESS context is initialized.
3198 : * @retval RETURN_DEVICE_ERROR context initialization failed.
3199 : */
3200 0 : libspdm_return_t libspdm_init_fips_selftest_context(void *fips_selftest_context)
3201 : {
3202 : libspdm_fips_selftest_context_t *context;
3203 0 : LIBSPDM_ASSERT(fips_selftest_context != NULL);
3204 :
3205 0 : context = fips_selftest_context;
3206 :
3207 : /*No tested for every used algo*/
3208 0 : context->tested_algo = 0;
3209 : /*self_test result is false for every used algo*/
3210 0 : context->self_test_result = 0;
3211 :
3212 0 : return LIBSPDM_STATUS_SUCCESS;
3213 : }
3214 :
3215 : /**
3216 : * Return the size in bytes of the fips_selftest_context.
3217 : *
3218 : * @return the size in bytes of the fips_selftest_context.
3219 : **/
3220 0 : size_t libspdm_get_fips_selftest_context_size(void)
3221 : {
3222 : size_t size;
3223 :
3224 0 : size = sizeof(libspdm_fips_selftest_context_t);
3225 0 : return size;
3226 : }
3227 :
3228 : /**
3229 : * import fips_selftest_context to spdm_context;
3230 : *
3231 : * @param[in,out] spdm_context A pointer to the spdm_context.
3232 : * @param[in] fips_selftest_context A pointer to the fips_selftest_context.
3233 : * @param[in] fips_selftest_context_size The size of fips_selftest_context.
3234 : *
3235 : * @retval true import fips_selftest_context successful.
3236 : * @retval false spdm_context or fips_selftest_context is null.
3237 : */
3238 0 : bool libspdm_import_fips_selftest_context_to_spdm_context(void *spdm_context,
3239 : void *fips_selftest_context,
3240 : size_t fips_selftest_context_size)
3241 : {
3242 : libspdm_fips_selftest_context_t *libspdm_fips_selftest_context;
3243 : libspdm_context_t *libspdm_context;
3244 :
3245 0 : libspdm_context = spdm_context;
3246 0 : libspdm_fips_selftest_context = fips_selftest_context;
3247 :
3248 0 : if ((libspdm_context == NULL) || (libspdm_fips_selftest_context == NULL)) {
3249 0 : return false;
3250 : }
3251 0 : if (fips_selftest_context_size != sizeof(libspdm_fips_selftest_context_t)) {
3252 0 : return false;
3253 : }
3254 :
3255 0 : libspdm_copy_mem(&(libspdm_context->fips_selftest_context),
3256 : sizeof(libspdm_fips_selftest_context_t),
3257 : libspdm_fips_selftest_context, sizeof(libspdm_fips_selftest_context_t));
3258 0 : return true;
3259 : }
3260 :
3261 : /**
3262 : * export fips_selftest_context from spdm_context;
3263 : *
3264 : * @param[in] spdm_context A pointer to the spdm_context.
3265 : * @param[in,out] fips_selftest_context A pointer to the fips_selftest_context.
3266 : * @param[in] fips_selftest_context_size The size of fips_selftest_context.
3267 : *
3268 : * @retval true export fips_selftest_context successful.
3269 : * @retval false spdm_context or fips_selftest_context is null.
3270 : */
3271 0 : bool libspdm_export_fips_selftest_context_from_spdm_context(void *spdm_context,
3272 : void *fips_selftest_context,
3273 : size_t fips_selftest_context_size)
3274 : {
3275 : libspdm_fips_selftest_context_t *libspdm_fips_selftest_context;
3276 : libspdm_context_t *libspdm_context;
3277 :
3278 0 : libspdm_context = spdm_context;
3279 0 : libspdm_fips_selftest_context = fips_selftest_context;
3280 :
3281 0 : if ((libspdm_context == NULL) || (libspdm_fips_selftest_context == NULL)) {
3282 0 : return false;
3283 : }
3284 0 : if (fips_selftest_context_size != sizeof(libspdm_fips_selftest_context_t)) {
3285 0 : return false;
3286 : }
3287 :
3288 0 : libspdm_copy_mem(libspdm_fips_selftest_context,
3289 : sizeof(libspdm_fips_selftest_context_t),
3290 0 : &(libspdm_context->fips_selftest_context),
3291 : sizeof(libspdm_fips_selftest_context_t));
3292 0 : return true;
3293 : }
3294 :
3295 : #endif /* LIBSPDM_FIPS_MODE */
3296 :
3297 : /**
3298 : * Initialize an SPDM context, as well as all secured message contexts,
3299 : * in the specified locations.
3300 : *
3301 : * The size in bytes of the spdm_context can be returned by
3302 : * libspdm_get_context_size_without_secured_context.
3303 : *
3304 : * The size in bytes of a single secured message context can be returned by
3305 : * libspdm_secured_message_get_context_size.
3306 : *
3307 : * @param spdm_context A pointer to the SPDM context.
3308 : * @param secured_contexts An array of pointers, with each entry containing
3309 : * the location of a secured message context.
3310 : * @param num_secured_contexts Number of secured message contexts to initialize.
3311 : * Currently, only LIBSPDM_MAX_SESSION_COUNT is supported.
3312 : *
3313 : * @retval RETURN_SUCCESS Contexts are initialized.
3314 : * @retval RETURN_DEVICE_ERROR Context initialization failed.
3315 : */
3316 109 : libspdm_return_t libspdm_init_context_with_secured_context(void *spdm_context,
3317 : void **secured_contexts,
3318 : size_t num_secured_contexts)
3319 : {
3320 : libspdm_context_t *context;
3321 : size_t index;
3322 :
3323 109 : LIBSPDM_ASSERT(spdm_context != NULL);
3324 109 : LIBSPDM_ASSERT(secured_contexts != NULL);
3325 109 : LIBSPDM_ASSERT(num_secured_contexts == LIBSPDM_MAX_SESSION_COUNT);
3326 :
3327 109 : context = spdm_context;
3328 109 : libspdm_zero_mem(context, sizeof(libspdm_context_t));
3329 109 : context->version = LIBSPDM_CONTEXT_STRUCT_VERSION;
3330 109 : context->transcript.message_a.max_buffer_size =
3331 : sizeof(context->transcript.message_a.buffer);
3332 109 : context->transcript.message_d.max_buffer_size =
3333 : sizeof(context->transcript.message_d.buffer);
3334 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
3335 : context->transcript.message_b.max_buffer_size =
3336 : sizeof(context->transcript.message_b.buffer);
3337 : context->transcript.message_c.max_buffer_size =
3338 : sizeof(context->transcript.message_c.buffer);
3339 : context->transcript.message_mut_b.max_buffer_size =
3340 : sizeof(context->transcript.message_mut_b.buffer);
3341 : context->transcript.message_mut_c.max_buffer_size =
3342 : sizeof(context->transcript.message_mut_c.buffer);
3343 : context->transcript.message_m.max_buffer_size =
3344 : sizeof(context->transcript.message_m.buffer);
3345 : context->transcript.message_e.max_buffer_size =
3346 : sizeof(context->transcript.message_e.buffer);
3347 : context->transcript.message_encap_e.max_buffer_size =
3348 : sizeof(context->transcript.message_encap_e.buffer);
3349 : #endif
3350 109 : context->response_state = LIBSPDM_RESPONSE_STATE_NORMAL;
3351 109 : context->local_context.version.spdm_version_count = SPDM_MAX_VERSION_COUNT;
3352 109 : context->local_context.version.spdm_version[0] = SPDM_MESSAGE_VERSION_10 <<
3353 : SPDM_VERSION_NUMBER_SHIFT_BIT;
3354 109 : context->local_context.version.spdm_version[1] = SPDM_MESSAGE_VERSION_11 <<
3355 : SPDM_VERSION_NUMBER_SHIFT_BIT;
3356 109 : context->local_context.version.spdm_version[2] = SPDM_MESSAGE_VERSION_12 <<
3357 : SPDM_VERSION_NUMBER_SHIFT_BIT;
3358 109 : context->local_context.version.spdm_version[3] = SPDM_MESSAGE_VERSION_13 <<
3359 : SPDM_VERSION_NUMBER_SHIFT_BIT;
3360 109 : context->local_context.version.spdm_version[4] = SPDM_MESSAGE_VERSION_14 <<
3361 : SPDM_VERSION_NUMBER_SHIFT_BIT;
3362 109 : context->local_context.secured_message_version.spdm_version_count =
3363 : SECURED_SPDM_MAX_VERSION_COUNT;
3364 109 : context->local_context.secured_message_version.spdm_version[0] =
3365 : SECURED_SPDM_VERSION_10 << SPDM_VERSION_NUMBER_SHIFT_BIT;
3366 109 : context->local_context.secured_message_version.spdm_version[1] =
3367 : SECURED_SPDM_VERSION_11 << SPDM_VERSION_NUMBER_SHIFT_BIT;
3368 109 : context->local_context.secured_message_version.spdm_version[2] =
3369 : SECURED_SPDM_VERSION_12 << SPDM_VERSION_NUMBER_SHIFT_BIT;
3370 109 : context->local_context.capability.st1 = SPDM_ST1_VALUE_US;
3371 :
3372 109 : context->mut_auth_cert_chain_buffer_size = 0;
3373 :
3374 109 : context->max_spdm_session_sequence_number = LIBSPDM_MAX_SPDM_SESSION_SEQUENCE_NUMBER;
3375 :
3376 109 : context->latest_session_id = INVALID_SESSION_ID;
3377 109 : context->last_spdm_request_session_id = INVALID_SESSION_ID;
3378 109 : context->last_spdm_request_session_id_valid = false;
3379 109 : context->last_spdm_request_size = 0;
3380 :
3381 : /* To be updated in libspdm_register_device_buffer_func */
3382 109 : context->local_context.capability.data_transfer_size = 0;
3383 109 : context->local_context.capability.sender_data_transfer_size = 0;
3384 109 : context->local_context.capability.max_spdm_msg_size = 0;
3385 :
3386 545 : for (index = 0; index < num_secured_contexts; index++) {
3387 436 : if (secured_contexts[index] == NULL) {
3388 0 : return LIBSPDM_STATUS_INVALID_PARAMETER;
3389 : }
3390 :
3391 436 : context->session_info[index].secured_message_context = secured_contexts[index];
3392 436 : libspdm_secured_message_init_context(
3393 : context->session_info[index].secured_message_context);
3394 : }
3395 :
3396 109 : return LIBSPDM_STATUS_SUCCESS;
3397 : }
3398 :
3399 : /**
3400 : * Initialize an SPDM context, as well as secured message contexts.
3401 : * The secured message contexts are appended to the context structure.
3402 : *
3403 : * The total size in bytes of the spdm_context and all secured message
3404 : * contexts can be returned by libspdm_get_context_size().
3405 : *
3406 : * @param spdm_context A pointer to the SPDM context.
3407 : *
3408 : * @retval RETURN_SUCCESS context is initialized.
3409 : * @retval RETURN_DEVICE_ERROR context initialization failed.
3410 : */
3411 108 : libspdm_return_t libspdm_init_context(void *spdm_context)
3412 : {
3413 : libspdm_context_t *context;
3414 : void *secured_context;
3415 : void *secured_contexts[LIBSPDM_MAX_SESSION_COUNT];
3416 : size_t secured_context_size;
3417 : size_t index;
3418 :
3419 108 : LIBSPDM_ASSERT(spdm_context != NULL);
3420 :
3421 : /* libspdm_get_context_size() allocates space for all secured message
3422 : * contexts. They are appended to the general SPDM context. */
3423 108 : context = spdm_context;
3424 108 : secured_context = (void *)((size_t)(context + 1));
3425 108 : secured_context_size = libspdm_secured_message_get_context_size();
3426 :
3427 540 : for (index = 0; index < LIBSPDM_MAX_SESSION_COUNT; index++)
3428 : {
3429 432 : secured_contexts[index] = (uint8_t *)secured_context + secured_context_size * index;
3430 : }
3431 :
3432 108 : return libspdm_init_context_with_secured_context(spdm_context,
3433 : secured_contexts,
3434 : LIBSPDM_MAX_SESSION_COUNT);
3435 : }
3436 :
3437 42 : void libspdm_reset_context(void *spdm_context)
3438 : {
3439 : libspdm_context_t *context;
3440 : size_t index;
3441 :
3442 42 : context = spdm_context;
3443 :
3444 : /*Clear all info about last connection*/
3445 :
3446 : /*need clear session info to free context before algo is zeroed.*/
3447 210 : for (index = 0; index < LIBSPDM_MAX_SESSION_COUNT; index++)
3448 : {
3449 168 : libspdm_session_info_init(context,
3450 : &context->session_info[index],
3451 : INVALID_SESSION_ID,
3452 : false);
3453 : }
3454 :
3455 42 : context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NOT_STARTED;
3456 42 : libspdm_zero_mem(&context->connection_info.version, sizeof(spdm_version_number_t));
3457 42 : libspdm_zero_mem(&context->connection_info.capability,
3458 : sizeof(libspdm_device_capability_t));
3459 42 : libspdm_zero_mem(&context->connection_info.algorithm, sizeof(libspdm_device_algorithm_t));
3460 42 : libspdm_zero_mem(&context->last_spdm_error, sizeof(libspdm_error_struct_t));
3461 42 : libspdm_zero_mem(&context->encap_context, sizeof(libspdm_encap_context_t));
3462 42 : context->connection_info.local_used_cert_chain_buffer_size = 0;
3463 42 : context->connection_info.local_used_cert_chain_buffer = NULL;
3464 42 : context->connection_info.multi_key_conn_req = false;
3465 42 : context->connection_info.multi_key_conn_rsp = false;
3466 : #if LIBSPDM_RESPOND_IF_READY_SUPPORT
3467 42 : context->cache_spdm_request_size = 0;
3468 : #endif
3469 42 : context->response_state = LIBSPDM_RESPONSE_STATE_NORMAL;
3470 42 : context->current_token = 0;
3471 42 : context->latest_session_id = INVALID_SESSION_ID;
3472 42 : context->last_spdm_request_session_id = INVALID_SESSION_ID;
3473 42 : context->last_spdm_request_session_id_valid = false;
3474 42 : context->last_spdm_request_size = 0;
3475 42 : context->mut_auth_cert_chain_buffer_size = 0;
3476 42 : context->current_dhe_session_count = 0;
3477 42 : context->current_psk_session_count = 0;
3478 42 : }
3479 :
3480 : /**
3481 : * Free the memory of contexts within the SPDM context.
3482 : * These are typically contexts whose memory has been allocated by the cryptography library.
3483 : * This function does not free the SPDM context itself.
3484 : *
3485 : * @param[in] spdm_context A pointer to the SPDM context.
3486 : *
3487 : */
3488 0 : void libspdm_deinit_context(void *spdm_context)
3489 : {
3490 : uint32_t session_id;
3491 : libspdm_context_t *context;
3492 : libspdm_session_info_t *session_info;
3493 : #if !(LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT)
3494 : void *pubkey_context;
3495 : bool is_requester;
3496 : uint8_t slot_index;
3497 : #endif
3498 :
3499 0 : context = spdm_context;
3500 :
3501 : #if !(LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT)
3502 0 : is_requester = context->local_context.is_requester;
3503 :
3504 0 : for (slot_index = 0; slot_index < SPDM_MAX_SLOT_COUNT; slot_index++) {
3505 0 : pubkey_context = context->connection_info.peer_used_cert_chain[slot_index].
3506 : leaf_cert_public_key;
3507 :
3508 0 : if (pubkey_context != NULL) {
3509 0 : if (is_requester) {
3510 0 : if (context->connection_info.algorithm.pqc_asym_algo != 0) {
3511 0 : libspdm_pqc_asym_free(
3512 : context->connection_info.algorithm.pqc_asym_algo, pubkey_context);
3513 : } else {
3514 0 : libspdm_asym_free(
3515 : context->connection_info.algorithm.base_asym_algo, pubkey_context);
3516 : }
3517 : } else {
3518 0 : if (context->connection_info.algorithm.req_pqc_asym_alg != 0) {
3519 0 : libspdm_req_pqc_asym_free(
3520 : context->connection_info.algorithm.req_pqc_asym_alg, pubkey_context);
3521 : } else {
3522 0 : libspdm_req_asym_free(
3523 0 : context->connection_info.algorithm.req_base_asym_alg, pubkey_context);
3524 : }
3525 : }
3526 :
3527 0 : context->connection_info.peer_used_cert_chain[slot_index].leaf_cert_public_key = NULL;
3528 : }
3529 : }
3530 : #endif
3531 :
3532 0 : libspdm_reset_message_a(context);
3533 0 : libspdm_reset_message_d(context);
3534 0 : libspdm_reset_message_b(context);
3535 0 : libspdm_reset_message_c(context);
3536 0 : libspdm_reset_message_mut_b(context);
3537 0 : libspdm_reset_message_mut_c(context);
3538 0 : for (session_id = 0; session_id < LIBSPDM_MAX_SESSION_COUNT; session_id++) {
3539 0 : session_info = &context->session_info[session_id];
3540 0 : libspdm_reset_message_m(context, session_info);
3541 0 : libspdm_reset_message_e(context, session_info);
3542 0 : libspdm_reset_message_encap_e(context, session_info);
3543 0 : libspdm_reset_message_encap_d(context, session_info);
3544 0 : libspdm_reset_message_k(context, session_info);
3545 0 : libspdm_reset_message_f(context, session_info);
3546 : }
3547 0 : }
3548 :
3549 : /**
3550 : * Return the size in bytes of the SPDM context. This includes all
3551 : * secured message context data as well.
3552 : *
3553 : * For just the SPDM context size, use libspdm_get_context_size_without_secured_context.
3554 : *
3555 : * @return the size in bytes of the SPDM context and secured message contexts.
3556 : **/
3557 108 : size_t libspdm_get_context_size(void)
3558 : {
3559 : size_t size;
3560 :
3561 108 : size = sizeof(libspdm_context_t) +
3562 108 : libspdm_secured_message_get_context_size() * LIBSPDM_MAX_SESSION_COUNT;
3563 108 : LIBSPDM_ASSERT (size == LIBSPDM_CONTEXT_SIZE_ALL);
3564 108 : return size;
3565 : }
3566 :
3567 : /**
3568 : * Return the size in bytes of just the SPDM context, without secured message context.
3569 : *
3570 : * For the complete context size, use libspdm_get_context_size.
3571 : *
3572 : * @return the size in bytes of the SPDM context.
3573 : **/
3574 1 : size_t libspdm_get_context_size_without_secured_context(void)
3575 : {
3576 : size_t size;
3577 :
3578 1 : size = sizeof(libspdm_context_t);
3579 1 : LIBSPDM_ASSERT (size == LIBSPDM_CONTEXT_SIZE_WITHOUT_SECURED_CONTEXT);
3580 1 : return size;
3581 : }
3582 :
3583 : /**
3584 : * Return the SPDMversion field of the version number struct.
3585 : *
3586 : * @param ver Spdm version number struct.
3587 : *
3588 : * @return the SPDMversion of the version number struct.
3589 : **/
3590 239 : uint8_t libspdm_get_version_from_version_number(const spdm_version_number_t ver)
3591 : {
3592 239 : return (uint8_t)(ver >> SPDM_VERSION_NUMBER_SHIFT_BIT);
3593 : }
3594 :
3595 : /**
3596 : * Sort SPDMversion in descending order.
3597 : *
3598 : * @param spdm_context A pointer to the SPDM context.
3599 : * @param ver_set A pointer to the version set.
3600 : * @param ver_num Version number.
3601 : */
3602 60 : void libspdm_version_number_sort(spdm_version_number_t *ver_set, size_t ver_num)
3603 : {
3604 : size_t index;
3605 : size_t index_sort;
3606 : size_t index_max;
3607 : spdm_version_number_t version;
3608 :
3609 : /* Select sort */
3610 60 : if (ver_num > 1) {
3611 135 : for (index_sort = 0; index_sort < ver_num; index_sort++) {
3612 103 : index_max = index_sort;
3613 230 : for (index = index_sort + 1; index < ver_num; index++) {
3614 : /* if ver_ser[index] higher than ver_set[index_max] */
3615 127 : if (ver_set[index] > ver_set[index_max]) {
3616 74 : index_max = index;
3617 : }
3618 : }
3619 : /* swap ver_ser[index_min] and ver_set[index_sort] */
3620 103 : version = ver_set[index_sort];
3621 103 : ver_set[index_sort] = ver_set[index_max];
3622 103 : ver_set[index_max] = version;
3623 : }
3624 : }
3625 60 : }
3626 :
3627 : /**
3628 : * Negotiate SPDMversion for connection.
3629 : * ver_set is the local version set of requester, res_ver_set is the version set of responder.
3630 : *
3631 : * @param common_version A pointer to store the common version.
3632 : * @param req_ver_set A pointer to the requester version set.
3633 : * @param req_ver_num Version number of requester.
3634 : * @param res_ver_set A pointer to the responder version set.
3635 : * @param res_ver_num Version number of responder.
3636 : *
3637 : * @retval true Negotiation successfully, connect version be saved to common_version.
3638 : * @retval false Negotiation failed.
3639 : */
3640 30 : bool libspdm_negotiate_connection_version(spdm_version_number_t *common_version,
3641 : spdm_version_number_t *req_ver_set,
3642 : size_t req_ver_num,
3643 : const spdm_version_number_t *res_ver_set,
3644 : size_t res_ver_num)
3645 : {
3646 : spdm_version_number_t req_version_list[LIBSPDM_MAX_VERSION_COUNT];
3647 : spdm_version_number_t res_version_list[LIBSPDM_MAX_VERSION_COUNT];
3648 : size_t req_index;
3649 : size_t res_index;
3650 :
3651 30 : if (req_ver_num > LIBSPDM_MAX_VERSION_COUNT || res_ver_num > LIBSPDM_MAX_VERSION_COUNT) {
3652 0 : return false;
3653 : }
3654 :
3655 30 : if (req_ver_set == NULL || req_ver_num == 0 || res_ver_set == NULL || res_ver_num == 0) {
3656 0 : return false;
3657 : }
3658 :
3659 30 : libspdm_zero_mem(req_version_list, sizeof(spdm_version_number_t) * LIBSPDM_MAX_VERSION_COUNT);
3660 30 : libspdm_zero_mem(res_version_list, sizeof(spdm_version_number_t) * LIBSPDM_MAX_VERSION_COUNT);
3661 :
3662 30 : libspdm_copy_mem(req_version_list, sizeof(spdm_version_number_t) * LIBSPDM_MAX_VERSION_COUNT,
3663 : req_ver_set, sizeof(spdm_version_number_t) * req_ver_num);
3664 30 : libspdm_copy_mem(res_version_list, sizeof(spdm_version_number_t) * LIBSPDM_MAX_VERSION_COUNT,
3665 : res_ver_set, sizeof(spdm_version_number_t) * res_ver_num);
3666 :
3667 : /* Sort SPDMversion in descending order. */
3668 30 : libspdm_version_number_sort(req_version_list, req_ver_num);
3669 30 : libspdm_version_number_sort(res_version_list, res_ver_num);
3670 :
3671 : /**
3672 : * Find highest same version and make req_index point to it.
3673 : * If not found, return false.
3674 : **/
3675 35 : for (res_index = 0; res_index < res_ver_num; res_index++) {
3676 67 : for (req_index = 0; req_index < req_ver_num; req_index++) {
3677 124 : if (libspdm_get_version_from_version_number(req_version_list[req_index]) ==
3678 62 : libspdm_get_version_from_version_number(res_version_list[res_index])) {
3679 29 : *common_version = req_version_list[req_index];
3680 29 : return true;
3681 : }
3682 : }
3683 : }
3684 1 : return false;
3685 : }
3686 :
3687 : #if LIBSPDM_EVENT_RECIPIENT_SUPPORT
3688 8 : void libspdm_register_event_callback(void *context,
3689 : libspdm_process_event_func process_event_func)
3690 : {
3691 : libspdm_context_t *spdm_context;
3692 :
3693 8 : spdm_context = context;
3694 8 : spdm_context->process_event = process_event_func;
3695 8 : }
3696 : #endif /* LIBSPDM_EVENT_RECIPIENT_SUPPORT */
|