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 : 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(
3254 : spdm_context, NULL, 0, get_cert_length, &cert_chain_size, cert_chain);
3255 : /* It may fail because the spdm does not support too many messages.
3256 : * assert_int_equal (status, LIBSPDM_STATUS_SUCCESS);*/
3257 : if (status == LIBSPDM_STATUS_SUCCESS) {
3258 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
3259 : count = (data_size + get_cert_length - 1) / get_cert_length;
3260 : assert_int_equal(
3261 : spdm_context->transcript.message_b.buffer_size,
3262 : sizeof(spdm_get_certificate_request_t) * count +
3263 : sizeof(spdm_certificate_response_t) * count +
3264 : data_size);
3265 : #endif
3266 : }
3267 1 : free(data);
3268 1 : }
3269 :
3270 : /**
3271 : * Test 15: request a long certificate chain
3272 : * Expected Behavior: receives a valid certificate chain with the correct number of Certificate messages
3273 : **/
3274 1 : static void req_get_certificate_case15(void **state)
3275 : {
3276 : libspdm_return_t status;
3277 : libspdm_test_context_t *spdm_test_context;
3278 : libspdm_context_t *spdm_context;
3279 : size_t cert_chain_size;
3280 : uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
3281 : void *data;
3282 : size_t data_size;
3283 : void *hash;
3284 : size_t hash_size;
3285 : const uint8_t *root_cert;
3286 : size_t root_cert_size;
3287 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
3288 : size_t count;
3289 : #endif
3290 :
3291 1 : spdm_test_context = *state;
3292 1 : spdm_context = spdm_test_context->spdm_context;
3293 1 : spdm_test_context->case_id = 0xF;
3294 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
3295 : SPDM_VERSION_NUMBER_SHIFT_BIT;
3296 : /* Setting SPDM context as the first steps of the protocol has been accomplished*/
3297 1 : spdm_context->connection_info.connection_state =
3298 : LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
3299 1 : spdm_context->connection_info.capability.flags |=
3300 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
3301 : /* Loading Root certificate and saving its hash*/
3302 :
3303 1 : libspdm_read_responder_public_certificate_chain_by_size(
3304 : /*MAXUINT16_CERT signature_algo is SHA256RSA */
3305 : m_libspdm_use_hash_algo, SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048,
3306 : LIBSPDM_TEST_CERT_MAXUINT16, &data, &data_size, &hash, &hash_size);
3307 1 : if (!libspdm_x509_get_cert_from_cert_chain(
3308 1 : (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
3309 1 : data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
3310 0 : assert(false);
3311 : }
3312 1 : spdm_context->local_context.peer_root_cert_provision_size[0] =
3313 : root_cert_size;
3314 1 : spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
3315 1 : spdm_context->connection_info.algorithm.base_hash_algo =
3316 : m_libspdm_use_hash_algo;
3317 1 : spdm_context->connection_info.algorithm.base_asym_algo =
3318 : m_libspdm_use_asym_algo;
3319 1 : spdm_context->connection_info.algorithm.req_base_asym_alg =
3320 : m_libspdm_use_req_asym_algo;
3321 : /* Resetting message buffer*/
3322 1 : libspdm_reset_message_b(spdm_context);
3323 : /* Calculating expected number of messages received*/
3324 :
3325 1 : cert_chain_size = sizeof(cert_chain);
3326 1 : libspdm_zero_mem(cert_chain, sizeof(cert_chain));
3327 1 : status = libspdm_get_certificate(spdm_context, NULL, 0, &cert_chain_size,
3328 : cert_chain);
3329 : /* It may fail because the spdm does not support too long message.
3330 : * assert_int_equal (status, LIBSPDM_STATUS_SUCCESS);*/
3331 : if (status == LIBSPDM_STATUS_SUCCESS) {
3332 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
3333 : count = (data_size + LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN - 1) /
3334 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
3335 : assert_int_equal(
3336 : spdm_context->transcript.message_b.buffer_size,
3337 : sizeof(spdm_get_certificate_request_t) * count +
3338 : sizeof(spdm_certificate_response_t) * count +
3339 : data_size);
3340 : #endif
3341 : }
3342 1 : free(data);
3343 1 : }
3344 :
3345 : /**
3346 : * Test 16: receiving an unexpected ERROR message from the responder.
3347 : * There are tests for all named codes, including some reserved ones
3348 : * (namely, 0x00, 0x0b, 0x0c, 0x3f, 0xfd, 0xfe).
3349 : * However, for having specific test cases, it is excluded from this case:
3350 : * Busy (0x03), ResponseNotReady (0x42), and RequestResync (0x43).
3351 : * Expected behavior: client returns a status of LIBSPDM_STATUS_ERROR_PEER.
3352 : **/
3353 1 : static void req_get_certificate_case16(void **state) {
3354 : libspdm_return_t status;
3355 : libspdm_test_context_t *spdm_test_context;
3356 : libspdm_context_t *spdm_context;
3357 : size_t cert_chain_size;
3358 : uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
3359 : void *data;
3360 : size_t data_size;
3361 : void *hash;
3362 : size_t hash_size;
3363 : const uint8_t *root_cert;
3364 : size_t root_cert_size;
3365 : uint16_t error_code;
3366 :
3367 1 : spdm_test_context = *state;
3368 1 : spdm_context = spdm_test_context->spdm_context;
3369 1 : spdm_test_context->case_id = 0x10;
3370 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_11 <<
3371 : SPDM_VERSION_NUMBER_SHIFT_BIT;
3372 1 : spdm_context->connection_info.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
3373 1 : libspdm_read_responder_public_certificate_chain (m_libspdm_use_hash_algo,
3374 : m_libspdm_use_asym_algo,
3375 : &data, &data_size,
3376 : &hash, &hash_size);
3377 1 : if (!libspdm_x509_get_cert_from_cert_chain(
3378 1 : (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
3379 1 : data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
3380 0 : assert(false);
3381 : }
3382 1 : spdm_context->local_context.peer_root_cert_provision_size[0] = root_cert_size;
3383 1 : spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
3384 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
3385 1 : spdm_context->connection_info.algorithm.base_asym_algo = m_libspdm_use_asym_algo;
3386 1 : spdm_context->connection_info.algorithm.req_base_asym_alg = m_libspdm_use_req_asym_algo;
3387 :
3388 1 : error_code = LIBSPDM_ERROR_CODE_RESERVED_00;
3389 19 : while(error_code <= 0xff) {
3390 18 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
3391 18 : libspdm_reset_message_b(spdm_context);
3392 :
3393 18 : cert_chain_size = sizeof(cert_chain);
3394 18 : libspdm_zero_mem (cert_chain, sizeof(cert_chain));
3395 18 : status = libspdm_get_certificate (spdm_context, NULL, 0, &cert_chain_size, cert_chain);
3396 18 : LIBSPDM_ASSERT_INT_EQUAL_CASE (status, LIBSPDM_STATUS_ERROR_PEER, error_code);
3397 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
3398 : /* assert_int_equal (spdm_context->transcript.message_b.buffer_size, 0);*/
3399 : LIBSPDM_ASSERT_INT_EQUAL_CASE (spdm_context->transcript.message_b.buffer_size, 0,
3400 : error_code);
3401 : #endif
3402 :
3403 18 : error_code++;
3404 18 : if(error_code == SPDM_ERROR_CODE_BUSY) { /*busy is treated in cases 5 and 6*/
3405 1 : error_code = SPDM_ERROR_CODE_UNEXPECTED_REQUEST;
3406 : }
3407 18 : if(error_code == LIBSPDM_ERROR_CODE_RESERVED_0D) { /*skip some reserved error codes (0d to 3e)*/
3408 1 : error_code = LIBSPDM_ERROR_CODE_RESERVED_3F;
3409 : }
3410 18 : if(error_code == SPDM_ERROR_CODE_RESPONSE_NOT_READY) { /*skip response not ready, request resync, and some reserved codes (44 to fc)*/
3411 1 : error_code = LIBSPDM_ERROR_CODE_RESERVED_FD;
3412 : }
3413 : }
3414 :
3415 1 : free(data);
3416 1 : }
3417 :
3418 : /**
3419 : * Test 17: Normal case, get a certificate chain start not with root cert. Validates certificate by using a preloaded chain.
3420 : * Expected Behavior: receives the correct number of Certificate messages
3421 : **/
3422 1 : static void req_get_certificate_case17(void **state)
3423 : {
3424 : libspdm_return_t status;
3425 : libspdm_test_context_t *spdm_test_context;
3426 : libspdm_context_t *spdm_context;
3427 : size_t cert_chain_size;
3428 : uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
3429 : void *data;
3430 : size_t data_size;
3431 : void *hash;
3432 : size_t hash_size;
3433 : const uint8_t *root_cert;
3434 : size_t root_cert_size;
3435 :
3436 1 : spdm_test_context = *state;
3437 1 : spdm_context = spdm_test_context->spdm_context;
3438 1 : spdm_test_context->case_id = 0x11;
3439 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
3440 : SPDM_VERSION_NUMBER_SHIFT_BIT;
3441 1 : spdm_context->connection_info.connection_state =
3442 : LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
3443 1 : spdm_context->connection_info.capability.flags |=
3444 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
3445 1 : if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
3446 : m_libspdm_use_asym_algo, &data,
3447 : &data_size, &hash, &hash_size)) {
3448 0 : assert(false);
3449 : }
3450 1 : if (!libspdm_x509_get_cert_from_cert_chain(
3451 1 : (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
3452 1 : data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
3453 0 : assert(false);
3454 : }
3455 :
3456 1 : spdm_context->local_context.peer_root_cert_provision_size[0] = root_cert_size;
3457 1 : spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
3458 1 : libspdm_reset_message_b(spdm_context);
3459 1 : spdm_context->connection_info.algorithm.base_hash_algo =
3460 : m_libspdm_use_hash_algo;
3461 1 : spdm_context->connection_info.algorithm.base_asym_algo =
3462 : m_libspdm_use_asym_algo;
3463 1 : spdm_context->connection_info.algorithm.req_base_asym_alg =
3464 : m_libspdm_use_req_asym_algo;
3465 1 : spdm_context->local_context.is_requester = true;
3466 :
3467 1 : cert_chain_size = sizeof(cert_chain);
3468 1 : libspdm_zero_mem(cert_chain, sizeof(cert_chain));
3469 1 : status = libspdm_get_certificate(spdm_context, NULL, 0, &cert_chain_size,
3470 : cert_chain);
3471 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
3472 1 : free(data);
3473 1 : }
3474 :
3475 : /**
3476 : * Test 18: Fail case, get a certificate chain start not with root cert and with wrong signature. Validates certificate by using a preloaded chain.
3477 : * Expected Behavior: receives the correct number of Certificate messages
3478 : **/
3479 1 : static void req_get_certificate_case18(void **state)
3480 : {
3481 : libspdm_return_t status;
3482 : libspdm_test_context_t *spdm_test_context;
3483 : libspdm_context_t *spdm_context;
3484 : size_t cert_chain_size;
3485 : uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
3486 : void *data;
3487 : size_t data_size;
3488 : void *hash;
3489 : size_t hash_size;
3490 : const uint8_t *root_cert;
3491 : size_t root_cert_size;
3492 :
3493 1 : spdm_test_context = *state;
3494 1 : spdm_context = spdm_test_context->spdm_context;
3495 1 : spdm_test_context->case_id = 0x12;
3496 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
3497 : SPDM_VERSION_NUMBER_SHIFT_BIT;
3498 1 : spdm_context->connection_info.connection_state =
3499 : LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
3500 1 : spdm_context->connection_info.capability.flags |=
3501 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
3502 1 : if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
3503 : m_libspdm_use_asym_algo, &data,
3504 : &data_size, &hash, &hash_size)) {
3505 0 : assert(false);
3506 : }
3507 1 : if (!libspdm_x509_get_cert_from_cert_chain(
3508 1 : (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
3509 1 : data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
3510 0 : assert(false);
3511 : }
3512 :
3513 1 : spdm_context->local_context.peer_root_cert_provision_size[0] = root_cert_size;
3514 1 : spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
3515 1 : libspdm_reset_message_b(spdm_context);
3516 1 : spdm_context->connection_info.algorithm.base_hash_algo =
3517 : m_libspdm_use_hash_algo;
3518 1 : spdm_context->connection_info.algorithm.base_asym_algo =
3519 : m_libspdm_use_asym_algo;
3520 1 : spdm_context->connection_info.algorithm.req_base_asym_alg =
3521 : m_libspdm_use_req_asym_algo;
3522 :
3523 1 : cert_chain_size = sizeof(cert_chain);
3524 1 : libspdm_zero_mem(cert_chain, sizeof(cert_chain));
3525 1 : status = libspdm_get_certificate(spdm_context, NULL, 0, &cert_chain_size,
3526 : cert_chain);
3527 1 : assert_int_equal(status, LIBSPDM_STATUS_VERIF_FAIL);
3528 1 : free(data);
3529 1 : }
3530 :
3531 : /**
3532 : * Test 19: Normal procedure, but one certificate in the retrieved certificate chain past its expiration date.
3533 : * Expected Behavior: get a LIBSPDM_STATUS_VERIF_FAIL, and receives the correct number of Certificate messages
3534 : **/
3535 1 : static void req_get_certificate_case19(void **state)
3536 : {
3537 : libspdm_return_t status;
3538 : libspdm_test_context_t *spdm_test_context;
3539 : libspdm_context_t *spdm_context;
3540 : size_t cert_chain_size;
3541 : uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
3542 : void *data;
3543 : size_t data_size;
3544 : void *hash;
3545 : size_t hash_size;
3546 : const uint8_t *root_cert;
3547 : size_t root_cert_size;
3548 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
3549 : size_t count;
3550 : #endif
3551 :
3552 1 : spdm_test_context = *state;
3553 1 : spdm_context = spdm_test_context->spdm_context;
3554 1 : spdm_test_context->case_id = 0x13;
3555 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
3556 : SPDM_VERSION_NUMBER_SHIFT_BIT;
3557 : /* Setting SPDM context as the first steps of the protocol has been accomplished*/
3558 1 : spdm_context->connection_info.connection_state =
3559 : LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
3560 1 : spdm_context->connection_info.capability.flags |=
3561 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
3562 : /* Loading the target expiration certificate chain and saving root certificate hash
3563 : * "rsa3072_Expiration/bundle_responder.certchain.der"*/
3564 1 : libspdm_libspdm_read_responder_public_certificate_chain_expiration(&data,
3565 : &data_size, &hash,
3566 : &hash_size);
3567 1 : libspdm_x509_get_cert_from_cert_chain(
3568 1 : (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
3569 1 : data_size - sizeof(spdm_cert_chain_t) - hash_size, 0,
3570 : &root_cert, &root_cert_size);
3571 1 : spdm_context->local_context.peer_root_cert_provision_size[0] =
3572 : root_cert_size;
3573 1 : spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
3574 1 : spdm_context->connection_info.algorithm.base_hash_algo =
3575 : SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_256;
3576 1 : spdm_context->connection_info.algorithm.base_asym_algo =
3577 : m_libspdm_use_asym_algo;
3578 1 : spdm_context->connection_info.algorithm.req_base_asym_alg =
3579 : m_libspdm_use_req_asym_algo;
3580 : /* Resetting message buffer*/
3581 1 : libspdm_reset_message_b(spdm_context);
3582 : /* Calculating expected number of messages received*/
3583 :
3584 1 : cert_chain_size = sizeof(cert_chain);
3585 1 : libspdm_zero_mem(cert_chain, sizeof(cert_chain));
3586 1 : status = libspdm_get_certificate(spdm_context, NULL, 0, &cert_chain_size,
3587 : cert_chain);
3588 1 : assert_int_equal(status, LIBSPDM_STATUS_VERIF_FAIL);
3589 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
3590 : count = (data_size + LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN - 1) /
3591 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
3592 : assert_int_equal(spdm_context->transcript.message_b.buffer_size,
3593 : sizeof(spdm_get_certificate_request_t) * count +
3594 : sizeof(spdm_certificate_response_t) * count +
3595 : data_size);
3596 : #endif
3597 1 : free(data);
3598 1 : }
3599 :
3600 : /**
3601 : * Test 20: Fail case, request a certificate chain, responder return portion_length is 0.
3602 : * Expected Behavior:returns a status of RETURN_DEVICE_ERROR.
3603 : **/
3604 1 : static void req_get_certificate_case20(void **state)
3605 : {
3606 : libspdm_return_t status;
3607 : libspdm_test_context_t *spdm_test_context;
3608 : libspdm_context_t *spdm_context;
3609 : size_t cert_chain_size;
3610 : uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
3611 : void *data;
3612 : size_t data_size;
3613 : void *hash;
3614 : size_t hash_size;
3615 : const uint8_t *root_cert;
3616 : size_t root_cert_size;
3617 :
3618 1 : spdm_test_context = *state;
3619 1 : spdm_context = spdm_test_context->spdm_context;
3620 1 : spdm_test_context->case_id = 0x14;
3621 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
3622 : SPDM_VERSION_NUMBER_SHIFT_BIT;
3623 1 : spdm_context->connection_info.connection_state =
3624 : LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
3625 1 : spdm_context->connection_info.capability.flags |=
3626 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
3627 1 : if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
3628 : m_libspdm_use_asym_algo, &data,
3629 : &data_size, &hash, &hash_size)) {
3630 0 : assert(false);
3631 : }
3632 1 : if (!libspdm_x509_get_cert_from_cert_chain(
3633 1 : (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
3634 1 : data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
3635 0 : assert(false);
3636 : }
3637 1 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "root cert data :\n"));
3638 1 : libspdm_dump_hex(
3639 : root_cert,
3640 : root_cert_size);
3641 1 : spdm_context->local_context.peer_root_cert_provision_size[0] =
3642 : root_cert_size;
3643 1 : spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
3644 1 : libspdm_reset_message_b(spdm_context);
3645 1 : spdm_context->connection_info.algorithm.base_hash_algo =
3646 : m_libspdm_use_hash_algo;
3647 1 : spdm_context->connection_info.algorithm.base_asym_algo =
3648 : m_libspdm_use_asym_algo;
3649 1 : spdm_context->connection_info.algorithm.req_base_asym_alg =
3650 : m_libspdm_use_req_asym_algo;
3651 :
3652 1 : cert_chain_size = sizeof(cert_chain);
3653 1 : libspdm_zero_mem(cert_chain, sizeof(cert_chain));
3654 1 : status = libspdm_get_certificate(spdm_context, NULL, 0, &cert_chain_size,
3655 : cert_chain);
3656 1 : assert_int_equal(status, LIBSPDM_STATUS_INVALID_MSG_FIELD);
3657 1 : free(data);
3658 1 : }
3659 :
3660 : /**
3661 : * Test 21: Fail case, request a certificate chain, responder return portion_length > spdm_request.length.
3662 : * Expected Behavior:returns a status of RETURN_DEVICE_ERROR.
3663 : **/
3664 1 : static void req_get_certificate_case21(void **state)
3665 : {
3666 : libspdm_return_t status;
3667 : libspdm_test_context_t *spdm_test_context;
3668 : libspdm_context_t *spdm_context;
3669 : size_t cert_chain_size;
3670 : uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
3671 : void *data;
3672 : size_t data_size;
3673 : void *hash;
3674 : size_t hash_size;
3675 : const uint8_t *root_cert;
3676 : size_t root_cert_size;
3677 :
3678 1 : spdm_test_context = *state;
3679 1 : spdm_context = spdm_test_context->spdm_context;
3680 1 : spdm_test_context->case_id = 0x15;
3681 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
3682 : SPDM_VERSION_NUMBER_SHIFT_BIT;
3683 1 : spdm_context->connection_info.connection_state =
3684 : LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
3685 1 : spdm_context->connection_info.capability.flags |=
3686 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
3687 1 : if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
3688 : m_libspdm_use_asym_algo, &data,
3689 : &data_size, &hash, &hash_size)) {
3690 0 : assert(false);
3691 : }
3692 1 : if (!libspdm_x509_get_cert_from_cert_chain(
3693 1 : (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
3694 1 : data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
3695 0 : assert(false);
3696 : }
3697 1 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "root cert data :\n"));
3698 1 : libspdm_dump_hex(
3699 : root_cert,
3700 : root_cert_size);
3701 1 : spdm_context->local_context.peer_root_cert_provision_size[0] =
3702 : root_cert_size;
3703 1 : spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
3704 1 : libspdm_reset_message_b(spdm_context);
3705 1 : spdm_context->connection_info.algorithm.base_hash_algo =
3706 : m_libspdm_use_hash_algo;
3707 1 : spdm_context->connection_info.algorithm.base_asym_algo =
3708 : m_libspdm_use_asym_algo;
3709 1 : spdm_context->connection_info.algorithm.req_base_asym_alg =
3710 : m_libspdm_use_req_asym_algo;
3711 :
3712 1 : cert_chain_size = sizeof(cert_chain);
3713 1 : libspdm_zero_mem(cert_chain, sizeof(cert_chain));
3714 1 : status = libspdm_get_certificate(spdm_context, NULL, 0, &cert_chain_size,
3715 : cert_chain);
3716 1 : assert_int_equal(status, LIBSPDM_STATUS_INVALID_MSG_FIELD);
3717 1 : free(data);
3718 1 : }
3719 :
3720 : /**
3721 : * Test 22: Fail case, request a certificate chain,
3722 : * spdm_request.offset + spdm_response->portion_length + spdm_response->remainder_length !=
3723 : * total_responder_cert_chain_buffer_length.
3724 : * Expected Behavior:returns a status of LIBSPDM_STATUS_INVALID_MSG_FIELD.
3725 : **/
3726 1 : static void req_get_certificate_case22(void **state)
3727 : {
3728 : libspdm_return_t status;
3729 : libspdm_test_context_t *spdm_test_context;
3730 : libspdm_context_t *spdm_context;
3731 : size_t cert_chain_size;
3732 : uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
3733 : void *data;
3734 : size_t data_size;
3735 : void *hash;
3736 : size_t hash_size;
3737 : const uint8_t *root_cert;
3738 : size_t root_cert_size;
3739 :
3740 1 : spdm_test_context = *state;
3741 1 : spdm_context = spdm_test_context->spdm_context;
3742 1 : spdm_test_context->case_id = 0x16;
3743 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
3744 : SPDM_VERSION_NUMBER_SHIFT_BIT;
3745 1 : spdm_context->connection_info.connection_state =
3746 : LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
3747 1 : spdm_context->connection_info.capability.flags |=
3748 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
3749 1 : if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
3750 : m_libspdm_use_asym_algo, &data,
3751 : &data_size, &hash, &hash_size)) {
3752 0 : assert(false);
3753 : }
3754 1 : if (!libspdm_x509_get_cert_from_cert_chain(
3755 1 : (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
3756 1 : data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
3757 0 : assert(false);
3758 : }
3759 1 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "root cert data :\n"));
3760 1 : libspdm_dump_hex(
3761 : root_cert,
3762 : root_cert_size);
3763 1 : spdm_context->local_context.peer_root_cert_provision_size[0] =
3764 : root_cert_size;
3765 1 : spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
3766 1 : libspdm_reset_message_b(spdm_context);
3767 1 : spdm_context->connection_info.algorithm.base_hash_algo =
3768 : m_libspdm_use_hash_algo;
3769 1 : spdm_context->connection_info.algorithm.base_asym_algo =
3770 : m_libspdm_use_asym_algo;
3771 1 : spdm_context->connection_info.algorithm.req_base_asym_alg =
3772 : m_libspdm_use_req_asym_algo;
3773 :
3774 1 : cert_chain_size = sizeof(cert_chain);
3775 1 : libspdm_zero_mem(cert_chain, sizeof(cert_chain));
3776 1 : status = libspdm_get_certificate(spdm_context, NULL, 0, &cert_chain_size,
3777 : cert_chain);
3778 1 : assert_int_equal(status, LIBSPDM_STATUS_INVALID_MSG_FIELD);
3779 1 : free(data);
3780 1 : }
3781 :
3782 : /**
3783 : * Test 23: request messages are successfully sent and response messages are successfully
3784 : * received. Buffer B already has arbitrary data.
3785 : * Expected Behavior: requester returns the status LIBSPDM_STATUS_SUCCESS and CERTIFICATE messages are
3786 : * received, buffer B appends the exchanged GET_CERTIFICATE and CERTIFICATE messages.
3787 : **/
3788 1 : static void req_get_certificate_case23(void **state)
3789 : {
3790 : libspdm_return_t status;
3791 : libspdm_test_context_t *spdm_test_context;
3792 : libspdm_context_t *spdm_context;
3793 : size_t cert_chain_size;
3794 : uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
3795 : void *data;
3796 : size_t data_size;
3797 : void *hash;
3798 : size_t hash_size;
3799 : const uint8_t *root_cert;
3800 : size_t root_cert_size;
3801 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
3802 : size_t arbitrary_size;
3803 : #endif
3804 :
3805 1 : spdm_test_context = *state;
3806 1 : spdm_context = spdm_test_context->spdm_context;
3807 1 : spdm_test_context->case_id = 0x17;
3808 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
3809 : SPDM_VERSION_NUMBER_SHIFT_BIT;
3810 1 : spdm_context->connection_info.connection_state =
3811 : LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
3812 1 : spdm_context->connection_info.capability.flags |=
3813 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
3814 1 : if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
3815 : m_libspdm_use_asym_algo, &data,
3816 : &data_size, &hash, &hash_size)) {
3817 0 : assert(false);
3818 : }
3819 1 : if (!libspdm_x509_get_cert_from_cert_chain(
3820 1 : (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
3821 1 : data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
3822 0 : assert(false);
3823 : }
3824 1 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "root cert data :\n"));
3825 1 : libspdm_dump_hex(root_cert, root_cert_size);
3826 1 : spdm_context->local_context.peer_root_cert_provision_size[0] = root_cert_size;
3827 1 : spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
3828 1 : libspdm_reset_message_b(spdm_context);
3829 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
3830 1 : spdm_context->connection_info.algorithm.base_asym_algo = m_libspdm_use_asym_algo;
3831 1 : spdm_context->connection_info.algorithm.req_base_asym_alg = m_libspdm_use_req_asym_algo;
3832 1 : spdm_context->local_context.is_requester = true;
3833 :
3834 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
3835 : /*filling B with arbitrary data*/
3836 : arbitrary_size = 8;
3837 : libspdm_set_mem(spdm_context->transcript.message_b.buffer, arbitrary_size, (uint8_t) 0xEE);
3838 : spdm_context->transcript.message_b.buffer_size = arbitrary_size;
3839 : #endif
3840 1 : cert_chain_size = sizeof(cert_chain);
3841 1 : libspdm_zero_mem(cert_chain, sizeof(cert_chain));
3842 1 : status = libspdm_get_certificate(spdm_context, NULL, 0, &cert_chain_size, cert_chain);
3843 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
3844 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
3845 : libspdm_dump_hex(m_libspdm_local_buffer, m_libspdm_local_buffer_size);
3846 : assert_int_equal(spdm_context->transcript.message_b.buffer_size,
3847 : (arbitrary_size + m_libspdm_local_buffer_size));
3848 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "m_libspdm_local_buffer (0x%x):\n",
3849 : m_libspdm_local_buffer_size));
3850 : libspdm_dump_hex(m_libspdm_local_buffer, m_libspdm_local_buffer_size);
3851 : assert_memory_equal(spdm_context->transcript.message_b.buffer + arbitrary_size,
3852 : m_libspdm_local_buffer, m_libspdm_local_buffer_size);
3853 : #endif
3854 1 : free(data);
3855 1 : }
3856 :
3857 : /**
3858 : * Test 24: test the Alias Cert model, hardware identify OID is found in AliasCert model cert
3859 : * Expected Behavior: return RETURN_SECURITY_VIOLATION
3860 : **/
3861 1 : static void req_get_certificate_case24(void **state)
3862 : {
3863 : libspdm_return_t status;
3864 : libspdm_test_context_t *spdm_test_context;
3865 : libspdm_context_t *spdm_context;
3866 : size_t cert_chain_size;
3867 : uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
3868 : void *data;
3869 : size_t data_size;
3870 : void *hash;
3871 : size_t hash_size;
3872 : const uint8_t *root_cert;
3873 : size_t root_cert_size;
3874 :
3875 1 : spdm_test_context = *state;
3876 1 : spdm_context = spdm_test_context->spdm_context;
3877 1 : spdm_test_context->case_id = 0x18;
3878 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
3879 : SPDM_VERSION_NUMBER_SHIFT_BIT;
3880 1 : spdm_context->connection_info.connection_state =
3881 : LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
3882 1 : spdm_context->connection_info.capability.flags |=
3883 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
3884 : /*The only different setting with normal case2: cert model is AliasCert model*/
3885 1 : spdm_context->connection_info.capability.flags |=
3886 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_ALIAS_CERT_CAP;
3887 1 : if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
3888 : m_libspdm_use_asym_algo, &data,
3889 : &data_size, &hash, &hash_size)) {
3890 0 : assert(false);
3891 : }
3892 1 : if (!libspdm_x509_get_cert_from_cert_chain(
3893 1 : (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
3894 1 : data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
3895 0 : assert(false);
3896 : }
3897 1 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "root cert data :\n"));
3898 1 : LIBSPDM_INTERNAL_DUMP_HEX(
3899 : root_cert,
3900 : root_cert_size);
3901 1 : spdm_context->local_context.peer_root_cert_provision_size[0] =
3902 : root_cert_size;
3903 1 : spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
3904 1 : libspdm_reset_message_b(spdm_context);
3905 1 : spdm_context->connection_info.algorithm.base_hash_algo =
3906 : m_libspdm_use_hash_algo;
3907 1 : spdm_context->connection_info.algorithm.base_asym_algo =
3908 : m_libspdm_use_asym_algo;
3909 1 : spdm_context->connection_info.algorithm.req_base_asym_alg =
3910 : m_libspdm_use_req_asym_algo;
3911 :
3912 1 : cert_chain_size = sizeof(cert_chain);
3913 1 : libspdm_zero_mem(cert_chain, sizeof(cert_chain));
3914 1 : status = libspdm_get_certificate(spdm_context, NULL, 0, &cert_chain_size,
3915 : cert_chain);
3916 1 : assert_int_equal(status, LIBSPDM_STATUS_VERIF_FAIL);
3917 1 : free(data);
3918 1 : }
3919 : #if LIBSPDM_ENABLE_CAPABILITY_CHAL_CAP
3920 : /**
3921 : * Test 25: Normal case, request a certificate chain
3922 : * Expected Behavior: receives a valid certificate chain with the correct number of Certificate messages
3923 : **/
3924 1 : static void req_get_certificate_case25(void **state)
3925 : {
3926 : libspdm_return_t status;
3927 : libspdm_test_context_t *spdm_test_context;
3928 : libspdm_context_t *spdm_context;
3929 : size_t cert_chain_size;
3930 : uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
3931 : void *data;
3932 : void *data1;
3933 : size_t data_size;
3934 : size_t data1_size;
3935 : void *hash;
3936 : void *hash1;
3937 : size_t hash_size;
3938 : size_t hash1_size;
3939 : const uint8_t *root_cert;
3940 : const uint8_t *root_cert1;
3941 : size_t root_cert_size;
3942 : size_t root_cert1_size;
3943 : uint8_t slot_id;
3944 : uint8_t measurement_hash[LIBSPDM_MAX_HASH_SIZE];
3945 :
3946 1 : spdm_test_context = *state;
3947 1 : spdm_context = spdm_test_context->spdm_context;
3948 1 : spdm_test_context->case_id = 0x19;
3949 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_11 <<
3950 : SPDM_VERSION_NUMBER_SHIFT_BIT;
3951 1 : spdm_context->connection_info.connection_state =
3952 : LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
3953 1 : spdm_context->connection_info.capability.flags |=
3954 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
3955 1 : spdm_context->connection_info.capability.flags &=
3956 : ~SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_ALIAS_CERT_CAP;
3957 1 : spdm_context->connection_info.capability.flags |=
3958 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHAL_CAP;
3959 1 : libspdm_reset_message_a(spdm_context);
3960 1 : libspdm_reset_message_b(spdm_context);
3961 1 : libspdm_reset_message_c(spdm_context);
3962 1 : spdm_context->connection_info.algorithm.base_hash_algo =
3963 : m_libspdm_use_hash_algo;
3964 1 : spdm_context->connection_info.algorithm.base_asym_algo =
3965 : m_libspdm_use_asym_algo;
3966 1 : spdm_context->connection_info.algorithm.req_base_asym_alg =
3967 : m_libspdm_use_req_asym_algo;
3968 1 : spdm_context->local_context.is_requester = true;
3969 :
3970 1 : if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
3971 : m_libspdm_use_asym_algo, &data,
3972 : &data_size, &hash, &hash_size)) {
3973 0 : assert(false);
3974 : }
3975 1 : if (!libspdm_x509_get_cert_from_cert_chain(
3976 1 : (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
3977 1 : data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
3978 0 : assert(false);
3979 : }
3980 1 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "root cert data :\n"));
3981 1 : libspdm_dump_hex(
3982 : root_cert,
3983 : root_cert_size);
3984 1 : spdm_context->local_context.peer_root_cert_provision_size[0] =
3985 : root_cert_size;
3986 1 : spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
3987 :
3988 1 : libspdm_read_responder_public_certificate_chain_per_slot(1, m_libspdm_use_hash_algo,
3989 : m_libspdm_use_asym_algo, &data1,
3990 : &data1_size, &hash1, &hash1_size);
3991 1 : libspdm_x509_get_cert_from_cert_chain((uint8_t *)data1 + sizeof(spdm_cert_chain_t) + hash1_size,
3992 1 : data1_size - sizeof(spdm_cert_chain_t) - hash1_size, 0,
3993 : &root_cert1, &root_cert1_size);
3994 1 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "root cert data :\n"));
3995 1 : libspdm_dump_hex(
3996 : root_cert1,
3997 : root_cert1_size);
3998 1 : spdm_context->local_context.peer_root_cert_provision_size[1] =
3999 : root_cert1_size;
4000 1 : spdm_context->local_context.peer_root_cert_provision[1] = root_cert1;
4001 :
4002 1 : m_get_cert = true;
4003 3 : for (slot_id = 0; slot_id < 2; slot_id++) {
4004 2 : cert_chain_size = sizeof(cert_chain);
4005 2 : libspdm_zero_mem(cert_chain, sizeof(cert_chain));
4006 2 : status = libspdm_get_certificate(spdm_context, NULL, slot_id, &cert_chain_size,
4007 : cert_chain);
4008 2 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "libspdm_get_certificate - %xu\n", status));
4009 2 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
4010 : }
4011 :
4012 1 : libspdm_reset_message_b(spdm_context);
4013 1 : m_get_cert = false;
4014 3 : for (slot_id = 0; slot_id < 2; slot_id++) {
4015 2 : libspdm_zero_mem(measurement_hash, sizeof(measurement_hash));
4016 2 : status = libspdm_challenge(
4017 : spdm_context, NULL, slot_id,
4018 : SPDM_CHALLENGE_REQUEST_NO_MEASUREMENT_SUMMARY_HASH,
4019 : measurement_hash, NULL);
4020 2 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "libspdm_challenge - %xu\n", status));
4021 2 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
4022 : }
4023 :
4024 1 : free(data);
4025 1 : free(data1);
4026 1 : }
4027 : #endif
4028 : /**
4029 : * Test 26: Normal case, request a certificate chain in a session
4030 : * Expected Behavior: receives a valid certificate chain with the correct number of Certificate messages
4031 : **/
4032 1 : static void req_get_certificate_case26(void **state)
4033 : {
4034 : libspdm_return_t status;
4035 : libspdm_test_context_t *spdm_test_context;
4036 : libspdm_context_t *spdm_context;
4037 : size_t cert_chain_size;
4038 : uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
4039 : void *data;
4040 : size_t data_size;
4041 : void *hash;
4042 : size_t hash_size;
4043 : const uint8_t *root_cert;
4044 : size_t root_cert_size;
4045 : uint32_t session_id;
4046 : libspdm_session_info_t *session_info;
4047 :
4048 1 : spdm_test_context = *state;
4049 1 : spdm_context = spdm_test_context->spdm_context;
4050 1 : spdm_test_context->case_id = 0x1A;
4051 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
4052 : SPDM_VERSION_NUMBER_SHIFT_BIT;
4053 1 : spdm_context->connection_info.connection_state =
4054 : LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
4055 1 : spdm_context->connection_info.capability.flags |=
4056 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
4057 1 : spdm_context->connection_info.capability.flags |=
4058 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_ALIAS_CERT_CAP;
4059 1 : spdm_context->connection_info.capability.flags &=
4060 : ~SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_ALIAS_CERT_CAP;
4061 1 : spdm_context->connection_info.capability.flags |=
4062 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_PSK_CAP;
4063 1 : spdm_context->connection_info.capability.flags |=
4064 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_ENCRYPT_CAP;
4065 1 : spdm_context->connection_info.capability.flags |=
4066 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MAC_CAP;
4067 1 : spdm_context->local_context.capability.flags |=
4068 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_PSK_CAP;
4069 1 : spdm_context->local_context.capability.flags |=
4070 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_ENCRYPT_CAP;
4071 1 : spdm_context->local_context.capability.flags |=
4072 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MAC_CAP;
4073 1 : spdm_context->connection_info.algorithm.dhe_named_group =
4074 : m_libspdm_use_dhe_algo;
4075 1 : spdm_context->connection_info.algorithm.aead_cipher_suite =
4076 : m_libspdm_use_aead_algo;
4077 :
4078 1 : if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
4079 : m_libspdm_use_asym_algo, &data,
4080 : &data_size, &hash, &hash_size)) {
4081 0 : assert(false);
4082 : }
4083 1 : if (!libspdm_x509_get_cert_from_cert_chain(
4084 1 : (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
4085 1 : data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
4086 0 : assert(false);
4087 : }
4088 1 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "root cert data :\n"));
4089 1 : libspdm_dump_hex(
4090 : root_cert,
4091 : root_cert_size);
4092 1 : spdm_context->local_context.peer_root_cert_provision_size[0] =
4093 : root_cert_size;
4094 1 : spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
4095 1 : libspdm_reset_message_b(spdm_context);
4096 1 : spdm_context->connection_info.algorithm.base_hash_algo =
4097 : m_libspdm_use_hash_algo;
4098 1 : spdm_context->connection_info.algorithm.base_asym_algo =
4099 : m_libspdm_use_asym_algo;
4100 1 : spdm_context->connection_info.algorithm.req_base_asym_alg =
4101 : m_libspdm_use_req_asym_algo;
4102 1 : spdm_context->local_context.is_requester = true;
4103 :
4104 1 : session_id = 0xFFFFFFFF;
4105 1 : session_info = &spdm_context->session_info[0];
4106 1 : libspdm_session_info_init(spdm_context, session_info, session_id,
4107 : SECURED_SPDM_VERSION_11 << SPDM_VERSION_NUMBER_SHIFT_BIT, true);
4108 1 : libspdm_secured_message_set_session_state(session_info->secured_message_context,
4109 : LIBSPDM_SESSION_STATE_ESTABLISHED);
4110 :
4111 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
4112 : session_info->session_transcript.message_m.buffer_size =
4113 : session_info->session_transcript.message_m.max_buffer_size;
4114 : #endif
4115 1 : cert_chain_size = sizeof(cert_chain);
4116 1 : libspdm_zero_mem(cert_chain, sizeof(cert_chain));
4117 1 : status = libspdm_get_certificate_ex(spdm_context, &session_id,
4118 : 0, &cert_chain_size,
4119 : cert_chain, NULL, 0);
4120 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
4121 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
4122 : assert_int_equal(session_info->session_transcript.message_m.buffer_size, 0);
4123 : #endif
4124 1 : free(data);
4125 1 : }
4126 :
4127 : /**
4128 : * Test 27: Fail case, responder return wrong SlotID 3, but it should be equal with SlotID 0 in request message.
4129 : * Expected Behavior:returns a status of INVALID_MSG_FIELD.
4130 : **/
4131 1 : static void req_get_certificate_case27(void **state)
4132 : {
4133 : libspdm_return_t status;
4134 : libspdm_test_context_t *spdm_test_context;
4135 : libspdm_context_t *spdm_context;
4136 : size_t cert_chain_size;
4137 : uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
4138 : void *data;
4139 : size_t data_size;
4140 : void *hash;
4141 : size_t hash_size;
4142 : const uint8_t *root_cert;
4143 : size_t root_cert_size;
4144 :
4145 1 : spdm_test_context = *state;
4146 1 : spdm_context = spdm_test_context->spdm_context;
4147 1 : spdm_test_context->case_id = 0x1B;
4148 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
4149 : SPDM_VERSION_NUMBER_SHIFT_BIT;
4150 1 : spdm_context->connection_info.connection_state =
4151 : LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
4152 1 : spdm_context->connection_info.capability.flags |=
4153 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
4154 1 : if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
4155 : m_libspdm_use_asym_algo, &data,
4156 : &data_size, &hash, &hash_size)) {
4157 0 : assert(false);
4158 : }
4159 1 : if (!libspdm_x509_get_cert_from_cert_chain(
4160 1 : (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
4161 1 : data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
4162 0 : assert(false);
4163 : }
4164 1 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "root cert data :\n"));
4165 1 : libspdm_dump_hex(
4166 : root_cert,
4167 : root_cert_size);
4168 1 : spdm_context->local_context.peer_root_cert_provision_size[0] =
4169 : root_cert_size;
4170 1 : spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
4171 1 : libspdm_reset_message_b(spdm_context);
4172 1 : spdm_context->connection_info.algorithm.base_hash_algo =
4173 : m_libspdm_use_hash_algo;
4174 1 : spdm_context->connection_info.algorithm.base_asym_algo =
4175 : m_libspdm_use_asym_algo;
4176 1 : spdm_context->connection_info.algorithm.req_base_asym_alg =
4177 : m_libspdm_use_req_asym_algo;
4178 :
4179 1 : cert_chain_size = sizeof(cert_chain);
4180 1 : libspdm_zero_mem(cert_chain, sizeof(cert_chain));
4181 1 : status = libspdm_get_certificate(spdm_context, NULL, 0, &cert_chain_size,
4182 : cert_chain);
4183 1 : assert_int_equal(status, LIBSPDM_STATUS_INVALID_MSG_FIELD);
4184 1 : free(data);
4185 :
4186 1 : if (m_libspdm_local_certificate_chain != NULL) {
4187 1 : free(m_libspdm_local_certificate_chain);
4188 1 : m_libspdm_local_certificate_chain = NULL;
4189 : }
4190 1 : }
4191 :
4192 : /**
4193 : * Test 28: Normal case, request a certificate chain. Validates certificate by using a preloaded chain instead of root hash
4194 : * Expected Behavior: receives the correct number of Certificate messages
4195 : **/
4196 1 : static void req_get_certificate_case28(void **state)
4197 : {
4198 : libspdm_return_t status;
4199 : libspdm_test_context_t *spdm_test_context;
4200 : libspdm_context_t *spdm_context;
4201 : size_t cert_chain_size;
4202 : uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
4203 : void *data;
4204 : size_t data_size;
4205 : void *hash;
4206 : size_t hash_size;
4207 : const uint8_t *root_cert;
4208 : size_t root_cert_size;
4209 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
4210 : size_t count;
4211 : #endif
4212 :
4213 1 : spdm_test_context = *state;
4214 1 : spdm_context = spdm_test_context->spdm_context;
4215 1 : spdm_test_context->case_id = 0x1C;
4216 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 <<
4217 : SPDM_VERSION_NUMBER_SHIFT_BIT;
4218 1 : spdm_context->connection_info.connection_state =
4219 : LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
4220 1 : spdm_context->connection_info.capability.flags |=
4221 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
4222 1 : spdm_context->connection_info.capability.flags |=
4223 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_ALIAS_CERT_CAP;
4224 1 : libspdm_read_responder_public_certificate_chain_alias_cert(
4225 : m_libspdm_use_hash_algo,
4226 : m_libspdm_use_asym_algo, &data,
4227 : &data_size, &hash, &hash_size);
4228 1 : if (!libspdm_x509_get_cert_from_cert_chain(
4229 1 : (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
4230 1 : data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
4231 0 : assert(false);
4232 : }
4233 :
4234 1 : spdm_context->local_context.peer_root_cert_provision_size[0] = 0;
4235 1 : spdm_context->local_context.peer_root_cert_provision[0] = NULL;
4236 1 : libspdm_reset_message_b(spdm_context);
4237 1 : spdm_context->connection_info.algorithm.base_hash_algo =
4238 : m_libspdm_use_hash_algo;
4239 1 : spdm_context->connection_info.algorithm.base_asym_algo =
4240 : m_libspdm_use_asym_algo;
4241 1 : spdm_context->connection_info.algorithm.req_base_asym_alg =
4242 : m_libspdm_use_req_asym_algo;
4243 1 : spdm_context->local_context.is_requester = true;
4244 :
4245 1 : cert_chain_size = sizeof(cert_chain);
4246 1 : libspdm_zero_mem(cert_chain, sizeof(cert_chain));
4247 1 : status = libspdm_get_certificate(spdm_context, NULL, 0, &cert_chain_size,
4248 : cert_chain);
4249 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
4250 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
4251 : count = (data_size + LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN - 1) /
4252 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN;
4253 : assert_int_equal(spdm_context->transcript.message_b.buffer_size,
4254 : sizeof(spdm_get_certificate_request_t) * count +
4255 : sizeof(spdm_certificate_response_t) * count +
4256 : data_size);
4257 : #endif
4258 1 : free(data);
4259 1 : }
4260 :
4261 : /**
4262 : * Test 29: Normal case, request a certificate chain. Validates certificate by using a preloaded chain instead of root hash
4263 : * Expected Behavior: receives the correct number of Certificate messages
4264 : **/
4265 1 : static void req_get_certificate_case29(void **state)
4266 : {
4267 : libspdm_return_t status;
4268 : libspdm_test_context_t *spdm_test_context;
4269 : libspdm_context_t *spdm_context;
4270 : size_t cert_chain_size;
4271 : uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
4272 : void *data;
4273 : size_t data_size;
4274 : void *hash;
4275 : size_t hash_size;
4276 : const uint8_t *root_cert;
4277 : size_t root_cert_size;
4278 :
4279 1 : spdm_test_context = *state;
4280 1 : spdm_context = spdm_test_context->spdm_context;
4281 1 : spdm_test_context->case_id = 0x1D;
4282 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 <<
4283 : SPDM_VERSION_NUMBER_SHIFT_BIT;
4284 1 : spdm_context->connection_info.connection_state =
4285 : LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
4286 1 : spdm_context->connection_info.capability.flags |=
4287 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
4288 1 : spdm_context->connection_info.capability.flags |=
4289 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_ALIAS_CERT_CAP;
4290 1 : libspdm_read_responder_public_certificate_chain_alias_cert(
4291 : m_libspdm_use_hash_algo,
4292 : m_libspdm_use_asym_algo, &data,
4293 : &data_size, &hash, &hash_size);
4294 1 : if (!libspdm_x509_get_cert_from_cert_chain(
4295 1 : (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
4296 1 : data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
4297 0 : assert(false);
4298 : }
4299 :
4300 1 : spdm_context->local_context.peer_root_cert_provision_size[0] = 0;
4301 1 : spdm_context->local_context.peer_root_cert_provision[0] = NULL;
4302 1 : libspdm_reset_message_b(spdm_context);
4303 1 : spdm_context->connection_info.algorithm.base_hash_algo =
4304 : m_libspdm_use_hash_algo;
4305 1 : spdm_context->connection_info.algorithm.base_asym_algo =
4306 : m_libspdm_use_asym_algo;
4307 1 : spdm_context->connection_info.algorithm.req_base_asym_alg =
4308 : m_libspdm_use_req_asym_algo;
4309 1 : spdm_context->local_context.is_requester = true;
4310 :
4311 1 : cert_chain_size = sizeof(cert_chain);
4312 1 : libspdm_zero_mem(cert_chain, sizeof(cert_chain));
4313 1 : status = libspdm_get_certificate(spdm_context, NULL, 0, &cert_chain_size,
4314 : cert_chain);
4315 1 : assert_int_equal(status, LIBSPDM_STATUS_VERIF_FAIL);
4316 1 : free(data);
4317 1 : }
4318 :
4319 : /**
4320 : * Test 30: check request attributes and response attributes ,
4321 : * Set CertModel to determine whether it meets expectations
4322 : * Expected Behavior: requester returns the status LIBSPDM_STATUS_SUCCESS
4323 : * Expected Behavior: CertModel is GenericCert model and slot 0 , returns a status of RETURN_DEVICE_ERROR.
4324 : * Expected Behavior: CertModel Value of 0 and certificate chain is valid, returns a status of RETURN_DEVICE_ERROR.
4325 : **/
4326 1 : static void req_get_certificate_case30(void **state)
4327 : {
4328 : libspdm_return_t status;
4329 : libspdm_test_context_t *spdm_test_context;
4330 : libspdm_context_t *spdm_context;
4331 : size_t cert_chain_size;
4332 : uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
4333 : void *data;
4334 : size_t data_size;
4335 : void *hash;
4336 : size_t hash_size;
4337 : const uint8_t *root_cert;
4338 : size_t root_cert_size;
4339 : libspdm_data_parameter_t parameter;
4340 :
4341 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
4342 : #else
4343 : uint8_t set_data_buffer_hash[LIBSPDM_MAX_HASH_SIZE];
4344 : uint32_t set_data_buffer_hash_size;
4345 : #endif
4346 :
4347 1 : spdm_test_context = *state;
4348 1 : spdm_context = spdm_test_context->spdm_context;
4349 1 : spdm_test_context->case_id = 0x1E;
4350 1 : spdm_context->retry_times = 1;
4351 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_13 <<
4352 : SPDM_VERSION_NUMBER_SHIFT_BIT;
4353 1 : spdm_context->connection_info.connection_state =
4354 : LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
4355 1 : spdm_context->connection_info.capability.flags = 0;
4356 1 : spdm_context->connection_info.capability.flags |=
4357 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
4358 1 : spdm_context->local_context.is_requester = true;
4359 1 : if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
4360 : m_libspdm_use_asym_algo, &data,
4361 : &data_size, &hash, &hash_size)) {
4362 0 : assert(false);
4363 : }
4364 1 : if (!libspdm_x509_get_cert_from_cert_chain(
4365 1 : (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
4366 1 : data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
4367 0 : assert(false);
4368 : }
4369 1 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "root cert data :\n"));
4370 1 : libspdm_dump_hex(
4371 : root_cert,
4372 : root_cert_size);
4373 1 : spdm_context->local_context.peer_root_cert_provision_size[0] =
4374 : root_cert_size;
4375 1 : spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
4376 1 : libspdm_reset_message_b(spdm_context);
4377 1 : spdm_context->connection_info.algorithm.base_hash_algo =
4378 : m_libspdm_use_hash_algo;
4379 1 : spdm_context->connection_info.algorithm.base_asym_algo =
4380 : m_libspdm_use_asym_algo;
4381 1 : spdm_context->connection_info.algorithm.req_base_asym_alg =
4382 : m_libspdm_use_req_asym_algo;
4383 :
4384 1 : libspdm_zero_mem(¶meter, sizeof(parameter));
4385 1 : parameter.location = LIBSPDM_DATA_LOCATION_CONNECTION;
4386 1 : parameter.additional_data[0] = 0;
4387 1 : libspdm_set_data(spdm_context, LIBSPDM_DATA_PEER_USED_CERT_CHAIN_BUFFER, ¶meter,
4388 : data, data_size);
4389 :
4390 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
4391 : spdm_context->transcript.message_m.buffer_size =
4392 : spdm_context->transcript.message_m.max_buffer_size;
4393 : #else
4394 1 : set_data_buffer_hash_size =
4395 : spdm_context->connection_info.peer_used_cert_chain[0].buffer_hash_size;
4396 1 : libspdm_copy_mem(set_data_buffer_hash, set_data_buffer_hash_size,
4397 1 : spdm_context->connection_info.peer_used_cert_chain[0].buffer_hash,
4398 : set_data_buffer_hash_size);
4399 : #endif
4400 :
4401 : /* Sub Case 1: CertModel Value of 1 , DeviceCert model*/
4402 1 : spdm_context->connection_info.multi_key_conn_rsp = true;
4403 1 : spdm_context->connection_info.peer_cert_info[0] = 0;
4404 1 : m_cert_model = SPDM_CERTIFICATE_INFO_CERT_MODEL_DEVICE_CERT;
4405 1 : libspdm_reset_message_b(spdm_context);
4406 1 : m_slot_id = 0;
4407 1 : m_calling_index = 0;
4408 :
4409 1 : cert_chain_size = sizeof(cert_chain);
4410 1 : libspdm_zero_mem(cert_chain, sizeof(cert_chain));
4411 1 : status = libspdm_get_certificate(spdm_context, NULL, m_slot_id, &cert_chain_size,
4412 : cert_chain);
4413 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
4414 1 : assert_int_equal(spdm_context->connection_info.peer_cert_info[0], m_cert_model);
4415 1 : assert_int_equal(cert_chain_size, m_libspdm_local_certificate_chain_size);
4416 1 : assert_memory_equal(cert_chain, m_libspdm_local_certificate_chain,
4417 : m_libspdm_local_certificate_chain_size);
4418 :
4419 : /* Sub Case 2: CertModel Value of 2 , AliasCert model*/
4420 1 : spdm_context->connection_info.multi_key_conn_rsp = true;
4421 1 : spdm_context->connection_info.peer_cert_info[0] = 0;
4422 1 : m_cert_model = SPDM_CERTIFICATE_INFO_CERT_MODEL_ALIAS_CERT;
4423 1 : libspdm_reset_message_b(spdm_context);
4424 1 : m_slot_id = 0;
4425 1 : m_calling_index = 0;
4426 :
4427 1 : cert_chain_size = sizeof(cert_chain);
4428 1 : libspdm_zero_mem(cert_chain, sizeof(cert_chain));
4429 1 : status = libspdm_get_certificate(spdm_context, NULL, m_slot_id, &cert_chain_size,
4430 : cert_chain);
4431 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
4432 1 : assert_int_equal(spdm_context->connection_info.peer_cert_info[0], m_cert_model);
4433 1 : assert_int_equal(cert_chain_size, m_libspdm_local_certificate_chain_size);
4434 1 : assert_memory_equal(cert_chain, m_libspdm_local_certificate_chain,
4435 : m_libspdm_local_certificate_chain_size);
4436 :
4437 : /* Sub Case 3: CertModel Value of 3 GenericCert model , slot_id set 1
4438 : * In all cases, the certificate model for slot 0 shall be either the device certificate model or the alias certificate model*/
4439 1 : spdm_context->connection_info.multi_key_conn_rsp = true;
4440 1 : spdm_context->connection_info.peer_cert_info[1] = 0;
4441 1 : m_cert_model = SPDM_CERTIFICATE_INFO_CERT_MODEL_GENERIC_CERT;
4442 1 : libspdm_reset_message_b(spdm_context);
4443 1 : m_slot_id = 1;
4444 1 : m_calling_index = 0;
4445 :
4446 1 : cert_chain_size = sizeof(cert_chain);
4447 1 : libspdm_zero_mem(cert_chain, sizeof(cert_chain));
4448 1 : status = libspdm_get_certificate(spdm_context, NULL, m_slot_id, &cert_chain_size,
4449 : cert_chain);
4450 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
4451 1 : assert_int_equal(spdm_context->connection_info.peer_cert_info[1], m_cert_model);
4452 1 : assert_int_equal(cert_chain_size, m_libspdm_local_certificate_chain_size);
4453 1 : assert_memory_equal(cert_chain, m_libspdm_local_certificate_chain,
4454 : m_libspdm_local_certificate_chain_size);
4455 :
4456 : /* Sub Case 4: CertModel Value of 3 , GenericCert model , slot_id set 0
4457 : * In all cases, the certificate model for slot 0 shall be either the device certificate model or the alias certificate model*/
4458 1 : spdm_context->connection_info.multi_key_conn_rsp = true;
4459 1 : spdm_context->connection_info.peer_cert_info[0] = 0;
4460 1 : m_cert_model = SPDM_CERTIFICATE_INFO_CERT_MODEL_GENERIC_CERT;
4461 1 : libspdm_reset_message_b(spdm_context);
4462 1 : m_slot_id = 0;
4463 1 : m_calling_index = 0;
4464 :
4465 1 : cert_chain_size = sizeof(cert_chain);
4466 1 : libspdm_zero_mem(cert_chain, sizeof(cert_chain));
4467 1 : status = libspdm_get_certificate(spdm_context, NULL, m_slot_id, &cert_chain_size,
4468 : cert_chain);
4469 1 : assert_int_equal(status, LIBSPDM_STATUS_INVALID_MSG_FIELD);
4470 1 : assert_int_equal(spdm_context->connection_info.peer_cert_info[0], 0);
4471 :
4472 : /* Sub Case 5: CertModel Value of 0 , MULTI_KEY_CONN_RSP is true*/
4473 : /* Value of 0 indicates either that the certificate slot does not contain any certificates or that the corresponding
4474 : * MULTI_KEY_CONN_REQ or MULTI_KEY_CONN_RSP is false. */
4475 1 : spdm_context->connection_info.multi_key_conn_rsp = true;
4476 1 : spdm_context->connection_info.peer_cert_info[0] = 0;
4477 1 : m_cert_model = SPDM_CERTIFICATE_INFO_CERT_MODEL_NONE;
4478 1 : libspdm_reset_message_b(spdm_context);
4479 1 : m_slot_id = 0;
4480 1 : m_calling_index = 0;
4481 :
4482 1 : cert_chain_size = sizeof(cert_chain);
4483 1 : libspdm_zero_mem(cert_chain, sizeof(cert_chain));
4484 1 : status = libspdm_get_certificate(spdm_context, NULL, m_slot_id, &cert_chain_size,
4485 : cert_chain);
4486 1 : assert_int_equal(status, LIBSPDM_STATUS_INVALID_MSG_FIELD);
4487 1 : assert_int_equal(spdm_context->connection_info.peer_cert_info[0], m_cert_model);
4488 :
4489 : /* Sub Case 6: CertModel Value of 0 , MULTI_KEY_CONN_RSP is false*/
4490 : /* Value of 0 indicates either that the certificate slot does not contain any certificates or that the corresponding
4491 : * MULTI_KEY_CONN_REQ or MULTI_KEY_CONN_RSP is false. */
4492 1 : spdm_context->connection_info.multi_key_conn_rsp = false;
4493 1 : spdm_context->connection_info.peer_cert_info[0] = 0;
4494 1 : m_cert_model = SPDM_CERTIFICATE_INFO_CERT_MODEL_NONE;
4495 1 : libspdm_reset_message_b(spdm_context);
4496 1 : m_slot_id = 0;
4497 1 : m_calling_index = 0;
4498 :
4499 1 : cert_chain_size = sizeof(cert_chain);
4500 1 : libspdm_zero_mem(cert_chain, sizeof(cert_chain));
4501 1 : status = libspdm_get_certificate(spdm_context, NULL, m_slot_id, &cert_chain_size,
4502 : cert_chain);
4503 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
4504 1 : assert_int_equal(spdm_context->connection_info.peer_cert_info[0], m_cert_model);
4505 1 : assert_int_equal(cert_chain_size, m_libspdm_local_certificate_chain_size);
4506 1 : assert_memory_equal(cert_chain, m_libspdm_local_certificate_chain,
4507 : m_libspdm_local_certificate_chain_size);
4508 :
4509 1 : free(data);
4510 1 : free(m_libspdm_local_certificate_chain);
4511 1 : m_libspdm_local_certificate_chain = NULL;
4512 1 : m_libspdm_local_certificate_chain_size = 0;
4513 1 : }
4514 :
4515 : /**
4516 : * Test 31: Fail case, input buffer size too small for holding cert chain.
4517 : * Expected Behavior: returns a status of BUFFER_TOO_SMALL.
4518 : **/
4519 1 : static void req_get_certificate_case31(void **state)
4520 : {
4521 : libspdm_return_t status;
4522 : libspdm_test_context_t *spdm_test_context;
4523 : libspdm_context_t *spdm_context;
4524 : size_t cert_chain_size;
4525 : uint8_t cert_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
4526 : void *data;
4527 : size_t data_size;
4528 : void *hash;
4529 : size_t hash_size;
4530 : const uint8_t *root_cert;
4531 : size_t root_cert_size;
4532 : libspdm_data_parameter_t parameter;
4533 : #if !LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
4534 : uint8_t set_data_buffer_hash[LIBSPDM_MAX_HASH_SIZE];
4535 : uint32_t set_data_buffer_hash_size;
4536 : #endif
4537 :
4538 1 : spdm_test_context = *state;
4539 1 : spdm_context = spdm_test_context->spdm_context;
4540 1 : spdm_test_context->case_id = 0x1F;
4541 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
4542 : SPDM_VERSION_NUMBER_SHIFT_BIT;
4543 1 : spdm_context->connection_info.connection_state =
4544 : LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
4545 1 : spdm_context->connection_info.capability.flags |=
4546 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
4547 1 : spdm_context->local_context.is_requester = true;
4548 1 : if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
4549 : m_libspdm_use_asym_algo, &data,
4550 : &data_size, &hash, &hash_size)) {
4551 0 : assert(false);
4552 : }
4553 1 : if (!libspdm_x509_get_cert_from_cert_chain(
4554 1 : (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
4555 1 : data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
4556 0 : assert(false);
4557 : }
4558 1 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "root cert data :\n"));
4559 1 : libspdm_dump_hex(
4560 : root_cert,
4561 : root_cert_size);
4562 1 : spdm_context->local_context.peer_root_cert_provision_size[0] =
4563 : root_cert_size;
4564 1 : spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
4565 1 : libspdm_reset_message_b(spdm_context);
4566 1 : spdm_context->connection_info.algorithm.base_hash_algo =
4567 : m_libspdm_use_hash_algo;
4568 1 : spdm_context->connection_info.algorithm.base_asym_algo =
4569 : m_libspdm_use_asym_algo;
4570 1 : spdm_context->connection_info.algorithm.req_base_asym_alg =
4571 : m_libspdm_use_req_asym_algo;
4572 :
4573 1 : libspdm_zero_mem(¶meter, sizeof(parameter));
4574 1 : parameter.location = LIBSPDM_DATA_LOCATION_CONNECTION;
4575 1 : parameter.additional_data[0] = 0;
4576 1 : libspdm_set_data(spdm_context, LIBSPDM_DATA_PEER_USED_CERT_CHAIN_BUFFER, ¶meter,
4577 : data, data_size);
4578 :
4579 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
4580 : spdm_context->transcript.message_m.buffer_size =
4581 : spdm_context->transcript.message_m.max_buffer_size;
4582 : #else
4583 1 : set_data_buffer_hash_size =
4584 : spdm_context->connection_info.peer_used_cert_chain[0].buffer_hash_size;
4585 1 : libspdm_copy_mem(set_data_buffer_hash, set_data_buffer_hash_size,
4586 1 : spdm_context->connection_info.peer_used_cert_chain[0].buffer_hash,
4587 : set_data_buffer_hash_size);
4588 : #endif
4589 : /* Set cert_chain_size to a value that is less than the actual size of the certificate chain */
4590 1 : cert_chain_size = data_size - 1;
4591 1 : libspdm_zero_mem(cert_chain, sizeof(cert_chain));
4592 1 : status = libspdm_get_certificate(spdm_context, NULL, 0, &cert_chain_size,
4593 : cert_chain);
4594 1 : assert_int_equal(status, LIBSPDM_STATUS_BUFFER_TOO_SMALL);
4595 1 : free(data);
4596 1 : if (m_libspdm_local_certificate_chain != NULL) {
4597 1 : free(m_libspdm_local_certificate_chain);
4598 1 : m_libspdm_local_certificate_chain = NULL;
4599 1 : m_libspdm_local_certificate_chain_size = 0;
4600 : }
4601 1 : }
4602 :
4603 1 : int libspdm_req_get_certificate_test(void)
4604 : {
4605 1 : const struct CMUnitTest test_cases[] = {
4606 : /* SendRequest failed*/
4607 : cmocka_unit_test(req_get_certificate_case1),
4608 : /* Successful response: check root certificate hash*/
4609 : cmocka_unit_test(req_get_certificate_case2),
4610 : /* connection_state check failed*/
4611 : cmocka_unit_test(req_get_certificate_case3),
4612 : /* Error response: SPDM_ERROR_CODE_INVALID_REQUEST*/
4613 : cmocka_unit_test(req_get_certificate_case4),
4614 : /* Always SPDM_ERROR_CODE_BUSY*/
4615 : cmocka_unit_test(req_get_certificate_case5),
4616 : /* SPDM_ERROR_CODE_BUSY + Successful response*/
4617 : cmocka_unit_test(req_get_certificate_case6),
4618 : /* Error response: SPDM_ERROR_CODE_REQUEST_RESYNCH*/
4619 : cmocka_unit_test(req_get_certificate_case7),
4620 : /* Always SPDM_ERROR_CODE_RESPONSE_NOT_READY*/
4621 : cmocka_unit_test(req_get_certificate_case8),
4622 : /* SPDM_ERROR_CODE_RESPONSE_NOT_READY + Successful response*/
4623 : cmocka_unit_test(req_get_certificate_case9),
4624 : /* Successful response: check certificate chain*/
4625 : cmocka_unit_test(req_get_certificate_case10),
4626 : /* Invalid certificate signature*/
4627 : cmocka_unit_test(req_get_certificate_case11),
4628 : /* Fail certificate chain check*/
4629 : cmocka_unit_test(req_get_certificate_case12),
4630 : /* Successful response: get a certificate chain that fits in one single message*/
4631 : cmocka_unit_test(req_get_certificate_case13),
4632 : /* Successful response: get certificate chain byte by byte*/
4633 : cmocka_unit_test(req_get_certificate_case14),
4634 : /* Successful response: get a long certificate chain*/
4635 : cmocka_unit_test(req_get_certificate_case15),
4636 : /* Unexpected errors*/
4637 : cmocka_unit_test(req_get_certificate_case16),
4638 : /* Successful response: get a certificate chain not start with root cert.*/
4639 : cmocka_unit_test(req_get_certificate_case17),
4640 : /* Fail response: get a certificate chain not start with root cert but with wrong signature.*/
4641 : cmocka_unit_test(req_get_certificate_case18),
4642 : /* Fail response: one certificate in the retrieved certificate chain past its expiration date.*/
4643 : cmocka_unit_test(req_get_certificate_case19),
4644 : /* Fail response: responder return portion_length is 0.*/
4645 : cmocka_unit_test(req_get_certificate_case20),
4646 : /* Fail response: responder return portion_length > spdm_request.length*/
4647 : cmocka_unit_test(req_get_certificate_case21),
4648 : /* Fail response: spdm_request.offset + spdm_response->portion_length + spdm_response->remainder_length !=
4649 : * total_responder_cert_chain_buffer_length.*/
4650 : cmocka_unit_test(req_get_certificate_case22),
4651 : /* Buffer verification*/
4652 : cmocka_unit_test(req_get_certificate_case23),
4653 : /* hardware identify OID is found in AliasCert model cert*/
4654 : cmocka_unit_test(req_get_certificate_case24),
4655 : #if LIBSPDM_ENABLE_CAPABILITY_CHAL_CAP
4656 : /* GetCert (0), GetCert(1) and Challenge(0) */
4657 : cmocka_unit_test(req_get_certificate_case25),
4658 : #endif
4659 : /* get cert in secure session */
4660 : cmocka_unit_test(req_get_certificate_case26),
4661 : /* Fail response: responder return wrong SlotID 3, not equal with SlotID 0 in request message. */
4662 : cmocka_unit_test(req_get_certificate_case27),
4663 : /*Successful response: get the entire alias_cert model cert_chain*/
4664 : cmocka_unit_test(req_get_certificate_case28),
4665 : /*Fail response: get the partial alias_cert model cert_chain*/
4666 : cmocka_unit_test(req_get_certificate_case29),
4667 : /* check request attributes and response attributes*/
4668 : cmocka_unit_test(req_get_certificate_case30),
4669 : /* Fail response: input buffer size too small for holding cert chain */
4670 : cmocka_unit_test(req_get_certificate_case31),
4671 : };
4672 :
4673 1 : libspdm_test_context_t test_context = {
4674 : LIBSPDM_TEST_CONTEXT_VERSION,
4675 : true,
4676 : send_message,
4677 : receive_message,
4678 : };
4679 :
4680 1 : libspdm_setup_test_context(&test_context);
4681 :
4682 1 : return cmocka_run_group_tests(test_cases,
4683 : libspdm_unit_test_group_setup,
4684 : libspdm_unit_test_group_teardown);
4685 : }
4686 :
4687 : #endif /* LIBSPDM_SEND_GET_CERTIFICATE_SUPPORT */
|