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