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