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