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