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