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