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