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