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 :
9 : /**
10 : * This function returns peer certificate chain buffer including spdm_cert_chain_t header.
11 : *
12 : * @param spdm_context A pointer to the SPDM context.
13 : * @param cert_chain_buffer Certificate chain buffer including spdm_cert_chain_t header.
14 : * @param cert_chain_buffer_size size in bytes of the certificate chain buffer.
15 : *
16 : * @retval true Peer certificate chain buffer including spdm_cert_chain_t header is returned.
17 : * @retval false Peer certificate chain buffer including spdm_cert_chain_t header is not found.
18 : **/
19 0 : bool libspdm_get_peer_cert_chain_buffer(void *spdm_context,
20 : const void **cert_chain_buffer,
21 : size_t *cert_chain_buffer_size)
22 : {
23 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
24 : libspdm_context_t *context;
25 : uint8_t slot_id;
26 :
27 : context = spdm_context;
28 : slot_id = context->connection_info.peer_used_cert_chain_slot_id;
29 : LIBSPDM_ASSERT(slot_id < SPDM_MAX_SLOT_COUNT);
30 : if (context->connection_info.peer_used_cert_chain[slot_id].buffer_size != 0) {
31 : *cert_chain_buffer = context->connection_info.peer_used_cert_chain[slot_id].buffer;
32 : *cert_chain_buffer_size = context->connection_info
33 : .peer_used_cert_chain[slot_id].buffer_size;
34 : return true;
35 : }
36 : #endif
37 0 : return false;
38 : }
39 :
40 : /**
41 : * This function returns peer certificate chain data without spdm_cert_chain_t header.
42 : *
43 : * @param spdm_context A pointer to the SPDM context.
44 : * @param cert_chain_data Certificate chain data without spdm_cert_chain_t header.
45 : * @param cert_chain_data_size size in bytes of the certificate chain data.
46 : *
47 : * @retval true Peer certificate chain data without spdm_cert_chain_t header is returned.
48 : * @retval false Peer certificate chain data without spdm_cert_chain_t header is not found.
49 : **/
50 0 : bool libspdm_get_peer_cert_chain_data(void *spdm_context,
51 : const void **cert_chain_data,
52 : size_t *cert_chain_data_size)
53 : {
54 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
55 : libspdm_context_t *context;
56 : size_t hash_size;
57 : bool result;
58 :
59 : context = spdm_context;
60 : hash_size = libspdm_get_hash_size(context->connection_info.algorithm.base_hash_algo);
61 :
62 : result = libspdm_get_peer_cert_chain_buffer(context, cert_chain_data,
63 : cert_chain_data_size);
64 : if (result) {
65 : *cert_chain_data =
66 : (const uint8_t *)*cert_chain_data + sizeof(spdm_cert_chain_t) + hash_size;
67 : *cert_chain_data_size =
68 : *cert_chain_data_size - (sizeof(spdm_cert_chain_t) + hash_size);
69 : return true;
70 : }
71 : #endif
72 0 : return false;
73 : }
74 :
75 : /**
76 : * This function returns local used certificate chain buffer including spdm_cert_chain_t header.
77 : *
78 : * @param spdm_context A pointer to the SPDM context.
79 : * @param cert_chain_buffer Certificate chain buffer including spdm_cert_chain_t header.
80 : * @param cert_chain_buffer_size size in bytes of the certificate chain buffer.
81 : *
82 : * @retval true Local used certificate chain buffer including spdm_cert_chain_t header is returned.
83 : * @retval false Local used certificate chain buffer including spdm_cert_chain_t header is not found.
84 : **/
85 34 : bool libspdm_get_local_cert_chain_buffer(void *spdm_context,
86 : const void **cert_chain_buffer,
87 : size_t *cert_chain_buffer_size)
88 : {
89 : libspdm_context_t *context;
90 :
91 34 : context = spdm_context;
92 34 : if (context->connection_info.local_used_cert_chain_buffer_size != 0) {
93 34 : *cert_chain_buffer = context->connection_info.local_used_cert_chain_buffer;
94 34 : *cert_chain_buffer_size = context->connection_info.local_used_cert_chain_buffer_size;
95 34 : return true;
96 : }
97 0 : return false;
98 : }
99 :
100 : /**
101 : * This function returns local used certificate chain data without spdm_cert_chain_t header.
102 : *
103 : * @param spdm_context A pointer to the SPDM context.
104 : * @param cert_chain_data Certificate chain data without spdm_cert_chain_t header.
105 : * @param cert_chain_data_size size in bytes of the certificate chain data.
106 : *
107 : * @retval true Local used certificate chain data without spdm_cert_chain_t header is returned.
108 : * @retval false Local used certificate chain data without spdm_cert_chain_t header is not found.
109 : **/
110 0 : bool libspdm_get_local_cert_chain_data(void *spdm_context,
111 : const void **cert_chain_data,
112 : size_t *cert_chain_data_size)
113 : {
114 : libspdm_context_t *context;
115 : bool result;
116 : size_t hash_size;
117 :
118 0 : context = spdm_context;
119 :
120 0 : result = libspdm_get_local_cert_chain_buffer(context, cert_chain_data,
121 : cert_chain_data_size);
122 0 : if (!result) {
123 0 : return false;
124 : }
125 :
126 0 : hash_size = libspdm_get_hash_size(context->connection_info.algorithm.base_hash_algo);
127 :
128 0 : *cert_chain_data = (const uint8_t *)*cert_chain_data + sizeof(spdm_cert_chain_t) + hash_size;
129 0 : *cert_chain_data_size = *cert_chain_data_size - (sizeof(spdm_cert_chain_t) + hash_size);
130 0 : return true;
131 : }
132 :
133 : /**
134 : * This function returns peer public key buffer.
135 : *
136 : * @param spdm_context A pointer to the SPDM context.
137 : * @param peer_public_key_buffer Peer public key buffer.
138 : * @param peer_public_key_buffer_size Size in bytes of peer public key buffer.
139 : *
140 : * @retval true Peer public key buffer is returned.
141 : * @retval false Peer public key buffer is not found.
142 : **/
143 3 : bool libspdm_get_peer_public_key_buffer(void *spdm_context,
144 : const void **peer_public_key_buffer,
145 : size_t *peer_public_key_buffer_size)
146 : {
147 : libspdm_context_t *context;
148 :
149 3 : context = spdm_context;
150 3 : if (context->local_context.peer_public_key_provision_size != 0) {
151 3 : *peer_public_key_buffer = context->local_context.peer_public_key_provision;
152 3 : *peer_public_key_buffer_size = context->local_context.peer_public_key_provision_size;
153 3 : return true;
154 : }
155 0 : return false;
156 : }
157 :
158 : /**
159 : * This function returns local public key buffer.
160 : *
161 : * @param spdm_context A pointer to the SPDM context.
162 : * @param local_public_key_buffer Local public key buffer.
163 : * @param local_public_key_buffer_size Size in bytes of local public key buffer.
164 : *
165 : * @retval true Local public key buffer is returned.
166 : * @retval false Local public key buffer is not found.
167 : **/
168 2 : bool libspdm_get_local_public_key_buffer(void *spdm_context,
169 : const void **local_public_key_buffer,
170 : size_t *local_public_key_buffer_size)
171 : {
172 : libspdm_context_t *context;
173 :
174 2 : context = spdm_context;
175 2 : if (context->local_context.local_public_key_provision_size != 0) {
176 2 : *local_public_key_buffer = context->local_context.local_public_key_provision;
177 2 : *local_public_key_buffer_size = context->local_context.local_public_key_provision_size;
178 2 : return true;
179 : }
180 0 : return false;
181 : }
182 :
183 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
184 : /*
185 : * This function calculates l1l2.
186 : * If session_info is NULL, this function will use M cache of SPDM context,
187 : * else will use M cache of SPDM session context.
188 : *
189 : * @param spdm_context A pointer to the SPDM context.
190 : * @param session_info A pointer to the SPDM session context.
191 : * @param l1l2 The buffer to store the l1l2.
192 : *
193 : * @retval RETURN_SUCCESS l1l2 is calculated.
194 : */
195 : bool libspdm_calculate_l1l2(libspdm_context_t *spdm_context,
196 : void *session_info,
197 : libspdm_l1l2_managed_buffer_t *l1l2)
198 : {
199 : libspdm_return_t status;
200 : libspdm_session_info_t *spdm_session_info;
201 :
202 : spdm_session_info = session_info;
203 :
204 : libspdm_init_managed_buffer(l1l2, sizeof(l1l2->buffer));
205 :
206 : if ((spdm_context->connection_info.version >> SPDM_VERSION_NUMBER_SHIFT_BIT) >
207 : SPDM_MESSAGE_VERSION_11) {
208 :
209 : /* Need append VCA since 1.2 script*/
210 :
211 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "message_a data :\n"));
212 : LIBSPDM_INTERNAL_DUMP_HEX(
213 : libspdm_get_managed_buffer(&spdm_context->transcript.message_a),
214 : libspdm_get_managed_buffer_size(&spdm_context->transcript.message_a));
215 : status = libspdm_append_managed_buffer(
216 : l1l2,
217 : libspdm_get_managed_buffer(&spdm_context->transcript.message_a),
218 : libspdm_get_managed_buffer_size(&spdm_context->transcript.message_a));
219 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
220 : return false;
221 : }
222 : }
223 :
224 : if (spdm_session_info == NULL) {
225 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "message_m data :\n"));
226 : LIBSPDM_INTERNAL_DUMP_HEX(
227 : libspdm_get_managed_buffer(&spdm_context->transcript.message_m),
228 : libspdm_get_managed_buffer_size(&spdm_context->transcript.message_m));
229 : status = libspdm_append_managed_buffer(
230 : l1l2,
231 : libspdm_get_managed_buffer(&spdm_context->transcript.message_m),
232 : libspdm_get_managed_buffer_size(&spdm_context->transcript.message_m));
233 : } else {
234 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "use message_m in session :\n"));
235 : LIBSPDM_INTERNAL_DUMP_HEX(
236 : libspdm_get_managed_buffer(&spdm_session_info->session_transcript.message_m),
237 : libspdm_get_managed_buffer_size(&spdm_session_info->session_transcript.message_m));
238 : status = libspdm_append_managed_buffer(
239 : l1l2,
240 : libspdm_get_managed_buffer(&spdm_session_info->session_transcript.message_m),
241 : libspdm_get_managed_buffer_size(&spdm_session_info->session_transcript.message_m));
242 : }
243 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
244 : return false;
245 : }
246 :
247 : /* Debug code only - calculate and print value of l1l2 hash*/
248 : LIBSPDM_DEBUG_CODE(
249 : uint8_t hash_data[LIBSPDM_MAX_HASH_SIZE];
250 : uint32_t hash_size = libspdm_get_hash_size(
251 : spdm_context->connection_info.algorithm.base_hash_algo);
252 : if (!libspdm_hash_all(
253 : spdm_context->connection_info.algorithm.base_hash_algo,
254 : libspdm_get_managed_buffer(l1l2),
255 : libspdm_get_managed_buffer_size(l1l2), hash_data)) {
256 : return false;
257 : }
258 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "l1l2 hash - "));
259 : LIBSPDM_INTERNAL_DUMP_DATA(hash_data, hash_size);
260 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "\n"));
261 : );
262 :
263 : return true;
264 : }
265 : #else
266 : /*
267 : * This function calculates l1l2 hash.
268 : * If session_info is NULL, this function will use M cache of SPDM context,
269 : * else will use M cache of SPDM session context.
270 : *
271 : * @param spdm_context A pointer to the SPDM context.
272 : * @param session_info A pointer to the SPDM session context.
273 : * @param l1l2_hash_size size in bytes of the l1l2 hash
274 : * @param l1l2_hash The buffer to store the l1l2 hash
275 : *
276 : * @retval RETURN_SUCCESS l1l2 is calculated.
277 : */
278 39 : bool libspdm_calculate_l1l2_hash(libspdm_context_t *spdm_context,
279 : void *session_info,
280 : size_t *l1l2_hash_size, void *l1l2_hash)
281 : {
282 : libspdm_session_info_t *spdm_session_info;
283 : bool result;
284 :
285 : uint32_t hash_size;
286 :
287 39 : spdm_session_info = session_info;
288 :
289 39 : hash_size = libspdm_get_hash_size(spdm_context->connection_info.algorithm.base_hash_algo);
290 :
291 39 : if (spdm_session_info == NULL) {
292 37 : result = libspdm_hash_final (spdm_context->connection_info.algorithm.base_hash_algo,
293 : spdm_context->transcript.digest_context_l1l2, l1l2_hash);
294 : } else {
295 2 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "use message_m in session :\n"));
296 2 : result = libspdm_hash_final (spdm_context->connection_info.algorithm.base_hash_algo,
297 : spdm_session_info->session_transcript.digest_context_l1l2,
298 : l1l2_hash);
299 : }
300 39 : if (!result) {
301 0 : return false;
302 : }
303 39 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "l1l2 hash - "));
304 39 : LIBSPDM_INTERNAL_DUMP_DATA(l1l2_hash, hash_size);
305 39 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "\n"));
306 :
307 39 : *l1l2_hash_size = hash_size;
308 :
309 39 : return true;
310 : }
311 : #endif /* LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT */
312 :
313 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
314 : /*
315 : * This function calculates m1m2.
316 : *
317 : * @param spdm_context A pointer to the SPDM context.
318 : * @param is_mut Indicate if this is from mutual authentication.
319 : * @param m1m2 The buffer to store the m1m2
320 : *
321 : * @retval RETURN_SUCCESS m1m2 is calculated.
322 : */
323 : static bool libspdm_calculate_m1m2(void *context, bool is_mut,
324 : libspdm_m1m2_managed_buffer_t *m1m2)
325 : {
326 : libspdm_context_t *spdm_context;
327 : libspdm_return_t status;
328 :
329 : spdm_context = context;
330 :
331 : libspdm_init_managed_buffer(m1m2, sizeof(m1m2->buffer));
332 :
333 : if (is_mut) {
334 : if ((spdm_context->connection_info.version >> SPDM_VERSION_NUMBER_SHIFT_BIT) >
335 : SPDM_MESSAGE_VERSION_11) {
336 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "message_a data :\n"));
337 : LIBSPDM_INTERNAL_DUMP_HEX(
338 : libspdm_get_managed_buffer(&spdm_context->transcript.message_a),
339 : libspdm_get_managed_buffer_size(&spdm_context->transcript.message_a));
340 : status = libspdm_append_managed_buffer(
341 : m1m2,
342 : libspdm_get_managed_buffer(&spdm_context->transcript.message_a),
343 : libspdm_get_managed_buffer_size(&spdm_context->transcript.message_a));
344 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
345 : return false;
346 : }
347 : }
348 :
349 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "message_mut_b data :\n"));
350 : LIBSPDM_INTERNAL_DUMP_HEX(
351 : libspdm_get_managed_buffer(&spdm_context->transcript.message_mut_b),
352 : libspdm_get_managed_buffer_size(&spdm_context->transcript.message_mut_b));
353 : status = libspdm_append_managed_buffer(
354 : m1m2,
355 : libspdm_get_managed_buffer(&spdm_context->transcript.message_mut_b),
356 : libspdm_get_managed_buffer_size(&spdm_context->transcript.message_mut_b));
357 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
358 : return false;
359 : }
360 :
361 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "message_mut_c data :\n"));
362 : LIBSPDM_INTERNAL_DUMP_HEX(
363 : libspdm_get_managed_buffer(&spdm_context->transcript.message_mut_c),
364 : libspdm_get_managed_buffer_size(&spdm_context->transcript.message_mut_c));
365 : status = libspdm_append_managed_buffer(
366 : m1m2,
367 : libspdm_get_managed_buffer(&spdm_context->transcript.message_mut_c),
368 : libspdm_get_managed_buffer_size(&spdm_context->transcript.message_mut_c));
369 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
370 : return false;
371 : }
372 :
373 : /* Debug code only - calculate and print value of m1m2 mut hash*/
374 : LIBSPDM_DEBUG_CODE(
375 : uint8_t hash_data[LIBSPDM_MAX_HASH_SIZE];
376 : uint32_t hash_size = libspdm_get_hash_size(
377 : spdm_context->connection_info.algorithm.base_hash_algo);
378 : if (!libspdm_hash_all(
379 : spdm_context->connection_info.algorithm.base_hash_algo,
380 : libspdm_get_managed_buffer(m1m2),
381 : libspdm_get_managed_buffer_size(m1m2), hash_data)) {
382 : return false;
383 : }
384 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "m1m2 Mut hash - "));
385 : LIBSPDM_INTERNAL_DUMP_DATA(hash_data, hash_size);
386 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "\n"));
387 : );
388 :
389 : } else {
390 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "message_a data :\n"));
391 : LIBSPDM_INTERNAL_DUMP_HEX(
392 : libspdm_get_managed_buffer(&spdm_context->transcript.message_a),
393 : libspdm_get_managed_buffer_size(&spdm_context->transcript.message_a));
394 : status = libspdm_append_managed_buffer(
395 : m1m2,
396 : libspdm_get_managed_buffer(&spdm_context->transcript.message_a),
397 : libspdm_get_managed_buffer_size(&spdm_context->transcript.message_a));
398 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
399 : return false;
400 : }
401 :
402 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "message_b data :\n"));
403 : LIBSPDM_INTERNAL_DUMP_HEX(
404 : libspdm_get_managed_buffer(&spdm_context->transcript.message_b),
405 : libspdm_get_managed_buffer_size(&spdm_context->transcript.message_b));
406 : status = libspdm_append_managed_buffer(
407 : m1m2,
408 : libspdm_get_managed_buffer(&spdm_context->transcript.message_b),
409 : libspdm_get_managed_buffer_size(&spdm_context->transcript.message_b));
410 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
411 : return false;
412 : }
413 :
414 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "message_c data :\n"));
415 : LIBSPDM_INTERNAL_DUMP_HEX(
416 : libspdm_get_managed_buffer(&spdm_context->transcript.message_c),
417 : libspdm_get_managed_buffer_size(&spdm_context->transcript.message_c));
418 : status = libspdm_append_managed_buffer(
419 : m1m2,
420 : libspdm_get_managed_buffer(&spdm_context->transcript.message_c),
421 : libspdm_get_managed_buffer_size(&spdm_context->transcript.message_c));
422 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
423 : return false;
424 : }
425 :
426 : /* Debug code only - calculate and print value of m1m2 hash*/
427 : LIBSPDM_DEBUG_CODE(
428 : uint8_t hash_data[LIBSPDM_MAX_HASH_SIZE];
429 : uint32_t hash_size = libspdm_get_hash_size(
430 : spdm_context->connection_info.algorithm.base_hash_algo);
431 : if (!libspdm_hash_all(
432 : spdm_context->connection_info.algorithm.base_hash_algo,
433 : libspdm_get_managed_buffer(m1m2),
434 : libspdm_get_managed_buffer_size(m1m2), hash_data)) {
435 : return false;
436 : }
437 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "m1m2 hash - "));
438 : LIBSPDM_INTERNAL_DUMP_DATA(hash_data, hash_size);
439 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "\n"));
440 : );
441 : }
442 :
443 : return true;
444 : }
445 : #else
446 : /*
447 : * This function calculates m1m2 hash.
448 : *
449 : * @param spdm_context A pointer to the SPDM context.
450 : * @param is_mut Indicate if this is from mutual authentication.
451 : * @param m1m2_hash_size size in bytes of the m1m2 hash
452 : * @param m1m2_hash The buffer to store the m1m2 hash
453 : *
454 : * @retval RETURN_SUCCESS m1m2 is calculated.
455 : */
456 31 : static bool libspdm_calculate_m1m2_hash(void *context, bool is_mut,
457 : size_t *m1m2_hash_size,
458 : void *m1m2_hash)
459 : {
460 : libspdm_context_t *spdm_context;
461 : uint32_t hash_size;
462 : bool result;
463 :
464 31 : spdm_context = context;
465 :
466 31 : hash_size = libspdm_get_hash_size(spdm_context->connection_info.algorithm.base_hash_algo);
467 :
468 31 : if (is_mut) {
469 6 : result = libspdm_hash_final (spdm_context->connection_info.algorithm.base_hash_algo,
470 : spdm_context->transcript.digest_context_mut_m1m2, m1m2_hash);
471 6 : if (!result) {
472 0 : return false;
473 : }
474 6 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "m1m2 Mut hash - "));
475 6 : LIBSPDM_INTERNAL_DUMP_DATA(m1m2_hash, hash_size);
476 6 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "\n"));
477 :
478 : } else {
479 25 : result = libspdm_hash_final (spdm_context->connection_info.algorithm.base_hash_algo,
480 : spdm_context->transcript.digest_context_m1m2, m1m2_hash);
481 25 : if (!result) {
482 0 : return false;
483 : }
484 25 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "m1m2 hash - "));
485 25 : LIBSPDM_INTERNAL_DUMP_DATA(m1m2_hash, hash_size);
486 25 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "\n"));
487 : }
488 :
489 31 : *m1m2_hash_size = hash_size;
490 :
491 31 : return true;
492 : }
493 : #endif
494 :
495 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
496 : /*
497 : * This function calculates il1il2.
498 : * If session_info is NULL, this function will use E cache of SPDM context,
499 : * else will use E cache of SPDM session context.
500 : *
501 : * @param spdm_context A pointer to the SPDM context.
502 : * @param session_info A pointer to the SPDM session context.
503 : * @param is_mut Indicate if this is from mutual authentication.
504 : * @param il1il2 The buffer to store the il1il2.
505 : *
506 : * @retval RETURN_SUCCESS il1il2 is calculated.
507 : */
508 : bool libspdm_calculate_il1il2(libspdm_context_t *spdm_context,
509 : void *session_info,
510 : bool is_mut,
511 : libspdm_il1il2_managed_buffer_t *il1il2)
512 : {
513 : libspdm_return_t status;
514 : libspdm_session_info_t *spdm_session_info;
515 :
516 : spdm_session_info = session_info;
517 :
518 : libspdm_init_managed_buffer(il1il2, sizeof(il1il2->buffer));
519 :
520 :
521 : if (is_mut) {
522 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "message_a data :\n"));
523 : LIBSPDM_INTERNAL_DUMP_HEX(
524 : libspdm_get_managed_buffer(&spdm_context->transcript.message_a),
525 : libspdm_get_managed_buffer_size(&spdm_context->transcript.message_a));
526 : status = libspdm_append_managed_buffer(
527 : il1il2,
528 : libspdm_get_managed_buffer(&spdm_context->transcript.message_a),
529 : libspdm_get_managed_buffer_size(&spdm_context->transcript.message_a));
530 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
531 : return false;
532 : }
533 :
534 : if (spdm_session_info == NULL) {
535 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "message_encap_e data :\n"));
536 : LIBSPDM_INTERNAL_DUMP_HEX(
537 : libspdm_get_managed_buffer(&spdm_context->transcript.message_encap_e),
538 : libspdm_get_managed_buffer_size(&spdm_context->transcript.message_encap_e));
539 : status = libspdm_append_managed_buffer(
540 : il1il2,
541 : libspdm_get_managed_buffer(&spdm_context->transcript.message_encap_e),
542 : libspdm_get_managed_buffer_size(&spdm_context->transcript.message_encap_e));
543 : } else {
544 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "use message_encap_e in session :\n"));
545 : LIBSPDM_INTERNAL_DUMP_HEX(
546 : libspdm_get_managed_buffer(&spdm_session_info->session_transcript.message_encap_e),
547 : libspdm_get_managed_buffer_size(
548 : &spdm_session_info->session_transcript.message_encap_e));
549 : status = libspdm_append_managed_buffer(
550 : il1il2,
551 : libspdm_get_managed_buffer(&spdm_session_info->session_transcript.message_encap_e),
552 : libspdm_get_managed_buffer_size(
553 : &spdm_session_info->session_transcript.message_encap_e));
554 : }
555 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
556 : return false;
557 : }
558 :
559 : /* Debug code only - calculate and print value of il1il2 hash*/
560 : LIBSPDM_DEBUG_CODE(
561 : uint8_t hash_data[LIBSPDM_MAX_HASH_SIZE];
562 : uint32_t hash_size = libspdm_get_hash_size(
563 : spdm_context->connection_info.algorithm.base_hash_algo);
564 : if (!libspdm_hash_all(
565 : spdm_context->connection_info.algorithm.base_hash_algo,
566 : libspdm_get_managed_buffer(il1il2),
567 : libspdm_get_managed_buffer_size(il1il2), hash_data)) {
568 : return false;
569 : }
570 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "il1il2 mut hash - "));
571 : LIBSPDM_INTERNAL_DUMP_DATA(hash_data, hash_size);
572 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "\n"));
573 : );
574 : } else {
575 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "message_a data :\n"));
576 : LIBSPDM_INTERNAL_DUMP_HEX(
577 : libspdm_get_managed_buffer(&spdm_context->transcript.message_a),
578 : libspdm_get_managed_buffer_size(&spdm_context->transcript.message_a));
579 : status = libspdm_append_managed_buffer(
580 : il1il2,
581 : libspdm_get_managed_buffer(&spdm_context->transcript.message_a),
582 : libspdm_get_managed_buffer_size(&spdm_context->transcript.message_a));
583 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
584 : return false;
585 : }
586 :
587 : if (spdm_session_info == NULL) {
588 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "message_e data :\n"));
589 : LIBSPDM_INTERNAL_DUMP_HEX(
590 : libspdm_get_managed_buffer(&spdm_context->transcript.message_e),
591 : libspdm_get_managed_buffer_size(&spdm_context->transcript.message_e));
592 : status = libspdm_append_managed_buffer(
593 : il1il2,
594 : libspdm_get_managed_buffer(&spdm_context->transcript.message_e),
595 : libspdm_get_managed_buffer_size(&spdm_context->transcript.message_e));
596 : } else {
597 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "use message_e in session :\n"));
598 : LIBSPDM_INTERNAL_DUMP_HEX(
599 : libspdm_get_managed_buffer(&spdm_session_info->session_transcript.message_e),
600 : libspdm_get_managed_buffer_size(&spdm_session_info->session_transcript.message_e));
601 : status = libspdm_append_managed_buffer(
602 : il1il2,
603 : libspdm_get_managed_buffer(&spdm_session_info->session_transcript.message_e),
604 : libspdm_get_managed_buffer_size(&spdm_session_info->session_transcript.message_e));
605 : }
606 : if (LIBSPDM_STATUS_IS_ERROR(status)) {
607 : return false;
608 : }
609 :
610 : /* Debug code only - calculate and print value of il1il2 hash*/
611 : LIBSPDM_DEBUG_CODE(
612 : uint8_t hash_data[LIBSPDM_MAX_HASH_SIZE];
613 : uint32_t hash_size = libspdm_get_hash_size(
614 : spdm_context->connection_info.algorithm.base_hash_algo);
615 : if (!libspdm_hash_all(
616 : spdm_context->connection_info.algorithm.base_hash_algo,
617 : libspdm_get_managed_buffer(il1il2),
618 : libspdm_get_managed_buffer_size(il1il2), hash_data)) {
619 : return false;
620 : }
621 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "il1il2 hash - "));
622 : LIBSPDM_INTERNAL_DUMP_DATA(hash_data, hash_size);
623 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "\n"));
624 : );
625 : }
626 :
627 : return true;
628 : }
629 : #else
630 : /*
631 : * This function calculates il1il2 hash.
632 : * If session_info is NULL, this function will use E cache of SPDM context,
633 : * else will use E cache of SPDM session context.
634 : *
635 : * @param spdm_context A pointer to the SPDM context.
636 : * @param session_info A pointer to the SPDM session context.
637 : * @param is_encap Indicate if this is from encapsulate request.
638 : * @param il1il2_hash_size size in bytes of the il1il2 hash
639 : * @param il1il2_hash The buffer to store the il1il2 hash
640 : *
641 : * @retval RETURN_SUCCESS il1il2 is calculated.
642 : */
643 31 : bool libspdm_calculate_il1il2_hash(libspdm_context_t *spdm_context,
644 : void *session_info, bool is_encap,
645 : size_t *il1il2_hash_size, void *il1il2_hash)
646 : {
647 : libspdm_session_info_t *spdm_session_info;
648 : bool result;
649 :
650 : uint32_t hash_size;
651 :
652 31 : spdm_session_info = session_info;
653 :
654 31 : hash_size = libspdm_get_hash_size(spdm_context->connection_info.algorithm.base_hash_algo);
655 :
656 31 : if (spdm_session_info == NULL) {
657 26 : if (is_encap) {
658 12 : result = libspdm_hash_final (spdm_context->connection_info.algorithm.base_hash_algo,
659 : spdm_context->transcript.digest_context_encap_il1il2,
660 : il1il2_hash);
661 : } else {
662 14 : result = libspdm_hash_final (spdm_context->connection_info.algorithm.base_hash_algo,
663 : spdm_context->transcript.digest_context_il1il2,
664 : il1il2_hash);
665 : }
666 : } else {
667 5 : if (is_encap) {
668 2 : result = libspdm_hash_final (spdm_context->connection_info.algorithm.base_hash_algo,
669 : spdm_session_info->session_transcript.digest_context_encap_il1il2,
670 : il1il2_hash);
671 : } else {
672 3 : result = libspdm_hash_final (spdm_context->connection_info.algorithm.base_hash_algo,
673 : spdm_session_info->session_transcript.digest_context_il1il2,
674 : il1il2_hash);
675 : }
676 : }
677 31 : if (!result) {
678 0 : return false;
679 : }
680 31 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "il1il2 hash - "));
681 31 : LIBSPDM_INTERNAL_DUMP_DATA(il1il2_hash, hash_size);
682 31 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "\n"));
683 :
684 31 : *il1il2_hash_size = hash_size;
685 :
686 31 : return true;
687 : }
688 : #endif /* LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT */
689 :
690 : /**
691 : * This function generates the certificate chain hash.
692 : *
693 : * @param spdm_context A pointer to the SPDM context.
694 : * @param slot_id The slot index of the certificate chain.
695 : * @param signature The buffer to store the certificate chain hash.
696 : *
697 : * @retval true certificate chain hash is generated.
698 : * @retval false certificate chain hash is not generated.
699 : **/
700 36 : bool libspdm_generate_cert_chain_hash(libspdm_context_t *spdm_context,
701 : size_t slot_id, uint8_t *hash)
702 : {
703 36 : LIBSPDM_ASSERT(slot_id < SPDM_MAX_SLOT_COUNT);
704 36 : return libspdm_hash_all(
705 : spdm_context->connection_info.algorithm.base_hash_algo,
706 : spdm_context->local_context.local_cert_chain_provision[slot_id],
707 : spdm_context->local_context.local_cert_chain_provision_size[slot_id], hash);
708 : }
709 :
710 : /**
711 : * This function generates the public key hash.
712 : *
713 : * @param spdm_context A pointer to the SPDM context.
714 : * @param hash The buffer to store the public key hash.
715 : *
716 : * @retval true public key hash is generated.
717 : * @retval false public key hash is not generated.
718 : **/
719 2 : bool libspdm_generate_public_key_hash(libspdm_context_t *spdm_context,
720 : uint8_t *hash)
721 : {
722 2 : return libspdm_hash_all(
723 : spdm_context->connection_info.algorithm.base_hash_algo,
724 : spdm_context->local_context.local_public_key_provision,
725 : spdm_context->local_context.local_public_key_provision_size, hash);
726 : }
727 :
728 : /**
729 : * Get the certificate slot mask
730 : *
731 : * @param[in] context A pointer to the SPDM context.
732 : *
733 : * @retval slot_mask get slot mask
734 : **/
735 10 : uint8_t libspdm_get_cert_slot_mask(libspdm_context_t *spdm_context)
736 : {
737 : size_t index;
738 : uint8_t slot_mask;
739 :
740 10 : slot_mask = 0;
741 90 : for (index = 0; index < SPDM_MAX_SLOT_COUNT; index++) {
742 80 : if (spdm_context->local_context.local_cert_chain_provision[index] != NULL) {
743 11 : slot_mask |= (1 << index);
744 : }
745 : }
746 :
747 10 : return slot_mask;
748 : }
749 :
750 : /**
751 : * Get the certificate slot count
752 : *
753 : * @param[in] context A pointer to the SPDM context.
754 : *
755 : * @retval slot_count get slot count
756 : **/
757 15 : uint8_t libspdm_get_cert_slot_count(libspdm_context_t *spdm_context)
758 : {
759 : size_t index;
760 : uint8_t slot_count;
761 :
762 15 : slot_count = 0;
763 135 : for (index = 0; index < SPDM_MAX_SLOT_COUNT; index++) {
764 120 : if (spdm_context->local_context.local_cert_chain_provision[index] != NULL) {
765 26 : slot_count++;
766 : }
767 : }
768 :
769 15 : return slot_count;
770 : }
771 :
772 : #if LIBSPDM_CERT_PARSE_SUPPORT
773 : /**
774 : * This function verifies the integrity of peer certificate chain buffer including
775 : * spdm_cert_chain_t header.
776 : *
777 : * @param spdm_context A pointer to the SPDM context.
778 : * @param cert_chain_buffer Certificate chain buffer including spdm_cert_chain_t header.
779 : * @param cert_chain_buffer_size size in bytes of the certificate chain buffer.
780 : *
781 : * @retval true Peer certificate chain buffer integrity verification passed.
782 : * @retval false Peer certificate chain buffer integrity verification failed.
783 : **/
784 34 : bool libspdm_verify_peer_cert_chain_buffer_integrity(libspdm_context_t *spdm_context,
785 : const void *cert_chain_buffer,
786 : size_t cert_chain_buffer_size)
787 : {
788 : bool result;
789 : uint8_t cert_model;
790 : bool is_requester;
791 :
792 34 : is_requester = spdm_context->local_context.is_requester;
793 :
794 34 : cert_model = SPDM_CERTIFICATE_INFO_CERT_MODEL_ALIAS_CERT;
795 : /* Responder does not determine Requester's certificate model */
796 34 : if (is_requester) {
797 34 : if ((spdm_context->connection_info.capability.flags &
798 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_ALIAS_CERT_CAP) == 0) {
799 31 : cert_model = SPDM_CERTIFICATE_INFO_CERT_MODEL_DEVICE_CERT;
800 : }
801 : }
802 :
803 34 : if (is_requester) {
804 34 : result = libspdm_verify_certificate_chain_buffer_with_pqc(
805 : spdm_context->connection_info.algorithm.base_hash_algo,
806 : spdm_context->connection_info.algorithm.base_asym_algo,
807 : spdm_context->connection_info.algorithm.pqc_asym_algo,
808 : cert_chain_buffer, cert_chain_buffer_size,
809 : false, cert_model);
810 : } else {
811 0 : result = libspdm_verify_certificate_chain_buffer_with_pqc(
812 : spdm_context->connection_info.algorithm.base_hash_algo,
813 0 : spdm_context->connection_info.algorithm.req_base_asym_alg,
814 : spdm_context->connection_info.algorithm.req_pqc_asym_alg,
815 : cert_chain_buffer, cert_chain_buffer_size,
816 : true, cert_model);
817 : }
818 :
819 34 : return result;
820 : }
821 :
822 : /**
823 : * This function verifies peer certificate chain authority.
824 : *
825 : * @param spdm_context A pointer to the SPDM context.
826 : * @param cert_chain_buffer Certificate chain buffer including spdm_cert_chain_t header.
827 : * @param cert_chain_buffer_size size in bytes of the certificate chain buffer.
828 : * @param trust_anchor A buffer to hold the trust_anchor which is used to validate the peer certificate, if not NULL.
829 : * @param trust_anchor_size A buffer to hold the trust_anchor_size, if not NULL.
830 : *
831 : * @retval true Peer certificate chain buffer authority verification passed.
832 : * Or there is no root_cert in local_context.
833 : * @retval false Peer certificate chain buffer authority verification failed.
834 : **/
835 29 : bool libspdm_verify_peer_cert_chain_buffer_authority(libspdm_context_t *spdm_context,
836 : const void *cert_chain_buffer,
837 : size_t cert_chain_buffer_size,
838 : const void **trust_anchor,
839 : size_t *trust_anchor_size)
840 : {
841 : const uint8_t *root_cert;
842 : size_t root_cert_size;
843 : uint8_t root_cert_index;
844 : size_t root_cert_hash_size;
845 : uint8_t root_cert_hash[LIBSPDM_MAX_HASH_SIZE];
846 : const uint8_t *received_root_cert;
847 : size_t received_root_cert_size;
848 : bool result;
849 :
850 29 : root_cert_index = 0;
851 29 : root_cert = spdm_context->local_context.peer_root_cert_provision[root_cert_index];
852 29 : root_cert_size = spdm_context->local_context.peer_root_cert_provision_size[root_cert_index];
853 :
854 29 : root_cert_hash_size = libspdm_get_hash_size(
855 : spdm_context->connection_info.algorithm.base_hash_algo);
856 :
857 29 : if ((root_cert != NULL) && (root_cert_size != 0)) {
858 60 : while ((root_cert != NULL) && (root_cert_size != 0)) {
859 60 : result = libspdm_hash_all(
860 : spdm_context->connection_info.algorithm.base_hash_algo,
861 : root_cert, root_cert_size, root_cert_hash);
862 60 : if (!result) {
863 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR,
864 : "!!! verify_peer_cert_chain_buffer - FAIL (hash calculation) !!!\n"));
865 0 : return false;
866 : }
867 :
868 60 : if (libspdm_consttime_is_mem_equal((const uint8_t *)cert_chain_buffer +
869 : sizeof(spdm_cert_chain_t),
870 : root_cert_hash, root_cert_hash_size)) {
871 21 : break;
872 : }
873 :
874 : #if (LIBSPDM_MAX_ROOT_CERT_SUPPORT) > 1
875 39 : if ((root_cert_index < ((LIBSPDM_MAX_ROOT_CERT_SUPPORT) -1)) &&
876 38 : (spdm_context->local_context.peer_root_cert_provision[root_cert_index + 1] !=
877 : NULL)) {
878 34 : root_cert_index++;
879 34 : root_cert = spdm_context->local_context.peer_root_cert_provision[root_cert_index];
880 34 : root_cert_size =
881 34 : spdm_context->local_context.peer_root_cert_provision_size[root_cert_index];
882 : } else
883 : #endif /* LIBSPDM_MAX_ROOT_CERT_SUPPORT */
884 : {
885 5 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR,
886 : "!!! verify_peer_cert_chain_buffer - "
887 : "FAIL (all root cert hash mismatch) !!!\n"));
888 5 : return false;
889 : }
890 : }
891 :
892 21 : result = libspdm_x509_get_cert_from_cert_chain(
893 21 : (const uint8_t *)cert_chain_buffer + sizeof(spdm_cert_chain_t) + root_cert_hash_size,
894 21 : cert_chain_buffer_size - sizeof(spdm_cert_chain_t) - root_cert_hash_size,
895 : 0, &received_root_cert, &received_root_cert_size);
896 21 : if (!result) {
897 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR,
898 : "!!! verify_peer_cert_chain_buffer - FAIL (cert retrieval fail) !!!\n"));
899 0 : return false;
900 : }
901 21 : if (libspdm_is_root_certificate(received_root_cert, received_root_cert_size)) {
902 20 : if ((root_cert != NULL) &&
903 20 : !libspdm_consttime_is_mem_equal(received_root_cert, root_cert, root_cert_size)) {
904 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR,
905 : "!!! verify_peer_cert_chain_buffer - "
906 : "FAIL (root cert mismatch) !!!\n"));
907 0 : return false;
908 : }
909 : } else {
910 1 : if (!libspdm_x509_verify_cert(received_root_cert, received_root_cert_size,
911 : root_cert, root_cert_size)) {
912 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR,
913 : "!!! verify_peer_cert_chain_buffer - "
914 : "FAIL (received root cert verify failed)!!!\n"));
915 0 : return false;
916 : }
917 : }
918 21 : if (trust_anchor != NULL) {
919 5 : *trust_anchor = root_cert;
920 : }
921 21 : if (trust_anchor_size != NULL) {
922 5 : *trust_anchor_size = root_cert_size;
923 : }
924 : }
925 : /*
926 : * When there is no root_cert in local_context, the return is true too.
927 : * No root_cert means the caller wants to verify the trust anchor of the cert chain.
928 : */
929 24 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "!!! verify_peer_cert_chain_buffer - PASS !!!\n"));
930 :
931 24 : return true;
932 : }
933 : #endif
934 :
935 : /**
936 : * This function generates the challenge signature based upon m1m2 for authentication.
937 : *
938 : * @param spdm_context A pointer to the SPDM context.
939 : * @param is_requester Indicate of the signature generation for a requester or a responder.
940 : * @param signature The buffer to store the challenge signature.
941 : *
942 : * @retval true challenge signature is generated.
943 : * @retval false challenge signature is not generated.
944 : **/
945 12 : bool libspdm_generate_challenge_auth_signature(libspdm_context_t *spdm_context,
946 : bool is_requester,
947 : uint8_t *signature)
948 : {
949 : bool result;
950 : size_t signature_size;
951 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
952 : libspdm_m1m2_managed_buffer_t m1m2;
953 : uint8_t *m1m2_buffer;
954 : size_t m1m2_buffer_size;
955 : #else
956 : uint8_t m1m2_hash[LIBSPDM_MAX_HASH_SIZE];
957 : size_t m1m2_hash_size;
958 : #endif
959 :
960 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
961 : result = libspdm_calculate_m1m2(spdm_context, is_requester, &m1m2);
962 : m1m2_buffer = libspdm_get_managed_buffer(&m1m2);
963 : m1m2_buffer_size = libspdm_get_managed_buffer_size(&m1m2);
964 : #else
965 12 : m1m2_hash_size = sizeof(m1m2_hash);
966 12 : result = libspdm_calculate_m1m2_hash(spdm_context, is_requester, &m1m2_hash_size, &m1m2_hash);
967 : #endif
968 12 : if (is_requester) {
969 3 : libspdm_reset_message_mut_b(spdm_context);
970 3 : libspdm_reset_message_mut_c(spdm_context);
971 : } else {
972 9 : libspdm_reset_message_b(spdm_context);
973 9 : libspdm_reset_message_c(spdm_context);
974 : }
975 12 : if (!result) {
976 0 : return false;
977 : }
978 :
979 12 : if (is_requester) {
980 : #if LIBSPDM_ENABLE_CAPABILITY_MUT_AUTH_CAP
981 3 : if (spdm_context->connection_info.algorithm.req_pqc_asym_alg != 0) {
982 0 : signature_size = libspdm_get_req_pqc_asym_signature_size(
983 : spdm_context->connection_info.algorithm.req_pqc_asym_alg);
984 : } else {
985 3 : signature_size = libspdm_get_req_asym_signature_size(
986 3 : spdm_context->connection_info.algorithm.req_base_asym_alg);
987 : }
988 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
989 : result = libspdm_requester_data_sign(
990 : #if LIBSPDM_HAL_PASS_SPDM_CONTEXT
991 : spdm_context,
992 : #endif
993 : spdm_context->connection_info.version, SPDM_CHALLENGE_AUTH,
994 : spdm_context->connection_info.algorithm.req_base_asym_alg,
995 : spdm_context->connection_info.algorithm.req_pqc_asym_alg,
996 : spdm_context->connection_info.algorithm.base_hash_algo,
997 : false, m1m2_buffer, m1m2_buffer_size, signature, &signature_size);
998 : #else
999 3 : result = libspdm_requester_data_sign(
1000 : #if LIBSPDM_HAL_PASS_SPDM_CONTEXT
1001 : spdm_context,
1002 : #endif
1003 3 : spdm_context->connection_info.version, SPDM_CHALLENGE_AUTH,
1004 3 : spdm_context->connection_info.algorithm.req_base_asym_alg,
1005 : spdm_context->connection_info.algorithm.req_pqc_asym_alg,
1006 : spdm_context->connection_info.algorithm.base_hash_algo,
1007 : true, m1m2_hash, m1m2_hash_size, signature, &signature_size);
1008 : #endif
1009 : #else /* LIBSPDM_ENABLE_CAPABILITY_MUT_AUTH_CAP */
1010 : result = false;
1011 : #endif /* LIBSPDM_ENABLE_CAPABILITY_MUT_AUTH_CAP */
1012 : } else {
1013 9 : if (spdm_context->connection_info.algorithm.pqc_asym_algo != 0) {
1014 0 : signature_size = libspdm_get_pqc_asym_signature_size(
1015 : spdm_context->connection_info.algorithm.pqc_asym_algo);
1016 : } else {
1017 9 : signature_size = libspdm_get_asym_signature_size(
1018 : spdm_context->connection_info.algorithm.base_asym_algo);
1019 : }
1020 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
1021 : result = libspdm_responder_data_sign(
1022 : #if LIBSPDM_HAL_PASS_SPDM_CONTEXT
1023 : spdm_context,
1024 : #endif
1025 : spdm_context->connection_info.version, SPDM_CHALLENGE_AUTH,
1026 : spdm_context->connection_info.algorithm.base_asym_algo,
1027 : spdm_context->connection_info.algorithm.pqc_asym_algo,
1028 : spdm_context->connection_info.algorithm.base_hash_algo,
1029 : false, m1m2_buffer, m1m2_buffer_size, signature,
1030 : &signature_size);
1031 : #else
1032 9 : result = libspdm_responder_data_sign(
1033 : #if LIBSPDM_HAL_PASS_SPDM_CONTEXT
1034 : spdm_context,
1035 : #endif
1036 9 : spdm_context->connection_info.version, SPDM_CHALLENGE_AUTH,
1037 : spdm_context->connection_info.algorithm.base_asym_algo,
1038 : spdm_context->connection_info.algorithm.pqc_asym_algo,
1039 : spdm_context->connection_info.algorithm.base_hash_algo,
1040 : true, m1m2_hash, m1m2_hash_size, signature,
1041 : &signature_size);
1042 : #endif
1043 : }
1044 :
1045 12 : return result;
1046 : }
1047 :
1048 : /**
1049 : * This function verifies the certificate chain hash.
1050 : *
1051 : * @param spdm_context A pointer to the SPDM context.
1052 : * @param certificate_chain_hash The certificate chain hash data buffer.
1053 : * @param certificate_chain_hash_size size in bytes of the certificate chain hash data buffer.
1054 : *
1055 : * @retval true hash verification pass.
1056 : * @retval false hash verification fail.
1057 : **/
1058 19 : bool libspdm_verify_certificate_chain_hash(libspdm_context_t *spdm_context,
1059 : const void *certificate_chain_hash,
1060 : size_t certificate_chain_hash_size)
1061 : {
1062 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
1063 : size_t hash_size;
1064 : uint8_t cert_chain_buffer_hash[LIBSPDM_MAX_HASH_SIZE];
1065 : const uint8_t *cert_chain_buffer;
1066 : size_t cert_chain_buffer_size;
1067 : bool result;
1068 : #else
1069 : uint8_t slot_id;
1070 : #endif
1071 :
1072 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
1073 : result = libspdm_get_peer_cert_chain_buffer(spdm_context,
1074 : (const void **)&cert_chain_buffer,
1075 : &cert_chain_buffer_size);
1076 : if (!result) {
1077 : return false;
1078 : }
1079 :
1080 : hash_size = libspdm_get_hash_size(spdm_context->connection_info.algorithm.base_hash_algo);
1081 :
1082 : result = libspdm_hash_all(spdm_context->connection_info.algorithm.base_hash_algo,
1083 : cert_chain_buffer, cert_chain_buffer_size,
1084 : cert_chain_buffer_hash);
1085 : if (!result) {
1086 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR,
1087 : "!!! verify_certificate_chain_hash - FAIL (hash calculation) !!!\n"));
1088 : return false;
1089 : }
1090 :
1091 : if (hash_size != certificate_chain_hash_size) {
1092 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR, "!!! verify_certificate_chain_hash - FAIL !!!\n"));
1093 : return false;
1094 : }
1095 : if (!libspdm_consttime_is_mem_equal(certificate_chain_hash, cert_chain_buffer_hash,
1096 : certificate_chain_hash_size)) {
1097 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR, "!!! verify_certificate_chain_hash - FAIL !!!\n"));
1098 : return false;
1099 : }
1100 : #else
1101 19 : slot_id = spdm_context->connection_info.peer_used_cert_chain_slot_id;
1102 19 : LIBSPDM_ASSERT(slot_id < SPDM_MAX_SLOT_COUNT);
1103 :
1104 19 : LIBSPDM_ASSERT(
1105 : spdm_context->connection_info.peer_used_cert_chain[slot_id].buffer_hash_size != 0);
1106 :
1107 19 : if (spdm_context->connection_info.peer_used_cert_chain[slot_id].buffer_hash_size !=
1108 : certificate_chain_hash_size) {
1109 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR, "!!! verify_certificate_chain_hash - FAIL !!!\n"));
1110 0 : return false;
1111 : }
1112 :
1113 19 : if (!libspdm_consttime_is_mem_equal(certificate_chain_hash,
1114 19 : spdm_context->connection_info.peer_used_cert_chain[slot_id].
1115 : buffer_hash, certificate_chain_hash_size)) {
1116 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR, "!!! verify_certificate_chain_hash - FAIL !!!\n"));
1117 0 : return false;
1118 : }
1119 : #endif
1120 19 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "!!! verify_certificate_chain_hash - PASS !!!\n"));
1121 19 : return true;
1122 : }
1123 :
1124 : /**
1125 : * This function verifies the public key hash.
1126 : *
1127 : * @param spdm_context A pointer to the SPDM context.
1128 : * @param public_key_hash The public key hash data buffer.
1129 : * @param public_key_hash_size size in bytes of the public key hash data buffer.
1130 : *
1131 : * @retval true hash verification pass.
1132 : * @retval false hash verification fail.
1133 : **/
1134 2 : bool libspdm_verify_public_key_hash(libspdm_context_t *spdm_context,
1135 : const void *public_key_hash,
1136 : size_t public_key_hash_size)
1137 : {
1138 : size_t hash_size;
1139 : uint8_t public_key_buffer_hash[LIBSPDM_MAX_HASH_SIZE];
1140 : bool result;
1141 :
1142 2 : hash_size = libspdm_get_hash_size(spdm_context->connection_info.algorithm.base_hash_algo);
1143 :
1144 2 : result = libspdm_hash_all(spdm_context->connection_info.algorithm.base_hash_algo,
1145 : spdm_context->local_context.peer_public_key_provision,
1146 : spdm_context->local_context.peer_public_key_provision_size,
1147 : public_key_buffer_hash);
1148 2 : if (!result) {
1149 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR,
1150 : "!!! verify_public_key_hash - FAIL (hash calculation) !!!\n"));
1151 0 : return false;
1152 : }
1153 :
1154 2 : if (hash_size != public_key_hash_size) {
1155 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR, "!!! verify_public_key_hash - FAIL !!!\n"));
1156 0 : return false;
1157 : }
1158 2 : if (!libspdm_consttime_is_mem_equal(public_key_hash, public_key_buffer_hash,
1159 : public_key_hash_size)) {
1160 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR, "!!! verify_public_key_hash - FAIL !!!\n"));
1161 0 : return false;
1162 : }
1163 :
1164 2 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "!!! verify_public_key_hash - PASS !!!\n"));
1165 2 : return true;
1166 : }
1167 :
1168 : /**
1169 : * This function verifies the challenge signature based upon m1m2.
1170 : *
1171 : * @param spdm_context A pointer to the SPDM context.
1172 : * @param is_requester Indicate of the signature verification for a requester or a responder.
1173 : * @param sign_data The signature data buffer.
1174 : * @param sign_data_size size in bytes of the signature data buffer.
1175 : *
1176 : * @retval true signature verification pass.
1177 : * @retval false signature verification fail.
1178 : **/
1179 19 : bool libspdm_verify_challenge_auth_signature(libspdm_context_t *spdm_context,
1180 : bool is_requester,
1181 : const void *sign_data,
1182 : size_t sign_data_size)
1183 : {
1184 : bool result;
1185 : void *context;
1186 : uint8_t slot_id;
1187 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
1188 : libspdm_m1m2_managed_buffer_t m1m2;
1189 : uint8_t *m1m2_buffer;
1190 : size_t m1m2_buffer_size;
1191 : const uint8_t *cert_buffer;
1192 : size_t cert_buffer_size;
1193 : const uint8_t *cert_chain_data;
1194 : size_t cert_chain_data_size;
1195 : #else
1196 : uint8_t m1m2_hash[LIBSPDM_MAX_HASH_SIZE];
1197 : size_t m1m2_hash_size;
1198 : #endif
1199 :
1200 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
1201 : result = libspdm_calculate_m1m2(spdm_context, !is_requester, &m1m2);
1202 : m1m2_buffer = libspdm_get_managed_buffer(&m1m2);
1203 : m1m2_buffer_size = libspdm_get_managed_buffer_size(&m1m2);
1204 : #else
1205 19 : m1m2_hash_size = sizeof(m1m2_hash);
1206 19 : result = libspdm_calculate_m1m2_hash(spdm_context, !is_requester, &m1m2_hash_size, &m1m2_hash);
1207 : #endif
1208 19 : if (is_requester) {
1209 16 : libspdm_reset_message_b(spdm_context);
1210 16 : libspdm_reset_message_c(spdm_context);
1211 : } else {
1212 3 : libspdm_reset_message_mut_b(spdm_context);
1213 3 : libspdm_reset_message_mut_c(spdm_context);
1214 : }
1215 19 : if (!result) {
1216 0 : return false;
1217 : }
1218 :
1219 19 : slot_id = spdm_context->connection_info.peer_used_cert_chain_slot_id;
1220 19 : LIBSPDM_ASSERT((slot_id < SPDM_MAX_SLOT_COUNT) || (slot_id == 0xFF));
1221 :
1222 19 : if (slot_id == 0xFF) {
1223 2 : if (is_requester) {
1224 1 : if (spdm_context->connection_info.algorithm.pqc_asym_algo != 0) {
1225 0 : result = libspdm_pqc_asym_get_public_key_from_der(
1226 : spdm_context->connection_info.algorithm.pqc_asym_algo,
1227 0 : spdm_context->local_context.peer_public_key_provision,
1228 : spdm_context->local_context.peer_public_key_provision_size,
1229 : &context);
1230 : } else {
1231 1 : result = libspdm_asym_get_public_key_from_der(
1232 : spdm_context->connection_info.algorithm.base_asym_algo,
1233 1 : spdm_context->local_context.peer_public_key_provision,
1234 : spdm_context->local_context.peer_public_key_provision_size,
1235 : &context);
1236 : }
1237 : } else {
1238 1 : if (spdm_context->connection_info.algorithm.req_pqc_asym_alg != 0) {
1239 0 : result = libspdm_req_pqc_asym_get_public_key_from_der(
1240 : spdm_context->connection_info.algorithm.req_pqc_asym_alg,
1241 0 : spdm_context->local_context.peer_public_key_provision,
1242 : spdm_context->local_context.peer_public_key_provision_size,
1243 : &context);
1244 : } else {
1245 1 : result = libspdm_req_asym_get_public_key_from_der(
1246 1 : spdm_context->connection_info.algorithm.req_base_asym_alg,
1247 1 : spdm_context->local_context.peer_public_key_provision,
1248 : spdm_context->local_context.peer_public_key_provision_size,
1249 : &context);
1250 : }
1251 : }
1252 2 : if (!result) {
1253 0 : return false;
1254 : }
1255 : } else {
1256 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
1257 : result = libspdm_get_peer_cert_chain_data(
1258 : spdm_context, (const void **)&cert_chain_data, &cert_chain_data_size);
1259 : if (!result) {
1260 : return false;
1261 : }
1262 :
1263 : /* Get leaf cert from cert chain*/
1264 : result = libspdm_x509_get_cert_from_cert_chain(
1265 : cert_chain_data, cert_chain_data_size, -1, &cert_buffer, &cert_buffer_size);
1266 : if (!result) {
1267 : return false;
1268 : }
1269 :
1270 : if (is_requester) {
1271 : if (spdm_context->connection_info.algorithm.pqc_asym_algo != 0) {
1272 : result = libspdm_pqc_asym_get_public_key_from_x509(
1273 : spdm_context->connection_info.algorithm.pqc_asym_algo,
1274 : cert_buffer, cert_buffer_size, &context);
1275 : } else {
1276 : result = libspdm_asym_get_public_key_from_x509(
1277 : spdm_context->connection_info.algorithm.base_asym_algo,
1278 : cert_buffer, cert_buffer_size, &context);
1279 : }
1280 : } else {
1281 : if (spdm_context->connection_info.algorithm.req_pqc_asym_alg != 0) {
1282 : result = libspdm_req_pqc_asym_get_public_key_from_x509(
1283 : spdm_context->connection_info.algorithm.req_pqc_asym_alg,
1284 : cert_buffer, cert_buffer_size, &context);
1285 : } else {
1286 : result = libspdm_req_asym_get_public_key_from_x509(
1287 : spdm_context->connection_info.algorithm.req_base_asym_alg,
1288 : cert_buffer, cert_buffer_size, &context);
1289 : }
1290 : }
1291 : if (!result) {
1292 : return false;
1293 : }
1294 : #else
1295 17 : context = spdm_context->connection_info.peer_used_cert_chain[slot_id].leaf_cert_public_key;
1296 17 : LIBSPDM_ASSERT(context != NULL);
1297 : #endif
1298 : }
1299 :
1300 19 : if (is_requester) {
1301 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
1302 : if (spdm_context->connection_info.algorithm.pqc_asym_algo != 0) {
1303 : result = libspdm_pqc_asym_verify(
1304 : spdm_context->connection_info.version, SPDM_CHALLENGE_AUTH,
1305 : spdm_context->connection_info.algorithm.pqc_asym_algo,
1306 : spdm_context->connection_info.algorithm.base_hash_algo,
1307 : context, m1m2_buffer, m1m2_buffer_size, sign_data, sign_data_size);
1308 : libspdm_pqc_asym_free(
1309 : spdm_context->connection_info.algorithm.pqc_asym_algo, context);
1310 : } else {
1311 : result = libspdm_asym_verify_ex(
1312 : spdm_context->connection_info.version, SPDM_CHALLENGE_AUTH,
1313 : spdm_context->connection_info.algorithm.base_asym_algo,
1314 : spdm_context->connection_info.algorithm.base_hash_algo,
1315 : context, m1m2_buffer, m1m2_buffer_size, sign_data, sign_data_size,
1316 : &spdm_context->spdm_10_11_verify_signature_endian);
1317 : libspdm_asym_free(
1318 : spdm_context->connection_info.algorithm.base_asym_algo, context);
1319 : }
1320 : #else
1321 16 : if (spdm_context->connection_info.algorithm.pqc_asym_algo != 0) {
1322 0 : result = libspdm_pqc_asym_verify_hash(
1323 0 : spdm_context->connection_info.version, SPDM_CHALLENGE_AUTH,
1324 : spdm_context->connection_info.algorithm.pqc_asym_algo,
1325 : spdm_context->connection_info.algorithm.base_hash_algo,
1326 : context, m1m2_hash, m1m2_hash_size, sign_data, sign_data_size);
1327 0 : if (slot_id == 0xFF) {
1328 0 : libspdm_pqc_asym_free(
1329 : spdm_context->connection_info.algorithm.pqc_asym_algo, context);
1330 : }
1331 : } else {
1332 16 : result = libspdm_asym_verify_hash_ex(
1333 16 : spdm_context->connection_info.version, SPDM_CHALLENGE_AUTH,
1334 : spdm_context->connection_info.algorithm.base_asym_algo,
1335 : spdm_context->connection_info.algorithm.base_hash_algo,
1336 : context, m1m2_hash, m1m2_hash_size, sign_data, sign_data_size,
1337 : &spdm_context->spdm_10_11_verify_signature_endian);
1338 16 : if (slot_id == 0xFF) {
1339 1 : libspdm_asym_free(
1340 : spdm_context->connection_info.algorithm.base_asym_algo, context);
1341 : }
1342 : }
1343 : #endif
1344 : } else {
1345 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
1346 : if (spdm_context->connection_info.algorithm.req_pqc_asym_alg != 0) {
1347 : result = libspdm_req_pqc_asym_verify(
1348 : spdm_context->connection_info.version, SPDM_CHALLENGE_AUTH,
1349 : spdm_context->connection_info.algorithm.req_pqc_asym_alg,
1350 : spdm_context->connection_info.algorithm.base_hash_algo,
1351 : context, m1m2_buffer, m1m2_buffer_size, sign_data, sign_data_size);
1352 : libspdm_req_pqc_asym_free(
1353 : spdm_context->connection_info.algorithm.req_pqc_asym_alg, context);
1354 : } else {
1355 : result = libspdm_req_asym_verify_ex(
1356 : spdm_context->connection_info.version, SPDM_CHALLENGE_AUTH,
1357 : spdm_context->connection_info.algorithm.req_base_asym_alg,
1358 : spdm_context->connection_info.algorithm.base_hash_algo,
1359 : context, m1m2_buffer, m1m2_buffer_size, sign_data, sign_data_size,
1360 : &spdm_context->spdm_10_11_verify_signature_endian);
1361 : libspdm_req_asym_free(
1362 : spdm_context->connection_info.algorithm.req_base_asym_alg, context);
1363 : }
1364 : #else
1365 3 : if (spdm_context->connection_info.algorithm.req_pqc_asym_alg != 0) {
1366 0 : result = libspdm_req_pqc_asym_verify_hash(
1367 0 : spdm_context->connection_info.version, SPDM_CHALLENGE_AUTH,
1368 : spdm_context->connection_info.algorithm.req_pqc_asym_alg,
1369 : spdm_context->connection_info.algorithm.base_hash_algo,
1370 : context, m1m2_hash, m1m2_hash_size, sign_data, sign_data_size);
1371 0 : if (slot_id == 0xFF) {
1372 0 : libspdm_req_pqc_asym_free(
1373 : spdm_context->connection_info.algorithm.req_pqc_asym_alg, context);
1374 : }
1375 : } else {
1376 3 : result = libspdm_req_asym_verify_hash_ex(
1377 3 : spdm_context->connection_info.version, SPDM_CHALLENGE_AUTH,
1378 3 : spdm_context->connection_info.algorithm.req_base_asym_alg,
1379 : spdm_context->connection_info.algorithm.base_hash_algo,
1380 : context, m1m2_hash, m1m2_hash_size, sign_data, sign_data_size,
1381 : &spdm_context->spdm_10_11_verify_signature_endian);
1382 3 : if (slot_id == 0xFF) {
1383 1 : libspdm_req_asym_free(
1384 1 : spdm_context->connection_info.algorithm.req_base_asym_alg, context);
1385 : }
1386 : }
1387 : #endif
1388 : }
1389 19 : if (!result) {
1390 1 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR,
1391 : "!!! verify_challenge_signature - FAIL !!!\n"));
1392 1 : return false;
1393 : }
1394 :
1395 18 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "!!! verify_challenge_signature - PASS !!!\n"));
1396 :
1397 18 : return true;
1398 : }
1399 :
1400 : /**
1401 : * This function calculate the measurement summary hash size.
1402 : *
1403 : * @param spdm_context A pointer to the SPDM context.
1404 : * @param is_requester Is the function called from a requester.
1405 : * @param measurement_summary_hash_type The type of the measurement summary hash.
1406 : *
1407 : * @return 0 measurement summary hash type is invalid, NO_MEAS hash type or no MEAS capabilities.
1408 : * @return measurement summary hash size according to type.
1409 : **/
1410 : uint32_t
1411 106 : libspdm_get_measurement_summary_hash_size(libspdm_context_t *spdm_context,
1412 : bool is_requester,
1413 : uint8_t measurement_summary_hash_type)
1414 : {
1415 106 : if (!libspdm_is_capabilities_flag_supported(
1416 : spdm_context, is_requester, 0,
1417 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP)) {
1418 55 : return 0;
1419 : }
1420 :
1421 51 : switch (measurement_summary_hash_type) {
1422 25 : case SPDM_REQUEST_NO_MEASUREMENT_SUMMARY_HASH:
1423 25 : return 0;
1424 : break;
1425 :
1426 24 : case SPDM_REQUEST_TCB_COMPONENT_MEASUREMENT_HASH:
1427 : case SPDM_REQUEST_ALL_MEASUREMENTS_HASH:
1428 24 : return libspdm_get_hash_size(spdm_context->connection_info.algorithm.base_hash_algo);
1429 : break;
1430 2 : default:
1431 2 : return 0;
1432 : break;
1433 : }
1434 : }
1435 :
1436 : /**
1437 : * This function generates the endpoint info signature based upon il1il2 for authentication.
1438 : *
1439 : * @param spdm_context A pointer to the SPDM context.
1440 : * @param session_info A pointer to the SPDM session context.
1441 : * @param is_requester Indicate of the signature generation for a requester or a responder.
1442 : * @param signature The buffer to store the endpoint info signature.
1443 : *
1444 : * @retval true challenge signature is generated.
1445 : * @retval false challenge signature is not generated.
1446 : **/
1447 9 : bool libspdm_generate_endpoint_info_signature(libspdm_context_t *spdm_context,
1448 : libspdm_session_info_t *session_info,
1449 : bool is_requester,
1450 : uint8_t *signature)
1451 : {
1452 : bool result;
1453 : size_t signature_size;
1454 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
1455 : libspdm_il1il2_managed_buffer_t il1il2;
1456 : uint8_t *il1il2_buffer;
1457 : size_t il1il2_buffer_size;
1458 : #else
1459 : uint8_t il1il2_hash[LIBSPDM_MAX_HASH_SIZE];
1460 : size_t il1il2_hash_size;
1461 : #endif
1462 :
1463 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
1464 : result = libspdm_calculate_il1il2(spdm_context, session_info, is_requester, &il1il2);
1465 : il1il2_buffer = libspdm_get_managed_buffer(&il1il2);
1466 : il1il2_buffer_size = libspdm_get_managed_buffer_size(&il1il2);
1467 : #else
1468 9 : il1il2_hash_size = sizeof(il1il2_hash);
1469 9 : result = libspdm_calculate_il1il2_hash(spdm_context, session_info, is_requester,
1470 : &il1il2_hash_size, &il1il2_hash);
1471 : #endif
1472 9 : if (is_requester) {
1473 5 : libspdm_reset_message_encap_e(spdm_context, session_info);
1474 : } else {
1475 4 : libspdm_reset_message_e(spdm_context, session_info);
1476 : }
1477 9 : if (!result) {
1478 0 : return false;
1479 : }
1480 :
1481 9 : if (is_requester) {
1482 : #if LIBSPDM_ENABLE_CAPABILITY_ENCAP_CAP
1483 5 : if (spdm_context->connection_info.algorithm.req_pqc_asym_alg != 0) {
1484 0 : signature_size = libspdm_get_req_pqc_asym_signature_size(
1485 : spdm_context->connection_info.algorithm.req_pqc_asym_alg);
1486 : } else {
1487 5 : signature_size = libspdm_get_req_asym_signature_size(
1488 5 : spdm_context->connection_info.algorithm.req_base_asym_alg);
1489 : }
1490 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
1491 : result = libspdm_requester_data_sign(
1492 : #if LIBSPDM_HAL_PASS_SPDM_CONTEXT
1493 : spdm_context,
1494 : #endif
1495 : spdm_context->connection_info.version, SPDM_ENDPOINT_INFO,
1496 : spdm_context->connection_info.algorithm.req_base_asym_alg,
1497 : spdm_context->connection_info.algorithm.req_pqc_asym_alg,
1498 : spdm_context->connection_info.algorithm.base_hash_algo,
1499 : false, il1il2_buffer, il1il2_buffer_size, signature, &signature_size);
1500 : #else
1501 5 : result = libspdm_requester_data_sign(
1502 : #if LIBSPDM_HAL_PASS_SPDM_CONTEXT
1503 : spdm_context,
1504 : #endif
1505 5 : spdm_context->connection_info.version, SPDM_ENDPOINT_INFO,
1506 5 : spdm_context->connection_info.algorithm.req_base_asym_alg,
1507 : spdm_context->connection_info.algorithm.req_pqc_asym_alg,
1508 : spdm_context->connection_info.algorithm.base_hash_algo,
1509 : true, il1il2_hash, il1il2_hash_size, signature, &signature_size);
1510 : #endif
1511 : #else /* LIBSPDM_ENABLE_CAPABILITY_ENCAP_CAP */
1512 : result = false;
1513 : #endif /* LIBSPDM_ENABLE_CAPABILITY_ENCAP_CAP */
1514 : } else {
1515 4 : if (spdm_context->connection_info.algorithm.pqc_asym_algo != 0) {
1516 0 : signature_size = libspdm_get_pqc_asym_signature_size(
1517 : spdm_context->connection_info.algorithm.pqc_asym_algo);
1518 : } else {
1519 4 : signature_size = libspdm_get_asym_signature_size(
1520 : spdm_context->connection_info.algorithm.base_asym_algo);
1521 : }
1522 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
1523 : result = libspdm_responder_data_sign(
1524 : #if LIBSPDM_HAL_PASS_SPDM_CONTEXT
1525 : spdm_context,
1526 : #endif
1527 : spdm_context->connection_info.version, SPDM_ENDPOINT_INFO,
1528 : spdm_context->connection_info.algorithm.base_asym_algo,
1529 : spdm_context->connection_info.algorithm.pqc_asym_algo,
1530 : spdm_context->connection_info.algorithm.base_hash_algo,
1531 : false, il1il2_buffer, il1il2_buffer_size, signature,
1532 : &signature_size);
1533 : #else
1534 4 : result = libspdm_responder_data_sign(
1535 : #if LIBSPDM_HAL_PASS_SPDM_CONTEXT
1536 : spdm_context,
1537 : #endif
1538 4 : spdm_context->connection_info.version, SPDM_ENDPOINT_INFO,
1539 : spdm_context->connection_info.algorithm.base_asym_algo,
1540 : spdm_context->connection_info.algorithm.pqc_asym_algo,
1541 : spdm_context->connection_info.algorithm.base_hash_algo,
1542 : true, il1il2_hash, il1il2_hash_size, signature,
1543 : &signature_size);
1544 : #endif
1545 : }
1546 :
1547 9 : return result;
1548 : }
1549 :
1550 : /**
1551 : * This function verifies the endpoint info signature based upon il1il2.
1552 : *
1553 : * @param spdm_context A pointer to the SPDM context.
1554 : * @param session_info A pointer to the SPDM session context.
1555 : * @param is_requester Indicate of the signature verification for a requester or a responder.
1556 : * @param sign_data The signature data buffer.
1557 : * @param sign_data_size size in bytes of the signature data buffer.
1558 : *
1559 : * @retval true signature verification pass.
1560 : * @retval false signature verification fail.
1561 : **/
1562 22 : bool libspdm_verify_endpoint_info_signature(libspdm_context_t *spdm_context,
1563 : libspdm_session_info_t *session_info,
1564 : bool is_requester,
1565 : const void *sign_data,
1566 : size_t sign_data_size)
1567 : {
1568 : bool result;
1569 : void *context;
1570 : uint8_t slot_id;
1571 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
1572 : libspdm_il1il2_managed_buffer_t il1il2;
1573 : uint8_t *il1il2_buffer;
1574 : size_t il1il2_buffer_size;
1575 : const uint8_t *cert_chain_data;
1576 : size_t cert_chain_data_size;
1577 : const uint8_t *cert_buffer;
1578 : size_t cert_buffer_size;
1579 : #else
1580 : uint8_t il1il2_hash[LIBSPDM_MAX_HASH_SIZE];
1581 : size_t il1il2_hash_size;
1582 : #endif
1583 :
1584 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
1585 : result = libspdm_calculate_il1il2(spdm_context, session_info,!is_requester, &il1il2);
1586 : il1il2_buffer = libspdm_get_managed_buffer(&il1il2);
1587 : il1il2_buffer_size = libspdm_get_managed_buffer_size(&il1il2);
1588 : #else
1589 22 : il1il2_hash_size = sizeof(il1il2_hash);
1590 22 : result = libspdm_calculate_il1il2_hash(spdm_context, session_info, !is_requester,
1591 22 : &il1il2_hash_size, il1il2_hash);
1592 : #endif
1593 22 : if (is_requester) {
1594 13 : libspdm_reset_message_e(spdm_context, session_info);
1595 : } else {
1596 9 : libspdm_reset_message_encap_e(spdm_context, session_info);
1597 : }
1598 22 : if (!result) {
1599 0 : return false;
1600 : }
1601 :
1602 22 : slot_id = spdm_context->connection_info.peer_used_cert_chain_slot_id;
1603 22 : LIBSPDM_ASSERT((slot_id < SPDM_MAX_SLOT_COUNT) || (slot_id == 0xF));
1604 :
1605 22 : if (slot_id == 0xF) {
1606 5 : if (is_requester) {
1607 2 : if (spdm_context->connection_info.algorithm.base_asym_algo != 0) {
1608 2 : result = libspdm_asym_get_public_key_from_der(
1609 : spdm_context->connection_info.algorithm.base_asym_algo,
1610 2 : spdm_context->local_context.peer_public_key_provision,
1611 : spdm_context->local_context.peer_public_key_provision_size,
1612 : &context);
1613 : }
1614 2 : if (spdm_context->connection_info.algorithm.pqc_asym_algo != 0) {
1615 0 : result = libspdm_pqc_asym_get_public_key_from_der(
1616 : spdm_context->connection_info.algorithm.pqc_asym_algo,
1617 0 : spdm_context->local_context.peer_public_key_provision,
1618 : spdm_context->local_context.peer_public_key_provision_size,
1619 : &context);
1620 : }
1621 : } else {
1622 3 : if (spdm_context->connection_info.algorithm.req_base_asym_alg != 0) {
1623 3 : result = libspdm_req_asym_get_public_key_from_der(
1624 3 : spdm_context->connection_info.algorithm.req_base_asym_alg,
1625 3 : spdm_context->local_context.peer_public_key_provision,
1626 : spdm_context->local_context.peer_public_key_provision_size,
1627 : &context);
1628 : }
1629 3 : if (spdm_context->connection_info.algorithm.req_pqc_asym_alg != 0) {
1630 0 : result = libspdm_req_pqc_asym_get_public_key_from_der(
1631 : spdm_context->connection_info.algorithm.req_pqc_asym_alg,
1632 0 : spdm_context->local_context.peer_public_key_provision,
1633 : spdm_context->local_context.peer_public_key_provision_size,
1634 : &context);
1635 : }
1636 : }
1637 5 : if (!result) {
1638 0 : return false;
1639 : }
1640 : } else {
1641 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
1642 : result = libspdm_get_peer_cert_chain_data(
1643 : spdm_context, (const void **)&cert_chain_data, &cert_chain_data_size);
1644 : if (!result) {
1645 : return false;
1646 : }
1647 :
1648 : /* Get leaf cert from cert chain*/
1649 : result = libspdm_x509_get_cert_from_cert_chain(cert_chain_data,
1650 : cert_chain_data_size, -1,
1651 : &cert_buffer, &cert_buffer_size);
1652 : if (!result) {
1653 : return false;
1654 : }
1655 :
1656 : if (is_requester) {
1657 : result = libspdm_asym_get_public_key_from_x509(
1658 : spdm_context->connection_info.algorithm.base_asym_algo,
1659 : cert_buffer, cert_buffer_size, &context);
1660 : } else {
1661 : result = libspdm_req_asym_get_public_key_from_x509(
1662 : spdm_context->connection_info.algorithm.req_base_asym_alg,
1663 : cert_buffer, cert_buffer_size, &context);
1664 : }
1665 : if (!result) {
1666 : return false;
1667 : }
1668 : #else
1669 17 : context = spdm_context->connection_info.peer_used_cert_chain[slot_id].leaf_cert_public_key;
1670 17 : LIBSPDM_ASSERT(context != NULL);
1671 : #endif
1672 : }
1673 :
1674 22 : if (is_requester) {
1675 13 : if (spdm_context->connection_info.algorithm.base_asym_algo != 0) {
1676 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
1677 : result = libspdm_asym_verify_ex(
1678 : spdm_context->connection_info.version, SPDM_ENDPOINT_INFO,
1679 : spdm_context->connection_info.algorithm.base_asym_algo,
1680 : spdm_context->connection_info.algorithm.base_hash_algo,
1681 : context, il1il2_buffer, il1il2_buffer_size, sign_data, sign_data_size,
1682 : &spdm_context->spdm_10_11_verify_signature_endian);
1683 : libspdm_asym_free(
1684 : spdm_context->connection_info.algorithm.base_asym_algo, context);
1685 : #else
1686 13 : result = libspdm_asym_verify_hash_ex(
1687 13 : spdm_context->connection_info.version, SPDM_ENDPOINT_INFO,
1688 : spdm_context->connection_info.algorithm.base_asym_algo,
1689 : spdm_context->connection_info.algorithm.base_hash_algo,
1690 : context, il1il2_hash, il1il2_hash_size, sign_data, sign_data_size,
1691 : &spdm_context->spdm_10_11_verify_signature_endian);
1692 13 : if (slot_id == 0xF) {
1693 2 : libspdm_asym_free(
1694 : spdm_context->connection_info.algorithm.base_asym_algo, context);
1695 : }
1696 : #endif
1697 : }
1698 13 : if (spdm_context->connection_info.algorithm.pqc_asym_algo != 0) {
1699 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
1700 : result = libspdm_pqc_asym_verify(
1701 : spdm_context->connection_info.version, SPDM_ENDPOINT_INFO,
1702 : spdm_context->connection_info.algorithm.pqc_asym_algo,
1703 : spdm_context->connection_info.algorithm.base_hash_algo,
1704 : context, il1il2_buffer, il1il2_buffer_size, sign_data, sign_data_size);
1705 : libspdm_pqc_asym_free(
1706 : spdm_context->connection_info.algorithm.pqc_asym_algo, context);
1707 : #else
1708 0 : result = libspdm_pqc_asym_verify_hash(
1709 0 : spdm_context->connection_info.version, SPDM_ENDPOINT_INFO,
1710 : spdm_context->connection_info.algorithm.pqc_asym_algo,
1711 : spdm_context->connection_info.algorithm.base_hash_algo,
1712 : context, il1il2_hash, il1il2_hash_size, sign_data, sign_data_size);
1713 0 : if (slot_id == 0xFF) {
1714 0 : libspdm_pqc_asym_free(
1715 : spdm_context->connection_info.algorithm.pqc_asym_algo, context);
1716 : }
1717 : #endif
1718 : }
1719 : } else {
1720 9 : if (spdm_context->connection_info.algorithm.req_base_asym_alg != 0) {
1721 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
1722 : result = libspdm_req_asym_verify_ex(
1723 : spdm_context->connection_info.version, SPDM_ENDPOINT_INFO,
1724 : spdm_context->connection_info.algorithm.req_base_asym_alg,
1725 : spdm_context->connection_info.algorithm.base_hash_algo,
1726 : context, il1il2_buffer, il1il2_buffer_size, sign_data, sign_data_size,
1727 : &spdm_context->spdm_10_11_verify_signature_endian);
1728 : libspdm_req_asym_free(
1729 : spdm_context->connection_info.algorithm.req_base_asym_alg, context);
1730 : #else
1731 9 : result = libspdm_req_asym_verify_hash_ex(
1732 9 : spdm_context->connection_info.version, SPDM_ENDPOINT_INFO,
1733 9 : spdm_context->connection_info.algorithm.req_base_asym_alg,
1734 : spdm_context->connection_info.algorithm.base_hash_algo,
1735 : context, il1il2_hash, il1il2_hash_size, sign_data, sign_data_size,
1736 : &spdm_context->spdm_10_11_verify_signature_endian);
1737 9 : if (slot_id == 0xF) {
1738 3 : libspdm_req_asym_free(
1739 3 : spdm_context->connection_info.algorithm.req_base_asym_alg, context);
1740 : }
1741 : #endif
1742 : }
1743 9 : if (spdm_context->connection_info.algorithm.req_pqc_asym_alg != 0) {
1744 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
1745 : result = libspdm_req_pqc_asym_verify(
1746 : spdm_context->connection_info.version, SPDM_ENDPOINT_INFO,
1747 : spdm_context->connection_info.algorithm.req_pqc_asym_alg,
1748 : spdm_context->connection_info.algorithm.base_hash_algo,
1749 : context, il1il2_buffer, il1il2_buffer_size, sign_data, sign_data_size);
1750 : libspdm_req_pqc_asym_free(
1751 : spdm_context->connection_info.algorithm.req_pqc_asym_alg, context);
1752 : #else
1753 0 : result = libspdm_req_pqc_asym_verify_hash(
1754 0 : spdm_context->connection_info.version, SPDM_ENDPOINT_INFO,
1755 : spdm_context->connection_info.algorithm.req_pqc_asym_alg,
1756 : spdm_context->connection_info.algorithm.base_hash_algo,
1757 : context, il1il2_hash, il1il2_hash_size, sign_data, sign_data_size);
1758 0 : if (slot_id == 0xFF) {
1759 0 : libspdm_req_pqc_asym_free(
1760 : spdm_context->connection_info.algorithm.req_pqc_asym_alg, context);
1761 : }
1762 : #endif
1763 : }
1764 : }
1765 22 : if (!result) {
1766 3 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR, "!!! verify_endpoint_info_signature - FAIL !!!\n"));
1767 3 : return false;
1768 : }
1769 :
1770 19 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "!!! verify_endpoint_info_signature - PASS !!!\n"));
1771 19 : return true;
1772 : }
|