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