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