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