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