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