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