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 "spdm_unit_test.h"
8 : #include "internal/libspdm_requester_lib.h"
9 : #include "internal/libspdm_secured_message_lib.h"
10 :
11 : #if LIBSPDM_SEND_GET_CERTIFICATE_SUPPORT
12 :
13 : static void *m_libspdm_local_certificate_chain;
14 : static size_t m_libspdm_local_certificate_chain_size;
15 :
16 : static size_t m_libspdm_local_buffer_size;
17 : static uint8_t m_libspdm_local_buffer[LIBSPDM_MAX_MESSAGE_M1M2_BUFFER_SIZE];
18 :
19 : static bool m_get_cert;
20 :
21 : static uint8_t m_cert_model;
22 :
23 : static uint8_t m_slot_id;
24 :
25 : static size_t m_calling_index;
26 :
27 :
28 : /* Loading the target expiration certificate chain and saving root certificate hash
29 : * "rsa3072_Expiration/bundle_responder.certchain.der"*/
30 2 : bool libspdm_libspdm_read_responder_public_certificate_chain_expiration(
31 : void **data, size_t *size, void **hash, size_t *hash_size)
32 : {
33 2 : uint32_t base_hash_algo = SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_256;
34 : bool res;
35 : void *file_data;
36 : size_t file_size;
37 : spdm_cert_chain_t *cert_chain;
38 : size_t cert_chain_size;
39 : char *file;
40 : const uint8_t *root_cert;
41 : size_t root_cert_len;
42 : size_t digest_size;
43 :
44 2 : *data = NULL;
45 2 : *size = 0;
46 2 : if (hash != NULL) {
47 1 : *hash = NULL;
48 : }
49 2 : if (hash_size != NULL) {
50 1 : *hash_size = 0;
51 : }
52 :
53 2 : file = "rsa3072_Expiration/bundle_responder.certchain.der";
54 2 : res = libspdm_read_input_file(file, &file_data, &file_size);
55 2 : if (!res) {
56 0 : return res;
57 : }
58 :
59 2 : digest_size = libspdm_get_hash_size(base_hash_algo);
60 :
61 2 : cert_chain_size = sizeof(spdm_cert_chain_t) + digest_size + file_size;
62 2 : cert_chain = (void *)malloc(cert_chain_size);
63 2 : if (cert_chain == NULL) {
64 0 : free(file_data);
65 0 : return false;
66 : }
67 2 : cert_chain->length = (uint32_t)cert_chain_size;
68 :
69 : /* Get Root Certificate and calculate hash value*/
70 :
71 2 : res = libspdm_x509_get_cert_from_cert_chain(file_data, file_size, 0, &root_cert,
72 : &root_cert_len);
73 2 : if (!res) {
74 0 : free(file_data);
75 0 : free(cert_chain);
76 0 : return res;
77 : }
78 :
79 2 : libspdm_hash_all(base_hash_algo, root_cert, root_cert_len,
80 2 : (uint8_t *)(cert_chain + 1));
81 2 : libspdm_copy_mem((uint8_t *)cert_chain + sizeof(spdm_cert_chain_t) + digest_size,
82 2 : cert_chain_size - (sizeof(spdm_cert_chain_t) + digest_size),
83 : file_data, file_size);
84 :
85 2 : *data = cert_chain;
86 2 : *size = cert_chain_size;
87 2 : if (hash != NULL) {
88 1 : *hash = (cert_chain + 1);
89 : }
90 2 : if (hash_size != NULL) {
91 1 : *hash_size = digest_size;
92 : }
93 :
94 2 : free(file_data);
95 2 : return true;
96 : }
97 :
98 1469 : libspdm_return_t libspdm_requester_get_certificate_test_send_message(
99 : void *spdm_context, size_t request_size, const void *request,
100 : uint64_t timeout)
101 : {
102 : libspdm_test_context_t *spdm_test_context;
103 :
104 1469 : spdm_test_context = libspdm_get_test_context();
105 1469 : switch (spdm_test_context->case_id) {
106 1 : case 0x1:
107 1 : return LIBSPDM_STATUS_SEND_FAIL;
108 2 : case 0x2:
109 2 : return LIBSPDM_STATUS_SUCCESS;
110 0 : case 0x3:
111 0 : return LIBSPDM_STATUS_SUCCESS;
112 1 : case 0x4:
113 1 : return LIBSPDM_STATUS_SUCCESS;
114 1 : case 0x5:
115 1 : return LIBSPDM_STATUS_SUCCESS;
116 3 : case 0x6:
117 3 : return LIBSPDM_STATUS_SUCCESS;
118 1 : case 0x7:
119 1 : return LIBSPDM_STATUS_SUCCESS;
120 2 : case 0x8:
121 2 : return LIBSPDM_STATUS_SUCCESS;
122 3 : case 0x9:
123 3 : return LIBSPDM_STATUS_SUCCESS;
124 2 : case 0xA:
125 2 : return LIBSPDM_STATUS_SUCCESS;
126 2 : case 0xB:
127 2 : return LIBSPDM_STATUS_SUCCESS;
128 2 : case 0xC:
129 2 : return LIBSPDM_STATUS_SUCCESS;
130 1 : case 0xD:
131 1 : return LIBSPDM_STATUS_SUCCESS;
132 1390 : case 0xE:
133 1390 : return LIBSPDM_STATUS_SUCCESS;
134 2 : case 0xF:
135 2 : return LIBSPDM_STATUS_SUCCESS;
136 18 : case 0x10:
137 18 : return LIBSPDM_STATUS_SUCCESS;
138 1 : case 0x11:
139 1 : return LIBSPDM_STATUS_SUCCESS;
140 1 : case 0x12:
141 1 : return LIBSPDM_STATUS_SUCCESS;
142 4 : case 0x13:
143 4 : return LIBSPDM_STATUS_SUCCESS;
144 1 : case 0x14:
145 1 : return LIBSPDM_STATUS_SUCCESS;
146 1 : case 0x15:
147 1 : return LIBSPDM_STATUS_SUCCESS;
148 2 : case 0x16:
149 2 : return LIBSPDM_STATUS_SUCCESS;
150 2 : case 0x17: {
151 : static uint16_t req_cnt = 0;
152 2 : const uint8_t *ptr = (const uint8_t *)request;
153 :
154 2 : if(req_cnt == 0) {
155 1 : m_libspdm_local_buffer_size = 0;
156 : }
157 2 : libspdm_copy_mem(&m_libspdm_local_buffer[m_libspdm_local_buffer_size],
158 : sizeof(m_libspdm_local_buffer) - m_libspdm_local_buffer_size,
159 2 : &ptr[1], request_size - 1);
160 2 : m_libspdm_local_buffer_size += (request_size - 1);
161 :
162 2 : req_cnt++;
163 : }
164 2 : return LIBSPDM_STATUS_SUCCESS;
165 2 : case 0x18:
166 2 : return LIBSPDM_STATUS_SUCCESS;
167 6 : case 0x19: {
168 : const uint8_t *ptr;
169 :
170 6 : ptr = (const uint8_t *)request;
171 6 : m_libspdm_local_buffer_size = 0;
172 6 : libspdm_copy_mem(m_libspdm_local_buffer, sizeof(m_libspdm_local_buffer), &ptr[1],
173 : request_size - 1);
174 6 : m_libspdm_local_buffer_size += (request_size - 1);
175 : }
176 6 : return LIBSPDM_STATUS_SUCCESS;
177 2 : case 0x1A:
178 2 : return LIBSPDM_STATUS_SUCCESS;
179 1 : case 0x1B:
180 1 : return LIBSPDM_STATUS_SUCCESS;
181 2 : case 0x1C:
182 2 : return LIBSPDM_STATUS_SUCCESS;
183 13 : case 0x1D:
184 : case 0x1E:
185 : case 0x1F:
186 13 : return LIBSPDM_STATUS_SUCCESS;
187 0 : default:
188 0 : return LIBSPDM_STATUS_SEND_FAIL;
189 : }
190 : }
191 :
192 1468 : libspdm_return_t libspdm_requester_get_certificate_test_receive_message(
193 : void *spdm_context, size_t *response_size,
194 : void **response, uint64_t timeout)
195 : {
196 : libspdm_test_context_t *spdm_test_context;
197 :
198 1468 : spdm_test_context = libspdm_get_test_context();
199 1468 : switch (spdm_test_context->case_id) {
200 0 : case 0x1:
201 0 : return LIBSPDM_STATUS_RECEIVE_FAIL;
202 :
203 2 : case 0x2: {
204 : spdm_certificate_response_t *spdm_response;
205 : size_t spdm_response_size;
206 : size_t transport_header_size;
207 : uint16_t portion_length;
208 : uint16_t remainder_length;
209 : size_t count;
210 : static size_t calling_index = 0;
211 :
212 2 : if (m_libspdm_local_certificate_chain == NULL) {
213 1 : libspdm_read_responder_public_certificate_chain(
214 : m_libspdm_use_hash_algo, m_libspdm_use_asym_algo,
215 : &m_libspdm_local_certificate_chain,
216 : &m_libspdm_local_certificate_chain_size, NULL, NULL);
217 : }
218 2 : if (m_libspdm_local_certificate_chain == NULL) {
219 0 : return LIBSPDM_STATUS_RECEIVE_FAIL;
220 : }
221 2 : count = (m_libspdm_local_certificate_chain_size +
222 2 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN - 1) /
223 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
224 2 : if (calling_index != count - 1) {
225 1 : portion_length = LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
226 1 : remainder_length =
227 1 : (uint16_t)(m_libspdm_local_certificate_chain_size -
228 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN *
229 1 : (calling_index + 1));
230 : } else {
231 1 : portion_length = (uint16_t)(
232 : m_libspdm_local_certificate_chain_size -
233 1 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * (count - 1));
234 1 : remainder_length = 0;
235 : }
236 :
237 2 : spdm_response_size =
238 2 : sizeof(spdm_certificate_response_t) + portion_length;
239 2 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
240 2 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
241 :
242 2 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_10;
243 2 : spdm_response->header.request_response_code = SPDM_CERTIFICATE;
244 2 : spdm_response->header.param1 = 0;
245 2 : spdm_response->header.param2 = 0;
246 2 : spdm_response->portion_length = portion_length;
247 2 : spdm_response->remainder_length = remainder_length;
248 2 : libspdm_copy_mem(spdm_response + 1,
249 2 : (size_t)(*response) + *response_size - (size_t)(spdm_response + 1),
250 2 : (uint8_t *)m_libspdm_local_certificate_chain +
251 2 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * calling_index,
252 : portion_length);
253 :
254 2 : libspdm_transport_test_encode_message(spdm_context, NULL, false,
255 : false, spdm_response_size,
256 : spdm_response, response_size,
257 : response);
258 :
259 2 : calling_index++;
260 2 : if (calling_index == count) {
261 1 : calling_index = 0;
262 1 : free(m_libspdm_local_certificate_chain);
263 1 : m_libspdm_local_certificate_chain = NULL;
264 1 : m_libspdm_local_certificate_chain_size = 0;
265 : }
266 : }
267 2 : return LIBSPDM_STATUS_SUCCESS;
268 :
269 0 : case 0x3: {
270 : spdm_certificate_response_t *spdm_response;
271 : size_t spdm_response_size;
272 : size_t transport_header_size;
273 : uint16_t portion_length;
274 : uint16_t remainder_length;
275 : size_t count;
276 : static size_t calling_index = 0;
277 :
278 0 : if (m_libspdm_local_certificate_chain == NULL) {
279 0 : libspdm_read_responder_public_certificate_chain(
280 : m_libspdm_use_hash_algo, m_libspdm_use_asym_algo,
281 : &m_libspdm_local_certificate_chain,
282 : &m_libspdm_local_certificate_chain_size, NULL, NULL);
283 : }
284 0 : if (m_libspdm_local_certificate_chain == NULL) {
285 0 : return LIBSPDM_STATUS_RECEIVE_FAIL;
286 : }
287 0 : count = (m_libspdm_local_certificate_chain_size +
288 0 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN - 1) /
289 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
290 0 : if (calling_index != count - 1) {
291 0 : portion_length = LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
292 0 : remainder_length =
293 0 : (uint16_t)(m_libspdm_local_certificate_chain_size -
294 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN *
295 0 : (calling_index + 1));
296 : } else {
297 0 : portion_length = (uint16_t)(
298 : m_libspdm_local_certificate_chain_size -
299 0 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * (count - 1));
300 0 : remainder_length = 0;
301 : }
302 :
303 0 : spdm_response_size =
304 0 : sizeof(spdm_certificate_response_t) + portion_length;
305 0 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
306 0 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
307 :
308 0 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_10;
309 0 : spdm_response->header.request_response_code = SPDM_CERTIFICATE;
310 0 : spdm_response->header.param1 = 0;
311 0 : spdm_response->header.param2 = 0;
312 0 : spdm_response->portion_length = portion_length;
313 0 : spdm_response->remainder_length = remainder_length;
314 0 : libspdm_copy_mem(spdm_response + 1,
315 0 : (size_t)(*response) + *response_size - (size_t)(spdm_response + 1),
316 0 : (uint8_t *)m_libspdm_local_certificate_chain +
317 0 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * calling_index,
318 : portion_length);
319 :
320 0 : libspdm_transport_test_encode_message(spdm_context, NULL, false,
321 : false, spdm_response_size,
322 : spdm_response, response_size,
323 : response);
324 :
325 0 : calling_index++;
326 0 : if (calling_index == count) {
327 0 : calling_index = 0;
328 0 : free(m_libspdm_local_certificate_chain);
329 0 : m_libspdm_local_certificate_chain = NULL;
330 0 : m_libspdm_local_certificate_chain_size = 0;
331 : }
332 : }
333 0 : return LIBSPDM_STATUS_SUCCESS;
334 :
335 1 : case 0x4: {
336 : spdm_error_response_t *spdm_response;
337 : size_t spdm_response_size;
338 : size_t transport_header_size;
339 :
340 1 : spdm_response_size = sizeof(spdm_error_response_t);
341 1 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
342 1 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
343 :
344 1 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_10;
345 1 : spdm_response->header.request_response_code = SPDM_ERROR;
346 1 : spdm_response->header.param1 = SPDM_ERROR_CODE_INVALID_REQUEST;
347 1 : spdm_response->header.param2 = 0;
348 :
349 1 : libspdm_transport_test_encode_message(spdm_context, NULL, false,
350 : false, spdm_response_size,
351 : spdm_response,
352 : response_size, response);
353 : }
354 1 : return LIBSPDM_STATUS_SUCCESS;
355 :
356 1 : case 0x5: {
357 : spdm_error_response_t *spdm_response;
358 : size_t spdm_response_size;
359 : size_t transport_header_size;
360 :
361 1 : spdm_response_size = sizeof(spdm_error_response_t);
362 1 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
363 1 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
364 :
365 1 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_10;
366 1 : spdm_response->header.request_response_code = SPDM_ERROR;
367 1 : spdm_response->header.param1 = SPDM_ERROR_CODE_BUSY;
368 1 : spdm_response->header.param2 = 0;
369 :
370 1 : libspdm_transport_test_encode_message(spdm_context, NULL, false,
371 : false, spdm_response_size,
372 : spdm_response,
373 : response_size, response);
374 : }
375 1 : return LIBSPDM_STATUS_SUCCESS;
376 :
377 3 : case 0x6: {
378 : static size_t sub_index1 = 0;
379 3 : if (sub_index1 == 0) {
380 : spdm_error_response_t *spdm_response;
381 : size_t spdm_response_size;
382 : size_t transport_header_size;
383 :
384 1 : spdm_response_size = sizeof(spdm_error_response_t);
385 1 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
386 1 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
387 :
388 1 : spdm_response->header.spdm_version =
389 : SPDM_MESSAGE_VERSION_10;
390 1 : spdm_response->header.request_response_code = SPDM_ERROR;
391 1 : spdm_response->header.param1 = SPDM_ERROR_CODE_BUSY;
392 1 : spdm_response->header.param2 = 0;
393 1 : sub_index1++;
394 :
395 1 : libspdm_transport_test_encode_message(
396 : spdm_context, NULL, false, false,
397 : spdm_response_size, spdm_response,
398 : response_size, response);
399 2 : } else if (sub_index1 == 1) {
400 : spdm_certificate_response_t *spdm_response;
401 : size_t spdm_response_size;
402 : size_t transport_header_size;
403 : uint16_t portion_length;
404 : uint16_t remainder_length;
405 : size_t count;
406 : static size_t calling_index = 0;
407 :
408 2 : if (m_libspdm_local_certificate_chain == NULL) {
409 1 : libspdm_read_responder_public_certificate_chain(
410 : m_libspdm_use_hash_algo, m_libspdm_use_asym_algo,
411 : &m_libspdm_local_certificate_chain,
412 : &m_libspdm_local_certificate_chain_size, NULL,
413 : NULL);
414 : }
415 2 : if (m_libspdm_local_certificate_chain == NULL) {
416 0 : return LIBSPDM_STATUS_RECEIVE_FAIL;
417 : }
418 2 : count = (m_libspdm_local_certificate_chain_size +
419 2 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN - 1) /
420 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
421 2 : if (calling_index != count - 1) {
422 1 : portion_length = LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
423 1 : remainder_length = (uint16_t)(
424 : m_libspdm_local_certificate_chain_size -
425 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN *
426 1 : (calling_index + 1));
427 : } else {
428 1 : portion_length = (uint16_t)(
429 : m_libspdm_local_certificate_chain_size -
430 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN *
431 1 : (count - 1));
432 1 : remainder_length = 0;
433 : }
434 :
435 2 : spdm_response_size = sizeof(spdm_certificate_response_t) +
436 : portion_length;
437 2 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
438 2 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
439 :
440 2 : spdm_response->header.spdm_version =
441 : SPDM_MESSAGE_VERSION_10;
442 2 : spdm_response->header.request_response_code =
443 : SPDM_CERTIFICATE;
444 2 : spdm_response->header.param1 = 0;
445 2 : spdm_response->header.param2 = 0;
446 2 : spdm_response->portion_length = portion_length;
447 2 : spdm_response->remainder_length = remainder_length;
448 2 : libspdm_copy_mem(spdm_response + 1,
449 2 : (size_t)(*response) + *response_size - (size_t)(spdm_response + 1),
450 2 : (uint8_t *)m_libspdm_local_certificate_chain +
451 2 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN *
452 : calling_index,
453 : portion_length);
454 :
455 2 : libspdm_transport_test_encode_message(
456 : spdm_context, NULL, false, false, spdm_response_size,
457 : spdm_response, response_size, response);
458 :
459 2 : calling_index++;
460 2 : if (calling_index == count) {
461 1 : calling_index = 0;
462 1 : free(m_libspdm_local_certificate_chain);
463 1 : m_libspdm_local_certificate_chain = NULL;
464 1 : m_libspdm_local_certificate_chain_size = 0;
465 : }
466 : }
467 : }
468 3 : return LIBSPDM_STATUS_SUCCESS;
469 :
470 1 : case 0x7: {
471 : spdm_error_response_t *spdm_response;
472 : size_t spdm_response_size;
473 : size_t transport_header_size;
474 :
475 1 : spdm_response_size = sizeof(spdm_error_response_t);
476 1 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
477 1 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
478 :
479 1 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_10;
480 1 : spdm_response->header.request_response_code = SPDM_ERROR;
481 1 : spdm_response->header.param1 = SPDM_ERROR_CODE_REQUEST_RESYNCH;
482 1 : spdm_response->header.param2 = 0;
483 :
484 1 : libspdm_transport_test_encode_message(spdm_context, NULL, false,
485 : false, spdm_response_size,
486 : spdm_response,
487 : response_size, response);
488 : }
489 1 : return LIBSPDM_STATUS_SUCCESS;
490 :
491 2 : case 0x8: {
492 : spdm_error_response_data_response_not_ready_t *spdm_response;
493 : size_t spdm_response_size;
494 : size_t transport_header_size;
495 :
496 2 : spdm_response_size = sizeof(spdm_error_response_data_response_not_ready_t);
497 2 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
498 2 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
499 :
500 2 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_10;
501 2 : spdm_response->header.request_response_code = SPDM_ERROR;
502 2 : spdm_response->header.param1 =
503 : SPDM_ERROR_CODE_RESPONSE_NOT_READY;
504 2 : spdm_response->header.param2 = 0;
505 2 : spdm_response->extend_error_data.rd_exponent = 1;
506 2 : spdm_response->extend_error_data.rd_tm = 2;
507 2 : spdm_response->extend_error_data.request_code =
508 : SPDM_GET_CERTIFICATE;
509 2 : spdm_response->extend_error_data.token = 0;
510 :
511 2 : libspdm_transport_test_encode_message(spdm_context, NULL, false,
512 : false, spdm_response_size,
513 : spdm_response,
514 : response_size, response);
515 : }
516 2 : return LIBSPDM_STATUS_SUCCESS;
517 :
518 3 : case 0x9: {
519 : static size_t sub_index2 = 0;
520 3 : if (sub_index2 == 0) {
521 : spdm_error_response_data_response_not_ready_t
522 : *spdm_response;
523 : size_t spdm_response_size;
524 : size_t transport_header_size;
525 :
526 1 : spdm_response_size = sizeof(spdm_error_response_data_response_not_ready_t);
527 1 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
528 1 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
529 :
530 1 : spdm_response->header.spdm_version =
531 : SPDM_MESSAGE_VERSION_10;
532 1 : spdm_response->header.request_response_code = SPDM_ERROR;
533 1 : spdm_response->header.param1 =
534 : SPDM_ERROR_CODE_RESPONSE_NOT_READY;
535 1 : spdm_response->header.param2 = 0;
536 1 : spdm_response->extend_error_data.rd_exponent = 1;
537 1 : spdm_response->extend_error_data.rd_tm = 2;
538 1 : spdm_response->extend_error_data.request_code =
539 : SPDM_GET_CERTIFICATE;
540 1 : spdm_response->extend_error_data.token = 1;
541 1 : sub_index2++;
542 :
543 1 : libspdm_transport_test_encode_message(
544 : spdm_context, NULL, false, false,
545 : spdm_response_size, spdm_response,
546 : response_size, response);
547 2 : } else if (sub_index2 == 1) {
548 : spdm_certificate_response_t *spdm_response;
549 : size_t spdm_response_size;
550 : size_t transport_header_size;
551 : uint16_t portion_length;
552 : uint16_t remainder_length;
553 : size_t count;
554 : static size_t calling_index = 0;
555 :
556 2 : if (m_libspdm_local_certificate_chain == NULL) {
557 1 : libspdm_read_responder_public_certificate_chain(
558 : m_libspdm_use_hash_algo, m_libspdm_use_asym_algo,
559 : &m_libspdm_local_certificate_chain,
560 : &m_libspdm_local_certificate_chain_size, NULL,
561 : NULL);
562 : }
563 2 : if (m_libspdm_local_certificate_chain == NULL) {
564 0 : return LIBSPDM_STATUS_RECEIVE_FAIL;
565 : }
566 2 : count = (m_libspdm_local_certificate_chain_size +
567 2 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN - 1) /
568 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
569 2 : if (calling_index != count - 1) {
570 1 : portion_length = LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
571 1 : remainder_length = (uint16_t)(
572 : m_libspdm_local_certificate_chain_size -
573 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN *
574 1 : (calling_index + 1));
575 : } else {
576 1 : portion_length = (uint16_t)(
577 : m_libspdm_local_certificate_chain_size -
578 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN *
579 1 : (count - 1));
580 1 : remainder_length = 0;
581 : }
582 :
583 2 : spdm_response_size = sizeof(spdm_certificate_response_t) +
584 : portion_length;
585 2 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
586 2 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
587 :
588 2 : spdm_response->header.spdm_version =
589 : SPDM_MESSAGE_VERSION_10;
590 2 : spdm_response->header.request_response_code =
591 : SPDM_CERTIFICATE;
592 2 : spdm_response->header.param1 = 0;
593 2 : spdm_response->header.param2 = 0;
594 2 : spdm_response->portion_length = portion_length;
595 2 : spdm_response->remainder_length = remainder_length;
596 2 : libspdm_copy_mem(spdm_response + 1,
597 2 : (size_t)(*response) + *response_size - (size_t)(spdm_response + 1),
598 2 : (uint8_t *)m_libspdm_local_certificate_chain +
599 2 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN *
600 : calling_index,
601 : portion_length);
602 :
603 2 : libspdm_transport_test_encode_message(
604 : spdm_context, NULL, false, false, spdm_response_size,
605 : spdm_response, response_size, response);
606 :
607 2 : calling_index++;
608 2 : if (calling_index == count) {
609 1 : calling_index = 0;
610 1 : free(m_libspdm_local_certificate_chain);
611 1 : m_libspdm_local_certificate_chain = NULL;
612 1 : m_libspdm_local_certificate_chain_size = 0;
613 : }
614 : }
615 : }
616 3 : return LIBSPDM_STATUS_SUCCESS;
617 :
618 2 : case 0xA: {
619 : spdm_certificate_response_t *spdm_response;
620 : size_t spdm_response_size;
621 : size_t transport_header_size;
622 : uint16_t portion_length;
623 : uint16_t remainder_length;
624 : size_t count;
625 : static size_t calling_index = 0;
626 :
627 2 : if (m_libspdm_local_certificate_chain == NULL) {
628 1 : libspdm_read_responder_public_certificate_chain(
629 : m_libspdm_use_hash_algo, m_libspdm_use_asym_algo,
630 : &m_libspdm_local_certificate_chain,
631 : &m_libspdm_local_certificate_chain_size, NULL, NULL);
632 : }
633 2 : if (m_libspdm_local_certificate_chain == NULL) {
634 0 : return LIBSPDM_STATUS_RECEIVE_FAIL;
635 : }
636 2 : count = (m_libspdm_local_certificate_chain_size +
637 2 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN - 1) /
638 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
639 2 : if (calling_index != count - 1) {
640 1 : portion_length = LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
641 1 : remainder_length =
642 1 : (uint16_t)(m_libspdm_local_certificate_chain_size -
643 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN *
644 1 : (calling_index + 1));
645 : } else {
646 1 : portion_length = (uint16_t)(
647 : m_libspdm_local_certificate_chain_size -
648 1 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * (count - 1));
649 1 : remainder_length = 0;
650 : }
651 :
652 2 : spdm_response_size =
653 2 : sizeof(spdm_certificate_response_t) + portion_length;
654 2 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
655 2 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
656 :
657 2 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_10;
658 2 : spdm_response->header.request_response_code = SPDM_CERTIFICATE;
659 2 : spdm_response->header.param1 = 0;
660 2 : spdm_response->header.param2 = 0;
661 2 : spdm_response->portion_length = portion_length;
662 2 : spdm_response->remainder_length = remainder_length;
663 2 : libspdm_copy_mem(spdm_response + 1,
664 2 : (size_t)(*response) + *response_size - (size_t)(spdm_response + 1),
665 2 : (uint8_t *)m_libspdm_local_certificate_chain +
666 2 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * calling_index,
667 : portion_length);
668 :
669 2 : libspdm_transport_test_encode_message(spdm_context, NULL, false,
670 : false, spdm_response_size,
671 : spdm_response, response_size,
672 : response);
673 :
674 2 : calling_index++;
675 2 : if (calling_index == count) {
676 1 : calling_index = 0;
677 1 : free(m_libspdm_local_certificate_chain);
678 1 : m_libspdm_local_certificate_chain = NULL;
679 1 : m_libspdm_local_certificate_chain_size = 0;
680 : }
681 : }
682 2 : return LIBSPDM_STATUS_SUCCESS;
683 :
684 2 : case 0xB: {
685 : spdm_certificate_response_t *spdm_response;
686 : size_t spdm_response_size;
687 : size_t transport_header_size;
688 : uint16_t portion_length;
689 : uint16_t remainder_length;
690 : size_t count;
691 : static size_t calling_index = 0;
692 :
693 : const uint8_t *leaf_cert_buffer;
694 : size_t leaf_cert_buffer_size;
695 : uint8_t *cert_buffer;
696 : size_t cert_buffer_size;
697 : size_t hash_size;
698 :
699 2 : if (m_libspdm_local_certificate_chain == NULL) {
700 1 : libspdm_read_responder_public_certificate_chain(
701 : m_libspdm_use_hash_algo, m_libspdm_use_asym_algo,
702 : &m_libspdm_local_certificate_chain,
703 : &m_libspdm_local_certificate_chain_size, NULL, NULL);
704 1 : if (m_libspdm_local_certificate_chain == NULL) {
705 0 : return LIBSPDM_STATUS_RECEIVE_FAIL;
706 : }
707 :
708 : /* load certificate*/
709 1 : hash_size = libspdm_get_hash_size(m_libspdm_use_hash_algo);
710 1 : cert_buffer = (uint8_t *)m_libspdm_local_certificate_chain +
711 1 : sizeof(spdm_cert_chain_t) + hash_size;
712 1 : cert_buffer_size = m_libspdm_local_certificate_chain_size -
713 1 : sizeof(spdm_cert_chain_t) -
714 : hash_size;
715 1 : if (!libspdm_x509_get_cert_from_cert_chain(
716 : cert_buffer, cert_buffer_size, -1,
717 : &leaf_cert_buffer,
718 : &leaf_cert_buffer_size)) {
719 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO,
720 : "!!! VerifyCertificateChain - FAIL (get leaf certificate failed)!!!\n"));
721 0 : return LIBSPDM_STATUS_RECEIVE_FAIL;
722 : }
723 : /* tamper certificate signature on purpose
724 : * arbitrarily change the last byte of the certificate signature*/
725 1 : cert_buffer[cert_buffer_size - 1]++;
726 : }
727 2 : count = (m_libspdm_local_certificate_chain_size +
728 2 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN - 1) /
729 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
730 2 : if (calling_index != count - 1) {
731 1 : portion_length = LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
732 1 : remainder_length =
733 1 : (uint16_t)(m_libspdm_local_certificate_chain_size -
734 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN *
735 1 : (calling_index + 1));
736 : } else {
737 1 : portion_length = (uint16_t)(
738 : m_libspdm_local_certificate_chain_size -
739 1 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * (count - 1));
740 1 : remainder_length = 0;
741 : }
742 :
743 2 : spdm_response_size =
744 2 : sizeof(spdm_certificate_response_t) + portion_length;
745 2 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
746 2 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
747 :
748 2 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_10;
749 2 : spdm_response->header.request_response_code = SPDM_CERTIFICATE;
750 2 : spdm_response->header.param1 = 0;
751 2 : spdm_response->header.param2 = 0;
752 2 : spdm_response->portion_length = portion_length;
753 2 : spdm_response->remainder_length = remainder_length;
754 2 : libspdm_copy_mem(spdm_response + 1,
755 2 : (size_t)(*response) + *response_size - (size_t)(spdm_response + 1),
756 2 : (uint8_t *)m_libspdm_local_certificate_chain +
757 2 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * calling_index,
758 : portion_length);
759 :
760 2 : libspdm_transport_test_encode_message(spdm_context, NULL, false,
761 : false, spdm_response_size,
762 : spdm_response, response_size,
763 : response);
764 :
765 2 : calling_index++;
766 2 : if (calling_index == count) {
767 1 : calling_index = 0;
768 1 : free(m_libspdm_local_certificate_chain);
769 1 : m_libspdm_local_certificate_chain = NULL;
770 1 : m_libspdm_local_certificate_chain_size = 0;
771 : }
772 : }
773 2 : return LIBSPDM_STATUS_SUCCESS;
774 :
775 2 : case 0xC: {
776 : spdm_certificate_response_t *spdm_response;
777 : size_t spdm_response_size;
778 : size_t transport_header_size;
779 : uint16_t portion_length;
780 : uint16_t remainder_length;
781 : size_t count;
782 : static size_t calling_index = 0;
783 :
784 2 : if (m_libspdm_local_certificate_chain == NULL) {
785 1 : libspdm_read_responder_public_certificate_chain(
786 : m_libspdm_use_hash_algo, m_libspdm_use_asym_algo,
787 : &m_libspdm_local_certificate_chain,
788 : &m_libspdm_local_certificate_chain_size, NULL, NULL);
789 : }
790 2 : if (m_libspdm_local_certificate_chain == NULL) {
791 0 : return LIBSPDM_STATUS_RECEIVE_FAIL;
792 : }
793 2 : count = (m_libspdm_local_certificate_chain_size +
794 2 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN - 1) /
795 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
796 2 : if (calling_index != count - 1) {
797 1 : portion_length = LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
798 1 : remainder_length =
799 1 : (uint16_t)(m_libspdm_local_certificate_chain_size -
800 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN *
801 1 : (calling_index + 1));
802 : } else {
803 1 : portion_length = (uint16_t)(
804 : m_libspdm_local_certificate_chain_size -
805 1 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * (count - 1));
806 1 : remainder_length = 0;
807 : }
808 :
809 2 : spdm_response_size =
810 2 : sizeof(spdm_certificate_response_t) + portion_length;
811 2 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
812 2 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
813 :
814 2 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_10;
815 2 : spdm_response->header.request_response_code = SPDM_CERTIFICATE;
816 2 : spdm_response->header.param1 = 0;
817 2 : spdm_response->header.param2 = 0;
818 2 : spdm_response->portion_length = portion_length;
819 2 : spdm_response->remainder_length = remainder_length;
820 2 : libspdm_copy_mem(spdm_response + 1,
821 2 : (size_t)(*response) + *response_size - (size_t)(spdm_response + 1),
822 2 : (uint8_t *)m_libspdm_local_certificate_chain +
823 2 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * calling_index,
824 : portion_length);
825 :
826 2 : libspdm_transport_test_encode_message(spdm_context, NULL, false,
827 : false, spdm_response_size,
828 : spdm_response, response_size,
829 : response);
830 :
831 2 : calling_index++;
832 2 : if (calling_index == count) {
833 1 : calling_index = 0;
834 1 : free(m_libspdm_local_certificate_chain);
835 1 : m_libspdm_local_certificate_chain = NULL;
836 1 : m_libspdm_local_certificate_chain_size = 0;
837 : }
838 : }
839 2 : return LIBSPDM_STATUS_SUCCESS;
840 :
841 1 : case 0xD: {
842 : spdm_certificate_response_t *spdm_response;
843 : size_t spdm_response_size;
844 : size_t transport_header_size;
845 : uint16_t portion_length;
846 : uint16_t remainder_length;
847 : size_t count;
848 : static size_t calling_index = 0;
849 :
850 1 : if (m_libspdm_local_certificate_chain == NULL) {
851 1 : libspdm_read_responder_public_certificate_chain_by_size(
852 : m_libspdm_use_hash_algo, m_libspdm_use_asym_algo,
853 : LIBSPDM_TEST_CERT_SMALL, &m_libspdm_local_certificate_chain,
854 : &m_libspdm_local_certificate_chain_size, NULL, NULL);
855 : }
856 1 : if (m_libspdm_local_certificate_chain == NULL) {
857 0 : return LIBSPDM_STATUS_RECEIVE_FAIL;
858 : }
859 1 : count = (m_libspdm_local_certificate_chain_size +
860 1 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN - 1) /
861 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
862 1 : if (calling_index != count - 1) {
863 0 : portion_length = LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
864 0 : remainder_length =
865 0 : (uint16_t)(m_libspdm_local_certificate_chain_size -
866 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN *
867 0 : (calling_index + 1));
868 : } else {
869 1 : portion_length = (uint16_t)(
870 : m_libspdm_local_certificate_chain_size -
871 1 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * (count - 1));
872 1 : remainder_length = 0;
873 : }
874 :
875 1 : spdm_response_size =
876 1 : sizeof(spdm_certificate_response_t) + portion_length;
877 1 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
878 1 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
879 :
880 1 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_10;
881 1 : spdm_response->header.request_response_code = SPDM_CERTIFICATE;
882 1 : spdm_response->header.param1 = 0;
883 1 : spdm_response->header.param2 = 0;
884 1 : spdm_response->portion_length = portion_length;
885 1 : spdm_response->remainder_length = remainder_length;
886 1 : libspdm_copy_mem(spdm_response + 1,
887 1 : (size_t)(*response) + *response_size - (size_t)(spdm_response + 1),
888 1 : (uint8_t *)m_libspdm_local_certificate_chain +
889 1 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * calling_index,
890 : portion_length);
891 :
892 1 : libspdm_transport_test_encode_message(spdm_context, NULL, false,
893 : false, spdm_response_size,
894 : spdm_response, response_size,
895 : response);
896 :
897 1 : calling_index++;
898 1 : if (calling_index == count) {
899 1 : calling_index = 0;
900 1 : free(m_libspdm_local_certificate_chain);
901 1 : m_libspdm_local_certificate_chain = NULL;
902 1 : m_libspdm_local_certificate_chain_size = 0;
903 : }
904 : }
905 1 : return LIBSPDM_STATUS_SUCCESS;
906 :
907 1390 : case 0xE: {
908 : spdm_certificate_response_t *spdm_response;
909 : size_t spdm_response_size;
910 : size_t transport_header_size;
911 : uint16_t portion_length;
912 : uint16_t remainder_length;
913 : uint16_t get_cert_length;
914 : size_t count;
915 : static size_t calling_index = 0;
916 :
917 : /* this should match the value on the test function*/
918 1390 : get_cert_length = 1;
919 :
920 1390 : if (m_libspdm_local_certificate_chain == NULL) {
921 1 : libspdm_read_responder_public_certificate_chain(
922 : m_libspdm_use_hash_algo, m_libspdm_use_asym_algo,
923 : &m_libspdm_local_certificate_chain,
924 : &m_libspdm_local_certificate_chain_size, NULL, NULL);
925 : }
926 1390 : if (m_libspdm_local_certificate_chain == NULL) {
927 0 : return LIBSPDM_STATUS_RECEIVE_FAIL;
928 : }
929 1390 : count = (m_libspdm_local_certificate_chain_size + get_cert_length + 1) /
930 : get_cert_length;
931 1390 : if (calling_index != count - 1) {
932 1390 : portion_length = get_cert_length;
933 1390 : remainder_length =
934 1390 : (uint16_t)(m_libspdm_local_certificate_chain_size -
935 1390 : get_cert_length * (calling_index + 1));
936 : } else {
937 0 : portion_length =
938 0 : (uint16_t)(m_libspdm_local_certificate_chain_size -
939 0 : get_cert_length * (count - 1));
940 0 : remainder_length = 0;
941 : }
942 :
943 1390 : spdm_response_size =
944 1390 : sizeof(spdm_certificate_response_t) + portion_length;
945 1390 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
946 1390 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
947 :
948 1390 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_10;
949 1390 : spdm_response->header.request_response_code = SPDM_CERTIFICATE;
950 1390 : spdm_response->header.param1 = 0;
951 1390 : spdm_response->header.param2 = 0;
952 1390 : spdm_response->portion_length = portion_length;
953 1390 : spdm_response->remainder_length = remainder_length;
954 1390 : libspdm_copy_mem(spdm_response + 1,
955 1390 : (size_t)(*response) + *response_size - (size_t)(spdm_response + 1),
956 1390 : (uint8_t *)m_libspdm_local_certificate_chain +
957 1390 : get_cert_length * calling_index,
958 : portion_length);
959 :
960 1390 : libspdm_transport_test_encode_message(spdm_context, NULL, false,
961 : false, spdm_response_size,
962 : spdm_response, response_size,
963 : response);
964 :
965 1390 : calling_index++;
966 1390 : if (calling_index == count) {
967 0 : calling_index = 0;
968 0 : free(m_libspdm_local_certificate_chain);
969 0 : m_libspdm_local_certificate_chain = NULL;
970 0 : m_libspdm_local_certificate_chain_size = 0;
971 : }
972 : }
973 1390 : return LIBSPDM_STATUS_SUCCESS;
974 :
975 2 : case 0xF: {
976 : spdm_certificate_response_t *spdm_response;
977 : size_t spdm_response_size;
978 : size_t transport_header_size;
979 : uint16_t portion_length;
980 : uint16_t remainder_length;
981 : size_t count;
982 : static size_t calling_index = 0;
983 :
984 2 : if (m_libspdm_local_certificate_chain == NULL) {
985 0 : libspdm_read_responder_public_certificate_chain_by_size(
986 : m_libspdm_use_hash_algo,
987 : /*MAXUINT16_CERT signature_algo is SHA256RSA */
988 : SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048,
989 : LIBSPDM_TEST_CERT_MAXUINT16, &m_libspdm_local_certificate_chain,
990 : &m_libspdm_local_certificate_chain_size, NULL, NULL);
991 : }
992 2 : if (m_libspdm_local_certificate_chain == NULL) {
993 0 : return LIBSPDM_STATUS_RECEIVE_FAIL;
994 : }
995 2 : count = (m_libspdm_local_certificate_chain_size +
996 2 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN - 1) /
997 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
998 2 : if (calling_index != count - 1) {
999 1 : portion_length = LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
1000 1 : remainder_length =
1001 1 : (uint16_t)(m_libspdm_local_certificate_chain_size -
1002 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN *
1003 1 : (calling_index + 1));
1004 : } else {
1005 1 : portion_length = (uint16_t)(
1006 : m_libspdm_local_certificate_chain_size -
1007 1 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * (count - 1));
1008 1 : remainder_length = 0;
1009 : }
1010 :
1011 2 : spdm_response_size =
1012 2 : sizeof(spdm_certificate_response_t) + portion_length;
1013 2 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
1014 2 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
1015 :
1016 2 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_10;
1017 2 : spdm_response->header.request_response_code = SPDM_CERTIFICATE;
1018 2 : spdm_response->header.param1 = 0;
1019 2 : spdm_response->header.param2 = 0;
1020 2 : spdm_response->portion_length = portion_length;
1021 2 : spdm_response->remainder_length = remainder_length;
1022 2 : libspdm_copy_mem(spdm_response + 1,
1023 2 : (size_t)(*response) + *response_size - (size_t)(spdm_response + 1),
1024 2 : (uint8_t *)m_libspdm_local_certificate_chain +
1025 2 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * calling_index,
1026 : portion_length);
1027 :
1028 2 : libspdm_transport_test_encode_message(spdm_context, NULL, false,
1029 : false, spdm_response_size,
1030 : spdm_response, response_size,
1031 : response);
1032 :
1033 2 : calling_index++;
1034 2 : if (calling_index == count) {
1035 1 : calling_index = 0;
1036 1 : free(m_libspdm_local_certificate_chain);
1037 1 : m_libspdm_local_certificate_chain = NULL;
1038 1 : m_libspdm_local_certificate_chain_size = 0;
1039 : }
1040 : }
1041 2 : return LIBSPDM_STATUS_SUCCESS;
1042 :
1043 18 : case 0x10:
1044 : {
1045 : static uint16_t error_code = LIBSPDM_ERROR_CODE_RESERVED_00;
1046 :
1047 : spdm_error_response_t *spdm_response;
1048 : size_t spdm_response_size;
1049 : size_t transport_header_size;
1050 :
1051 18 : spdm_response_size = sizeof(spdm_error_response_t);
1052 18 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
1053 18 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
1054 :
1055 18 : if(error_code <= 0xff) {
1056 18 : libspdm_zero_mem (spdm_response, spdm_response_size);
1057 18 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_11;
1058 18 : spdm_response->header.request_response_code = SPDM_ERROR;
1059 18 : spdm_response->header.param1 = (uint8_t) error_code;
1060 18 : spdm_response->header.param2 = 0;
1061 :
1062 18 : libspdm_transport_test_encode_message (spdm_context, NULL, false, false,
1063 : spdm_response_size, spdm_response,
1064 : response_size, response);
1065 : }
1066 :
1067 18 : error_code++;
1068 18 : if(error_code == SPDM_ERROR_CODE_BUSY) { /*busy is treated in cases 5 and 6*/
1069 1 : error_code = SPDM_ERROR_CODE_UNEXPECTED_REQUEST;
1070 : }
1071 18 : if(error_code == LIBSPDM_ERROR_CODE_RESERVED_0D) { /*skip some reserved error codes (0d to 3e)*/
1072 1 : error_code = LIBSPDM_ERROR_CODE_RESERVED_3F;
1073 : }
1074 18 : if(error_code == SPDM_ERROR_CODE_RESPONSE_NOT_READY) { /*skip response not ready, request resync, and some reserved codes (44 to fc)*/
1075 1 : error_code = LIBSPDM_ERROR_CODE_RESERVED_FD;
1076 : }
1077 : }
1078 18 : return LIBSPDM_STATUS_SUCCESS;
1079 :
1080 1 : case 0x11: {
1081 : spdm_certificate_response_t *spdm_response;
1082 : size_t spdm_response_size;
1083 : size_t transport_header_size;
1084 : uint16_t portion_length;
1085 : uint16_t remainder_length;
1086 : size_t count;
1087 : static size_t calling_index = 0;
1088 :
1089 : const uint8_t *leaf_cert_buffer;
1090 : size_t leaf_cert_buffer_size;
1091 : uint8_t *cert_buffer;
1092 : size_t cert_buffer_size;
1093 : size_t hash_size;
1094 : uint8_t cert_chain_without_root[LIBSPDM_MAX_CERT_CHAIN_SIZE];
1095 : size_t cert_chain_without_root_size;
1096 : void *root_cert_data;
1097 : size_t root_cert_size;
1098 :
1099 1 : root_cert_size = 0;
1100 1 : cert_buffer_size = 0;
1101 1 : hash_size = 0;
1102 :
1103 1 : if (m_libspdm_local_certificate_chain == NULL) {
1104 1 : libspdm_read_responder_public_certificate_chain(
1105 : m_libspdm_use_hash_algo, m_libspdm_use_asym_algo,
1106 : &m_libspdm_local_certificate_chain,
1107 : &m_libspdm_local_certificate_chain_size, NULL, NULL);
1108 1 : if (m_libspdm_local_certificate_chain == NULL) {
1109 0 : return LIBSPDM_STATUS_RECEIVE_FAIL;
1110 : }
1111 : }
1112 :
1113 : /* read root certificate size*/
1114 1 : libspdm_read_responder_root_public_certificate(
1115 : m_libspdm_use_hash_algo, m_libspdm_use_asym_algo,
1116 : &root_cert_data,
1117 : &root_cert_size, NULL, NULL);
1118 : /* load certificate*/
1119 1 : hash_size = libspdm_get_hash_size(m_libspdm_use_hash_algo);
1120 1 : root_cert_size = root_cert_size - sizeof(spdm_cert_chain_t) - hash_size;
1121 1 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "root_cert_size %zu \n", root_cert_size));
1122 1 : cert_buffer = (uint8_t *)m_libspdm_local_certificate_chain +
1123 1 : sizeof(spdm_cert_chain_t) + hash_size + root_cert_size;
1124 1 : cert_buffer_size = m_libspdm_local_certificate_chain_size -
1125 1 : sizeof(spdm_cert_chain_t) -
1126 1 : hash_size - root_cert_size;
1127 :
1128 1 : if (!libspdm_x509_get_cert_from_cert_chain(
1129 : cert_buffer, cert_buffer_size, -1,
1130 : &leaf_cert_buffer,
1131 : &leaf_cert_buffer_size)) {
1132 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO,
1133 : "!!! VerifyCertificateChain - FAIL (get leaf certificate failed)!!!\n"));
1134 0 : return LIBSPDM_STATUS_RECEIVE_FAIL;
1135 : }
1136 :
1137 1 : libspdm_copy_mem(cert_chain_without_root,
1138 : sizeof(cert_chain_without_root),
1139 : m_libspdm_local_certificate_chain,
1140 : sizeof(spdm_cert_chain_t) + hash_size);
1141 1 : libspdm_copy_mem(cert_chain_without_root + sizeof(spdm_cert_chain_t) + hash_size,
1142 : sizeof(cert_chain_without_root) - (sizeof(spdm_cert_chain_t) + hash_size),
1143 : cert_buffer,
1144 : cert_buffer_size);
1145 1 : cert_chain_without_root_size = m_libspdm_local_certificate_chain_size - root_cert_size;
1146 1 : ((spdm_cert_chain_t *)cert_chain_without_root)->length =
1147 1 : (uint16_t)cert_chain_without_root_size;
1148 1 : count = (cert_chain_without_root_size +
1149 1 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN - 1) /
1150 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
1151 1 : if (calling_index != count - 1) {
1152 0 : portion_length = LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
1153 0 : remainder_length =
1154 0 : (uint16_t)(cert_chain_without_root_size -
1155 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN *
1156 0 : (calling_index + 1));
1157 : } else {
1158 1 : portion_length = (uint16_t)(
1159 : cert_chain_without_root_size -
1160 1 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * (count - 1));
1161 1 : remainder_length = 0;
1162 : }
1163 :
1164 1 : spdm_response_size =
1165 1 : sizeof(spdm_certificate_response_t) + portion_length;
1166 1 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
1167 1 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
1168 :
1169 1 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_10;
1170 1 : spdm_response->header.request_response_code = SPDM_CERTIFICATE;
1171 1 : spdm_response->header.param1 = 0;
1172 1 : spdm_response->header.param2 = 0;
1173 1 : spdm_response->portion_length = portion_length;
1174 1 : spdm_response->remainder_length = remainder_length;
1175 : /* send certchain without root*/
1176 1 : libspdm_copy_mem(spdm_response + 1,
1177 1 : (size_t)(*response) + *response_size - (size_t)(spdm_response + 1),
1178 : (uint8_t *)cert_chain_without_root +
1179 1 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * calling_index,
1180 : portion_length);
1181 :
1182 1 : libspdm_transport_test_encode_message(spdm_context, NULL, false,
1183 : false, spdm_response_size,
1184 : spdm_response, response_size,
1185 : response);
1186 :
1187 1 : calling_index++;
1188 1 : if (calling_index == count) {
1189 1 : calling_index = 0;
1190 1 : free(m_libspdm_local_certificate_chain);
1191 1 : m_libspdm_local_certificate_chain = NULL;
1192 1 : m_libspdm_local_certificate_chain_size = 0;
1193 : }
1194 :
1195 1 : free(root_cert_data);
1196 : }
1197 1 : return LIBSPDM_STATUS_SUCCESS;
1198 :
1199 1 : case 0x12: {
1200 : spdm_certificate_response_t *spdm_response;
1201 : size_t spdm_response_size;
1202 : size_t transport_header_size;
1203 : uint16_t portion_length;
1204 : uint16_t remainder_length;
1205 : size_t count;
1206 : static size_t calling_index = 0;
1207 :
1208 : const uint8_t *leaf_cert_buffer;
1209 : size_t leaf_cert_buffer_size;
1210 : uint8_t *cert_buffer;
1211 : size_t cert_buffer_size;
1212 : size_t hash_size;
1213 : uint8_t cert_chain_without_root[LIBSPDM_MAX_CERT_CHAIN_SIZE];
1214 : size_t cert_chain_without_root_size;
1215 : void *root_cert_data;
1216 : size_t root_cert_size;
1217 :
1218 1 : root_cert_size = 0;
1219 1 : cert_buffer_size = 0;
1220 1 : hash_size = 0;
1221 :
1222 1 : if (m_libspdm_local_certificate_chain == NULL) {
1223 1 : libspdm_read_responder_public_certificate_chain(
1224 : m_libspdm_use_hash_algo, m_libspdm_use_asym_algo,
1225 : &m_libspdm_local_certificate_chain,
1226 : &m_libspdm_local_certificate_chain_size, NULL, NULL);
1227 1 : if (m_libspdm_local_certificate_chain == NULL) {
1228 0 : return LIBSPDM_STATUS_RECEIVE_FAIL;
1229 : }
1230 : }
1231 :
1232 : /* read root certificate size*/
1233 1 : libspdm_read_responder_root_public_certificate(
1234 : m_libspdm_use_hash_algo, m_libspdm_use_asym_algo,
1235 : &root_cert_data,
1236 : &root_cert_size, NULL, NULL);
1237 : /* load certificate*/
1238 1 : hash_size = libspdm_get_hash_size(m_libspdm_use_hash_algo);
1239 1 : root_cert_size = root_cert_size - sizeof(spdm_cert_chain_t) - hash_size;
1240 1 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "root_cert_size %zu \n", root_cert_size));
1241 1 : cert_buffer = (uint8_t *)m_libspdm_local_certificate_chain +
1242 1 : sizeof(spdm_cert_chain_t) + hash_size + root_cert_size;
1243 1 : cert_buffer_size = m_libspdm_local_certificate_chain_size -
1244 1 : sizeof(spdm_cert_chain_t) -
1245 1 : hash_size - root_cert_size;
1246 :
1247 1 : if (!libspdm_x509_get_cert_from_cert_chain(
1248 : cert_buffer, cert_buffer_size, -1,
1249 : &leaf_cert_buffer,
1250 : &leaf_cert_buffer_size)) {
1251 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO,
1252 : "!!! VerifyCertificateChain - FAIL (get leaf certificate failed)!!!\n"));
1253 0 : return LIBSPDM_STATUS_RECEIVE_FAIL;
1254 : }
1255 : /* tamper certificate signature on purpose
1256 : * arbitrarily change the last byte of the certificate signature*/
1257 1 : cert_buffer[cert_buffer_size - 1]++;
1258 :
1259 1 : libspdm_copy_mem(cert_chain_without_root,
1260 : sizeof(cert_chain_without_root),
1261 : m_libspdm_local_certificate_chain,
1262 : sizeof(spdm_cert_chain_t) + hash_size);
1263 1 : libspdm_copy_mem(cert_chain_without_root + sizeof(spdm_cert_chain_t) + hash_size,
1264 : sizeof(cert_chain_without_root) - (sizeof(spdm_cert_chain_t) + hash_size),
1265 : cert_buffer,
1266 : cert_buffer_size);
1267 1 : cert_chain_without_root_size = m_libspdm_local_certificate_chain_size - root_cert_size;
1268 1 : ((spdm_cert_chain_t *)cert_chain_without_root)->length =
1269 1 : (uint16_t)cert_chain_without_root_size;
1270 1 : count = (cert_chain_without_root_size +
1271 1 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN - 1) /
1272 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
1273 1 : if (calling_index != count - 1) {
1274 0 : portion_length = LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
1275 0 : remainder_length =
1276 0 : (uint16_t)(cert_chain_without_root_size -
1277 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN *
1278 0 : (calling_index + 1));
1279 : } else {
1280 1 : portion_length = (uint16_t)(
1281 : cert_chain_without_root_size -
1282 1 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * (count - 1));
1283 1 : remainder_length = 0;
1284 : }
1285 :
1286 1 : spdm_response_size =
1287 1 : sizeof(spdm_certificate_response_t) + portion_length;
1288 1 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
1289 1 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
1290 :
1291 1 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_10;
1292 1 : spdm_response->header.request_response_code = SPDM_CERTIFICATE;
1293 1 : spdm_response->header.param1 = 0;
1294 1 : spdm_response->header.param2 = 0;
1295 1 : spdm_response->portion_length = portion_length;
1296 1 : spdm_response->remainder_length = remainder_length;
1297 : /* send certchain without root*/
1298 1 : libspdm_copy_mem(spdm_response + 1,
1299 1 : (size_t)(*response) + *response_size - (size_t)(spdm_response + 1),
1300 : (uint8_t *)cert_chain_without_root +
1301 1 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * calling_index,
1302 : portion_length);
1303 :
1304 1 : libspdm_transport_test_encode_message(spdm_context, NULL, false,
1305 : false, spdm_response_size,
1306 : spdm_response, response_size,
1307 : response);
1308 :
1309 1 : calling_index++;
1310 1 : if (calling_index == count) {
1311 1 : calling_index = 0;
1312 1 : free(m_libspdm_local_certificate_chain);
1313 1 : m_libspdm_local_certificate_chain = NULL;
1314 1 : m_libspdm_local_certificate_chain_size = 0;
1315 : }
1316 :
1317 1 : free(root_cert_data);
1318 : }
1319 1 : return LIBSPDM_STATUS_SUCCESS;
1320 :
1321 4 : case 0x13: {
1322 : spdm_certificate_response_t *spdm_response;
1323 : size_t spdm_response_size;
1324 : size_t transport_header_size;
1325 : uint16_t portion_length;
1326 : uint16_t remainder_length;
1327 : size_t count;
1328 : static size_t calling_index = 0;
1329 :
1330 4 : if (m_libspdm_local_certificate_chain == NULL) {
1331 1 : libspdm_libspdm_read_responder_public_certificate_chain_expiration(
1332 : &m_libspdm_local_certificate_chain,
1333 : &m_libspdm_local_certificate_chain_size, NULL, NULL);
1334 : }
1335 4 : if (m_libspdm_local_certificate_chain == NULL) {
1336 0 : return LIBSPDM_STATUS_RECEIVE_FAIL;
1337 : }
1338 4 : count = (m_libspdm_local_certificate_chain_size +
1339 4 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN - 1) /
1340 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
1341 4 : if (calling_index != count - 1) {
1342 3 : portion_length = LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
1343 3 : remainder_length =
1344 3 : (uint16_t)(m_libspdm_local_certificate_chain_size -
1345 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN *
1346 3 : (calling_index + 1));
1347 : } else {
1348 1 : portion_length = (uint16_t)(
1349 : m_libspdm_local_certificate_chain_size -
1350 1 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * (count - 1));
1351 1 : remainder_length = 0;
1352 : }
1353 :
1354 4 : spdm_response_size =
1355 4 : sizeof(spdm_certificate_response_t) + portion_length;
1356 4 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
1357 4 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
1358 :
1359 4 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_10;
1360 4 : spdm_response->header.request_response_code = SPDM_CERTIFICATE;
1361 4 : spdm_response->header.param1 = 0;
1362 4 : spdm_response->header.param2 = 0;
1363 4 : spdm_response->portion_length = portion_length;
1364 4 : spdm_response->remainder_length = remainder_length;
1365 4 : libspdm_copy_mem(spdm_response + 1,
1366 4 : (size_t)(*response) + *response_size - (size_t)(spdm_response + 1),
1367 4 : (uint8_t *)m_libspdm_local_certificate_chain +
1368 4 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * calling_index,
1369 : portion_length);
1370 :
1371 4 : libspdm_transport_test_encode_message(spdm_context, NULL, false,
1372 : false, spdm_response_size,
1373 : spdm_response, response_size,
1374 : response);
1375 :
1376 4 : calling_index++;
1377 4 : if (calling_index == count) {
1378 1 : calling_index = 0;
1379 1 : free(m_libspdm_local_certificate_chain);
1380 1 : m_libspdm_local_certificate_chain = NULL;
1381 1 : m_libspdm_local_certificate_chain_size = 0;
1382 : }
1383 : }
1384 4 : return LIBSPDM_STATUS_SUCCESS;
1385 :
1386 1 : case 0x14: {
1387 : spdm_certificate_response_t *spdm_response;
1388 : size_t spdm_response_size;
1389 : size_t transport_header_size;
1390 : uint16_t portion_length;
1391 : uint16_t remainder_length;
1392 : size_t count;
1393 : static size_t calling_index = 0;
1394 :
1395 1 : if (m_libspdm_local_certificate_chain == NULL) {
1396 1 : libspdm_read_responder_public_certificate_chain(
1397 : m_libspdm_use_hash_algo, m_libspdm_use_asym_algo,
1398 : &m_libspdm_local_certificate_chain,
1399 : &m_libspdm_local_certificate_chain_size, NULL, NULL);
1400 : }
1401 1 : if (m_libspdm_local_certificate_chain == NULL) {
1402 0 : return LIBSPDM_STATUS_RECEIVE_FAIL;
1403 : }
1404 1 : count = (m_libspdm_local_certificate_chain_size +
1405 1 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN - 1) /
1406 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
1407 1 : if (calling_index != count - 1) {
1408 1 : portion_length = 0; /* Fail response: responder return portion_length is 0.*/
1409 1 : remainder_length =
1410 1 : (uint16_t)(m_libspdm_local_certificate_chain_size -
1411 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN *
1412 1 : (calling_index + 1));
1413 : } else {
1414 0 : portion_length = (uint16_t)(
1415 : m_libspdm_local_certificate_chain_size -
1416 0 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * (count - 1));
1417 0 : remainder_length = 0;
1418 : }
1419 :
1420 1 : spdm_response_size =
1421 1 : sizeof(spdm_certificate_response_t) + portion_length;
1422 1 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
1423 1 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
1424 :
1425 1 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_10;
1426 1 : spdm_response->header.request_response_code = SPDM_CERTIFICATE;
1427 1 : spdm_response->header.param1 = 0;
1428 1 : spdm_response->header.param2 = 0;
1429 1 : spdm_response->portion_length = portion_length;
1430 1 : spdm_response->remainder_length = remainder_length;
1431 1 : libspdm_copy_mem(spdm_response + 1,
1432 1 : (size_t)(*response) + *response_size - (size_t)(spdm_response + 1),
1433 1 : (uint8_t *)m_libspdm_local_certificate_chain +
1434 1 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * calling_index,
1435 : portion_length);
1436 :
1437 1 : libspdm_transport_test_encode_message(spdm_context, NULL, false,
1438 : false, spdm_response_size,
1439 : spdm_response, response_size,
1440 : response);
1441 :
1442 1 : calling_index++;
1443 1 : if (calling_index == count) {
1444 0 : calling_index = 0;
1445 0 : free(m_libspdm_local_certificate_chain);
1446 0 : m_libspdm_local_certificate_chain = NULL;
1447 0 : m_libspdm_local_certificate_chain_size = 0;
1448 : }
1449 : }
1450 1 : return LIBSPDM_STATUS_SUCCESS;
1451 :
1452 1 : case 0x15: {
1453 : spdm_certificate_response_t *spdm_response;
1454 : size_t spdm_response_size;
1455 : size_t transport_header_size;
1456 : uint16_t portion_length;
1457 : uint16_t remainder_length;
1458 : size_t count;
1459 : static size_t calling_index = 0;
1460 :
1461 1 : if (m_libspdm_local_certificate_chain == NULL) {
1462 0 : libspdm_read_responder_public_certificate_chain(
1463 : m_libspdm_use_hash_algo, m_libspdm_use_asym_algo,
1464 : &m_libspdm_local_certificate_chain,
1465 : &m_libspdm_local_certificate_chain_size, NULL, NULL);
1466 : }
1467 1 : if (m_libspdm_local_certificate_chain == NULL) {
1468 0 : return LIBSPDM_STATUS_RECEIVE_FAIL;
1469 : }
1470 1 : count = (m_libspdm_local_certificate_chain_size +
1471 1 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN - 1) /
1472 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
1473 1 : if (calling_index != count - 1) {
1474 1 : portion_length = LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN + 1; /* Fail response: responder return portion_length > spdm_request.length*/
1475 1 : remainder_length =
1476 1 : (uint16_t)(m_libspdm_local_certificate_chain_size -
1477 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN *
1478 1 : (calling_index + 1));
1479 : } else {
1480 0 : portion_length = (uint16_t)(
1481 : m_libspdm_local_certificate_chain_size -
1482 0 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * (count - 1));
1483 0 : remainder_length = 0;
1484 : }
1485 :
1486 1 : spdm_response_size =
1487 1 : sizeof(spdm_certificate_response_t) + portion_length;
1488 1 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
1489 1 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
1490 :
1491 1 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_10;
1492 1 : spdm_response->header.request_response_code = SPDM_CERTIFICATE;
1493 1 : spdm_response->header.param1 = 0;
1494 1 : spdm_response->header.param2 = 0;
1495 1 : spdm_response->portion_length = portion_length;
1496 1 : spdm_response->remainder_length = remainder_length;
1497 1 : libspdm_copy_mem(spdm_response + 1,
1498 1 : (size_t)(*response) + *response_size - (size_t)(spdm_response + 1),
1499 1 : (uint8_t *)m_libspdm_local_certificate_chain +
1500 1 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * calling_index,
1501 : portion_length);
1502 :
1503 1 : libspdm_transport_test_encode_message(spdm_context, NULL, false,
1504 : false, spdm_response_size,
1505 : spdm_response, response_size,
1506 : response);
1507 :
1508 1 : calling_index++;
1509 1 : if (calling_index == count) {
1510 0 : calling_index = 0;
1511 0 : free(m_libspdm_local_certificate_chain);
1512 0 : m_libspdm_local_certificate_chain = NULL;
1513 0 : m_libspdm_local_certificate_chain_size = 0;
1514 : }
1515 : }
1516 1 : return LIBSPDM_STATUS_SUCCESS;
1517 :
1518 2 : case 0x16: {
1519 : spdm_certificate_response_t *spdm_response;
1520 : size_t spdm_response_size;
1521 : size_t transport_header_size;
1522 : uint16_t portion_length;
1523 : uint16_t remainder_length;
1524 : size_t count;
1525 : static size_t calling_index = 0;
1526 :
1527 2 : if (m_libspdm_local_certificate_chain == NULL) {
1528 0 : libspdm_read_responder_public_certificate_chain(
1529 : m_libspdm_use_hash_algo, m_libspdm_use_asym_algo,
1530 : &m_libspdm_local_certificate_chain,
1531 : &m_libspdm_local_certificate_chain_size, NULL, NULL);
1532 : }
1533 2 : if (m_libspdm_local_certificate_chain == NULL) {
1534 0 : return LIBSPDM_STATUS_RECEIVE_FAIL;
1535 : }
1536 2 : count = (m_libspdm_local_certificate_chain_size +
1537 2 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN - 1) /
1538 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
1539 2 : if (calling_index != count - 1) {
1540 1 : portion_length = LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
1541 : /* Fail response: spdm_request.offset + spdm_response->portion_length + spdm_response->remainder_length !=
1542 : * total_responder_cert_chain_buffer_length.*/
1543 1 : remainder_length =
1544 1 : (uint16_t)(m_libspdm_local_certificate_chain_size - 1 -
1545 1 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN *(calling_index + 1));
1546 :
1547 : } else {
1548 1 : portion_length = (uint16_t)(
1549 : m_libspdm_local_certificate_chain_size -
1550 1 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * (count - 1));
1551 1 : remainder_length = 0;
1552 : }
1553 :
1554 2 : spdm_response_size =
1555 2 : sizeof(spdm_certificate_response_t) + portion_length;
1556 2 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
1557 2 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
1558 :
1559 2 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_10;
1560 2 : spdm_response->header.request_response_code = SPDM_CERTIFICATE;
1561 2 : spdm_response->header.param1 = 0;
1562 2 : spdm_response->header.param2 = 0;
1563 2 : spdm_response->portion_length = portion_length;
1564 2 : spdm_response->remainder_length = remainder_length;
1565 2 : libspdm_copy_mem(spdm_response + 1,
1566 2 : (size_t)(*response) + *response_size - (size_t)(spdm_response + 1),
1567 2 : (uint8_t *)m_libspdm_local_certificate_chain +
1568 2 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * calling_index,
1569 : portion_length);
1570 :
1571 2 : libspdm_transport_test_encode_message(spdm_context, NULL, false,
1572 : false, spdm_response_size,
1573 : spdm_response, response_size,
1574 : response);
1575 :
1576 2 : calling_index++;
1577 2 : if (calling_index == count) {
1578 1 : calling_index = 0;
1579 1 : free(m_libspdm_local_certificate_chain);
1580 1 : m_libspdm_local_certificate_chain = NULL;
1581 1 : m_libspdm_local_certificate_chain_size = 0;
1582 : }
1583 : }
1584 2 : return LIBSPDM_STATUS_SUCCESS;
1585 :
1586 2 : case 0x17: {
1587 : spdm_certificate_response_t *spdm_response;
1588 : size_t spdm_response_size;
1589 : size_t transport_header_size;
1590 : uint16_t portion_length;
1591 : uint16_t remainder_length;
1592 : size_t count;
1593 : static size_t calling_index = 0;
1594 :
1595 2 : if (m_libspdm_local_certificate_chain == NULL) {
1596 1 : libspdm_read_responder_public_certificate_chain(
1597 : m_libspdm_use_hash_algo, m_libspdm_use_asym_algo,
1598 : &m_libspdm_local_certificate_chain,
1599 : &m_libspdm_local_certificate_chain_size, NULL, NULL);
1600 : }
1601 2 : if (m_libspdm_local_certificate_chain == NULL) {
1602 0 : return LIBSPDM_STATUS_RECEIVE_FAIL;
1603 : }
1604 2 : count = (m_libspdm_local_certificate_chain_size + LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN - 1) /
1605 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
1606 2 : if (calling_index != count - 1) {
1607 1 : portion_length = LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
1608 1 : remainder_length =
1609 1 : (uint16_t)(m_libspdm_local_certificate_chain_size -
1610 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN *
1611 1 : (calling_index + 1));
1612 : } else {
1613 1 : portion_length = (uint16_t)(
1614 : m_libspdm_local_certificate_chain_size -
1615 1 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * (count - 1));
1616 1 : remainder_length = 0;
1617 : }
1618 :
1619 2 : spdm_response_size =
1620 2 : sizeof(spdm_certificate_response_t) + portion_length;
1621 2 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
1622 2 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
1623 :
1624 2 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_10;
1625 2 : spdm_response->header.request_response_code = SPDM_CERTIFICATE;
1626 2 : spdm_response->header.param1 = 0;
1627 2 : spdm_response->header.param2 = 0;
1628 2 : spdm_response->portion_length = portion_length;
1629 2 : spdm_response->remainder_length = remainder_length;
1630 2 : libspdm_copy_mem(spdm_response + 1,
1631 2 : (size_t)(*response) + *response_size - (size_t)(spdm_response + 1),
1632 2 : (uint8_t *)m_libspdm_local_certificate_chain +
1633 2 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * calling_index,
1634 : portion_length);
1635 :
1636 2 : libspdm_copy_mem(&m_libspdm_local_buffer[m_libspdm_local_buffer_size],
1637 : sizeof(m_libspdm_local_buffer) - m_libspdm_local_buffer_size,
1638 : spdm_response, spdm_response_size);
1639 2 : m_libspdm_local_buffer_size += spdm_response_size;
1640 :
1641 2 : libspdm_transport_test_encode_message(spdm_context, NULL, false,
1642 : false, spdm_response_size,
1643 : spdm_response, response_size,
1644 : response);
1645 :
1646 2 : calling_index++;
1647 2 : if (calling_index == count) {
1648 1 : calling_index = 0;
1649 1 : free(m_libspdm_local_certificate_chain);
1650 1 : m_libspdm_local_certificate_chain = NULL;
1651 1 : m_libspdm_local_certificate_chain_size = 0;
1652 : }
1653 : }
1654 2 : return LIBSPDM_STATUS_SUCCESS;
1655 :
1656 2 : case 0x18: {
1657 : spdm_certificate_response_t *spdm_response;
1658 : size_t spdm_response_size;
1659 : size_t transport_header_size;
1660 : uint16_t portion_length;
1661 : uint16_t remainder_length;
1662 : size_t count;
1663 : static size_t calling_index = 0;
1664 :
1665 2 : if (m_libspdm_local_certificate_chain == NULL) {
1666 1 : libspdm_read_responder_public_certificate_chain(
1667 : m_libspdm_use_hash_algo, m_libspdm_use_asym_algo,
1668 : &m_libspdm_local_certificate_chain,
1669 : &m_libspdm_local_certificate_chain_size, NULL, NULL);
1670 : }
1671 2 : if (m_libspdm_local_certificate_chain == NULL) {
1672 0 : return LIBSPDM_STATUS_RECEIVE_FAIL;
1673 : }
1674 2 : count = (m_libspdm_local_certificate_chain_size +
1675 2 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN - 1) /
1676 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
1677 2 : if (calling_index != count - 1) {
1678 1 : portion_length = LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
1679 1 : remainder_length =
1680 1 : (uint16_t)(m_libspdm_local_certificate_chain_size -
1681 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN *
1682 1 : (calling_index + 1));
1683 : } else {
1684 1 : portion_length = (uint16_t)(
1685 : m_libspdm_local_certificate_chain_size -
1686 1 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * (count - 1));
1687 1 : remainder_length = 0;
1688 : }
1689 :
1690 2 : spdm_response_size =
1691 2 : sizeof(spdm_certificate_response_t) + portion_length;
1692 2 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
1693 2 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
1694 :
1695 2 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_10;
1696 2 : spdm_response->header.request_response_code = SPDM_CERTIFICATE;
1697 2 : spdm_response->header.param1 = 0;
1698 2 : spdm_response->header.param2 = 0;
1699 2 : spdm_response->portion_length = portion_length;
1700 2 : spdm_response->remainder_length = remainder_length;
1701 2 : libspdm_copy_mem(spdm_response + 1,
1702 2 : (size_t)(*response) + *response_size - (size_t)(spdm_response + 1),
1703 2 : (uint8_t *)m_libspdm_local_certificate_chain +
1704 2 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * calling_index,
1705 : portion_length);
1706 :
1707 2 : libspdm_transport_test_encode_message(spdm_context, NULL, false,
1708 : false, spdm_response_size,
1709 : spdm_response, response_size,
1710 : response);
1711 :
1712 2 : calling_index++;
1713 2 : if (calling_index == count) {
1714 1 : calling_index = 0;
1715 1 : free(m_libspdm_local_certificate_chain);
1716 1 : m_libspdm_local_certificate_chain = NULL;
1717 1 : m_libspdm_local_certificate_chain_size = 0;
1718 : }
1719 : }
1720 2 : return LIBSPDM_STATUS_SUCCESS;
1721 :
1722 6 : case 0x19: {
1723 6 : if (m_get_cert) {
1724 : spdm_certificate_response_t *spdm_response;
1725 : size_t spdm_response_size;
1726 : size_t transport_header_size;
1727 : uint16_t portion_length;
1728 : uint16_t remainder_length;
1729 : size_t count;
1730 : static size_t calling_index = 0;
1731 : static uint8_t slot_id = 0;
1732 :
1733 4 : if (m_libspdm_local_certificate_chain == NULL) {
1734 2 : if (slot_id == 0) {
1735 1 : libspdm_read_responder_public_certificate_chain(
1736 : m_libspdm_use_hash_algo, m_libspdm_use_asym_algo,
1737 : &m_libspdm_local_certificate_chain,
1738 : &m_libspdm_local_certificate_chain_size, NULL, NULL);
1739 : } else {
1740 1 : libspdm_read_responder_public_certificate_chain_per_slot(
1741 : 1, m_libspdm_use_hash_algo, m_libspdm_use_asym_algo,
1742 : &m_libspdm_local_certificate_chain,
1743 : &m_libspdm_local_certificate_chain_size, NULL, NULL);
1744 : }
1745 : }
1746 4 : if (m_libspdm_local_certificate_chain == NULL) {
1747 0 : return LIBSPDM_STATUS_RECEIVE_FAIL;
1748 : }
1749 4 : count = (m_libspdm_local_certificate_chain_size +
1750 4 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN + 1) /
1751 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
1752 4 : if (calling_index != count - 1) {
1753 2 : portion_length = LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
1754 2 : remainder_length =
1755 2 : (uint16_t)(m_libspdm_local_certificate_chain_size -
1756 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN *
1757 2 : (calling_index + 1));
1758 : } else {
1759 2 : portion_length = (uint16_t)(
1760 : m_libspdm_local_certificate_chain_size -
1761 2 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * (count - 1));
1762 2 : remainder_length = 0;
1763 : }
1764 :
1765 4 : spdm_response_size =
1766 4 : sizeof(spdm_certificate_response_t) + portion_length;
1767 4 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
1768 4 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
1769 :
1770 4 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_11;
1771 4 : spdm_response->header.request_response_code = SPDM_CERTIFICATE;
1772 4 : spdm_response->header.param1 = slot_id;
1773 4 : spdm_response->header.param2 = 0;
1774 4 : spdm_response->portion_length = portion_length;
1775 4 : spdm_response->remainder_length = remainder_length;
1776 4 : libspdm_copy_mem(spdm_response + 1,
1777 4 : (size_t)(*response) + *response_size - (size_t)(spdm_response + 1),
1778 4 : (uint8_t *)m_libspdm_local_certificate_chain +
1779 4 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * calling_index,
1780 : portion_length);
1781 :
1782 4 : libspdm_transport_test_encode_message(spdm_context, NULL, false,
1783 : false, spdm_response_size,
1784 : spdm_response, response_size,
1785 : response);
1786 :
1787 4 : calling_index++;
1788 4 : if (calling_index == count) {
1789 2 : calling_index = 0;
1790 2 : free(m_libspdm_local_certificate_chain);
1791 2 : m_libspdm_local_certificate_chain = NULL;
1792 2 : m_libspdm_local_certificate_chain_size = 0;
1793 2 : slot_id++;
1794 : }
1795 : } else { /*correct CHALLENGE_AUTH message*/
1796 : spdm_challenge_auth_response_t *spdm_response;
1797 : void *data;
1798 : size_t data_size;
1799 : uint8_t *ptr;
1800 : uint8_t hash_data[LIBSPDM_MAX_HASH_SIZE];
1801 : size_t sig_size;
1802 : size_t spdm_response_size;
1803 : size_t transport_header_size;
1804 : static uint8_t slot_id = 0;
1805 :
1806 2 : if (slot_id == 0) {
1807 1 : libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
1808 : m_libspdm_use_asym_algo, &data,
1809 : &data_size, NULL, NULL);
1810 : } else {
1811 1 : libspdm_read_responder_public_certificate_chain_per_slot(1,
1812 : m_libspdm_use_hash_algo,
1813 : m_libspdm_use_asym_algo,
1814 : &data,
1815 : &data_size, NULL, NULL);
1816 : }
1817 : ((libspdm_context_t *)spdm_context)
1818 2 : ->local_context.local_cert_chain_provision_size[slot_id] =
1819 : data_size;
1820 : ((libspdm_context_t *)spdm_context)
1821 2 : ->local_context.local_cert_chain_provision[slot_id] = data;
1822 : ((libspdm_context_t *)spdm_context)
1823 2 : ->connection_info.algorithm.base_asym_algo =
1824 : m_libspdm_use_asym_algo;
1825 : ((libspdm_context_t *)spdm_context)
1826 2 : ->connection_info.algorithm.base_hash_algo =
1827 : m_libspdm_use_hash_algo;
1828 2 : spdm_response_size = sizeof(spdm_challenge_auth_response_t) +
1829 2 : libspdm_get_hash_size(m_libspdm_use_hash_algo) +
1830 2 : SPDM_NONCE_SIZE + 0 + sizeof(uint16_t) + 0 +
1831 2 : libspdm_get_asym_signature_size(m_libspdm_use_asym_algo);
1832 2 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
1833 2 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
1834 :
1835 2 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_11;
1836 2 : spdm_response->header.request_response_code =
1837 : SPDM_CHALLENGE_AUTH;
1838 2 : spdm_response->header.param1 = slot_id & 0xF;
1839 2 : spdm_response->header.param2 = (1 << slot_id);
1840 2 : ptr = (void *)(spdm_response + 1);
1841 2 : libspdm_hash_all(
1842 : m_libspdm_use_hash_algo,
1843 : ((libspdm_context_t *)spdm_context)
1844 : ->local_context.local_cert_chain_provision[slot_id],
1845 : ((libspdm_context_t *)spdm_context)
1846 : ->local_context
1847 : .local_cert_chain_provision_size[slot_id],
1848 : ptr);
1849 2 : free(data);
1850 2 : ptr += libspdm_get_hash_size(m_libspdm_use_hash_algo);
1851 2 : libspdm_get_random_number(SPDM_NONCE_SIZE, ptr);
1852 2 : ptr += SPDM_NONCE_SIZE;
1853 : /* libspdm_zero_mem (ptr, libspdm_get_hash_size (m_libspdm_use_hash_algo));
1854 : * ptr += libspdm_get_hash_size (m_libspdm_use_hash_algo);*/
1855 2 : *(uint16_t *)ptr = 0;
1856 2 : ptr += sizeof(uint16_t);
1857 2 : libspdm_copy_mem(&m_libspdm_local_buffer[m_libspdm_local_buffer_size],
1858 : sizeof(m_libspdm_local_buffer) -
1859 2 : (&m_libspdm_local_buffer[m_libspdm_local_buffer_size] -
1860 : m_libspdm_local_buffer),
1861 2 : spdm_response, (size_t)ptr - (size_t)spdm_response);
1862 2 : m_libspdm_local_buffer_size += ((size_t)ptr - (size_t)spdm_response);
1863 2 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "m_libspdm_local_buffer_size (0x%zx):\n",
1864 : m_libspdm_local_buffer_size));
1865 2 : libspdm_dump_hex(m_libspdm_local_buffer, m_libspdm_local_buffer_size);
1866 2 : libspdm_hash_all(m_libspdm_use_hash_algo, m_libspdm_local_buffer,
1867 : m_libspdm_local_buffer_size, hash_data);
1868 2 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "HashDataSize (0x%x):\n",
1869 : libspdm_get_hash_size(m_libspdm_use_hash_algo)));
1870 2 : libspdm_dump_hex(m_libspdm_local_buffer, m_libspdm_local_buffer_size);
1871 2 : sig_size = libspdm_get_asym_signature_size(m_libspdm_use_asym_algo);
1872 2 : libspdm_responder_data_sign(
1873 : spdm_context,
1874 2 : spdm_response->header.spdm_version << SPDM_VERSION_NUMBER_SHIFT_BIT,
1875 : SPDM_CHALLENGE_AUTH,
1876 : m_libspdm_use_asym_algo, m_libspdm_use_pqc_asym_algo, m_libspdm_use_hash_algo,
1877 : false, m_libspdm_local_buffer, m_libspdm_local_buffer_size,
1878 : ptr, &sig_size);
1879 2 : ptr += sig_size;
1880 :
1881 2 : libspdm_transport_test_encode_message(spdm_context, NULL, false,
1882 : false, spdm_response_size,
1883 : spdm_response, response_size,
1884 : response);
1885 2 : slot_id++;
1886 : }
1887 : }
1888 6 : return LIBSPDM_STATUS_SUCCESS;
1889 :
1890 2 : case 0x1A: {
1891 : spdm_certificate_response_t *spdm_response;
1892 : size_t spdm_response_size;
1893 : size_t transport_header_size;
1894 : uint16_t portion_length;
1895 : uint16_t remainder_length;
1896 : size_t count;
1897 : static size_t calling_index = 0;
1898 : uint32_t session_id;
1899 : libspdm_session_info_t *session_info;
1900 : uint8_t *scratch_buffer;
1901 : size_t scratch_buffer_size;
1902 :
1903 2 : session_id = 0xFFFFFFFF;
1904 :
1905 2 : if (m_libspdm_local_certificate_chain == NULL) {
1906 1 : libspdm_read_responder_public_certificate_chain(
1907 : m_libspdm_use_hash_algo, m_libspdm_use_asym_algo,
1908 : &m_libspdm_local_certificate_chain,
1909 : &m_libspdm_local_certificate_chain_size, NULL, NULL);
1910 : }
1911 2 : if (m_libspdm_local_certificate_chain == NULL) {
1912 0 : return LIBSPDM_STATUS_RECEIVE_FAIL;
1913 : }
1914 2 : count = (m_libspdm_local_certificate_chain_size +
1915 2 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN + 1) /
1916 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
1917 2 : if (calling_index != count - 1) {
1918 1 : portion_length = LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
1919 1 : remainder_length =
1920 1 : (uint16_t)(m_libspdm_local_certificate_chain_size -
1921 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN *
1922 1 : (calling_index + 1));
1923 : } else {
1924 1 : portion_length = (uint16_t)(
1925 : m_libspdm_local_certificate_chain_size -
1926 1 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * (count - 1));
1927 1 : remainder_length = 0;
1928 : }
1929 :
1930 2 : spdm_response_size =
1931 2 : sizeof(spdm_certificate_response_t) + portion_length;
1932 2 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
1933 2 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
1934 :
1935 2 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_10;
1936 2 : spdm_response->header.request_response_code = SPDM_CERTIFICATE;
1937 2 : spdm_response->header.param1 = 0;
1938 2 : spdm_response->header.param2 = 0;
1939 2 : spdm_response->portion_length = portion_length;
1940 2 : spdm_response->remainder_length = remainder_length;
1941 :
1942 : /* For secure message, message is in sender buffer, we need copy it to scratch buffer.
1943 : * transport_message is always in sender buffer. */
1944 2 : libspdm_get_scratch_buffer (spdm_context, (void **)&scratch_buffer, &scratch_buffer_size);
1945 :
1946 2 : libspdm_copy_mem(spdm_response + 1,
1947 2 : (size_t)(*response) + *response_size - (size_t)(spdm_response + 1),
1948 2 : (uint8_t *)m_libspdm_local_certificate_chain +
1949 2 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * calling_index,
1950 : portion_length);
1951 2 : libspdm_copy_mem (scratch_buffer + transport_header_size,
1952 : scratch_buffer_size - transport_header_size,
1953 : spdm_response, spdm_response_size);
1954 2 : spdm_response = (void *)(scratch_buffer + transport_header_size);
1955 :
1956 2 : libspdm_transport_test_encode_message(spdm_context, &session_id, false,
1957 : false, spdm_response_size,
1958 : spdm_response, response_size,
1959 : response);
1960 :
1961 2 : calling_index++;
1962 2 : if (calling_index == count) {
1963 1 : calling_index = 0;
1964 1 : free(m_libspdm_local_certificate_chain);
1965 1 : m_libspdm_local_certificate_chain = NULL;
1966 1 : m_libspdm_local_certificate_chain_size = 0;
1967 : }
1968 2 : session_info = libspdm_get_session_info_via_session_id(
1969 : spdm_context, session_id);
1970 2 : if (session_info == NULL) {
1971 0 : return LIBSPDM_STATUS_RECEIVE_FAIL;
1972 : }
1973 : /* WALKAROUND: If just use single context to encode message and then decode message */
1974 : ((libspdm_secured_message_context_t
1975 2 : *)(session_info->secured_message_context))
1976 2 : ->application_secret.response_data_sequence_number--;
1977 : }
1978 2 : return LIBSPDM_STATUS_SUCCESS;
1979 :
1980 1 : case 0x1B: {
1981 : spdm_certificate_response_t *spdm_response;
1982 : size_t spdm_response_size;
1983 : size_t transport_header_size;
1984 : uint16_t portion_length;
1985 : uint16_t remainder_length;
1986 : size_t count;
1987 : static size_t calling_index = 0;
1988 :
1989 1 : if (m_libspdm_local_certificate_chain == NULL) {
1990 1 : libspdm_read_responder_public_certificate_chain(
1991 : m_libspdm_use_hash_algo, m_libspdm_use_asym_algo,
1992 : &m_libspdm_local_certificate_chain,
1993 : &m_libspdm_local_certificate_chain_size, NULL, NULL);
1994 : }
1995 1 : if (m_libspdm_local_certificate_chain == NULL) {
1996 0 : return LIBSPDM_STATUS_RECEIVE_FAIL;
1997 : }
1998 1 : count = (m_libspdm_local_certificate_chain_size +
1999 1 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN - 1) /
2000 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
2001 1 : if (calling_index != count - 1) {
2002 1 : portion_length = LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
2003 1 : remainder_length =
2004 1 : (uint16_t)(m_libspdm_local_certificate_chain_size -
2005 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN *
2006 1 : (calling_index + 1));
2007 : } else {
2008 0 : portion_length = (uint16_t)(
2009 : m_libspdm_local_certificate_chain_size -
2010 0 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * (count - 1));
2011 0 : remainder_length = 0;
2012 : }
2013 :
2014 1 : spdm_response_size =
2015 1 : sizeof(spdm_certificate_response_t) + portion_length;
2016 1 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
2017 1 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
2018 :
2019 1 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_10;
2020 1 : spdm_response->header.request_response_code = SPDM_CERTIFICATE;
2021 1 : spdm_response->header.param1 = 3; /* Fail response: responder return wrong SlotID 3, not equal with SlotID 0 in request message. */
2022 1 : spdm_response->header.param2 = 0;
2023 1 : spdm_response->portion_length = portion_length;
2024 1 : spdm_response->remainder_length = remainder_length;
2025 1 : libspdm_copy_mem(spdm_response + 1,
2026 1 : (size_t)(*response) + *response_size - (size_t)(spdm_response + 1),
2027 1 : (uint8_t *)m_libspdm_local_certificate_chain +
2028 1 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * calling_index,
2029 : portion_length);
2030 :
2031 1 : libspdm_transport_test_encode_message(spdm_context, NULL, false,
2032 : false, spdm_response_size,
2033 : spdm_response, response_size,
2034 : response);
2035 :
2036 1 : calling_index++;
2037 1 : if (calling_index == count) {
2038 0 : calling_index = 0;
2039 0 : free(m_libspdm_local_certificate_chain);
2040 0 : m_libspdm_local_certificate_chain = NULL;
2041 0 : m_libspdm_local_certificate_chain_size = 0;
2042 : }
2043 : }
2044 1 : return LIBSPDM_STATUS_SUCCESS;
2045 :
2046 2 : case 0x1C: {
2047 : spdm_certificate_response_t *spdm_response;
2048 : size_t spdm_response_size;
2049 : size_t transport_header_size;
2050 : uint16_t portion_length;
2051 : uint16_t remainder_length;
2052 : size_t count;
2053 : static size_t calling_index = 0;
2054 :
2055 2 : if (m_libspdm_local_certificate_chain == NULL) {
2056 1 : libspdm_read_responder_public_certificate_chain_alias_cert(
2057 : m_libspdm_use_hash_algo, m_libspdm_use_asym_algo,
2058 : &m_libspdm_local_certificate_chain,
2059 : &m_libspdm_local_certificate_chain_size, NULL, NULL);
2060 : }
2061 2 : if (m_libspdm_local_certificate_chain == NULL) {
2062 0 : return LIBSPDM_STATUS_RECEIVE_FAIL;
2063 : }
2064 2 : count = (m_libspdm_local_certificate_chain_size +
2065 2 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN - 1) /
2066 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
2067 2 : if (calling_index != count - 1) {
2068 1 : portion_length = LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
2069 1 : remainder_length =
2070 1 : (uint16_t)(m_libspdm_local_certificate_chain_size -
2071 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN *
2072 1 : (calling_index + 1));
2073 : } else {
2074 1 : portion_length = (uint16_t)(
2075 : m_libspdm_local_certificate_chain_size -
2076 1 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * (count - 1));
2077 1 : remainder_length = 0;
2078 : }
2079 :
2080 2 : spdm_response_size =
2081 2 : sizeof(spdm_certificate_response_t) + portion_length;
2082 2 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
2083 2 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
2084 :
2085 2 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_12;
2086 2 : spdm_response->header.request_response_code = SPDM_CERTIFICATE;
2087 2 : spdm_response->header.param1 = 0;
2088 2 : spdm_response->header.param2 = 0;
2089 2 : spdm_response->portion_length = portion_length;
2090 2 : spdm_response->remainder_length = remainder_length;
2091 2 : libspdm_copy_mem(spdm_response + 1,
2092 2 : (size_t)(*response) + *response_size - (size_t)(spdm_response + 1),
2093 2 : (uint8_t *)m_libspdm_local_certificate_chain +
2094 2 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * calling_index,
2095 : portion_length);
2096 :
2097 2 : libspdm_transport_test_encode_message(spdm_context, NULL, false,
2098 : false, spdm_response_size,
2099 : spdm_response, response_size,
2100 : response);
2101 :
2102 2 : calling_index++;
2103 2 : if (calling_index == count) {
2104 1 : calling_index = 0;
2105 1 : free(m_libspdm_local_certificate_chain);
2106 1 : m_libspdm_local_certificate_chain = NULL;
2107 1 : m_libspdm_local_certificate_chain_size = 0;
2108 : }
2109 : }
2110 2 : return LIBSPDM_STATUS_SUCCESS;
2111 :
2112 2 : case 0x1D: {
2113 : spdm_certificate_response_t *spdm_response;
2114 : size_t spdm_response_size;
2115 : size_t transport_header_size;
2116 : uint16_t portion_length;
2117 : uint16_t remainder_length;
2118 : size_t count;
2119 : static size_t calling_index = 0;
2120 :
2121 2 : if (m_libspdm_local_certificate_chain == NULL) {
2122 1 : libspdm_read_responder_public_certificate_chain_alias_cert_till_dev_cert_ca(
2123 : m_libspdm_use_hash_algo, m_libspdm_use_asym_algo,
2124 : &m_libspdm_local_certificate_chain,
2125 : &m_libspdm_local_certificate_chain_size, NULL, NULL);
2126 : }
2127 2 : if (m_libspdm_local_certificate_chain == NULL) {
2128 0 : return LIBSPDM_STATUS_RECEIVE_FAIL;
2129 : }
2130 2 : count = (m_libspdm_local_certificate_chain_size +
2131 2 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN - 1) /
2132 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
2133 2 : if (calling_index != count - 1) {
2134 1 : portion_length = LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
2135 1 : remainder_length =
2136 1 : (uint16_t)(m_libspdm_local_certificate_chain_size -
2137 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN *
2138 1 : (calling_index + 1));
2139 : } else {
2140 1 : portion_length = (uint16_t)(
2141 : m_libspdm_local_certificate_chain_size -
2142 1 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * (count - 1));
2143 1 : remainder_length = 0;
2144 : }
2145 :
2146 2 : spdm_response_size =
2147 2 : sizeof(spdm_certificate_response_t) + portion_length;
2148 2 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
2149 2 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
2150 :
2151 2 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_12;
2152 2 : spdm_response->header.request_response_code = SPDM_CERTIFICATE;
2153 2 : spdm_response->header.param1 = 0;
2154 2 : spdm_response->header.param2 = 0;
2155 2 : spdm_response->portion_length = portion_length;
2156 2 : spdm_response->remainder_length = remainder_length;
2157 2 : libspdm_copy_mem(spdm_response + 1,
2158 2 : (size_t)(*response) + *response_size - (size_t)(spdm_response + 1),
2159 2 : (uint8_t *)m_libspdm_local_certificate_chain +
2160 2 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * calling_index,
2161 : portion_length);
2162 :
2163 2 : libspdm_transport_test_encode_message(spdm_context, NULL, false,
2164 : false, spdm_response_size,
2165 : spdm_response, response_size,
2166 : response);
2167 :
2168 2 : calling_index++;
2169 2 : if (calling_index == count) {
2170 1 : calling_index = 0;
2171 1 : free(m_libspdm_local_certificate_chain);
2172 1 : m_libspdm_local_certificate_chain = NULL;
2173 1 : m_libspdm_local_certificate_chain_size = 0;
2174 : }
2175 : }
2176 2 : return LIBSPDM_STATUS_SUCCESS;
2177 10 : case 0x1E: {
2178 : spdm_certificate_response_t *spdm_response;
2179 : size_t spdm_response_size;
2180 : size_t transport_header_size;
2181 : uint16_t portion_length;
2182 : uint16_t remainder_length;
2183 : size_t count;
2184 :
2185 10 : if (m_calling_index ==0) {
2186 6 : free(m_libspdm_local_certificate_chain);
2187 6 : m_libspdm_local_certificate_chain = NULL;
2188 6 : m_libspdm_local_certificate_chain_size = 0;
2189 : }
2190 :
2191 10 : if (m_libspdm_local_certificate_chain == NULL) {
2192 6 : libspdm_read_responder_public_certificate_chain(
2193 : m_libspdm_use_hash_algo, m_libspdm_use_asym_algo,
2194 : &m_libspdm_local_certificate_chain,
2195 : &m_libspdm_local_certificate_chain_size, NULL, NULL);
2196 : }
2197 10 : if (m_libspdm_local_certificate_chain == NULL) {
2198 0 : return LIBSPDM_STATUS_RECEIVE_FAIL;
2199 : }
2200 10 : count = (m_libspdm_local_certificate_chain_size +
2201 10 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN - 1) /
2202 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
2203 10 : if (m_calling_index != count - 1) {
2204 6 : portion_length = LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
2205 6 : remainder_length =
2206 6 : (uint16_t)(m_libspdm_local_certificate_chain_size -
2207 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN *
2208 6 : (m_calling_index + 1));
2209 : } else {
2210 4 : portion_length = (uint16_t)(
2211 : m_libspdm_local_certificate_chain_size -
2212 4 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * (count - 1));
2213 4 : remainder_length = 0;
2214 : }
2215 :
2216 10 : spdm_response_size =
2217 10 : sizeof(spdm_certificate_response_t) + portion_length;
2218 10 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
2219 10 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
2220 :
2221 10 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_13;
2222 10 : spdm_response->header.request_response_code = SPDM_CERTIFICATE;
2223 10 : spdm_response->header.param1 = m_slot_id;
2224 10 : spdm_response->header.param2 = m_cert_model;
2225 10 : spdm_response->portion_length = portion_length;
2226 10 : spdm_response->remainder_length = remainder_length;
2227 :
2228 10 : libspdm_copy_mem(spdm_response + 1,
2229 10 : (size_t)(*response) + *response_size - (size_t)(spdm_response + 1),
2230 10 : (uint8_t *)m_libspdm_local_certificate_chain +
2231 10 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * m_calling_index,
2232 : portion_length);
2233 :
2234 10 : libspdm_transport_test_encode_message(spdm_context, NULL, false,
2235 : false, spdm_response_size,
2236 : spdm_response, response_size,
2237 : response);
2238 :
2239 10 : m_calling_index++;
2240 : }
2241 10 : return LIBSPDM_STATUS_SUCCESS;
2242 1 : case 0x1F: {
2243 : spdm_certificate_response_t *spdm_response;
2244 : size_t spdm_response_size;
2245 : size_t transport_header_size;
2246 : uint16_t portion_length;
2247 : uint16_t remainder_length;
2248 : size_t count;
2249 : static size_t calling_index = 0;
2250 :
2251 1 : if (m_libspdm_local_certificate_chain == NULL) {
2252 0 : libspdm_read_responder_public_certificate_chain(
2253 : m_libspdm_use_hash_algo, m_libspdm_use_asym_algo,
2254 : &m_libspdm_local_certificate_chain,
2255 : &m_libspdm_local_certificate_chain_size, NULL, NULL);
2256 : }
2257 1 : if (m_libspdm_local_certificate_chain == NULL) {
2258 0 : return LIBSPDM_STATUS_RECEIVE_FAIL;
2259 : }
2260 1 : count = (m_libspdm_local_certificate_chain_size +
2261 1 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN - 1) /
2262 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
2263 1 : if (calling_index != count - 1) {
2264 1 : portion_length = LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
2265 1 : remainder_length =
2266 1 : (uint16_t)(m_libspdm_local_certificate_chain_size -
2267 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN *
2268 1 : (calling_index + 1));
2269 : } else {
2270 0 : portion_length = (uint16_t)(
2271 : m_libspdm_local_certificate_chain_size -
2272 0 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * (count - 1));
2273 0 : remainder_length = 0;
2274 : }
2275 :
2276 1 : spdm_response_size =
2277 1 : sizeof(spdm_certificate_response_t) + portion_length;
2278 1 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
2279 1 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
2280 :
2281 1 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_10;
2282 1 : spdm_response->header.request_response_code = SPDM_CERTIFICATE;
2283 1 : spdm_response->header.param1 = 0;
2284 1 : spdm_response->header.param2 = 0;
2285 1 : spdm_response->portion_length = portion_length;
2286 1 : spdm_response->remainder_length = remainder_length;
2287 1 : libspdm_copy_mem(spdm_response + 1,
2288 1 : (size_t)(*response) + *response_size - (size_t)(spdm_response + 1),
2289 1 : (uint8_t *)m_libspdm_local_certificate_chain +
2290 1 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN * calling_index,
2291 : portion_length);
2292 :
2293 1 : libspdm_transport_test_encode_message(spdm_context, NULL, false,
2294 : false, spdm_response_size,
2295 : spdm_response, response_size,
2296 : response);
2297 :
2298 1 : calling_index++;
2299 1 : if (calling_index == count) {
2300 0 : calling_index = 0;
2301 0 : free(m_libspdm_local_certificate_chain);
2302 0 : m_libspdm_local_certificate_chain = NULL;
2303 0 : m_libspdm_local_certificate_chain_size = 0;
2304 : }
2305 : }
2306 1 : return LIBSPDM_STATUS_SUCCESS;
2307 0 : default:
2308 0 : return LIBSPDM_STATUS_RECEIVE_FAIL;
2309 : }
2310 : }
2311 :
2312 : /**
2313 : * Test 1: message could not be sent
2314 : * Expected Behavior: get a LIBSPDM_STATUS_SEND_FAIL, with no CERTIFICATE messages received (checked in transcript.message_b buffer)
2315 : **/
2316 1 : void libspdm_test_requester_get_certificate_case1(void **state)
2317 : {
2318 : libspdm_return_t status;
2319 : libspdm_test_context_t *spdm_test_context;
2320 : libspdm_context_t *spdm_context;
2321 : size_t cert_chain_size;
2322 : uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
2323 : void *data;
2324 : size_t data_size;
2325 : void *hash;
2326 : size_t hash_size;
2327 : const uint8_t *root_cert;
2328 : size_t root_cert_size;
2329 :
2330 1 : spdm_test_context = *state;
2331 1 : spdm_context = spdm_test_context->spdm_context;
2332 1 : spdm_test_context->case_id = 0x1;
2333 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
2334 : SPDM_VERSION_NUMBER_SHIFT_BIT;
2335 1 : spdm_context->connection_info.connection_state =
2336 : LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
2337 1 : spdm_context->connection_info.capability.flags |=
2338 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
2339 1 : if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
2340 : m_libspdm_use_asym_algo, &data,
2341 : &data_size, &hash, &hash_size)) {
2342 0 : assert(false);
2343 : }
2344 1 : if (!libspdm_x509_get_cert_from_cert_chain(
2345 1 : (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
2346 1 : data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
2347 0 : assert(false);
2348 : }
2349 1 : spdm_context->local_context.peer_root_cert_provision_size[0] =
2350 : root_cert_size;
2351 1 : spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
2352 1 : libspdm_reset_message_b(spdm_context);
2353 1 : spdm_context->connection_info.algorithm.base_hash_algo =
2354 : m_libspdm_use_hash_algo;
2355 1 : spdm_context->connection_info.algorithm.base_asym_algo =
2356 : m_libspdm_use_asym_algo;
2357 1 : spdm_context->connection_info.algorithm.req_base_asym_alg =
2358 : m_libspdm_use_req_asym_algo;
2359 :
2360 1 : cert_chain_size = sizeof(cert_chain);
2361 1 : libspdm_zero_mem(cert_chain, sizeof(cert_chain));
2362 1 : status = libspdm_get_certificate(spdm_context, NULL, 0, &cert_chain_size,
2363 : cert_chain);
2364 1 : assert_int_equal(status, LIBSPDM_STATUS_SEND_FAIL);
2365 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
2366 : assert_int_equal(spdm_context->transcript.message_b.buffer_size, 0);
2367 : #endif
2368 1 : free(data);
2369 1 : }
2370 :
2371 : /**
2372 : * Test 2: Normal case, request a certificate chain
2373 : * Expected Behavior: receives a valid certificate chain with the correct number of Certificate messages
2374 : **/
2375 1 : void libspdm_test_requester_get_certificate_case2(void **state)
2376 : {
2377 : libspdm_return_t status;
2378 : libspdm_test_context_t *spdm_test_context;
2379 : libspdm_context_t *spdm_context;
2380 : size_t cert_chain_size;
2381 : uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
2382 : void *data;
2383 : size_t data_size;
2384 : void *hash;
2385 : size_t hash_size;
2386 : const uint8_t *root_cert;
2387 : size_t root_cert_size;
2388 : libspdm_data_parameter_t parameter;
2389 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
2390 : size_t count;
2391 : #else
2392 : uint8_t set_data_buffer_hash[LIBSPDM_MAX_HASH_SIZE];
2393 : uint32_t set_data_buffer_hash_size;
2394 : #endif
2395 :
2396 1 : spdm_test_context = *state;
2397 1 : spdm_context = spdm_test_context->spdm_context;
2398 1 : spdm_test_context->case_id = 0x2;
2399 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
2400 : SPDM_VERSION_NUMBER_SHIFT_BIT;
2401 1 : spdm_context->connection_info.connection_state =
2402 : LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
2403 1 : spdm_context->connection_info.capability.flags |=
2404 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
2405 1 : spdm_context->local_context.is_requester = true;
2406 1 : if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
2407 : m_libspdm_use_asym_algo, &data,
2408 : &data_size, &hash, &hash_size)) {
2409 0 : assert(false);
2410 : }
2411 1 : if (!libspdm_x509_get_cert_from_cert_chain(
2412 1 : (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
2413 1 : data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
2414 0 : assert(false);
2415 : }
2416 1 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "root cert data :\n"));
2417 1 : libspdm_dump_hex(
2418 : root_cert,
2419 : root_cert_size);
2420 1 : spdm_context->local_context.peer_root_cert_provision_size[0] =
2421 : root_cert_size;
2422 1 : spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
2423 1 : libspdm_reset_message_b(spdm_context);
2424 1 : spdm_context->connection_info.algorithm.base_hash_algo =
2425 : m_libspdm_use_hash_algo;
2426 1 : spdm_context->connection_info.algorithm.base_asym_algo =
2427 : m_libspdm_use_asym_algo;
2428 1 : spdm_context->connection_info.algorithm.req_base_asym_alg =
2429 : m_libspdm_use_req_asym_algo;
2430 :
2431 1 : libspdm_zero_mem(¶meter, sizeof(parameter));
2432 1 : parameter.location = LIBSPDM_DATA_LOCATION_CONNECTION;
2433 1 : parameter.additional_data[0] = 0;
2434 1 : libspdm_set_data(spdm_context, LIBSPDM_DATA_PEER_USED_CERT_CHAIN_BUFFER, ¶meter,
2435 : data, data_size);
2436 :
2437 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
2438 : spdm_context->transcript.message_m.buffer_size =
2439 : spdm_context->transcript.message_m.max_buffer_size;
2440 : #else
2441 1 : set_data_buffer_hash_size =
2442 : spdm_context->connection_info.peer_used_cert_chain[0].buffer_hash_size;
2443 1 : libspdm_copy_mem(set_data_buffer_hash, set_data_buffer_hash_size,
2444 1 : spdm_context->connection_info.peer_used_cert_chain[0].buffer_hash,
2445 : set_data_buffer_hash_size);
2446 : #endif
2447 1 : cert_chain_size = sizeof(cert_chain);
2448 1 : libspdm_zero_mem(cert_chain, sizeof(cert_chain));
2449 1 : status = libspdm_get_certificate(spdm_context, NULL, 0, &cert_chain_size,
2450 : cert_chain);
2451 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
2452 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
2453 : count = (data_size + LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN - 1) /
2454 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
2455 : assert_int_equal(spdm_context->transcript.message_b.buffer_size,
2456 : sizeof(spdm_get_certificate_request_t) * count +
2457 : sizeof(spdm_certificate_response_t) * count +
2458 : data_size);
2459 : assert_int_equal(spdm_context->transcript.message_m.buffer_size, 0);
2460 : #else
2461 : /*
2462 : * libspdm_get_certificate will get leaf_cert_public_key when LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT is not enabled.
2463 : * The follow check is for libspdm_set_data.
2464 : **/
2465 1 : assert_int_equal(set_data_buffer_hash_size,
2466 : spdm_context->connection_info.peer_used_cert_chain[0].buffer_hash_size);
2467 :
2468 1 : assert_memory_equal(set_data_buffer_hash,
2469 : spdm_context->connection_info.peer_used_cert_chain[0].buffer_hash,
2470 : set_data_buffer_hash_size);
2471 : #endif/*LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT*/
2472 1 : free(data);
2473 1 : }
2474 :
2475 : /**
2476 : * Test 3: simulate wrong connection_state when sending GET_CERTIFICATE (missing SPDM_GET_DIGESTS_RECEIVE_FLAG and SPDM_GET_CAPABILITIES_RECEIVE_FLAG)
2477 : * Expected Behavior: get a LIBSPDM_STATUS_INVALID_STATE_LOCAL, with no CERTIFICATE messages received (checked in transcript.message_b buffer)
2478 : **/
2479 1 : void libspdm_test_requester_get_certificate_case3(void **state)
2480 : {
2481 : libspdm_return_t status;
2482 : libspdm_test_context_t *spdm_test_context;
2483 : libspdm_context_t *spdm_context;
2484 : size_t cert_chain_size;
2485 : uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
2486 : void *data;
2487 : size_t data_size;
2488 : void *hash;
2489 : size_t hash_size;
2490 : const uint8_t *root_cert;
2491 : size_t root_cert_size;
2492 :
2493 1 : spdm_test_context = *state;
2494 1 : spdm_context = spdm_test_context->spdm_context;
2495 1 : spdm_test_context->case_id = 0x3;
2496 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
2497 : SPDM_VERSION_NUMBER_SHIFT_BIT;
2498 1 : spdm_context->connection_info.connection_state =
2499 : LIBSPDM_CONNECTION_STATE_NOT_STARTED;
2500 1 : spdm_context->connection_info.capability.flags |=
2501 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
2502 1 : if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
2503 : m_libspdm_use_asym_algo, &data,
2504 : &data_size, &hash, &hash_size)) {
2505 0 : assert(false);
2506 : }
2507 1 : if (!libspdm_x509_get_cert_from_cert_chain(
2508 1 : (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
2509 1 : data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
2510 0 : assert(false);
2511 : }
2512 1 : spdm_context->local_context.peer_root_cert_provision_size[0] =
2513 : root_cert_size;
2514 1 : spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
2515 1 : libspdm_reset_message_b(spdm_context);
2516 1 : spdm_context->connection_info.algorithm.base_hash_algo =
2517 : m_libspdm_use_hash_algo;
2518 1 : spdm_context->connection_info.algorithm.base_asym_algo =
2519 : m_libspdm_use_asym_algo;
2520 1 : spdm_context->connection_info.algorithm.req_base_asym_alg =
2521 : m_libspdm_use_req_asym_algo;
2522 :
2523 1 : cert_chain_size = sizeof(cert_chain);
2524 1 : libspdm_zero_mem(cert_chain, sizeof(cert_chain));
2525 1 : status = libspdm_get_certificate(spdm_context, NULL, 0, &cert_chain_size,
2526 : cert_chain);
2527 1 : assert_int_equal(status, LIBSPDM_STATUS_INVALID_STATE_LOCAL);
2528 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
2529 : assert_int_equal(spdm_context->transcript.message_b.buffer_size, 0);
2530 : #endif
2531 1 : free(data);
2532 1 : }
2533 :
2534 : /**
2535 : * Test 4: force responder to send an ERROR message with code SPDM_ERROR_CODE_INVALID_REQUEST
2536 : * Expected Behavior: get a LIBSPDM_STATUS_ERROR_PEER, with no CERTIFICATE messages received (checked in transcript.message_b buffer)
2537 : **/
2538 1 : void libspdm_test_requester_get_certificate_case4(void **state)
2539 : {
2540 : libspdm_return_t status;
2541 : libspdm_test_context_t *spdm_test_context;
2542 : libspdm_context_t *spdm_context;
2543 : size_t cert_chain_size;
2544 : uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
2545 : void *data;
2546 : size_t data_size;
2547 : void *hash;
2548 : size_t hash_size;
2549 : const uint8_t *root_cert;
2550 : size_t root_cert_size;
2551 :
2552 1 : spdm_test_context = *state;
2553 1 : spdm_context = spdm_test_context->spdm_context;
2554 1 : spdm_test_context->case_id = 0x4;
2555 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
2556 : SPDM_VERSION_NUMBER_SHIFT_BIT;
2557 1 : spdm_context->connection_info.connection_state =
2558 : LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
2559 1 : spdm_context->connection_info.capability.flags |=
2560 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
2561 1 : if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
2562 : m_libspdm_use_asym_algo, &data,
2563 : &data_size, &hash, &hash_size)) {
2564 0 : assert(false);
2565 : }
2566 1 : if (!libspdm_x509_get_cert_from_cert_chain(
2567 1 : (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
2568 1 : data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
2569 0 : assert(false);
2570 : }
2571 1 : spdm_context->local_context.peer_root_cert_provision_size[0] =
2572 : root_cert_size;
2573 1 : spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
2574 1 : libspdm_reset_message_b(spdm_context);
2575 1 : spdm_context->connection_info.algorithm.base_hash_algo =
2576 : m_libspdm_use_hash_algo;
2577 1 : spdm_context->connection_info.algorithm.base_asym_algo =
2578 : m_libspdm_use_asym_algo;
2579 1 : spdm_context->connection_info.algorithm.req_base_asym_alg =
2580 : m_libspdm_use_req_asym_algo;
2581 :
2582 1 : cert_chain_size = sizeof(cert_chain);
2583 1 : libspdm_zero_mem(cert_chain, sizeof(cert_chain));
2584 1 : status = libspdm_get_certificate(spdm_context, NULL, 0, &cert_chain_size,
2585 : cert_chain);
2586 1 : assert_int_equal(status, LIBSPDM_STATUS_ERROR_PEER);
2587 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
2588 : assert_int_equal(spdm_context->transcript.message_b.buffer_size, 0);
2589 : #endif
2590 1 : free(data);
2591 1 : }
2592 :
2593 : /**
2594 : * Test 5: force responder to send an ERROR message with code SPDM_ERROR_CODE_BUSY
2595 : * Expected Behavior: get a LIBSPDM_STATUS_BUSY_PEER, with no CERTIFICATE messages received (checked in transcript.message_b buffer)
2596 : **/
2597 1 : void libspdm_test_requester_get_certificate_case5(void **state)
2598 : {
2599 : libspdm_return_t status;
2600 : libspdm_test_context_t *spdm_test_context;
2601 : libspdm_context_t *spdm_context;
2602 : size_t cert_chain_size;
2603 : uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
2604 : void *data;
2605 : size_t data_size;
2606 : void *hash;
2607 : size_t hash_size;
2608 : const uint8_t *root_cert;
2609 : size_t root_cert_size;
2610 :
2611 1 : spdm_test_context = *state;
2612 1 : spdm_context = spdm_test_context->spdm_context;
2613 1 : spdm_test_context->case_id = 0x5;
2614 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
2615 : SPDM_VERSION_NUMBER_SHIFT_BIT;
2616 1 : spdm_context->connection_info.connection_state =
2617 : LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
2618 1 : spdm_context->connection_info.capability.flags |=
2619 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
2620 1 : if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
2621 : m_libspdm_use_asym_algo, &data,
2622 : &data_size, &hash, &hash_size)) {
2623 0 : assert(false);
2624 : }
2625 1 : if (!libspdm_x509_get_cert_from_cert_chain(
2626 1 : (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
2627 1 : data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
2628 0 : assert(false);
2629 : }
2630 1 : spdm_context->local_context.peer_root_cert_provision_size[0] =
2631 : root_cert_size;
2632 1 : spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
2633 1 : libspdm_reset_message_b(spdm_context);
2634 1 : spdm_context->connection_info.algorithm.base_hash_algo =
2635 : m_libspdm_use_hash_algo;
2636 1 : spdm_context->connection_info.algorithm.base_asym_algo =
2637 : m_libspdm_use_asym_algo;
2638 1 : spdm_context->connection_info.algorithm.req_base_asym_alg =
2639 : m_libspdm_use_req_asym_algo;
2640 :
2641 1 : cert_chain_size = sizeof(cert_chain);
2642 1 : libspdm_zero_mem(cert_chain, sizeof(cert_chain));
2643 1 : status = libspdm_get_certificate(spdm_context, NULL, 0, &cert_chain_size,
2644 : cert_chain);
2645 1 : assert_int_equal(status, LIBSPDM_STATUS_BUSY_PEER);
2646 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
2647 : assert_int_equal(spdm_context->transcript.message_b.buffer_size, 0);
2648 : #endif
2649 1 : free(data);
2650 1 : }
2651 :
2652 : /**
2653 : * Test 6: force responder to first send an ERROR message with code SPDM_ERROR_CODE_BUSY, but functions normally afterwards
2654 : * Expected Behavior: receives the correct number of CERTIFICATE messages
2655 : **/
2656 1 : void libspdm_test_requester_get_certificate_case6(void **state)
2657 : {
2658 : libspdm_return_t status;
2659 : libspdm_test_context_t *spdm_test_context;
2660 : libspdm_context_t *spdm_context;
2661 : size_t cert_chain_size;
2662 : uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
2663 : void *data;
2664 : size_t data_size;
2665 : void *hash;
2666 : size_t hash_size;
2667 : const uint8_t *root_cert;
2668 : size_t root_cert_size;
2669 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
2670 : size_t count;
2671 : #endif
2672 1 : spdm_test_context = *state;
2673 1 : spdm_context = spdm_test_context->spdm_context;
2674 1 : spdm_test_context->case_id = 0x6;
2675 1 : spdm_context->retry_times = 3;
2676 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
2677 : SPDM_VERSION_NUMBER_SHIFT_BIT;
2678 1 : spdm_context->connection_info.connection_state =
2679 : LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
2680 1 : spdm_context->connection_info.capability.flags |=
2681 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
2682 1 : spdm_context->local_context.is_requester = true;
2683 1 : if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
2684 : m_libspdm_use_asym_algo, &data,
2685 : &data_size, &hash, &hash_size)) {
2686 0 : assert(false);
2687 : }
2688 1 : if (!libspdm_x509_get_cert_from_cert_chain(
2689 1 : (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
2690 1 : data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
2691 0 : assert(false);
2692 : }
2693 1 : spdm_context->local_context.peer_root_cert_provision_size[0] =
2694 : root_cert_size;
2695 1 : spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
2696 1 : libspdm_reset_message_b(spdm_context);
2697 1 : spdm_context->connection_info.algorithm.base_hash_algo =
2698 : m_libspdm_use_hash_algo;
2699 1 : spdm_context->connection_info.algorithm.base_asym_algo =
2700 : m_libspdm_use_asym_algo;
2701 1 : spdm_context->connection_info.algorithm.req_base_asym_alg =
2702 : m_libspdm_use_req_asym_algo;
2703 :
2704 1 : cert_chain_size = sizeof(cert_chain);
2705 1 : libspdm_zero_mem(cert_chain, sizeof(cert_chain));
2706 1 : status = libspdm_get_certificate(spdm_context, NULL, 0, &cert_chain_size,
2707 : cert_chain);
2708 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
2709 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
2710 : count = (data_size + LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN - 1) /
2711 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
2712 : assert_int_equal(spdm_context->transcript.message_b.buffer_size,
2713 : sizeof(spdm_get_certificate_request_t) * count +
2714 : sizeof(spdm_certificate_response_t) * count +
2715 : data_size);
2716 : #endif
2717 1 : free(data);
2718 1 : }
2719 :
2720 : /**
2721 : * Test 7: force responder to send an ERROR message with code SPDM_ERROR_CODE_REQUEST_RESYNCH
2722 : * Expected Behavior: get a LIBSPDM_STATUS_RESYNCH_PEER, with no CERTIFICATE messages received (checked in transcript.message_b buffer)
2723 : **/
2724 1 : void libspdm_test_requester_get_certificate_case7(void **state)
2725 : {
2726 : libspdm_return_t status;
2727 : libspdm_test_context_t *spdm_test_context;
2728 : libspdm_context_t *spdm_context;
2729 : size_t cert_chain_size;
2730 : uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
2731 : void *data;
2732 : size_t data_size;
2733 : void *hash;
2734 : size_t hash_size;
2735 : const uint8_t *root_cert;
2736 : size_t root_cert_size;
2737 :
2738 1 : spdm_test_context = *state;
2739 1 : spdm_context = spdm_test_context->spdm_context;
2740 1 : spdm_test_context->case_id = 0x7;
2741 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
2742 : SPDM_VERSION_NUMBER_SHIFT_BIT;
2743 1 : spdm_context->connection_info.connection_state =
2744 : LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
2745 1 : spdm_context->connection_info.capability.flags |=
2746 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
2747 1 : if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
2748 : m_libspdm_use_asym_algo, &data,
2749 : &data_size, &hash, &hash_size)) {
2750 0 : assert(false);
2751 : }
2752 1 : if (!libspdm_x509_get_cert_from_cert_chain(
2753 1 : (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
2754 1 : data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
2755 0 : assert(false);
2756 : }
2757 1 : spdm_context->local_context.peer_root_cert_provision_size[0] =
2758 : root_cert_size;
2759 1 : spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
2760 1 : libspdm_reset_message_b(spdm_context);
2761 1 : spdm_context->connection_info.algorithm.base_hash_algo =
2762 : m_libspdm_use_hash_algo;
2763 1 : spdm_context->connection_info.algorithm.base_asym_algo =
2764 : m_libspdm_use_asym_algo;
2765 1 : spdm_context->connection_info.algorithm.req_base_asym_alg =
2766 : m_libspdm_use_req_asym_algo;
2767 :
2768 1 : cert_chain_size = sizeof(cert_chain);
2769 1 : libspdm_zero_mem(cert_chain, sizeof(cert_chain));
2770 1 : status = libspdm_get_certificate(spdm_context, NULL, 0, &cert_chain_size,
2771 : cert_chain);
2772 1 : assert_int_equal(status, LIBSPDM_STATUS_RESYNCH_PEER);
2773 1 : assert_int_equal(spdm_context->connection_info.connection_state,
2774 : LIBSPDM_CONNECTION_STATE_NOT_STARTED);
2775 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
2776 : assert_int_equal(spdm_context->transcript.message_b.buffer_size, 0);
2777 : #endif
2778 1 : free(data);
2779 1 : }
2780 :
2781 : /**
2782 : * Test 8: force responder to send an ERROR message with code SPDM_ERROR_CODE_RESPONSE_NOT_READY
2783 : * Expected Behavior: get a LIBSPDM_STATUS_ERROR_PEER
2784 : **/
2785 1 : void libspdm_test_requester_get_certificate_case8(void **state)
2786 : {
2787 : libspdm_return_t status;
2788 : libspdm_test_context_t *spdm_test_context;
2789 : libspdm_context_t *spdm_context;
2790 : size_t cert_chain_size;
2791 : uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
2792 : void *data;
2793 : size_t data_size;
2794 : void *hash;
2795 : size_t hash_size;
2796 : const uint8_t *root_cert;
2797 : size_t root_cert_size;
2798 :
2799 1 : spdm_test_context = *state;
2800 1 : spdm_context = spdm_test_context->spdm_context;
2801 1 : spdm_test_context->case_id = 0x8;
2802 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
2803 : SPDM_VERSION_NUMBER_SHIFT_BIT;
2804 1 : spdm_context->connection_info.connection_state =
2805 : LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
2806 1 : spdm_context->connection_info.capability.flags |=
2807 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
2808 1 : if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
2809 : m_libspdm_use_asym_algo, &data,
2810 : &data_size, &hash, &hash_size)) {
2811 0 : assert(false);
2812 : }
2813 1 : if (!libspdm_x509_get_cert_from_cert_chain(
2814 1 : (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
2815 1 : data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
2816 0 : assert(false);
2817 : }
2818 1 : spdm_context->local_context.peer_root_cert_provision_size[0] =
2819 : root_cert_size;
2820 1 : spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
2821 1 : libspdm_reset_message_b(spdm_context);
2822 1 : spdm_context->connection_info.algorithm.base_hash_algo =
2823 : m_libspdm_use_hash_algo;
2824 1 : spdm_context->connection_info.algorithm.base_asym_algo =
2825 : m_libspdm_use_asym_algo;
2826 1 : spdm_context->connection_info.algorithm.req_base_asym_alg =
2827 : m_libspdm_use_req_asym_algo;
2828 :
2829 1 : cert_chain_size = sizeof(cert_chain);
2830 1 : libspdm_zero_mem(cert_chain, sizeof(cert_chain));
2831 1 : status = libspdm_get_certificate(spdm_context, NULL, 0, &cert_chain_size,
2832 : cert_chain);
2833 1 : assert_int_equal(status, LIBSPDM_STATUS_NOT_READY_PEER);
2834 1 : free(data);
2835 1 : }
2836 :
2837 : /**
2838 : * Test 9: force responder to first send an ERROR message with code SPDM_ERROR_CODE_RESPONSE_NOT_READY, but functions normally afterwards
2839 : * Expected Behavior: receives the correct number of CERTIFICATE messages
2840 : **/
2841 1 : void libspdm_test_requester_get_certificate_case9(void **state)
2842 : {
2843 : libspdm_return_t status;
2844 : libspdm_test_context_t *spdm_test_context;
2845 : libspdm_context_t *spdm_context;
2846 : size_t cert_chain_size;
2847 : uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
2848 : void *data;
2849 : size_t data_size;
2850 : void *hash;
2851 : size_t hash_size;
2852 : const uint8_t *root_cert;
2853 : size_t root_cert_size;
2854 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
2855 : size_t count;
2856 : #endif
2857 :
2858 1 : spdm_test_context = *state;
2859 1 : spdm_context = spdm_test_context->spdm_context;
2860 1 : spdm_test_context->case_id = 0x9;
2861 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
2862 : SPDM_VERSION_NUMBER_SHIFT_BIT;
2863 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
2864 1 : spdm_context->connection_info.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
2865 1 : if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
2866 : m_libspdm_use_asym_algo, &data,
2867 : &data_size, &hash, &hash_size)) {
2868 0 : assert(false);
2869 : }
2870 1 : if (!libspdm_x509_get_cert_from_cert_chain(
2871 1 : (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
2872 1 : data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
2873 0 : assert(false);
2874 : }
2875 1 : spdm_context->local_context.peer_root_cert_provision_size[0] = root_cert_size;
2876 1 : spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
2877 1 : libspdm_reset_message_b(spdm_context);
2878 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
2879 1 : spdm_context->connection_info.algorithm.base_asym_algo = m_libspdm_use_asym_algo;
2880 1 : spdm_context->connection_info.algorithm.req_base_asym_alg = m_libspdm_use_req_asym_algo;
2881 1 : spdm_context->local_context.is_requester = true;
2882 :
2883 1 : cert_chain_size = sizeof(cert_chain);
2884 1 : libspdm_zero_mem(cert_chain, sizeof(cert_chain));
2885 1 : status = libspdm_get_certificate(spdm_context, NULL, 0, &cert_chain_size,
2886 : cert_chain);
2887 : if (LIBSPDM_RESPOND_IF_READY_SUPPORT) {
2888 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
2889 : } else {
2890 : assert_int_equal(status, LIBSPDM_STATUS_NOT_READY_PEER);
2891 : }
2892 :
2893 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
2894 : count = (data_size + LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN - 1) / LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
2895 : assert_int_equal(spdm_context->transcript.message_b.buffer_size,
2896 : sizeof(spdm_get_certificate_request_t) * count +
2897 : sizeof(spdm_certificate_response_t) * count + data_size);
2898 : #endif
2899 1 : free(data);
2900 1 : }
2901 :
2902 : /**
2903 : * Test 10: Normal case, request a certificate chain. Validates certificate by using a preloaded chain instead of root hash
2904 : * Expected Behavior: receives the correct number of Certificate messages
2905 : **/
2906 1 : void libspdm_test_requester_get_certificate_case10(void **state)
2907 : {
2908 : libspdm_return_t status;
2909 : libspdm_test_context_t *spdm_test_context;
2910 : libspdm_context_t *spdm_context;
2911 : size_t cert_chain_size;
2912 : uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
2913 : void *data;
2914 : size_t data_size;
2915 : void *hash;
2916 : size_t hash_size;
2917 : const uint8_t *root_cert;
2918 : size_t root_cert_size;
2919 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
2920 : size_t count;
2921 : #endif
2922 :
2923 1 : spdm_test_context = *state;
2924 1 : spdm_context = spdm_test_context->spdm_context;
2925 1 : spdm_test_context->case_id = 0xA;
2926 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
2927 : SPDM_VERSION_NUMBER_SHIFT_BIT;
2928 1 : spdm_context->connection_info.connection_state =
2929 : LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
2930 1 : spdm_context->connection_info.capability.flags |=
2931 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
2932 1 : if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
2933 : m_libspdm_use_asym_algo, &data,
2934 : &data_size, &hash, &hash_size)) {
2935 0 : assert(false);
2936 : }
2937 1 : if (!libspdm_x509_get_cert_from_cert_chain(
2938 1 : (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
2939 1 : data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
2940 0 : assert(false);
2941 : }
2942 :
2943 1 : spdm_context->local_context.peer_root_cert_provision_size[0] = 0;
2944 1 : spdm_context->local_context.peer_root_cert_provision[0] = NULL;
2945 1 : libspdm_reset_message_b(spdm_context);
2946 1 : spdm_context->connection_info.algorithm.base_hash_algo =
2947 : m_libspdm_use_hash_algo;
2948 1 : spdm_context->connection_info.algorithm.base_asym_algo =
2949 : m_libspdm_use_asym_algo;
2950 1 : spdm_context->connection_info.algorithm.req_base_asym_alg =
2951 : m_libspdm_use_req_asym_algo;
2952 1 : spdm_context->local_context.is_requester = true;
2953 :
2954 1 : cert_chain_size = sizeof(cert_chain);
2955 1 : libspdm_zero_mem(cert_chain, sizeof(cert_chain));
2956 1 : status = libspdm_get_certificate(spdm_context, NULL, 0, &cert_chain_size,
2957 : cert_chain);
2958 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
2959 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
2960 : count = (data_size + LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN - 1) /
2961 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
2962 : assert_int_equal(spdm_context->transcript.message_b.buffer_size,
2963 : sizeof(spdm_get_certificate_request_t) * count +
2964 : sizeof(spdm_certificate_response_t) * count +
2965 : data_size);
2966 : #endif
2967 1 : free(data);
2968 1 : }
2969 :
2970 : /**
2971 : * Test 11: Normal procedure, but the retrieved certificate chain has an invalid signature
2972 : * Expected Behavior: get a LIBSPDM_STATUS_VERIF_FAIL, and receives the correct number of Certificate messages
2973 : **/
2974 1 : void libspdm_test_requester_get_certificate_case11(void **state)
2975 : {
2976 : libspdm_return_t status;
2977 : libspdm_test_context_t *spdm_test_context;
2978 : libspdm_context_t *spdm_context;
2979 : size_t cert_chain_size;
2980 : uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
2981 : void *data;
2982 : size_t data_size;
2983 : void *hash;
2984 : size_t hash_size;
2985 : const uint8_t *root_cert;
2986 : size_t root_cert_size;
2987 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
2988 : size_t count;
2989 : #endif
2990 1 : spdm_test_context = *state;
2991 1 : spdm_context = spdm_test_context->spdm_context;
2992 1 : spdm_test_context->case_id = 0xB;
2993 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
2994 : SPDM_VERSION_NUMBER_SHIFT_BIT;
2995 : /* Setting SPDM context as the first steps of the protocol has been accomplished*/
2996 1 : spdm_context->connection_info.connection_state =
2997 : LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
2998 1 : spdm_context->connection_info.capability.flags |=
2999 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
3000 : /* Loading certificate chain and saving root certificate hash*/
3001 1 : if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
3002 : m_libspdm_use_asym_algo, &data,
3003 : &data_size, &hash, &hash_size)) {
3004 0 : assert(false);
3005 : }
3006 1 : if (!libspdm_x509_get_cert_from_cert_chain(
3007 1 : (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
3008 1 : data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
3009 0 : assert(false);
3010 : }
3011 1 : spdm_context->local_context.peer_root_cert_provision_size[0] =
3012 : root_cert_size;
3013 1 : spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
3014 1 : spdm_context->connection_info.algorithm.base_hash_algo =
3015 : m_libspdm_use_hash_algo;
3016 1 : spdm_context->connection_info.algorithm.base_asym_algo =
3017 : m_libspdm_use_asym_algo;
3018 1 : spdm_context->connection_info.algorithm.req_base_asym_alg =
3019 : m_libspdm_use_req_asym_algo;
3020 :
3021 : /* Resetting message buffer*/
3022 1 : libspdm_reset_message_b(spdm_context);
3023 : /* Calculating expected number of messages received*/
3024 :
3025 1 : cert_chain_size = sizeof(cert_chain);
3026 1 : libspdm_zero_mem(cert_chain, sizeof(cert_chain));
3027 1 : status = libspdm_get_certificate(spdm_context, NULL, 0, &cert_chain_size,
3028 : cert_chain);
3029 1 : assert_int_equal(status, LIBSPDM_STATUS_VERIF_FAIL);
3030 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
3031 : count = (data_size + LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN - 1) /
3032 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
3033 : assert_int_equal(spdm_context->transcript.message_b.buffer_size,
3034 : sizeof(spdm_get_certificate_request_t) * count +
3035 : sizeof(spdm_certificate_response_t) * count +
3036 : data_size);
3037 : #endif
3038 1 : free(data);
3039 1 : }
3040 :
3041 : /**
3042 : * Test 12: Normal procedure, but the retrieved root certificate does not match
3043 : * Expected Behavior: get a LIBSPDM_STATUS_VERIF_NO_AUTHORITY, and receives the correct number of Certificate messages
3044 : **/
3045 1 : void libspdm_test_requester_get_certificate_case12(void **state)
3046 : {
3047 : libspdm_return_t status;
3048 : libspdm_test_context_t *spdm_test_context;
3049 : libspdm_context_t *spdm_context;
3050 : size_t cert_chain_size;
3051 : uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
3052 : uint8_t root_cert_buffer[LIBSPDM_MAX_CERT_CHAIN_SIZE];
3053 : void *data;
3054 : size_t data_size;
3055 : void *hash;
3056 : size_t hash_size;
3057 : const uint8_t *root_cert;
3058 : size_t root_cert_size;
3059 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
3060 : size_t count;
3061 : #endif
3062 :
3063 1 : spdm_test_context = *state;
3064 1 : spdm_context = spdm_test_context->spdm_context;
3065 1 : spdm_test_context->case_id = 0xC;
3066 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
3067 : SPDM_VERSION_NUMBER_SHIFT_BIT;
3068 : /* Setting SPDM context as the first steps of the protocol has been accomplished*/
3069 1 : spdm_context->connection_info.connection_state =
3070 : LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
3071 1 : spdm_context->connection_info.capability.flags |=
3072 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
3073 1 : if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
3074 : m_libspdm_use_asym_algo, &data,
3075 : &data_size, &hash, &hash_size)) {
3076 0 : assert(false);
3077 : }
3078 1 : if (!libspdm_x509_get_cert_from_cert_chain(
3079 1 : (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
3080 1 : data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
3081 0 : assert(false);
3082 : }
3083 : /* arbitrarily changes the root certificate on purpose*/
3084 1 : if (root_cert != NULL) {
3085 1 : memcpy(root_cert_buffer, root_cert, root_cert_size);
3086 1 : root_cert_buffer[0]++;
3087 : }
3088 1 : spdm_context->local_context.peer_root_cert_provision_size[0] =
3089 : root_cert_size;
3090 1 : spdm_context->local_context.peer_root_cert_provision[0] = root_cert_buffer;
3091 1 : spdm_context->connection_info.algorithm.base_hash_algo =
3092 : m_libspdm_use_hash_algo;
3093 1 : spdm_context->connection_info.algorithm.base_asym_algo =
3094 : m_libspdm_use_asym_algo;
3095 1 : spdm_context->connection_info.algorithm.req_base_asym_alg =
3096 : m_libspdm_use_req_asym_algo;
3097 : /* Resetting message buffer*/
3098 1 : libspdm_reset_message_b(spdm_context);
3099 : /* Calculating expected number of messages received*/
3100 1 : spdm_context->local_context.is_requester = true;
3101 :
3102 1 : cert_chain_size = sizeof(cert_chain);
3103 1 : libspdm_zero_mem(cert_chain, sizeof(cert_chain));
3104 1 : status = libspdm_get_certificate(spdm_context, NULL, 0, &cert_chain_size,
3105 : cert_chain);
3106 1 : assert_int_equal(status, LIBSPDM_STATUS_VERIF_NO_AUTHORITY);
3107 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
3108 : count = (data_size + LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN - 1) /
3109 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
3110 : assert_int_equal(spdm_context->transcript.message_b.buffer_size,
3111 : sizeof(spdm_get_certificate_request_t) * count +
3112 : sizeof(spdm_certificate_response_t) * count +
3113 : data_size);
3114 : #endif
3115 1 : free(data);
3116 1 : }
3117 :
3118 : /**
3119 : * Test 13: Gets a short certificate chain (fits in 1 message)
3120 : * Expected Behavior: receives a valid certificate chain with the correct number of Certificate messages
3121 : **/
3122 1 : void libspdm_test_requester_get_certificate_case13(void **state)
3123 : {
3124 : libspdm_return_t status;
3125 : libspdm_test_context_t *spdm_test_context;
3126 : libspdm_context_t *spdm_context;
3127 : size_t cert_chain_size;
3128 : uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
3129 : void *data;
3130 : size_t data_size;
3131 : void *hash;
3132 : size_t hash_size;
3133 : const uint8_t *root_cert;
3134 : size_t root_cert_size;
3135 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
3136 : size_t count;
3137 : #endif
3138 :
3139 : /* This case requires a short certificate chain (fits in 1 message) for testing,
3140 : * so skip when m_libspdm_use_asym_algo is other than ECC_P256 */
3141 1 : if (m_libspdm_use_asym_algo !=
3142 : SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_ECDSA_ECC_NIST_P256) {
3143 0 : return;
3144 : }
3145 :
3146 1 : spdm_test_context = *state;
3147 1 : spdm_context = spdm_test_context->spdm_context;
3148 1 : spdm_test_context->case_id = 0xD;
3149 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
3150 : SPDM_VERSION_NUMBER_SHIFT_BIT;
3151 : /* Setting SPDM context as the first steps of the protocol has been accomplished*/
3152 1 : spdm_context->connection_info.connection_state =
3153 : LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
3154 1 : spdm_context->connection_info.capability.flags |=
3155 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
3156 : /* Loading Root certificate and saving its hash*/
3157 1 : libspdm_read_responder_public_certificate_chain_by_size(
3158 : m_libspdm_use_hash_algo, m_libspdm_use_asym_algo, LIBSPDM_TEST_CERT_SMALL, &data,
3159 : &data_size, &hash, &hash_size);
3160 1 : if (!libspdm_x509_get_cert_from_cert_chain(
3161 1 : (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
3162 1 : data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
3163 0 : assert(false);
3164 : }
3165 1 : spdm_context->local_context.peer_root_cert_provision_size[0] =
3166 : root_cert_size;
3167 1 : spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
3168 1 : spdm_context->connection_info.algorithm.base_hash_algo =
3169 : m_libspdm_use_hash_algo;
3170 1 : spdm_context->connection_info.algorithm.base_asym_algo =
3171 : m_libspdm_use_asym_algo;
3172 1 : spdm_context->connection_info.algorithm.req_base_asym_alg =
3173 : m_libspdm_use_req_asym_algo;
3174 1 : spdm_context->local_context.is_requester = true;
3175 : /* Resetting message buffer*/
3176 1 : libspdm_reset_message_b(spdm_context);
3177 : /* Calculating expected number of messages received*/
3178 :
3179 1 : cert_chain_size = sizeof(cert_chain);
3180 1 : libspdm_zero_mem(cert_chain, sizeof(cert_chain));
3181 1 : status = libspdm_get_certificate(spdm_context, NULL, 0, &cert_chain_size,
3182 : cert_chain);
3183 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
3184 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
3185 : count = (data_size + LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN - 1) /
3186 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
3187 : assert_int_equal(spdm_context->transcript.message_b.buffer_size,
3188 : sizeof(spdm_get_certificate_request_t) * count +
3189 : sizeof(spdm_certificate_response_t) * count +
3190 : data_size);
3191 : #endif
3192 1 : free(data);
3193 : }
3194 :
3195 : /**
3196 : * Test 14: request a whole certificate chain byte by byte
3197 : * Expected Behavior: receives a valid certificate chain with the correct number of Certificate messages
3198 : **/
3199 1 : void libspdm_test_requester_get_certificate_case14(void **state)
3200 : {
3201 : libspdm_return_t status;
3202 : libspdm_test_context_t *spdm_test_context;
3203 : libspdm_context_t *spdm_context;
3204 : size_t cert_chain_size;
3205 : uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
3206 : void *data;
3207 : size_t data_size;
3208 : void *hash;
3209 : size_t hash_size;
3210 : const uint8_t *root_cert;
3211 : size_t root_cert_size;
3212 : uint16_t get_cert_length;
3213 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
3214 : size_t count;
3215 : #endif
3216 : /* Get certificate chain byte by byte*/
3217 1 : get_cert_length = 1;
3218 :
3219 1 : spdm_test_context = *state;
3220 1 : spdm_context = spdm_test_context->spdm_context;
3221 1 : spdm_test_context->case_id = 0xE;
3222 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
3223 : SPDM_VERSION_NUMBER_SHIFT_BIT;
3224 : /* Setting SPDM context as the first steps of the protocol has been accomplished*/
3225 1 : spdm_context->connection_info.connection_state =
3226 : LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
3227 1 : spdm_context->connection_info.capability.flags |=
3228 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
3229 : /* Loading Root certificate and saving its hash*/
3230 1 : if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
3231 : m_libspdm_use_asym_algo, &data,
3232 : &data_size, &hash, &hash_size)) {
3233 0 : assert(false);
3234 : }
3235 1 : if (!libspdm_x509_get_cert_from_cert_chain(
3236 1 : (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
3237 1 : data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
3238 0 : assert(false);
3239 : }
3240 1 : spdm_context->local_context.peer_root_cert_provision_size[0] =
3241 : root_cert_size;
3242 1 : spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
3243 1 : spdm_context->connection_info.algorithm.base_hash_algo =
3244 : m_libspdm_use_hash_algo;
3245 1 : spdm_context->connection_info.algorithm.base_asym_algo =
3246 : m_libspdm_use_asym_algo;
3247 1 : spdm_context->connection_info.algorithm.req_base_asym_alg =
3248 : m_libspdm_use_req_asym_algo;
3249 : /* Resetting message buffer*/
3250 1 : libspdm_reset_message_b(spdm_context);
3251 : /* Calculating expected number of messages received*/
3252 :
3253 1 : cert_chain_size = sizeof(cert_chain);
3254 1 : libspdm_zero_mem(cert_chain, sizeof(cert_chain));
3255 1 : status = libspdm_get_certificate_choose_length(
3256 : spdm_context, NULL, 0, get_cert_length, &cert_chain_size, cert_chain);
3257 : /* It may fail because the spdm does not support too many messages.
3258 : * assert_int_equal (status, LIBSPDM_STATUS_SUCCESS);*/
3259 : if (status == LIBSPDM_STATUS_SUCCESS) {
3260 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
3261 : count = (data_size + get_cert_length - 1) / get_cert_length;
3262 : assert_int_equal(
3263 : spdm_context->transcript.message_b.buffer_size,
3264 : sizeof(spdm_get_certificate_request_t) * count +
3265 : sizeof(spdm_certificate_response_t) * count +
3266 : data_size);
3267 : #endif
3268 : }
3269 1 : free(data);
3270 1 : }
3271 :
3272 : /**
3273 : * Test 15: request a long certificate chain
3274 : * Expected Behavior: receives a valid certificate chain with the correct number of Certificate messages
3275 : **/
3276 1 : void libspdm_test_requester_get_certificate_case15(void **state)
3277 : {
3278 : libspdm_return_t status;
3279 : libspdm_test_context_t *spdm_test_context;
3280 : libspdm_context_t *spdm_context;
3281 : size_t cert_chain_size;
3282 : uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
3283 : void *data;
3284 : size_t data_size;
3285 : void *hash;
3286 : size_t hash_size;
3287 : const uint8_t *root_cert;
3288 : size_t root_cert_size;
3289 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
3290 : size_t count;
3291 : #endif
3292 :
3293 1 : spdm_test_context = *state;
3294 1 : spdm_context = spdm_test_context->spdm_context;
3295 1 : spdm_test_context->case_id = 0xF;
3296 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
3297 : SPDM_VERSION_NUMBER_SHIFT_BIT;
3298 : /* Setting SPDM context as the first steps of the protocol has been accomplished*/
3299 1 : spdm_context->connection_info.connection_state =
3300 : LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
3301 1 : spdm_context->connection_info.capability.flags |=
3302 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
3303 : /* Loading Root certificate and saving its hash*/
3304 :
3305 1 : libspdm_read_responder_public_certificate_chain_by_size(
3306 : /*MAXUINT16_CERT signature_algo is SHA256RSA */
3307 : m_libspdm_use_hash_algo, SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048,
3308 : LIBSPDM_TEST_CERT_MAXUINT16, &data, &data_size, &hash, &hash_size);
3309 1 : if (!libspdm_x509_get_cert_from_cert_chain(
3310 1 : (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
3311 1 : data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
3312 0 : assert(false);
3313 : }
3314 1 : spdm_context->local_context.peer_root_cert_provision_size[0] =
3315 : root_cert_size;
3316 1 : spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
3317 1 : spdm_context->connection_info.algorithm.base_hash_algo =
3318 : m_libspdm_use_hash_algo;
3319 1 : spdm_context->connection_info.algorithm.base_asym_algo =
3320 : m_libspdm_use_asym_algo;
3321 1 : spdm_context->connection_info.algorithm.req_base_asym_alg =
3322 : m_libspdm_use_req_asym_algo;
3323 : /* Resetting message buffer*/
3324 1 : libspdm_reset_message_b(spdm_context);
3325 : /* Calculating expected number of messages received*/
3326 :
3327 1 : cert_chain_size = sizeof(cert_chain);
3328 1 : libspdm_zero_mem(cert_chain, sizeof(cert_chain));
3329 1 : status = libspdm_get_certificate(spdm_context, NULL, 0, &cert_chain_size,
3330 : cert_chain);
3331 : /* It may fail because the spdm does not support too long message.
3332 : * assert_int_equal (status, LIBSPDM_STATUS_SUCCESS);*/
3333 : if (status == LIBSPDM_STATUS_SUCCESS) {
3334 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
3335 : count = (data_size + LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN - 1) /
3336 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
3337 : assert_int_equal(
3338 : spdm_context->transcript.message_b.buffer_size,
3339 : sizeof(spdm_get_certificate_request_t) * count +
3340 : sizeof(spdm_certificate_response_t) * count +
3341 : data_size);
3342 : #endif
3343 : }
3344 1 : free(data);
3345 1 : }
3346 :
3347 : /**
3348 : * Test 16: receiving an unexpected ERROR message from the responder.
3349 : * There are tests for all named codes, including some reserved ones
3350 : * (namely, 0x00, 0x0b, 0x0c, 0x3f, 0xfd, 0xfe).
3351 : * However, for having specific test cases, it is excluded from this case:
3352 : * Busy (0x03), ResponseNotReady (0x42), and RequestResync (0x43).
3353 : * Expected behavior: client returns a status of LIBSPDM_STATUS_ERROR_PEER.
3354 : **/
3355 1 : void libspdm_test_requester_get_certificate_case16(void **state) {
3356 : libspdm_return_t status;
3357 : libspdm_test_context_t *spdm_test_context;
3358 : libspdm_context_t *spdm_context;
3359 : size_t cert_chain_size;
3360 : uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
3361 : void *data;
3362 : size_t data_size;
3363 : void *hash;
3364 : size_t hash_size;
3365 : const uint8_t *root_cert;
3366 : size_t root_cert_size;
3367 : uint16_t error_code;
3368 :
3369 1 : spdm_test_context = *state;
3370 1 : spdm_context = spdm_test_context->spdm_context;
3371 1 : spdm_test_context->case_id = 0x10;
3372 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_11 <<
3373 : SPDM_VERSION_NUMBER_SHIFT_BIT;
3374 1 : spdm_context->connection_info.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
3375 1 : libspdm_read_responder_public_certificate_chain (m_libspdm_use_hash_algo,
3376 : m_libspdm_use_asym_algo,
3377 : &data, &data_size,
3378 : &hash, &hash_size);
3379 1 : if (!libspdm_x509_get_cert_from_cert_chain(
3380 1 : (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
3381 1 : data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
3382 0 : assert(false);
3383 : }
3384 1 : spdm_context->local_context.peer_root_cert_provision_size[0] = root_cert_size;
3385 1 : spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
3386 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
3387 1 : spdm_context->connection_info.algorithm.base_asym_algo = m_libspdm_use_asym_algo;
3388 1 : spdm_context->connection_info.algorithm.req_base_asym_alg = m_libspdm_use_req_asym_algo;
3389 :
3390 1 : error_code = LIBSPDM_ERROR_CODE_RESERVED_00;
3391 19 : while(error_code <= 0xff) {
3392 18 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
3393 18 : libspdm_reset_message_b(spdm_context);
3394 :
3395 18 : cert_chain_size = sizeof(cert_chain);
3396 18 : libspdm_zero_mem (cert_chain, sizeof(cert_chain));
3397 18 : status = libspdm_get_certificate (spdm_context, NULL, 0, &cert_chain_size, cert_chain);
3398 18 : LIBSPDM_ASSERT_INT_EQUAL_CASE (status, LIBSPDM_STATUS_ERROR_PEER, error_code);
3399 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
3400 : /* assert_int_equal (spdm_context->transcript.message_b.buffer_size, 0);*/
3401 : LIBSPDM_ASSERT_INT_EQUAL_CASE (spdm_context->transcript.message_b.buffer_size, 0,
3402 : error_code);
3403 : #endif
3404 :
3405 18 : error_code++;
3406 18 : if(error_code == SPDM_ERROR_CODE_BUSY) { /*busy is treated in cases 5 and 6*/
3407 1 : error_code = SPDM_ERROR_CODE_UNEXPECTED_REQUEST;
3408 : }
3409 18 : if(error_code == LIBSPDM_ERROR_CODE_RESERVED_0D) { /*skip some reserved error codes (0d to 3e)*/
3410 1 : error_code = LIBSPDM_ERROR_CODE_RESERVED_3F;
3411 : }
3412 18 : if(error_code == SPDM_ERROR_CODE_RESPONSE_NOT_READY) { /*skip response not ready, request resync, and some reserved codes (44 to fc)*/
3413 1 : error_code = LIBSPDM_ERROR_CODE_RESERVED_FD;
3414 : }
3415 : }
3416 :
3417 1 : free(data);
3418 1 : }
3419 :
3420 : /**
3421 : * Test 17: Normal case, get a certificate chain start not with root cert. Validates certificate by using a preloaded chain.
3422 : * Expected Behavior: receives the correct number of Certificate messages
3423 : **/
3424 1 : void libspdm_test_requester_get_certificate_case17(void **state)
3425 : {
3426 : libspdm_return_t status;
3427 : libspdm_test_context_t *spdm_test_context;
3428 : libspdm_context_t *spdm_context;
3429 : size_t cert_chain_size;
3430 : uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
3431 : void *data;
3432 : size_t data_size;
3433 : void *hash;
3434 : size_t hash_size;
3435 : const uint8_t *root_cert;
3436 : size_t root_cert_size;
3437 :
3438 1 : spdm_test_context = *state;
3439 1 : spdm_context = spdm_test_context->spdm_context;
3440 1 : spdm_test_context->case_id = 0x11;
3441 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
3442 : SPDM_VERSION_NUMBER_SHIFT_BIT;
3443 1 : spdm_context->connection_info.connection_state =
3444 : LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
3445 1 : spdm_context->connection_info.capability.flags |=
3446 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
3447 1 : if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
3448 : m_libspdm_use_asym_algo, &data,
3449 : &data_size, &hash, &hash_size)) {
3450 0 : assert(false);
3451 : }
3452 1 : if (!libspdm_x509_get_cert_from_cert_chain(
3453 1 : (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
3454 1 : data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
3455 0 : assert(false);
3456 : }
3457 :
3458 1 : spdm_context->local_context.peer_root_cert_provision_size[0] = root_cert_size;
3459 1 : spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
3460 1 : libspdm_reset_message_b(spdm_context);
3461 1 : spdm_context->connection_info.algorithm.base_hash_algo =
3462 : m_libspdm_use_hash_algo;
3463 1 : spdm_context->connection_info.algorithm.base_asym_algo =
3464 : m_libspdm_use_asym_algo;
3465 1 : spdm_context->connection_info.algorithm.req_base_asym_alg =
3466 : m_libspdm_use_req_asym_algo;
3467 1 : spdm_context->local_context.is_requester = true;
3468 :
3469 1 : cert_chain_size = sizeof(cert_chain);
3470 1 : libspdm_zero_mem(cert_chain, sizeof(cert_chain));
3471 1 : status = libspdm_get_certificate(spdm_context, NULL, 0, &cert_chain_size,
3472 : cert_chain);
3473 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
3474 1 : free(data);
3475 1 : }
3476 :
3477 : /**
3478 : * Test 18: Fail case, get a certificate chain start not with root cert and with wrong signature. Validates certificate by using a preloaded chain.
3479 : * Expected Behavior: receives the correct number of Certificate messages
3480 : **/
3481 1 : void libspdm_test_requester_get_certificate_case18(void **state)
3482 : {
3483 : libspdm_return_t status;
3484 : libspdm_test_context_t *spdm_test_context;
3485 : libspdm_context_t *spdm_context;
3486 : size_t cert_chain_size;
3487 : uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
3488 : void *data;
3489 : size_t data_size;
3490 : void *hash;
3491 : size_t hash_size;
3492 : const uint8_t *root_cert;
3493 : size_t root_cert_size;
3494 :
3495 1 : spdm_test_context = *state;
3496 1 : spdm_context = spdm_test_context->spdm_context;
3497 1 : spdm_test_context->case_id = 0x12;
3498 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
3499 : SPDM_VERSION_NUMBER_SHIFT_BIT;
3500 1 : spdm_context->connection_info.connection_state =
3501 : LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
3502 1 : spdm_context->connection_info.capability.flags |=
3503 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
3504 1 : if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
3505 : m_libspdm_use_asym_algo, &data,
3506 : &data_size, &hash, &hash_size)) {
3507 0 : assert(false);
3508 : }
3509 1 : if (!libspdm_x509_get_cert_from_cert_chain(
3510 1 : (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
3511 1 : data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
3512 0 : assert(false);
3513 : }
3514 :
3515 1 : spdm_context->local_context.peer_root_cert_provision_size[0] = root_cert_size;
3516 1 : spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
3517 1 : libspdm_reset_message_b(spdm_context);
3518 1 : spdm_context->connection_info.algorithm.base_hash_algo =
3519 : m_libspdm_use_hash_algo;
3520 1 : spdm_context->connection_info.algorithm.base_asym_algo =
3521 : m_libspdm_use_asym_algo;
3522 1 : spdm_context->connection_info.algorithm.req_base_asym_alg =
3523 : m_libspdm_use_req_asym_algo;
3524 :
3525 1 : cert_chain_size = sizeof(cert_chain);
3526 1 : libspdm_zero_mem(cert_chain, sizeof(cert_chain));
3527 1 : status = libspdm_get_certificate(spdm_context, NULL, 0, &cert_chain_size,
3528 : cert_chain);
3529 1 : assert_int_equal(status, LIBSPDM_STATUS_VERIF_FAIL);
3530 1 : free(data);
3531 1 : }
3532 :
3533 : /**
3534 : * Test 19: Normal procedure, but one certificate in the retrieved certificate chain past its expiration date.
3535 : * Expected Behavior: get a LIBSPDM_STATUS_VERIF_FAIL, and receives the correct number of Certificate messages
3536 : **/
3537 1 : void libspdm_test_requester_get_certificate_case19(void **state)
3538 : {
3539 : libspdm_return_t status;
3540 : libspdm_test_context_t *spdm_test_context;
3541 : libspdm_context_t *spdm_context;
3542 : size_t cert_chain_size;
3543 : uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
3544 : void *data;
3545 : size_t data_size;
3546 : void *hash;
3547 : size_t hash_size;
3548 : const uint8_t *root_cert;
3549 : size_t root_cert_size;
3550 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
3551 : size_t count;
3552 : #endif
3553 :
3554 1 : spdm_test_context = *state;
3555 1 : spdm_context = spdm_test_context->spdm_context;
3556 1 : spdm_test_context->case_id = 0x13;
3557 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
3558 : SPDM_VERSION_NUMBER_SHIFT_BIT;
3559 : /* Setting SPDM context as the first steps of the protocol has been accomplished*/
3560 1 : spdm_context->connection_info.connection_state =
3561 : LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
3562 1 : spdm_context->connection_info.capability.flags |=
3563 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
3564 : /* Loading the target expiration certificate chain and saving root certificate hash
3565 : * "rsa3072_Expiration/bundle_responder.certchain.der"*/
3566 1 : libspdm_libspdm_read_responder_public_certificate_chain_expiration(&data,
3567 : &data_size, &hash,
3568 : &hash_size);
3569 1 : libspdm_x509_get_cert_from_cert_chain(
3570 1 : (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
3571 1 : data_size - sizeof(spdm_cert_chain_t) - hash_size, 0,
3572 : &root_cert, &root_cert_size);
3573 1 : spdm_context->local_context.peer_root_cert_provision_size[0] =
3574 : root_cert_size;
3575 1 : spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
3576 1 : spdm_context->connection_info.algorithm.base_hash_algo =
3577 : SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_256;
3578 1 : spdm_context->connection_info.algorithm.base_asym_algo =
3579 : m_libspdm_use_asym_algo;
3580 1 : spdm_context->connection_info.algorithm.req_base_asym_alg =
3581 : m_libspdm_use_req_asym_algo;
3582 : /* Resetting message buffer*/
3583 1 : libspdm_reset_message_b(spdm_context);
3584 : /* Calculating expected number of messages received*/
3585 :
3586 1 : cert_chain_size = sizeof(cert_chain);
3587 1 : libspdm_zero_mem(cert_chain, sizeof(cert_chain));
3588 1 : status = libspdm_get_certificate(spdm_context, NULL, 0, &cert_chain_size,
3589 : cert_chain);
3590 1 : assert_int_equal(status, LIBSPDM_STATUS_VERIF_FAIL);
3591 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
3592 : count = (data_size + LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN - 1) /
3593 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
3594 : assert_int_equal(spdm_context->transcript.message_b.buffer_size,
3595 : sizeof(spdm_get_certificate_request_t) * count +
3596 : sizeof(spdm_certificate_response_t) * count +
3597 : data_size);
3598 : #endif
3599 1 : free(data);
3600 1 : }
3601 :
3602 : /**
3603 : * Test 20: Fail case, request a certificate chain, responder return portion_length is 0.
3604 : * Expected Behavior:returns a status of RETURN_DEVICE_ERROR.
3605 : **/
3606 1 : void libspdm_test_requester_get_certificate_case20(void **state)
3607 : {
3608 : libspdm_return_t status;
3609 : libspdm_test_context_t *spdm_test_context;
3610 : libspdm_context_t *spdm_context;
3611 : size_t cert_chain_size;
3612 : uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
3613 : void *data;
3614 : size_t data_size;
3615 : void *hash;
3616 : size_t hash_size;
3617 : const uint8_t *root_cert;
3618 : size_t root_cert_size;
3619 :
3620 1 : spdm_test_context = *state;
3621 1 : spdm_context = spdm_test_context->spdm_context;
3622 1 : spdm_test_context->case_id = 0x14;
3623 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
3624 : SPDM_VERSION_NUMBER_SHIFT_BIT;
3625 1 : spdm_context->connection_info.connection_state =
3626 : LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
3627 1 : spdm_context->connection_info.capability.flags |=
3628 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
3629 1 : if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
3630 : m_libspdm_use_asym_algo, &data,
3631 : &data_size, &hash, &hash_size)) {
3632 0 : assert(false);
3633 : }
3634 1 : if (!libspdm_x509_get_cert_from_cert_chain(
3635 1 : (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
3636 1 : data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
3637 0 : assert(false);
3638 : }
3639 1 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "root cert data :\n"));
3640 1 : libspdm_dump_hex(
3641 : root_cert,
3642 : root_cert_size);
3643 1 : spdm_context->local_context.peer_root_cert_provision_size[0] =
3644 : root_cert_size;
3645 1 : spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
3646 1 : libspdm_reset_message_b(spdm_context);
3647 1 : spdm_context->connection_info.algorithm.base_hash_algo =
3648 : m_libspdm_use_hash_algo;
3649 1 : spdm_context->connection_info.algorithm.base_asym_algo =
3650 : m_libspdm_use_asym_algo;
3651 1 : spdm_context->connection_info.algorithm.req_base_asym_alg =
3652 : m_libspdm_use_req_asym_algo;
3653 :
3654 1 : cert_chain_size = sizeof(cert_chain);
3655 1 : libspdm_zero_mem(cert_chain, sizeof(cert_chain));
3656 1 : status = libspdm_get_certificate(spdm_context, NULL, 0, &cert_chain_size,
3657 : cert_chain);
3658 1 : assert_int_equal(status, LIBSPDM_STATUS_INVALID_MSG_FIELD);
3659 1 : free(data);
3660 1 : }
3661 :
3662 : /**
3663 : * Test 21: Fail case, request a certificate chain, responder return portion_length > spdm_request.length.
3664 : * Expected Behavior:returns a status of RETURN_DEVICE_ERROR.
3665 : **/
3666 1 : void libspdm_test_requester_get_certificate_case21(void **state)
3667 : {
3668 : libspdm_return_t status;
3669 : libspdm_test_context_t *spdm_test_context;
3670 : libspdm_context_t *spdm_context;
3671 : size_t cert_chain_size;
3672 : uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
3673 : void *data;
3674 : size_t data_size;
3675 : void *hash;
3676 : size_t hash_size;
3677 : const uint8_t *root_cert;
3678 : size_t root_cert_size;
3679 :
3680 1 : spdm_test_context = *state;
3681 1 : spdm_context = spdm_test_context->spdm_context;
3682 1 : spdm_test_context->case_id = 0x15;
3683 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
3684 : SPDM_VERSION_NUMBER_SHIFT_BIT;
3685 1 : spdm_context->connection_info.connection_state =
3686 : LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
3687 1 : spdm_context->connection_info.capability.flags |=
3688 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
3689 1 : if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
3690 : m_libspdm_use_asym_algo, &data,
3691 : &data_size, &hash, &hash_size)) {
3692 0 : assert(false);
3693 : }
3694 1 : if (!libspdm_x509_get_cert_from_cert_chain(
3695 1 : (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
3696 1 : data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
3697 0 : assert(false);
3698 : }
3699 1 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "root cert data :\n"));
3700 1 : libspdm_dump_hex(
3701 : root_cert,
3702 : root_cert_size);
3703 1 : spdm_context->local_context.peer_root_cert_provision_size[0] =
3704 : root_cert_size;
3705 1 : spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
3706 1 : libspdm_reset_message_b(spdm_context);
3707 1 : spdm_context->connection_info.algorithm.base_hash_algo =
3708 : m_libspdm_use_hash_algo;
3709 1 : spdm_context->connection_info.algorithm.base_asym_algo =
3710 : m_libspdm_use_asym_algo;
3711 1 : spdm_context->connection_info.algorithm.req_base_asym_alg =
3712 : m_libspdm_use_req_asym_algo;
3713 :
3714 1 : cert_chain_size = sizeof(cert_chain);
3715 1 : libspdm_zero_mem(cert_chain, sizeof(cert_chain));
3716 1 : status = libspdm_get_certificate(spdm_context, NULL, 0, &cert_chain_size,
3717 : cert_chain);
3718 1 : assert_int_equal(status, LIBSPDM_STATUS_INVALID_MSG_FIELD);
3719 1 : free(data);
3720 1 : }
3721 :
3722 : /**
3723 : * Test 22: Fail case, request a certificate chain,
3724 : * spdm_request.offset + spdm_response->portion_length + spdm_response->remainder_length !=
3725 : * total_responder_cert_chain_buffer_length.
3726 : * Expected Behavior:returns a status of LIBSPDM_STATUS_INVALID_MSG_FIELD.
3727 : **/
3728 1 : void libspdm_test_requester_get_certificate_case22(void **state)
3729 : {
3730 : libspdm_return_t status;
3731 : libspdm_test_context_t *spdm_test_context;
3732 : libspdm_context_t *spdm_context;
3733 : size_t cert_chain_size;
3734 : uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
3735 : void *data;
3736 : size_t data_size;
3737 : void *hash;
3738 : size_t hash_size;
3739 : const uint8_t *root_cert;
3740 : size_t root_cert_size;
3741 :
3742 1 : spdm_test_context = *state;
3743 1 : spdm_context = spdm_test_context->spdm_context;
3744 1 : spdm_test_context->case_id = 0x16;
3745 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
3746 : SPDM_VERSION_NUMBER_SHIFT_BIT;
3747 1 : spdm_context->connection_info.connection_state =
3748 : LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
3749 1 : spdm_context->connection_info.capability.flags |=
3750 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
3751 1 : if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
3752 : m_libspdm_use_asym_algo, &data,
3753 : &data_size, &hash, &hash_size)) {
3754 0 : assert(false);
3755 : }
3756 1 : if (!libspdm_x509_get_cert_from_cert_chain(
3757 1 : (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
3758 1 : data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
3759 0 : assert(false);
3760 : }
3761 1 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "root cert data :\n"));
3762 1 : libspdm_dump_hex(
3763 : root_cert,
3764 : root_cert_size);
3765 1 : spdm_context->local_context.peer_root_cert_provision_size[0] =
3766 : root_cert_size;
3767 1 : spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
3768 1 : libspdm_reset_message_b(spdm_context);
3769 1 : spdm_context->connection_info.algorithm.base_hash_algo =
3770 : m_libspdm_use_hash_algo;
3771 1 : spdm_context->connection_info.algorithm.base_asym_algo =
3772 : m_libspdm_use_asym_algo;
3773 1 : spdm_context->connection_info.algorithm.req_base_asym_alg =
3774 : m_libspdm_use_req_asym_algo;
3775 :
3776 1 : cert_chain_size = sizeof(cert_chain);
3777 1 : libspdm_zero_mem(cert_chain, sizeof(cert_chain));
3778 1 : status = libspdm_get_certificate(spdm_context, NULL, 0, &cert_chain_size,
3779 : cert_chain);
3780 1 : assert_int_equal(status, LIBSPDM_STATUS_INVALID_MSG_FIELD);
3781 1 : free(data);
3782 1 : }
3783 :
3784 : /**
3785 : * Test 23: request messages are successfully sent and response messages are successfully
3786 : * received. Buffer B already has arbitrary data.
3787 : * Expected Behavior: requester returns the status RETURN_SUCCESS and CERTIFICATE messages are
3788 : * received, buffer B appends the exchanged GET_CERTIFICATE and CERTIFICATE messages.
3789 : **/
3790 1 : void libspdm_test_requester_get_certificate_case23(void **state)
3791 : {
3792 : libspdm_return_t status;
3793 : libspdm_test_context_t *spdm_test_context;
3794 : libspdm_context_t *spdm_context;
3795 : size_t cert_chain_size;
3796 : uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
3797 : void *data;
3798 : size_t data_size;
3799 : void *hash;
3800 : size_t hash_size;
3801 : const uint8_t *root_cert;
3802 : size_t root_cert_size;
3803 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
3804 : size_t arbitrary_size;
3805 : #endif
3806 :
3807 1 : spdm_test_context = *state;
3808 1 : spdm_context = spdm_test_context->spdm_context;
3809 1 : spdm_test_context->case_id = 0x17;
3810 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
3811 : SPDM_VERSION_NUMBER_SHIFT_BIT;
3812 1 : spdm_context->connection_info.connection_state =
3813 : LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
3814 1 : spdm_context->connection_info.capability.flags |=
3815 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
3816 1 : if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
3817 : m_libspdm_use_asym_algo, &data,
3818 : &data_size, &hash, &hash_size)) {
3819 0 : assert(false);
3820 : }
3821 1 : if (!libspdm_x509_get_cert_from_cert_chain(
3822 1 : (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
3823 1 : data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
3824 0 : assert(false);
3825 : }
3826 1 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "root cert data :\n"));
3827 1 : libspdm_dump_hex(root_cert, root_cert_size);
3828 1 : spdm_context->local_context.peer_root_cert_provision_size[0] = root_cert_size;
3829 1 : spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
3830 1 : libspdm_reset_message_b(spdm_context);
3831 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
3832 1 : spdm_context->connection_info.algorithm.base_asym_algo = m_libspdm_use_asym_algo;
3833 1 : spdm_context->connection_info.algorithm.req_base_asym_alg = m_libspdm_use_req_asym_algo;
3834 1 : spdm_context->local_context.is_requester = true;
3835 :
3836 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
3837 : /*filling B with arbitrary data*/
3838 : arbitrary_size = 8;
3839 : libspdm_set_mem(spdm_context->transcript.message_b.buffer, arbitrary_size, (uint8_t) 0xEE);
3840 : spdm_context->transcript.message_b.buffer_size = arbitrary_size;
3841 : #endif
3842 1 : cert_chain_size = sizeof(cert_chain);
3843 1 : libspdm_zero_mem(cert_chain, sizeof(cert_chain));
3844 1 : status = libspdm_get_certificate(spdm_context, NULL, 0, &cert_chain_size, cert_chain);
3845 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
3846 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
3847 : libspdm_dump_hex(m_libspdm_local_buffer, m_libspdm_local_buffer_size);
3848 : assert_int_equal(spdm_context->transcript.message_b.buffer_size,
3849 : (arbitrary_size + m_libspdm_local_buffer_size));
3850 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "m_libspdm_local_buffer (0x%x):\n",
3851 : m_libspdm_local_buffer_size));
3852 : libspdm_dump_hex(m_libspdm_local_buffer, m_libspdm_local_buffer_size);
3853 : assert_memory_equal(spdm_context->transcript.message_b.buffer + arbitrary_size,
3854 : m_libspdm_local_buffer, m_libspdm_local_buffer_size);
3855 : #endif
3856 1 : free(data);
3857 1 : }
3858 :
3859 : /**
3860 : * Test 24: test the Alias Cert model, hardware identify OID is found in AliasCert model cert
3861 : * Expected Behavior: return RETURN_SECURITY_VIOLATION
3862 : **/
3863 1 : void libspdm_test_requester_get_certificate_case24(void **state)
3864 : {
3865 : libspdm_return_t status;
3866 : libspdm_test_context_t *spdm_test_context;
3867 : libspdm_context_t *spdm_context;
3868 : size_t cert_chain_size;
3869 : uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
3870 : void *data;
3871 : size_t data_size;
3872 : void *hash;
3873 : size_t hash_size;
3874 : const uint8_t *root_cert;
3875 : size_t root_cert_size;
3876 :
3877 1 : spdm_test_context = *state;
3878 1 : spdm_context = spdm_test_context->spdm_context;
3879 1 : spdm_test_context->case_id = 0x18;
3880 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
3881 : SPDM_VERSION_NUMBER_SHIFT_BIT;
3882 1 : spdm_context->connection_info.connection_state =
3883 : LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
3884 1 : spdm_context->connection_info.capability.flags |=
3885 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
3886 : /*The only different setting with normal case2: cert model is AliasCert model*/
3887 1 : spdm_context->connection_info.capability.flags |=
3888 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_ALIAS_CERT_CAP;
3889 1 : if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
3890 : m_libspdm_use_asym_algo, &data,
3891 : &data_size, &hash, &hash_size)) {
3892 0 : assert(false);
3893 : }
3894 1 : if (!libspdm_x509_get_cert_from_cert_chain(
3895 1 : (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
3896 1 : data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
3897 0 : assert(false);
3898 : }
3899 1 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "root cert data :\n"));
3900 1 : LIBSPDM_INTERNAL_DUMP_HEX(
3901 : root_cert,
3902 : root_cert_size);
3903 1 : spdm_context->local_context.peer_root_cert_provision_size[0] =
3904 : root_cert_size;
3905 1 : spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
3906 1 : libspdm_reset_message_b(spdm_context);
3907 1 : spdm_context->connection_info.algorithm.base_hash_algo =
3908 : m_libspdm_use_hash_algo;
3909 1 : spdm_context->connection_info.algorithm.base_asym_algo =
3910 : m_libspdm_use_asym_algo;
3911 1 : spdm_context->connection_info.algorithm.req_base_asym_alg =
3912 : m_libspdm_use_req_asym_algo;
3913 :
3914 1 : cert_chain_size = sizeof(cert_chain);
3915 1 : libspdm_zero_mem(cert_chain, sizeof(cert_chain));
3916 1 : status = libspdm_get_certificate(spdm_context, NULL, 0, &cert_chain_size,
3917 : cert_chain);
3918 1 : assert_int_equal(status, LIBSPDM_STATUS_VERIF_FAIL);
3919 1 : free(data);
3920 1 : }
3921 : #if LIBSPDM_ENABLE_CAPABILITY_CHAL_CAP
3922 : /**
3923 : * Test 25: Normal case, request a certificate chain
3924 : * Expected Behavior: receives a valid certificate chain with the correct number of Certificate messages
3925 : **/
3926 1 : void libspdm_test_requester_get_certificate_case25(void **state)
3927 : {
3928 : libspdm_return_t status;
3929 : libspdm_test_context_t *spdm_test_context;
3930 : libspdm_context_t *spdm_context;
3931 : size_t cert_chain_size;
3932 : uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
3933 : void *data;
3934 : void *data1;
3935 : size_t data_size;
3936 : size_t data1_size;
3937 : void *hash;
3938 : void *hash1;
3939 : size_t hash_size;
3940 : size_t hash1_size;
3941 : const uint8_t *root_cert;
3942 : const uint8_t *root_cert1;
3943 : size_t root_cert_size;
3944 : size_t root_cert1_size;
3945 : uint8_t slot_id;
3946 : uint8_t measurement_hash[LIBSPDM_MAX_HASH_SIZE];
3947 :
3948 1 : spdm_test_context = *state;
3949 1 : spdm_context = spdm_test_context->spdm_context;
3950 1 : spdm_test_context->case_id = 0x19;
3951 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_11 <<
3952 : SPDM_VERSION_NUMBER_SHIFT_BIT;
3953 1 : spdm_context->connection_info.connection_state =
3954 : LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
3955 1 : spdm_context->connection_info.capability.flags |=
3956 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
3957 1 : spdm_context->connection_info.capability.flags &=
3958 : ~SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_ALIAS_CERT_CAP;
3959 1 : spdm_context->connection_info.capability.flags |=
3960 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHAL_CAP;
3961 1 : libspdm_reset_message_a(spdm_context);
3962 1 : libspdm_reset_message_b(spdm_context);
3963 1 : libspdm_reset_message_c(spdm_context);
3964 1 : spdm_context->connection_info.algorithm.base_hash_algo =
3965 : m_libspdm_use_hash_algo;
3966 1 : spdm_context->connection_info.algorithm.base_asym_algo =
3967 : m_libspdm_use_asym_algo;
3968 1 : spdm_context->connection_info.algorithm.req_base_asym_alg =
3969 : m_libspdm_use_req_asym_algo;
3970 1 : spdm_context->local_context.is_requester = true;
3971 :
3972 1 : if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
3973 : m_libspdm_use_asym_algo, &data,
3974 : &data_size, &hash, &hash_size)) {
3975 0 : assert(false);
3976 : }
3977 1 : if (!libspdm_x509_get_cert_from_cert_chain(
3978 1 : (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
3979 1 : data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
3980 0 : assert(false);
3981 : }
3982 1 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "root cert data :\n"));
3983 1 : libspdm_dump_hex(
3984 : root_cert,
3985 : root_cert_size);
3986 1 : spdm_context->local_context.peer_root_cert_provision_size[0] =
3987 : root_cert_size;
3988 1 : spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
3989 :
3990 1 : libspdm_read_responder_public_certificate_chain_per_slot(1, m_libspdm_use_hash_algo,
3991 : m_libspdm_use_asym_algo, &data1,
3992 : &data1_size, &hash1, &hash1_size);
3993 1 : libspdm_x509_get_cert_from_cert_chain((uint8_t *)data1 + sizeof(spdm_cert_chain_t) + hash1_size,
3994 1 : data1_size - sizeof(spdm_cert_chain_t) - hash1_size, 0,
3995 : &root_cert1, &root_cert1_size);
3996 1 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "root cert data :\n"));
3997 1 : libspdm_dump_hex(
3998 : root_cert1,
3999 : root_cert1_size);
4000 1 : spdm_context->local_context.peer_root_cert_provision_size[1] =
4001 : root_cert1_size;
4002 1 : spdm_context->local_context.peer_root_cert_provision[1] = root_cert1;
4003 :
4004 1 : m_get_cert = true;
4005 3 : for (slot_id = 0; slot_id < 2; slot_id++) {
4006 2 : cert_chain_size = sizeof(cert_chain);
4007 2 : libspdm_zero_mem(cert_chain, sizeof(cert_chain));
4008 2 : status = libspdm_get_certificate(spdm_context, NULL, slot_id, &cert_chain_size,
4009 : cert_chain);
4010 2 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "libspdm_get_certificate - %xu\n", status));
4011 2 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
4012 : }
4013 :
4014 1 : libspdm_reset_message_b(spdm_context);
4015 1 : m_get_cert = false;
4016 3 : for (slot_id = 0; slot_id < 2; slot_id++) {
4017 2 : libspdm_zero_mem(measurement_hash, sizeof(measurement_hash));
4018 2 : status = libspdm_challenge(
4019 : spdm_context, NULL, slot_id,
4020 : SPDM_CHALLENGE_REQUEST_NO_MEASUREMENT_SUMMARY_HASH,
4021 : measurement_hash, NULL);
4022 2 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "libspdm_challenge - %xu\n", status));
4023 2 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
4024 : }
4025 :
4026 1 : free(data);
4027 1 : free(data1);
4028 1 : }
4029 : #endif
4030 : /**
4031 : * Test 26: Normal case, request a certificate chain in a session
4032 : * Expected Behavior: receives a valid certificate chain with the correct number of Certificate messages
4033 : **/
4034 1 : void libspdm_test_requester_get_certificate_case26(void **state)
4035 : {
4036 : libspdm_return_t status;
4037 : libspdm_test_context_t *spdm_test_context;
4038 : libspdm_context_t *spdm_context;
4039 : size_t cert_chain_size;
4040 : uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
4041 : void *data;
4042 : size_t data_size;
4043 : void *hash;
4044 : size_t hash_size;
4045 : const uint8_t *root_cert;
4046 : size_t root_cert_size;
4047 : uint32_t session_id;
4048 : libspdm_session_info_t *session_info;
4049 :
4050 1 : spdm_test_context = *state;
4051 1 : spdm_context = spdm_test_context->spdm_context;
4052 1 : spdm_test_context->case_id = 0x1A;
4053 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
4054 : SPDM_VERSION_NUMBER_SHIFT_BIT;
4055 1 : spdm_context->connection_info.connection_state =
4056 : LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
4057 1 : spdm_context->connection_info.capability.flags |=
4058 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
4059 1 : spdm_context->connection_info.capability.flags |=
4060 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_ALIAS_CERT_CAP;
4061 1 : spdm_context->connection_info.capability.flags &=
4062 : ~SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_ALIAS_CERT_CAP;
4063 1 : spdm_context->connection_info.capability.flags |=
4064 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_PSK_CAP;
4065 1 : spdm_context->connection_info.capability.flags |=
4066 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_ENCRYPT_CAP;
4067 1 : spdm_context->connection_info.capability.flags |=
4068 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MAC_CAP;
4069 1 : spdm_context->local_context.capability.flags |=
4070 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_PSK_CAP;
4071 1 : spdm_context->local_context.capability.flags |=
4072 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_ENCRYPT_CAP;
4073 1 : spdm_context->local_context.capability.flags |=
4074 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MAC_CAP;
4075 1 : spdm_context->connection_info.algorithm.dhe_named_group =
4076 : m_libspdm_use_dhe_algo;
4077 1 : spdm_context->connection_info.algorithm.aead_cipher_suite =
4078 : m_libspdm_use_aead_algo;
4079 :
4080 1 : if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
4081 : m_libspdm_use_asym_algo, &data,
4082 : &data_size, &hash, &hash_size)) {
4083 0 : assert(false);
4084 : }
4085 1 : if (!libspdm_x509_get_cert_from_cert_chain(
4086 1 : (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
4087 1 : data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
4088 0 : assert(false);
4089 : }
4090 1 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "root cert data :\n"));
4091 1 : libspdm_dump_hex(
4092 : root_cert,
4093 : root_cert_size);
4094 1 : spdm_context->local_context.peer_root_cert_provision_size[0] =
4095 : root_cert_size;
4096 1 : spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
4097 1 : libspdm_reset_message_b(spdm_context);
4098 1 : spdm_context->connection_info.algorithm.base_hash_algo =
4099 : m_libspdm_use_hash_algo;
4100 1 : spdm_context->connection_info.algorithm.base_asym_algo =
4101 : m_libspdm_use_asym_algo;
4102 1 : spdm_context->connection_info.algorithm.req_base_asym_alg =
4103 : m_libspdm_use_req_asym_algo;
4104 1 : spdm_context->local_context.is_requester = true;
4105 :
4106 1 : session_id = 0xFFFFFFFF;
4107 1 : session_info = &spdm_context->session_info[0];
4108 1 : libspdm_session_info_init(spdm_context, session_info, session_id, true);
4109 1 : libspdm_secured_message_set_session_state(session_info->secured_message_context,
4110 : LIBSPDM_SESSION_STATE_ESTABLISHED);
4111 :
4112 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
4113 : session_info->session_transcript.message_m.buffer_size =
4114 : session_info->session_transcript.message_m.max_buffer_size;
4115 : #endif
4116 1 : cert_chain_size = sizeof(cert_chain);
4117 1 : libspdm_zero_mem(cert_chain, sizeof(cert_chain));
4118 1 : status = libspdm_get_certificate_ex(spdm_context, &session_id,
4119 : 0, &cert_chain_size,
4120 : cert_chain, NULL, 0);
4121 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
4122 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
4123 : assert_int_equal(session_info->session_transcript.message_m.buffer_size, 0);
4124 : #endif
4125 1 : free(data);
4126 1 : }
4127 :
4128 : /**
4129 : * Test 27: Fail case, responder return wrong SlotID 3, but it should be equal with SlotID 0 in request message.
4130 : * Expected Behavior:returns a status of INVALID_MSG_FIELD.
4131 : **/
4132 1 : void libspdm_test_requester_get_certificate_case27(void **state)
4133 : {
4134 : libspdm_return_t status;
4135 : libspdm_test_context_t *spdm_test_context;
4136 : libspdm_context_t *spdm_context;
4137 : size_t cert_chain_size;
4138 : uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
4139 : void *data;
4140 : size_t data_size;
4141 : void *hash;
4142 : size_t hash_size;
4143 : const uint8_t *root_cert;
4144 : size_t root_cert_size;
4145 :
4146 1 : spdm_test_context = *state;
4147 1 : spdm_context = spdm_test_context->spdm_context;
4148 1 : spdm_test_context->case_id = 0x1B;
4149 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
4150 : SPDM_VERSION_NUMBER_SHIFT_BIT;
4151 1 : spdm_context->connection_info.connection_state =
4152 : LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
4153 1 : spdm_context->connection_info.capability.flags |=
4154 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
4155 1 : if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
4156 : m_libspdm_use_asym_algo, &data,
4157 : &data_size, &hash, &hash_size)) {
4158 0 : assert(false);
4159 : }
4160 1 : if (!libspdm_x509_get_cert_from_cert_chain(
4161 1 : (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
4162 1 : data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
4163 0 : assert(false);
4164 : }
4165 1 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "root cert data :\n"));
4166 1 : libspdm_dump_hex(
4167 : root_cert,
4168 : root_cert_size);
4169 1 : spdm_context->local_context.peer_root_cert_provision_size[0] =
4170 : root_cert_size;
4171 1 : spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
4172 1 : libspdm_reset_message_b(spdm_context);
4173 1 : spdm_context->connection_info.algorithm.base_hash_algo =
4174 : m_libspdm_use_hash_algo;
4175 1 : spdm_context->connection_info.algorithm.base_asym_algo =
4176 : m_libspdm_use_asym_algo;
4177 1 : spdm_context->connection_info.algorithm.req_base_asym_alg =
4178 : m_libspdm_use_req_asym_algo;
4179 :
4180 1 : cert_chain_size = sizeof(cert_chain);
4181 1 : libspdm_zero_mem(cert_chain, sizeof(cert_chain));
4182 1 : status = libspdm_get_certificate(spdm_context, NULL, 0, &cert_chain_size,
4183 : cert_chain);
4184 1 : assert_int_equal(status, LIBSPDM_STATUS_INVALID_MSG_FIELD);
4185 1 : free(data);
4186 :
4187 1 : if (m_libspdm_local_certificate_chain != NULL) {
4188 1 : free(m_libspdm_local_certificate_chain);
4189 1 : m_libspdm_local_certificate_chain = NULL;
4190 : }
4191 1 : }
4192 :
4193 : /**
4194 : * Test 28: Normal case, request a certificate chain. Validates certificate by using a preloaded chain instead of root hash
4195 : * Expected Behavior: receives the correct number of Certificate messages
4196 : **/
4197 1 : void libspdm_test_requester_get_certificate_case28(void **state)
4198 : {
4199 : libspdm_return_t status;
4200 : libspdm_test_context_t *spdm_test_context;
4201 : libspdm_context_t *spdm_context;
4202 : size_t cert_chain_size;
4203 : uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
4204 : void *data;
4205 : size_t data_size;
4206 : void *hash;
4207 : size_t hash_size;
4208 : const uint8_t *root_cert;
4209 : size_t root_cert_size;
4210 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
4211 : size_t count;
4212 : #endif
4213 :
4214 1 : spdm_test_context = *state;
4215 1 : spdm_context = spdm_test_context->spdm_context;
4216 1 : spdm_test_context->case_id = 0x1C;
4217 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 <<
4218 : SPDM_VERSION_NUMBER_SHIFT_BIT;
4219 1 : spdm_context->connection_info.connection_state =
4220 : LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
4221 1 : spdm_context->connection_info.capability.flags |=
4222 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
4223 1 : spdm_context->connection_info.capability.flags |=
4224 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_ALIAS_CERT_CAP;
4225 1 : libspdm_read_responder_public_certificate_chain_alias_cert(
4226 : m_libspdm_use_hash_algo,
4227 : m_libspdm_use_asym_algo, &data,
4228 : &data_size, &hash, &hash_size);
4229 1 : if (!libspdm_x509_get_cert_from_cert_chain(
4230 1 : (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
4231 1 : data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
4232 0 : assert(false);
4233 : }
4234 :
4235 1 : spdm_context->local_context.peer_root_cert_provision_size[0] = 0;
4236 1 : spdm_context->local_context.peer_root_cert_provision[0] = NULL;
4237 1 : libspdm_reset_message_b(spdm_context);
4238 1 : spdm_context->connection_info.algorithm.base_hash_algo =
4239 : m_libspdm_use_hash_algo;
4240 1 : spdm_context->connection_info.algorithm.base_asym_algo =
4241 : m_libspdm_use_asym_algo;
4242 1 : spdm_context->connection_info.algorithm.req_base_asym_alg =
4243 : m_libspdm_use_req_asym_algo;
4244 1 : spdm_context->local_context.is_requester = true;
4245 :
4246 1 : cert_chain_size = sizeof(cert_chain);
4247 1 : libspdm_zero_mem(cert_chain, sizeof(cert_chain));
4248 1 : status = libspdm_get_certificate(spdm_context, NULL, 0, &cert_chain_size,
4249 : cert_chain);
4250 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
4251 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
4252 : count = (data_size + LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN - 1) /
4253 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
4254 : assert_int_equal(spdm_context->transcript.message_b.buffer_size,
4255 : sizeof(spdm_get_certificate_request_t) * count +
4256 : sizeof(spdm_certificate_response_t) * count +
4257 : data_size);
4258 : #endif
4259 1 : free(data);
4260 1 : }
4261 :
4262 : /**
4263 : * Test 29: Normal case, request a certificate chain. Validates certificate by using a preloaded chain instead of root hash
4264 : * Expected Behavior: receives the correct number of Certificate messages
4265 : **/
4266 1 : void libspdm_test_requester_get_certificate_case29(void **state)
4267 : {
4268 : libspdm_return_t status;
4269 : libspdm_test_context_t *spdm_test_context;
4270 : libspdm_context_t *spdm_context;
4271 : size_t cert_chain_size;
4272 : uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
4273 : void *data;
4274 : size_t data_size;
4275 : void *hash;
4276 : size_t hash_size;
4277 : const uint8_t *root_cert;
4278 : size_t root_cert_size;
4279 :
4280 1 : spdm_test_context = *state;
4281 1 : spdm_context = spdm_test_context->spdm_context;
4282 1 : spdm_test_context->case_id = 0x1D;
4283 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 <<
4284 : SPDM_VERSION_NUMBER_SHIFT_BIT;
4285 1 : spdm_context->connection_info.connection_state =
4286 : LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
4287 1 : spdm_context->connection_info.capability.flags |=
4288 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
4289 1 : spdm_context->connection_info.capability.flags |=
4290 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_ALIAS_CERT_CAP;
4291 1 : libspdm_read_responder_public_certificate_chain_alias_cert(
4292 : m_libspdm_use_hash_algo,
4293 : m_libspdm_use_asym_algo, &data,
4294 : &data_size, &hash, &hash_size);
4295 1 : if (!libspdm_x509_get_cert_from_cert_chain(
4296 1 : (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
4297 1 : data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
4298 0 : assert(false);
4299 : }
4300 :
4301 1 : spdm_context->local_context.peer_root_cert_provision_size[0] = 0;
4302 1 : spdm_context->local_context.peer_root_cert_provision[0] = NULL;
4303 1 : libspdm_reset_message_b(spdm_context);
4304 1 : spdm_context->connection_info.algorithm.base_hash_algo =
4305 : m_libspdm_use_hash_algo;
4306 1 : spdm_context->connection_info.algorithm.base_asym_algo =
4307 : m_libspdm_use_asym_algo;
4308 1 : spdm_context->connection_info.algorithm.req_base_asym_alg =
4309 : m_libspdm_use_req_asym_algo;
4310 1 : spdm_context->local_context.is_requester = true;
4311 :
4312 1 : cert_chain_size = sizeof(cert_chain);
4313 1 : libspdm_zero_mem(cert_chain, sizeof(cert_chain));
4314 1 : status = libspdm_get_certificate(spdm_context, NULL, 0, &cert_chain_size,
4315 : cert_chain);
4316 1 : assert_int_equal(status, LIBSPDM_STATUS_VERIF_FAIL);
4317 1 : free(data);
4318 1 : }
4319 :
4320 : /**
4321 : * Test 30: check request attributes and response attributes ,
4322 : * Set CertModel to determine whether it meets expectations
4323 : * Expected Behavior: requester returns the status LIBSPDM_STATUS_SUCCESS
4324 : * Expected Behavior: CertModel is GenericCert model and slot 0 , returns a status of RETURN_DEVICE_ERROR.
4325 : * Expected Behavior: CertModel Value of 0 and certificate chain is valid, returns a status of RETURN_DEVICE_ERROR.
4326 : **/
4327 1 : void libspdm_test_requester_get_certificate_case30(void **state)
4328 : {
4329 : libspdm_return_t status;
4330 : libspdm_test_context_t *spdm_test_context;
4331 : libspdm_context_t *spdm_context;
4332 : size_t cert_chain_size;
4333 : uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
4334 : void *data;
4335 : size_t data_size;
4336 : void *hash;
4337 : size_t hash_size;
4338 : const uint8_t *root_cert;
4339 : size_t root_cert_size;
4340 : libspdm_data_parameter_t parameter;
4341 :
4342 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
4343 : #else
4344 : uint8_t set_data_buffer_hash[LIBSPDM_MAX_HASH_SIZE];
4345 : uint32_t set_data_buffer_hash_size;
4346 : #endif
4347 :
4348 1 : spdm_test_context = *state;
4349 1 : spdm_context = spdm_test_context->spdm_context;
4350 1 : spdm_test_context->case_id = 0x1E;
4351 1 : spdm_context->retry_times = 1;
4352 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_13 <<
4353 : SPDM_VERSION_NUMBER_SHIFT_BIT;
4354 1 : spdm_context->connection_info.connection_state =
4355 : LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
4356 1 : spdm_context->connection_info.capability.flags = 0;
4357 1 : spdm_context->connection_info.capability.flags |=
4358 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
4359 1 : spdm_context->local_context.is_requester = true;
4360 1 : if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
4361 : m_libspdm_use_asym_algo, &data,
4362 : &data_size, &hash, &hash_size)) {
4363 0 : assert(false);
4364 : }
4365 1 : if (!libspdm_x509_get_cert_from_cert_chain(
4366 1 : (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
4367 1 : data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
4368 0 : assert(false);
4369 : }
4370 1 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "root cert data :\n"));
4371 1 : libspdm_dump_hex(
4372 : root_cert,
4373 : root_cert_size);
4374 1 : spdm_context->local_context.peer_root_cert_provision_size[0] =
4375 : root_cert_size;
4376 1 : spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
4377 1 : libspdm_reset_message_b(spdm_context);
4378 1 : spdm_context->connection_info.algorithm.base_hash_algo =
4379 : m_libspdm_use_hash_algo;
4380 1 : spdm_context->connection_info.algorithm.base_asym_algo =
4381 : m_libspdm_use_asym_algo;
4382 1 : spdm_context->connection_info.algorithm.req_base_asym_alg =
4383 : m_libspdm_use_req_asym_algo;
4384 :
4385 1 : libspdm_zero_mem(¶meter, sizeof(parameter));
4386 1 : parameter.location = LIBSPDM_DATA_LOCATION_CONNECTION;
4387 1 : parameter.additional_data[0] = 0;
4388 1 : libspdm_set_data(spdm_context, LIBSPDM_DATA_PEER_USED_CERT_CHAIN_BUFFER, ¶meter,
4389 : data, data_size);
4390 :
4391 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
4392 : spdm_context->transcript.message_m.buffer_size =
4393 : spdm_context->transcript.message_m.max_buffer_size;
4394 : #else
4395 1 : set_data_buffer_hash_size =
4396 : spdm_context->connection_info.peer_used_cert_chain[0].buffer_hash_size;
4397 1 : libspdm_copy_mem(set_data_buffer_hash, set_data_buffer_hash_size,
4398 1 : spdm_context->connection_info.peer_used_cert_chain[0].buffer_hash,
4399 : set_data_buffer_hash_size);
4400 : #endif
4401 :
4402 : /* Sub Case 1: CertModel Value of 1 , DeviceCert model*/
4403 1 : spdm_context->connection_info.multi_key_conn_rsp = true;
4404 1 : spdm_context->connection_info.peer_cert_info[0] = 0;
4405 1 : m_cert_model = SPDM_CERTIFICATE_INFO_CERT_MODEL_DEVICE_CERT;
4406 1 : libspdm_reset_message_b(spdm_context);
4407 1 : m_slot_id = 0;
4408 1 : m_calling_index = 0;
4409 :
4410 1 : cert_chain_size = sizeof(cert_chain);
4411 1 : libspdm_zero_mem(cert_chain, sizeof(cert_chain));
4412 1 : status = libspdm_get_certificate(spdm_context, NULL, m_slot_id, &cert_chain_size,
4413 : cert_chain);
4414 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
4415 1 : assert_int_equal(spdm_context->connection_info.peer_cert_info[0], m_cert_model);
4416 1 : assert_int_equal(cert_chain_size, m_libspdm_local_certificate_chain_size);
4417 1 : assert_memory_equal(cert_chain, m_libspdm_local_certificate_chain,
4418 : m_libspdm_local_certificate_chain_size);
4419 :
4420 : /* Sub Case 2: CertModel Value of 2 , AliasCert model*/
4421 1 : spdm_context->connection_info.multi_key_conn_rsp = true;
4422 1 : spdm_context->connection_info.peer_cert_info[0] = 0;
4423 1 : m_cert_model = SPDM_CERTIFICATE_INFO_CERT_MODEL_ALIAS_CERT;
4424 1 : libspdm_reset_message_b(spdm_context);
4425 1 : m_slot_id = 0;
4426 1 : m_calling_index = 0;
4427 :
4428 1 : cert_chain_size = sizeof(cert_chain);
4429 1 : libspdm_zero_mem(cert_chain, sizeof(cert_chain));
4430 1 : status = libspdm_get_certificate(spdm_context, NULL, m_slot_id, &cert_chain_size,
4431 : cert_chain);
4432 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
4433 1 : assert_int_equal(spdm_context->connection_info.peer_cert_info[0], m_cert_model);
4434 1 : assert_int_equal(cert_chain_size, m_libspdm_local_certificate_chain_size);
4435 1 : assert_memory_equal(cert_chain, m_libspdm_local_certificate_chain,
4436 : m_libspdm_local_certificate_chain_size);
4437 :
4438 : /* Sub Case 3: CertModel Value of 3 GenericCert model , slot_id set 1
4439 : * In all cases, the certificate model for slot 0 shall be either the device certificate model or the alias certificate model*/
4440 1 : spdm_context->connection_info.multi_key_conn_rsp = true;
4441 1 : spdm_context->connection_info.peer_cert_info[1] = 0;
4442 1 : m_cert_model = SPDM_CERTIFICATE_INFO_CERT_MODEL_GENERIC_CERT;
4443 1 : libspdm_reset_message_b(spdm_context);
4444 1 : m_slot_id = 1;
4445 1 : m_calling_index = 0;
4446 :
4447 1 : cert_chain_size = sizeof(cert_chain);
4448 1 : libspdm_zero_mem(cert_chain, sizeof(cert_chain));
4449 1 : status = libspdm_get_certificate(spdm_context, NULL, m_slot_id, &cert_chain_size,
4450 : cert_chain);
4451 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
4452 1 : assert_int_equal(spdm_context->connection_info.peer_cert_info[1], m_cert_model);
4453 1 : assert_int_equal(cert_chain_size, m_libspdm_local_certificate_chain_size);
4454 1 : assert_memory_equal(cert_chain, m_libspdm_local_certificate_chain,
4455 : m_libspdm_local_certificate_chain_size);
4456 :
4457 : /* Sub Case 4: CertModel Value of 3 , GenericCert model , slot_id set 0
4458 : * In all cases, the certificate model for slot 0 shall be either the device certificate model or the alias certificate model*/
4459 1 : spdm_context->connection_info.multi_key_conn_rsp = true;
4460 1 : spdm_context->connection_info.peer_cert_info[0] = 0;
4461 1 : m_cert_model = SPDM_CERTIFICATE_INFO_CERT_MODEL_GENERIC_CERT;
4462 1 : libspdm_reset_message_b(spdm_context);
4463 1 : m_slot_id = 0;
4464 1 : m_calling_index = 0;
4465 :
4466 1 : cert_chain_size = sizeof(cert_chain);
4467 1 : libspdm_zero_mem(cert_chain, sizeof(cert_chain));
4468 1 : status = libspdm_get_certificate(spdm_context, NULL, m_slot_id, &cert_chain_size,
4469 : cert_chain);
4470 1 : assert_int_equal(status, LIBSPDM_STATUS_INVALID_MSG_FIELD);
4471 1 : assert_int_equal(spdm_context->connection_info.peer_cert_info[0], 0);
4472 :
4473 : /* Sub Case 5: CertModel Value of 0 , MULTI_KEY_CONN_RSP is true*/
4474 : /* Value of 0 indicates either that the certificate slot does not contain any certificates or that the corresponding
4475 : * MULTI_KEY_CONN_REQ or MULTI_KEY_CONN_RSP is false. */
4476 1 : spdm_context->connection_info.multi_key_conn_rsp = true;
4477 1 : spdm_context->connection_info.peer_cert_info[0] = 0;
4478 1 : m_cert_model = SPDM_CERTIFICATE_INFO_CERT_MODEL_NONE;
4479 1 : libspdm_reset_message_b(spdm_context);
4480 1 : m_slot_id = 0;
4481 1 : m_calling_index = 0;
4482 :
4483 1 : cert_chain_size = sizeof(cert_chain);
4484 1 : libspdm_zero_mem(cert_chain, sizeof(cert_chain));
4485 1 : status = libspdm_get_certificate(spdm_context, NULL, m_slot_id, &cert_chain_size,
4486 : cert_chain);
4487 1 : assert_int_equal(status, LIBSPDM_STATUS_INVALID_MSG_FIELD);
4488 1 : assert_int_equal(spdm_context->connection_info.peer_cert_info[0], m_cert_model);
4489 :
4490 : /* Sub Case 6: CertModel Value of 0 , MULTI_KEY_CONN_RSP is false*/
4491 : /* Value of 0 indicates either that the certificate slot does not contain any certificates or that the corresponding
4492 : * MULTI_KEY_CONN_REQ or MULTI_KEY_CONN_RSP is false. */
4493 1 : spdm_context->connection_info.multi_key_conn_rsp = false;
4494 1 : spdm_context->connection_info.peer_cert_info[0] = 0;
4495 1 : m_cert_model = SPDM_CERTIFICATE_INFO_CERT_MODEL_NONE;
4496 1 : libspdm_reset_message_b(spdm_context);
4497 1 : m_slot_id = 0;
4498 1 : m_calling_index = 0;
4499 :
4500 1 : cert_chain_size = sizeof(cert_chain);
4501 1 : libspdm_zero_mem(cert_chain, sizeof(cert_chain));
4502 1 : status = libspdm_get_certificate(spdm_context, NULL, m_slot_id, &cert_chain_size,
4503 : cert_chain);
4504 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
4505 1 : assert_int_equal(spdm_context->connection_info.peer_cert_info[0], m_cert_model);
4506 1 : assert_int_equal(cert_chain_size, m_libspdm_local_certificate_chain_size);
4507 1 : assert_memory_equal(cert_chain, m_libspdm_local_certificate_chain,
4508 : m_libspdm_local_certificate_chain_size);
4509 :
4510 1 : free(data);
4511 1 : free(m_libspdm_local_certificate_chain);
4512 1 : }
4513 :
4514 : /**
4515 : * Test 31: Fail case, input buffer size too small for holding cert chain.
4516 : * Expected Behavior: returns a status of BUFFER_TOO_SMALL.
4517 : **/
4518 1 : void libspdm_test_requester_get_certificate_case31(void **state)
4519 : {
4520 : libspdm_return_t status;
4521 : libspdm_test_context_t *spdm_test_context;
4522 : libspdm_context_t *spdm_context;
4523 : size_t cert_chain_size;
4524 : uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
4525 : void *data;
4526 : size_t data_size;
4527 : void *hash;
4528 : size_t hash_size;
4529 : const uint8_t *root_cert;
4530 : size_t root_cert_size;
4531 : libspdm_data_parameter_t parameter;
4532 : #if !LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
4533 : uint8_t set_data_buffer_hash[LIBSPDM_MAX_HASH_SIZE];
4534 : uint32_t set_data_buffer_hash_size;
4535 : #endif
4536 :
4537 1 : spdm_test_context = *state;
4538 1 : spdm_context = spdm_test_context->spdm_context;
4539 1 : spdm_test_context->case_id = 0x1F;
4540 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
4541 : SPDM_VERSION_NUMBER_SHIFT_BIT;
4542 1 : spdm_context->connection_info.connection_state =
4543 : LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
4544 1 : spdm_context->connection_info.capability.flags |=
4545 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
4546 1 : spdm_context->local_context.is_requester = true;
4547 1 : if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
4548 : m_libspdm_use_asym_algo, &data,
4549 : &data_size, &hash, &hash_size)) {
4550 0 : assert(false);
4551 : }
4552 1 : if (!libspdm_x509_get_cert_from_cert_chain(
4553 1 : (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
4554 1 : data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
4555 0 : assert(false);
4556 : }
4557 1 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "root cert data :\n"));
4558 1 : libspdm_dump_hex(
4559 : root_cert,
4560 : root_cert_size);
4561 1 : spdm_context->local_context.peer_root_cert_provision_size[0] =
4562 : root_cert_size;
4563 1 : spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
4564 1 : libspdm_reset_message_b(spdm_context);
4565 1 : spdm_context->connection_info.algorithm.base_hash_algo =
4566 : m_libspdm_use_hash_algo;
4567 1 : spdm_context->connection_info.algorithm.base_asym_algo =
4568 : m_libspdm_use_asym_algo;
4569 1 : spdm_context->connection_info.algorithm.req_base_asym_alg =
4570 : m_libspdm_use_req_asym_algo;
4571 :
4572 1 : libspdm_zero_mem(¶meter, sizeof(parameter));
4573 1 : parameter.location = LIBSPDM_DATA_LOCATION_CONNECTION;
4574 1 : parameter.additional_data[0] = 0;
4575 1 : libspdm_set_data(spdm_context, LIBSPDM_DATA_PEER_USED_CERT_CHAIN_BUFFER, ¶meter,
4576 : data, data_size);
4577 :
4578 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
4579 : spdm_context->transcript.message_m.buffer_size =
4580 : spdm_context->transcript.message_m.max_buffer_size;
4581 : #else
4582 1 : set_data_buffer_hash_size =
4583 : spdm_context->connection_info.peer_used_cert_chain[0].buffer_hash_size;
4584 1 : libspdm_copy_mem(set_data_buffer_hash, set_data_buffer_hash_size,
4585 1 : spdm_context->connection_info.peer_used_cert_chain[0].buffer_hash,
4586 : set_data_buffer_hash_size);
4587 : #endif
4588 : /* Set cert_chain_size to a value that is less than the actual size of the certificate chain */
4589 1 : cert_chain_size = data_size - 1;
4590 1 : libspdm_zero_mem(cert_chain, sizeof(cert_chain));
4591 1 : status = libspdm_get_certificate(spdm_context, NULL, 0, &cert_chain_size,
4592 : cert_chain);
4593 1 : assert_int_equal(status, LIBSPDM_STATUS_BUFFER_TOO_SMALL);
4594 1 : free(data);
4595 1 : }
4596 :
4597 1 : int libspdm_requester_get_certificate_test_main(void)
4598 : {
4599 1 : const struct CMUnitTest spdm_requester_get_certificate_tests[] = {
4600 : /* SendRequest failed*/
4601 : cmocka_unit_test(libspdm_test_requester_get_certificate_case1),
4602 : /* Successful response: check root certificate hash*/
4603 : cmocka_unit_test(libspdm_test_requester_get_certificate_case2),
4604 : /* connection_state check failed*/
4605 : cmocka_unit_test(libspdm_test_requester_get_certificate_case3),
4606 : /* Error response: SPDM_ERROR_CODE_INVALID_REQUEST*/
4607 : cmocka_unit_test(libspdm_test_requester_get_certificate_case4),
4608 : /* Always SPDM_ERROR_CODE_BUSY*/
4609 : cmocka_unit_test(libspdm_test_requester_get_certificate_case5),
4610 : /* SPDM_ERROR_CODE_BUSY + Successful response*/
4611 : cmocka_unit_test(libspdm_test_requester_get_certificate_case6),
4612 : /* Error response: SPDM_ERROR_CODE_REQUEST_RESYNCH*/
4613 : cmocka_unit_test(libspdm_test_requester_get_certificate_case7),
4614 : /* Always SPDM_ERROR_CODE_RESPONSE_NOT_READY*/
4615 : cmocka_unit_test(libspdm_test_requester_get_certificate_case8),
4616 : /* SPDM_ERROR_CODE_RESPONSE_NOT_READY + Successful response*/
4617 : cmocka_unit_test(libspdm_test_requester_get_certificate_case9),
4618 : /* Successful response: check certificate chain*/
4619 : cmocka_unit_test(libspdm_test_requester_get_certificate_case10),
4620 : /* Invalid certificate signature*/
4621 : cmocka_unit_test(libspdm_test_requester_get_certificate_case11),
4622 : /* Fail certificate chain check*/
4623 : cmocka_unit_test(libspdm_test_requester_get_certificate_case12),
4624 : /* Successful response: get a certificate chain that fits in one single message*/
4625 : cmocka_unit_test(libspdm_test_requester_get_certificate_case13),
4626 : /* Successful response: get certificate chain byte by byte*/
4627 : cmocka_unit_test(libspdm_test_requester_get_certificate_case14),
4628 : /* Successful response: get a long certificate chain*/
4629 : cmocka_unit_test(libspdm_test_requester_get_certificate_case15),
4630 : /* Unexpected errors*/
4631 : cmocka_unit_test(libspdm_test_requester_get_certificate_case16),
4632 : /* Successful response: get a certificate chain not start with root cert.*/
4633 : cmocka_unit_test(libspdm_test_requester_get_certificate_case17),
4634 : /* Fail response: get a certificate chain not start with root cert but with wrong signature.*/
4635 : cmocka_unit_test(libspdm_test_requester_get_certificate_case18),
4636 : /* Fail response: one certificate in the retrieved certificate chain past its expiration date.*/
4637 : cmocka_unit_test(libspdm_test_requester_get_certificate_case19),
4638 : /* Fail response: responder return portion_length is 0.*/
4639 : cmocka_unit_test(libspdm_test_requester_get_certificate_case20),
4640 : /* Fail response: responder return portion_length > spdm_request.length*/
4641 : cmocka_unit_test(libspdm_test_requester_get_certificate_case21),
4642 : /* Fail response: spdm_request.offset + spdm_response->portion_length + spdm_response->remainder_length !=
4643 : * total_responder_cert_chain_buffer_length.*/
4644 : cmocka_unit_test(libspdm_test_requester_get_certificate_case22),
4645 : /* Buffer verification*/
4646 : cmocka_unit_test(libspdm_test_requester_get_certificate_case23),
4647 : /* hardware identify OID is found in AliasCert model cert*/
4648 : cmocka_unit_test(libspdm_test_requester_get_certificate_case24),
4649 : #if LIBSPDM_ENABLE_CAPABILITY_CHAL_CAP
4650 : /* GetCert (0), GetCert(1) and Challenge(0) */
4651 : cmocka_unit_test(libspdm_test_requester_get_certificate_case25),
4652 : #endif
4653 : /* get cert in secure session */
4654 : cmocka_unit_test(libspdm_test_requester_get_certificate_case26),
4655 : /* Fail response: responder return wrong SlotID 3, not equal with SlotID 0 in request message. */
4656 : cmocka_unit_test(libspdm_test_requester_get_certificate_case27),
4657 : /*Successful response: get the entire alias_cert model cert_chain*/
4658 : cmocka_unit_test(libspdm_test_requester_get_certificate_case28),
4659 : /*Fail response: get the partial alias_cert model cert_chain*/
4660 : cmocka_unit_test(libspdm_test_requester_get_certificate_case29),
4661 : /* check request attributes and response attributes*/
4662 : cmocka_unit_test(libspdm_test_requester_get_certificate_case30),
4663 : /* Fail response: input buffer size too small for holding cert chain */
4664 : cmocka_unit_test(libspdm_test_requester_get_certificate_case31),
4665 : };
4666 :
4667 1 : libspdm_test_context_t test_context = {
4668 : LIBSPDM_TEST_CONTEXT_VERSION,
4669 : true,
4670 : libspdm_requester_get_certificate_test_send_message,
4671 : libspdm_requester_get_certificate_test_receive_message,
4672 : };
4673 :
4674 1 : libspdm_setup_test_context(&test_context);
4675 :
4676 1 : return cmocka_run_group_tests(spdm_requester_get_certificate_tests,
4677 : libspdm_unit_test_group_setup,
4678 : libspdm_unit_test_group_teardown);
4679 : }
4680 :
4681 : #endif /* LIBSPDM_SEND_GET_CERTIFICATE_SUPPORT */
|