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_responder_lib.h"
10 : #include "internal/libspdm_secured_message_lib.h"
11 :
12 : libspdm_return_t spdm_device_acquire_sender_buffer (
13 : void *context, void **msg_buf_ptr);
14 :
15 : void spdm_device_release_sender_buffer (void *context, const void *msg_buf_ptr);
16 :
17 : libspdm_return_t spdm_device_acquire_receiver_buffer (
18 : void *context, void **msg_buf_ptr);
19 :
20 : void spdm_device_release_receiver_buffer (void *context, const void *msg_buf_ptr);
21 :
22 : static uint32_t libspdm_opaque_data = 0xDEADBEEF;
23 :
24 : /**
25 : * This function verifies peer certificate chain buffer including spdm_cert_chain_t header.
26 : *
27 : * @param spdm_context A pointer to the SPDM context.
28 : * @param cert_chain_buffer Certificate chain buffer including spdm_cert_chain_t header.
29 : * @param cert_chain_buffer_size Size in bytes of the certificate chain buffer.
30 : * @param trust_anchor A buffer to hold the trust_anchor which is used to validate the
31 : * peer certificate, if not NULL.
32 : * @param trust_anchor_size A buffer to hold the trust_anchor_size, if not NULL.
33 : *
34 : * @retval true Peer certificate chain buffer verification passed.
35 : * @retval false Peer certificate chain buffer verification failed.
36 : **/
37 9 : static bool libspdm_verify_peer_cert_chain_buffer(void *spdm_context,
38 : const void *cert_chain_buffer,
39 : size_t cert_chain_buffer_size,
40 : const void **trust_anchor,
41 : size_t *trust_anchor_size)
42 : {
43 : bool result;
44 :
45 : /*verify peer cert chain integrity*/
46 9 : result = libspdm_verify_peer_cert_chain_buffer_integrity(spdm_context, cert_chain_buffer,
47 : cert_chain_buffer_size);
48 9 : if (!result) {
49 0 : return false;
50 : }
51 :
52 : /*verify peer cert chain authority*/
53 9 : result = libspdm_verify_peer_cert_chain_buffer_authority(spdm_context, cert_chain_buffer,
54 : cert_chain_buffer_size, trust_anchor,
55 : trust_anchor_size);
56 9 : if (!result) {
57 3 : return false;
58 : }
59 :
60 6 : return true;
61 : }
62 :
63 : /**
64 : * Return the size in bytes of multi element opaque data supported version.
65 : *
66 : * @param version_count Secure version count.
67 : *
68 : * @return the size in bytes of opaque data supported version.
69 : **/
70 38 : size_t libspdm_get_multi_element_opaque_data_supported_version_data_size(
71 : libspdm_context_t *spdm_context, uint8_t version_count, uint8_t element_num)
72 : {
73 : size_t size;
74 : uint8_t element_index;
75 :
76 38 : if (libspdm_get_connection_version (spdm_context) >= SPDM_MESSAGE_VERSION_12) {
77 19 : size = sizeof(spdm_general_opaque_data_table_header_t);
78 64 : for (element_index = 0; element_index < element_num; element_index++) {
79 45 : size += sizeof(secured_message_opaque_element_table_header_t) +
80 : sizeof(secured_message_opaque_element_supported_version_t) +
81 45 : sizeof(spdm_version_number_t) * version_count;
82 : /* Add Padding*/
83 45 : size = (size + 3) & ~3;
84 : }
85 : } else {
86 19 : size = sizeof(secured_message_general_opaque_data_table_header_t);
87 64 : for (element_index = 0; element_index < element_num; element_index++) {
88 45 : size += sizeof(secured_message_opaque_element_table_header_t) +
89 : sizeof(secured_message_opaque_element_supported_version_t) +
90 45 : sizeof(spdm_version_number_t) * version_count;
91 : /* Add Padding*/
92 45 : size = (size + 3) & ~3;
93 : }
94 : }
95 :
96 38 : return size;
97 : }
98 :
99 : /**
100 : * Build opaque data supported version test.
101 : *
102 : * @param data_out_size[in] size in bytes of the data_out.
103 : * On input, it means the size in bytes of data_out buffer.
104 : * On output, it means the size in bytes of copied data_out buffer if LIBSPDM_STATUS_SUCCESS is returned,
105 : * and means the size in bytes of desired data_out buffer if RETURN_BUFFER_TOO_SMALL is returned.
106 : * @param data_out[in] A pointer to the destination buffer to store the opaque data supported version.
107 : * @param element_num[in] in this test function, the element number < 9 is right. because element id is changed with element_index
108 : **/
109 : libspdm_return_t
110 4 : libspdm_build_multi_element_opaque_data_supported_version_test(libspdm_context_t *spdm_context,
111 : size_t *data_out_size,
112 : void *data_out,
113 : uint8_t element_num)
114 : {
115 : size_t final_data_size;
116 : secured_message_general_opaque_data_table_header_t
117 : *general_opaque_data_table_header;
118 : spdm_general_opaque_data_table_header_t
119 : *spdm_general_opaque_data_table_header;
120 : secured_message_opaque_element_table_header_t
121 : *opaque_element_table_header;
122 : secured_message_opaque_element_supported_version_t
123 : *opaque_element_support_version;
124 : spdm_version_number_t *versions_list;
125 : void *end;
126 : uint8_t element_index;
127 :
128 4 : if (spdm_context->local_context.secured_message_version.secured_message_version_count == 0) {
129 0 : *data_out_size = 0;
130 0 : return LIBSPDM_STATUS_SUCCESS;
131 : }
132 :
133 : final_data_size =
134 4 : libspdm_get_multi_element_opaque_data_supported_version_data_size(
135 : spdm_context,
136 4 : spdm_context->local_context.secured_message_version.secured_message_version_count,
137 : element_num);
138 4 : if (*data_out_size < final_data_size) {
139 0 : *data_out_size = final_data_size;
140 0 : return LIBSPDM_STATUS_BUFFER_TOO_SMALL;
141 : }
142 :
143 4 : if (libspdm_get_connection_version (spdm_context) >= SPDM_MESSAGE_VERSION_12) {
144 2 : spdm_general_opaque_data_table_header = data_out;
145 2 : spdm_general_opaque_data_table_header->total_elements = element_num;
146 2 : libspdm_write_uint24(spdm_general_opaque_data_table_header->reserved, 0);
147 2 : opaque_element_table_header =
148 : (void *)(spdm_general_opaque_data_table_header + 1);
149 : } else {
150 2 : general_opaque_data_table_header = data_out;
151 2 : general_opaque_data_table_header->spec_id =
152 : SECURED_MESSAGE_OPAQUE_DATA_SPEC_ID;
153 2 : general_opaque_data_table_header->opaque_version =
154 : SECURED_MESSAGE_OPAQUE_VERSION;
155 2 : general_opaque_data_table_header->total_elements = element_num;
156 2 : general_opaque_data_table_header->reserved = 0;
157 2 : opaque_element_table_header =
158 : (void *)(general_opaque_data_table_header + 1);
159 : }
160 :
161 34 : for (element_index = 0; element_index < element_num; element_index++) {
162 : /*id is changed with element_index*/
163 30 : opaque_element_table_header->id = element_index;
164 30 : opaque_element_table_header->vendor_len = 0;
165 30 : opaque_element_table_header->opaque_element_data_len =
166 30 : sizeof(secured_message_opaque_element_supported_version_t) +
167 30 : sizeof(spdm_version_number_t) *
168 30 : spdm_context->local_context.secured_message_version.secured_message_version_count;
169 :
170 30 : opaque_element_support_version =
171 : (void *)(opaque_element_table_header + 1);
172 30 : opaque_element_support_version->sm_data_version =
173 : SECURED_MESSAGE_OPAQUE_ELEMENT_SMDATA_DATA_VERSION;
174 30 : opaque_element_support_version->sm_data_id =
175 : SECURED_MESSAGE_OPAQUE_ELEMENT_SMDATA_ID_SUPPORTED_VERSION;
176 30 : opaque_element_support_version->version_count =
177 30 : spdm_context->local_context.secured_message_version.secured_message_version_count;
178 :
179 30 : versions_list = (void *)(opaque_element_support_version + 1);
180 :
181 30 : libspdm_copy_mem(versions_list,
182 30 : *data_out_size - ((uint8_t*)versions_list - (uint8_t*)data_out),
183 30 : spdm_context->local_context.secured_message_version.secured_message_version,
184 30 : spdm_context->local_context.secured_message_version.secured_message_version_count *
185 : sizeof(spdm_version_number_t));
186 :
187 : /*move to next element*/
188 30 : if (libspdm_get_connection_version (spdm_context) >= SPDM_MESSAGE_VERSION_12) {
189 15 : opaque_element_table_header =
190 : (secured_message_opaque_element_table_header_t *)(
191 : (uint8_t *)opaque_element_table_header +
192 15 : libspdm_get_multi_element_opaque_data_supported_version_data_size(
193 : spdm_context,
194 15 : spdm_context->local_context.secured_message_version.secured_message_version_count,
195 15 : 1) -
196 : sizeof(spdm_general_opaque_data_table_header_t));
197 : } else {
198 15 : opaque_element_table_header =
199 : (secured_message_opaque_element_table_header_t *)(
200 : (uint8_t *)opaque_element_table_header +
201 15 : libspdm_get_multi_element_opaque_data_supported_version_data_size(
202 : spdm_context,
203 15 : spdm_context->local_context.secured_message_version.secured_message_version_count,
204 15 : 1) -
205 : sizeof(secured_message_general_opaque_data_table_header_t));
206 : }
207 :
208 : /* Zero Padding. *data_out_size does not need to be changed, because data is 0 padded */
209 30 : end = versions_list +
210 30 : spdm_context->local_context.secured_message_version.secured_message_version_count;
211 30 : libspdm_zero_mem(end, (size_t)data_out + final_data_size - (size_t)end);
212 : }
213 :
214 4 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO,
215 : "successful build multi element opaque data supported version! \n"));
216 4 : return LIBSPDM_STATUS_SUCCESS;
217 : }
218 :
219 : /**
220 : * Return the size in bytes of multi element opaque data selection version.
221 : *
222 : * @param version_count Secure version count.
223 : *
224 : * @return the size in bytes of opaque data selection version.
225 : **/
226 8 : size_t libspdm_get_multi_element_opaque_data_version_selection_data_size(
227 : const libspdm_context_t *spdm_context, uint8_t element_num)
228 : {
229 : size_t size;
230 : uint8_t element_index;
231 :
232 8 : if (spdm_context->local_context.secured_message_version.secured_message_version_count == 0) {
233 0 : return 0;
234 : }
235 :
236 8 : if (libspdm_get_connection_version (spdm_context) >= SPDM_MESSAGE_VERSION_12) {
237 4 : size = sizeof(spdm_general_opaque_data_table_header_t);
238 34 : for (element_index = 0; element_index < element_num; element_index++) {
239 30 : size += sizeof(secured_message_opaque_element_table_header_t) +
240 : sizeof(secured_message_opaque_element_version_selection_t);
241 : /* Add Padding*/
242 30 : size = (size + 3) & ~3;
243 : }
244 : } else {
245 4 : size = sizeof(secured_message_general_opaque_data_table_header_t);
246 34 : for (element_index = 0; element_index < element_num; element_index++) {
247 30 : size += sizeof(secured_message_opaque_element_table_header_t) +
248 : sizeof(secured_message_opaque_element_version_selection_t);
249 : /* Add Padding*/
250 30 : size = (size + 3) & ~3;
251 : }
252 : }
253 :
254 8 : return size;
255 : }
256 :
257 4 : static libspdm_return_t libspdm_build_opaque_data_version_selection_data_test(
258 : const libspdm_context_t *spdm_context, spdm_version_number_t secured_message_version,
259 : size_t *data_out_size, void *data_out, uint8_t element_num)
260 : {
261 : size_t final_data_size;
262 : secured_message_general_opaque_data_table_header_t
263 : *general_opaque_data_table_header;
264 : spdm_general_opaque_data_table_header_t
265 : *spdm_general_opaque_data_table_header;
266 : secured_message_opaque_element_table_header_t
267 : *opaque_element_table_header;
268 : secured_message_opaque_element_version_selection_t
269 : *opaque_element_version_section;
270 : void *end;
271 : uint8_t element_index;
272 : size_t current_element_len;
273 :
274 4 : if (spdm_context->local_context.secured_message_version.secured_message_version_count == 0) {
275 0 : *data_out_size = 0;
276 0 : return LIBSPDM_STATUS_SUCCESS;
277 : }
278 :
279 4 : final_data_size = libspdm_get_multi_element_opaque_data_version_selection_data_size(
280 : spdm_context, element_num);
281 :
282 4 : if (*data_out_size < final_data_size) {
283 0 : *data_out_size = final_data_size;
284 0 : return LIBSPDM_STATUS_BUFFER_TOO_SMALL;
285 : }
286 :
287 4 : if (libspdm_get_connection_version (spdm_context) >= SPDM_MESSAGE_VERSION_12) {
288 2 : spdm_general_opaque_data_table_header = data_out;
289 2 : spdm_general_opaque_data_table_header->total_elements = element_num;
290 2 : libspdm_write_uint24(spdm_general_opaque_data_table_header->reserved, 0);
291 :
292 2 : opaque_element_table_header = (void *)(spdm_general_opaque_data_table_header + 1);
293 : } else {
294 2 : general_opaque_data_table_header = data_out;
295 2 : general_opaque_data_table_header->spec_id = SECURED_MESSAGE_OPAQUE_DATA_SPEC_ID;
296 2 : general_opaque_data_table_header->opaque_version = SECURED_MESSAGE_OPAQUE_VERSION;
297 2 : general_opaque_data_table_header->total_elements = element_num;
298 2 : general_opaque_data_table_header->reserved = 0;
299 :
300 2 : opaque_element_table_header = (void *)(general_opaque_data_table_header + 1);
301 : }
302 :
303 34 : for (element_index = 0; element_index < element_num; element_index++) {
304 : /*id is changed with element_index*/
305 30 : opaque_element_table_header->id = element_index;
306 30 : opaque_element_table_header->vendor_len = 0;
307 30 : opaque_element_table_header->opaque_element_data_len =
308 : sizeof(secured_message_opaque_element_version_selection_t);
309 :
310 30 : opaque_element_version_section = (void *)(opaque_element_table_header + 1);
311 30 : opaque_element_version_section->sm_data_version =
312 : SECURED_MESSAGE_OPAQUE_ELEMENT_SMDATA_DATA_VERSION;
313 30 : opaque_element_version_section->sm_data_id =
314 : SECURED_MESSAGE_OPAQUE_ELEMENT_SMDATA_ID_VERSION_SELECTION;
315 30 : opaque_element_version_section->selected_version = secured_message_version;
316 :
317 : /*move to next element*/
318 30 : current_element_len = sizeof(secured_message_opaque_element_table_header_t) +
319 30 : opaque_element_table_header->opaque_element_data_len;
320 : /* Add Padding*/
321 30 : current_element_len = (current_element_len + 3) & ~3;
322 :
323 30 : opaque_element_table_header =
324 : (secured_message_opaque_element_table_header_t *)(
325 : (uint8_t *)opaque_element_table_header + current_element_len);
326 : }
327 :
328 : /* Zero Padding*/
329 4 : end = opaque_element_version_section + 1;
330 4 : libspdm_zero_mem(end, (size_t)data_out + final_data_size - (size_t)end);
331 :
332 4 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO,
333 : "successful build multi element opaque data selection version! \n"));
334 :
335 4 : return LIBSPDM_STATUS_SUCCESS;
336 : }
337 :
338 :
339 : /**
340 : * Test 1: Basic test - tests happy path of setting and getting opaque data from
341 : * context successfully.
342 : **/
343 1 : static void libspdm_test_common_context_data_case1(void **state)
344 : {
345 : libspdm_return_t status;
346 : libspdm_test_context_t *spdm_test_context;
347 : libspdm_context_t *spdm_context;
348 1 : void *data = (void *)&libspdm_opaque_data;
349 1 : void *return_data = NULL;
350 1 : size_t data_return_size = 0;
351 :
352 1 : spdm_test_context = *state;
353 1 : spdm_context = spdm_test_context->spdm_context;
354 1 : spdm_test_context->case_id = 0x1;
355 :
356 1 : status = libspdm_set_data(spdm_context, LIBSPDM_DATA_APP_CONTEXT_DATA,
357 : NULL, &data, sizeof(data));
358 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
359 :
360 1 : data_return_size = sizeof(return_data);
361 1 : status = libspdm_get_data(spdm_context, LIBSPDM_DATA_APP_CONTEXT_DATA,
362 : NULL, &return_data, &data_return_size);
363 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
364 :
365 1 : assert_memory_equal(data, return_data, sizeof(data));
366 1 : assert_int_equal(data_return_size, sizeof(void*));
367 :
368 : /* check that nothing changed at the data location */
369 1 : assert_int_equal(libspdm_opaque_data, 0xDEADBEEF);
370 1 : }
371 :
372 : /**
373 : * Test 2: Test failure paths of setting opaque data in context. libspdm_set_data
374 : * should fail when an invalid size is passed.
375 : **/
376 1 : static void libspdm_test_common_context_data_case2(void **state)
377 : {
378 : libspdm_return_t status;
379 : libspdm_test_context_t *spdm_test_context;
380 : libspdm_context_t *spdm_context;
381 1 : void *data = (void *)&libspdm_opaque_data;
382 1 : void *return_data = NULL;
383 1 : void *current_return_data = NULL;
384 1 : size_t data_return_size = 0;
385 :
386 1 : spdm_test_context = *state;
387 1 : spdm_context = spdm_test_context->spdm_context;
388 1 : spdm_test_context->case_id = 0x2;
389 :
390 : /**
391 : * Get current opaque data in context. May have been set in previous
392 : * tests. This will be used to compare later to ensure the value hasn't
393 : * changed after a failed set data.
394 : */
395 1 : data_return_size = sizeof(current_return_data);
396 1 : status = libspdm_get_data(spdm_context, LIBSPDM_DATA_APP_CONTEXT_DATA,
397 : NULL, ¤t_return_data, &data_return_size);
398 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
399 1 : assert_int_equal(data_return_size, sizeof(void*));
400 :
401 : /* Ensure nothing has changed between subsequent calls to get data */
402 1 : assert_ptr_equal(current_return_data, &libspdm_opaque_data);
403 :
404 : /*
405 : * Set data with invalid size, it should fail. Read back to ensure that
406 : * no data was set.
407 : */
408 1 : status = libspdm_set_data(spdm_context, LIBSPDM_DATA_APP_CONTEXT_DATA,
409 : NULL, &data, 500);
410 1 : assert_int_equal(status, LIBSPDM_STATUS_INVALID_PARAMETER);
411 :
412 1 : data_return_size = sizeof(return_data);
413 1 : status = libspdm_get_data(spdm_context, LIBSPDM_DATA_APP_CONTEXT_DATA,
414 : NULL, &return_data, &data_return_size);
415 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
416 1 : assert_ptr_equal(return_data, current_return_data);
417 1 : assert_int_equal(data_return_size, sizeof(void*));
418 :
419 : /* check that nothing changed at the data location */
420 1 : assert_int_equal(libspdm_opaque_data, 0xDEADBEEF);
421 1 : }
422 :
423 : /**
424 : * Test 3: Test failure paths of setting opaque data in context. libspdm_set_data
425 : * should fail when data contains NULL value.
426 : **/
427 1 : static void libspdm_test_common_context_data_case3(void **state)
428 : {
429 : libspdm_return_t status;
430 : libspdm_test_context_t *spdm_test_context;
431 : libspdm_context_t *spdm_context;
432 1 : void *data = NULL;
433 1 : void *return_data = NULL;
434 1 : void *current_return_data = NULL;
435 1 : size_t data_return_size = 0;
436 :
437 1 : spdm_test_context = *state;
438 1 : spdm_context = spdm_test_context->spdm_context;
439 1 : spdm_test_context->case_id = 0x3;
440 :
441 : /**
442 : * Get current opaque data in context. May have been set in previous
443 : * tests. This will be used to compare later to ensure the value hasn't
444 : * changed after a failed set data.
445 : */
446 1 : data_return_size = sizeof(current_return_data);
447 1 : status = libspdm_get_data(spdm_context, LIBSPDM_DATA_APP_CONTEXT_DATA,
448 : NULL, ¤t_return_data, &data_return_size);
449 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
450 1 : assert_int_equal(data_return_size, sizeof(void*));
451 :
452 : /* Ensure nothing has changed between subsequent calls to get data */
453 1 : assert_ptr_equal(current_return_data, &libspdm_opaque_data);
454 :
455 :
456 : /*
457 : * Set data with NULL data, it should fail. Read back to ensure that
458 : * no data was set.
459 : */
460 1 : status = libspdm_set_data(spdm_context, LIBSPDM_DATA_APP_CONTEXT_DATA,
461 : NULL, &data, sizeof(void *));
462 1 : assert_int_equal(status, LIBSPDM_STATUS_INVALID_PARAMETER);
463 :
464 1 : data_return_size = sizeof(return_data);
465 1 : status = libspdm_get_data(spdm_context, LIBSPDM_DATA_APP_CONTEXT_DATA,
466 : NULL, &return_data, &data_return_size);
467 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
468 1 : assert_ptr_equal(return_data, current_return_data);
469 1 : assert_int_equal(data_return_size, sizeof(void*));
470 :
471 : /* check that nothing changed at the data location */
472 1 : assert_int_equal(libspdm_opaque_data, 0xDEADBEEF);
473 :
474 1 : }
475 :
476 : /**
477 : * Test 4: Test failure paths of getting opaque data in context. libspdm_get_data
478 : * should fail when the size of buffer to get is too small.
479 : **/
480 1 : static void libspdm_test_common_context_data_case4(void **state)
481 : {
482 : libspdm_return_t status;
483 : libspdm_test_context_t *spdm_test_context;
484 : libspdm_context_t *spdm_context;
485 1 : void *data = (void *)&libspdm_opaque_data;
486 1 : void *return_data = NULL;
487 1 : size_t data_return_size = 0;
488 :
489 1 : spdm_test_context = *state;
490 1 : spdm_context = spdm_test_context->spdm_context;
491 1 : spdm_test_context->case_id = 0x4;
492 :
493 : /*
494 : * Set data successfully.
495 : */
496 1 : status = libspdm_set_data(spdm_context, LIBSPDM_DATA_APP_CONTEXT_DATA,
497 : NULL, &data, sizeof(void *));
498 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
499 :
500 : /*
501 : * Fail get data due to insufficient buffer for return value. returned
502 : * data size must return required buffer size.
503 : */
504 1 : data_return_size = sizeof(void*) - 1;
505 1 : status = libspdm_get_data(spdm_context, LIBSPDM_DATA_APP_CONTEXT_DATA,
506 : NULL, &return_data, &data_return_size);
507 1 : assert_int_equal(status, LIBSPDM_STATUS_BUFFER_TOO_SMALL);
508 1 : assert_int_equal(data_return_size, sizeof(void*));
509 :
510 : /* check that nothing changed at the data location */
511 1 : assert_int_equal(libspdm_opaque_data, 0xDEADBEEF);
512 1 : }
513 :
514 : /**
515 : * Test 5: There is no root cert.
516 : * Expected Behavior: Return true result.
517 : **/
518 1 : void libspdm_test_verify_peer_cert_chain_buffer_case5(void **state)
519 : {
520 : libspdm_test_context_t *spdm_test_context;
521 : libspdm_context_t *spdm_context;
522 : void *data;
523 : size_t data_size;
524 : void *hash;
525 : size_t hash_size;
526 : const uint8_t *root_cert;
527 : size_t root_cert_size;
528 :
529 : const void *trust_anchor;
530 : size_t trust_anchor_size;
531 : bool result;
532 : uint8_t root_cert_index;
533 :
534 1 : spdm_test_context = *state;
535 1 : spdm_context = spdm_test_context->spdm_context;
536 1 : spdm_test_context->case_id = 0x5;
537 : /* Setting SPDM context as the first steps of the protocol has been accomplished*/
538 1 : spdm_context->connection_info.connection_state =
539 : LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
540 1 : spdm_context->connection_info.capability.flags |=
541 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
542 : /* Loading Root certificate and saving its hash*/
543 1 : if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
544 : m_libspdm_use_asym_algo, &data,
545 : &data_size, &hash, &hash_size)) {
546 0 : assert(false);
547 : }
548 1 : if (!libspdm_x509_get_cert_from_cert_chain(
549 1 : (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
550 1 : data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
551 0 : assert(false);
552 : }
553 :
554 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
555 1 : spdm_context->connection_info.algorithm.base_asym_algo= m_libspdm_use_asym_algo;
556 1 : spdm_context->local_context.is_requester = true;
557 :
558 : /*clear root cert array*/
559 11 : for (root_cert_index = 0; root_cert_index < LIBSPDM_MAX_ROOT_CERT_SUPPORT; root_cert_index++) {
560 10 : spdm_context->local_context.peer_root_cert_provision_size[root_cert_index] = 0;
561 10 : spdm_context->local_context.peer_root_cert_provision[root_cert_index] = NULL;
562 : }
563 1 : result = libspdm_verify_peer_cert_chain_buffer(spdm_context, data, data_size, &trust_anchor,
564 : &trust_anchor_size);
565 1 : assert_int_equal (result, true);
566 :
567 1 : free(data);
568 1 : }
569 :
570 : /**
571 : * Test 6: There is one root cert. And the root cert has two case: match root cert, mismatch root cert.
572 : *
573 : * case Expected Behavior
574 : * there is one match root cert; return false
575 : * there is one mismatch root cert; return true, and the return trust_anchor is root cert.
576 : **/
577 1 : void libspdm_test_verify_peer_cert_chain_buffer_case6(void **state)
578 : {
579 : libspdm_test_context_t *spdm_test_context;
580 : libspdm_context_t *spdm_context;
581 : void *data;
582 : size_t data_size;
583 : void *hash;
584 : size_t hash_size;
585 : const uint8_t *root_cert;
586 : size_t root_cert_size;
587 :
588 : void *data_test;
589 : size_t data_size_test;
590 : void *hash_test;
591 : size_t hash_size_test;
592 : const uint8_t *root_cert_test;
593 : size_t root_cert_size_test;
594 1 : uint32_t m_libspdm_use_asym_algo_test =SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048;
595 :
596 : const void *trust_anchor;
597 : size_t trust_anchor_size;
598 : bool result;
599 : uint8_t root_cert_index;
600 :
601 1 : spdm_test_context = *state;
602 1 : spdm_context = spdm_test_context->spdm_context;
603 1 : spdm_test_context->case_id = 0x6;
604 : /* Setting SPDM context as the first steps of the protocol has been accomplished*/
605 1 : spdm_context->connection_info.connection_state =
606 : LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
607 1 : spdm_context->connection_info.capability.flags |=
608 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
609 1 : spdm_context->local_context.is_requester = true;
610 :
611 : /* Loading Root certificate and saving its hash*/
612 1 : if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
613 : m_libspdm_use_asym_algo, &data,
614 : &data_size, &hash, &hash_size)) {
615 0 : assert(false);
616 : }
617 1 : if (!libspdm_x509_get_cert_from_cert_chain(
618 1 : (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
619 1 : data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
620 0 : assert(false);
621 : }
622 : /* Loading Other test Root certificate and saving its hash*/
623 1 : if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
624 : m_libspdm_use_asym_algo_test, &data_test,
625 : &data_size_test, &hash_test, &hash_size_test)) {
626 0 : return;
627 : }
628 1 : libspdm_x509_get_cert_from_cert_chain(
629 1 : (uint8_t *)data_test + sizeof(spdm_cert_chain_t) + hash_size_test,
630 1 : data_size_test - sizeof(spdm_cert_chain_t) - hash_size_test, 0,
631 : &root_cert_test, &root_cert_size_test);
632 :
633 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
634 1 : spdm_context->connection_info.algorithm.base_asym_algo= m_libspdm_use_asym_algo;
635 :
636 : /*clear root cert array*/
637 11 : for (root_cert_index = 0; root_cert_index < LIBSPDM_MAX_ROOT_CERT_SUPPORT; root_cert_index++) {
638 10 : spdm_context->local_context.peer_root_cert_provision_size[root_cert_index] = 0;
639 10 : spdm_context->local_context.peer_root_cert_provision[root_cert_index] = NULL;
640 : }
641 :
642 : /*case: match root cert case*/
643 1 : spdm_context->local_context.peer_root_cert_provision_size[0] =root_cert_size_test;
644 1 : spdm_context->local_context.peer_root_cert_provision[0] = root_cert_test;
645 1 : result = libspdm_verify_peer_cert_chain_buffer(spdm_context, data, data_size, &trust_anchor,
646 : &trust_anchor_size);
647 1 : assert_int_equal (result, false);
648 :
649 : /*case: mismatch root cert case*/
650 1 : spdm_context->local_context.peer_root_cert_provision_size[0] =root_cert_size;
651 1 : spdm_context->local_context.peer_root_cert_provision[0] = root_cert;
652 1 : result = libspdm_verify_peer_cert_chain_buffer(spdm_context, data, data_size, &trust_anchor,
653 : &trust_anchor_size);
654 1 : assert_int_equal (result, true);
655 1 : assert_ptr_equal (trust_anchor, root_cert);
656 :
657 1 : free(data);
658 1 : free(data_test);
659 : }
660 :
661 : /**
662 : * Test 7: There are LIBSPDM_MAX_ROOT_CERT_SUPPORT/2 root cert.
663 : *
664 : * case Expected Behavior
665 : * there is no match root cert; return false
666 : * there is one match root cert in the end; return true, and the return trust_anchor is root cert.
667 : * there is one match root cert in the middle; return true, and the return trust_anchor is root cert.
668 : **/
669 1 : void libspdm_test_verify_peer_cert_chain_buffer_case7(void **state)
670 : {
671 : libspdm_test_context_t *spdm_test_context;
672 : libspdm_context_t *spdm_context;
673 : void *data;
674 : size_t data_size;
675 : void *hash;
676 : size_t hash_size;
677 : const uint8_t *root_cert;
678 : size_t root_cert_size;
679 :
680 : void *data_test;
681 : size_t data_size_test;
682 : void *hash_test;
683 : size_t hash_size_test;
684 : const uint8_t *root_cert_test;
685 : size_t root_cert_size_test;
686 1 : uint32_t m_libspdm_use_asym_algo_test =SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048;
687 :
688 : const void *trust_anchor;
689 : size_t trust_anchor_size;
690 : bool result;
691 : uint8_t root_cert_index;
692 :
693 1 : spdm_test_context = *state;
694 1 : spdm_context = spdm_test_context->spdm_context;
695 1 : spdm_test_context->case_id = 0x7;
696 : /* Setting SPDM context as the first steps of the protocol has been accomplished*/
697 1 : spdm_context->connection_info.connection_state =
698 : LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
699 1 : spdm_context->connection_info.capability.flags |=
700 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
701 1 : spdm_context->local_context.is_requester = true;
702 : /* Loading Root certificate and saving its hash*/
703 1 : if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
704 : m_libspdm_use_asym_algo, &data,
705 : &data_size, &hash, &hash_size)) {
706 0 : assert(false);
707 : }
708 1 : if (!libspdm_x509_get_cert_from_cert_chain(
709 1 : (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
710 1 : data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
711 0 : assert(false);
712 : }
713 : /* Loading Other test Root certificate and saving its hash*/
714 1 : if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
715 : m_libspdm_use_asym_algo_test, &data_test,
716 : &data_size_test, &hash_test, &hash_size_test)) {
717 0 : return;
718 : }
719 1 : libspdm_x509_get_cert_from_cert_chain(
720 1 : (uint8_t *)data_test + sizeof(spdm_cert_chain_t) + hash_size_test,
721 1 : data_size_test - sizeof(spdm_cert_chain_t) - hash_size_test, 0,
722 : &root_cert_test, &root_cert_size_test);
723 :
724 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
725 1 : spdm_context->connection_info.algorithm.base_asym_algo= m_libspdm_use_asym_algo;
726 :
727 : /*clear root cert array*/
728 11 : for (root_cert_index = 0; root_cert_index < LIBSPDM_MAX_ROOT_CERT_SUPPORT; root_cert_index++) {
729 10 : spdm_context->local_context.peer_root_cert_provision_size[root_cert_index] = 0;
730 10 : spdm_context->local_context.peer_root_cert_provision[root_cert_index] = NULL;
731 : }
732 :
733 : /*case: there is no match root cert*/
734 6 : for (root_cert_index = 0; root_cert_index < (LIBSPDM_MAX_ROOT_CERT_SUPPORT / 2);
735 5 : root_cert_index++) {
736 5 : spdm_context->local_context.peer_root_cert_provision_size[root_cert_index] =
737 : root_cert_size_test;
738 5 : spdm_context->local_context.peer_root_cert_provision[root_cert_index] = root_cert_test;
739 : }
740 1 : result = libspdm_verify_peer_cert_chain_buffer(spdm_context, data, data_size, &trust_anchor,
741 : &trust_anchor_size);
742 1 : assert_int_equal (result, false);
743 :
744 : /*case: there is no match root cert in the end*/
745 : spdm_context->local_context.peer_root_cert_provision_size[LIBSPDM_MAX_ROOT_CERT_SUPPORT / 2 -
746 1 : 1] =root_cert_size;
747 : spdm_context->local_context.peer_root_cert_provision[LIBSPDM_MAX_ROOT_CERT_SUPPORT / 2 -
748 1 : 1] = root_cert;
749 1 : result = libspdm_verify_peer_cert_chain_buffer(spdm_context, data, data_size, &trust_anchor,
750 : &trust_anchor_size);
751 1 : assert_int_equal (result, true);
752 1 : assert_ptr_equal (trust_anchor, root_cert);
753 :
754 : /*case: there is no match root cert in the middle*/
755 : spdm_context->local_context.peer_root_cert_provision_size[LIBSPDM_MAX_ROOT_CERT_SUPPORT /
756 1 : 4] =root_cert_size;
757 : spdm_context->local_context.peer_root_cert_provision[LIBSPDM_MAX_ROOT_CERT_SUPPORT /
758 1 : 4] = root_cert;
759 1 : result = libspdm_verify_peer_cert_chain_buffer(spdm_context, data, data_size, &trust_anchor,
760 : &trust_anchor_size);
761 1 : assert_int_equal (result, true);
762 1 : assert_ptr_equal (trust_anchor, root_cert);
763 :
764 1 : free(data);
765 1 : free(data_test);
766 : }
767 :
768 :
769 : /**
770 : * Test 8: There are full(LIBSPDM_MAX_ROOT_CERT_SUPPORT - 1) root cert.
771 : *
772 : * case Expected Behavior
773 : * there is no match root cert; return false
774 : * there is one match root cert in the end; return true, and the return trust_anchor is root cert.
775 : * there is one match root cert in the middle; return true, and the return trust_anchor is root cert.
776 : **/
777 1 : void libspdm_test_verify_peer_cert_chain_buffer_case8(void **state)
778 : {
779 : libspdm_test_context_t *spdm_test_context;
780 : libspdm_context_t *spdm_context;
781 : void *data;
782 : size_t data_size;
783 : void *hash;
784 : size_t hash_size;
785 : const uint8_t *root_cert;
786 : size_t root_cert_size;
787 :
788 : void *data_test;
789 : size_t data_size_test;
790 : void *hash_test;
791 : size_t hash_size_test;
792 : const uint8_t *root_cert_test;
793 : size_t root_cert_size_test;
794 1 : uint32_t m_libspdm_use_asym_algo_test =SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048;
795 :
796 : const void *trust_anchor;
797 : size_t trust_anchor_size;
798 : bool result;
799 : uint8_t root_cert_index;
800 :
801 1 : spdm_test_context = *state;
802 1 : spdm_context = spdm_test_context->spdm_context;
803 1 : spdm_test_context->case_id = 0x8;
804 : /* Setting SPDM context as the first steps of the protocol has been accomplished*/
805 1 : spdm_context->connection_info.connection_state =
806 : LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
807 1 : spdm_context->connection_info.capability.flags |=
808 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
809 1 : spdm_context->local_context.is_requester = true;
810 : /* Loading Root certificate and saving its hash*/
811 1 : if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
812 : m_libspdm_use_asym_algo, &data,
813 : &data_size, &hash, &hash_size)) {
814 0 : assert(false);
815 : }
816 1 : if (!libspdm_x509_get_cert_from_cert_chain(
817 1 : (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
818 1 : data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
819 0 : assert(false);
820 : }
821 : /* Loading Other test Root certificate and saving its hash*/
822 1 : if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
823 : m_libspdm_use_asym_algo_test, &data_test,
824 : &data_size_test, &hash_test, &hash_size_test)) {
825 0 : return;
826 : }
827 1 : libspdm_x509_get_cert_from_cert_chain(
828 1 : (uint8_t *)data_test + sizeof(spdm_cert_chain_t) + hash_size_test,
829 1 : data_size_test - sizeof(spdm_cert_chain_t) - hash_size_test, 0,
830 : &root_cert_test, &root_cert_size_test);
831 :
832 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
833 1 : spdm_context->connection_info.algorithm.base_asym_algo= m_libspdm_use_asym_algo;
834 :
835 : /*case: there is no match root cert*/
836 11 : for (root_cert_index = 0; root_cert_index < LIBSPDM_MAX_ROOT_CERT_SUPPORT; root_cert_index++) {
837 10 : spdm_context->local_context.peer_root_cert_provision_size[root_cert_index] =
838 : root_cert_size_test;
839 10 : spdm_context->local_context.peer_root_cert_provision[root_cert_index] = root_cert_test;
840 : }
841 1 : result = libspdm_verify_peer_cert_chain_buffer(spdm_context, data, data_size, &trust_anchor,
842 : &trust_anchor_size);
843 1 : assert_int_equal (result, false);
844 :
845 : /*case: there is no match root cert in the end*/
846 : spdm_context->local_context.peer_root_cert_provision_size[LIBSPDM_MAX_ROOT_CERT_SUPPORT -
847 1 : 1] =root_cert_size;
848 : spdm_context->local_context.peer_root_cert_provision[LIBSPDM_MAX_ROOT_CERT_SUPPORT -
849 1 : 1] = root_cert;
850 1 : result = libspdm_verify_peer_cert_chain_buffer(spdm_context, data, data_size, &trust_anchor,
851 : &trust_anchor_size);
852 1 : assert_int_equal (result, true);
853 1 : assert_ptr_equal (trust_anchor, root_cert);
854 :
855 : /*case: there is no match root cert in the middle*/
856 11 : for (root_cert_index = 0; root_cert_index < LIBSPDM_MAX_ROOT_CERT_SUPPORT; root_cert_index++) {
857 10 : spdm_context->local_context.peer_root_cert_provision_size[root_cert_index] =
858 : root_cert_size_test;
859 10 : spdm_context->local_context.peer_root_cert_provision[root_cert_index] = root_cert_test;
860 : }
861 : spdm_context->local_context.peer_root_cert_provision_size[LIBSPDM_MAX_ROOT_CERT_SUPPORT /
862 1 : 2] =root_cert_size;
863 : spdm_context->local_context.peer_root_cert_provision[LIBSPDM_MAX_ROOT_CERT_SUPPORT /
864 1 : 2] = root_cert;
865 1 : result = libspdm_verify_peer_cert_chain_buffer(spdm_context, data, data_size, &trust_anchor,
866 : &trust_anchor_size);
867 1 : assert_int_equal (result, true);
868 1 : assert_ptr_equal (trust_anchor, root_cert);
869 :
870 1 : free(data);
871 1 : free(data_test);
872 : }
873 :
874 : /**
875 : * Test 9: test set data for root cert.
876 : *
877 : * case Expected Behavior
878 : * there is null root cert; return LIBSPDM_STATUS_SUCCESS, and the root cert is set successfully.
879 : * there is full root cert; return RETURN_OUT_OF_RESOURCES.
880 : **/
881 1 : static void libspdm_test_set_data_case9(void **state)
882 : {
883 : libspdm_return_t status;
884 : libspdm_test_context_t *spdm_test_context;
885 : libspdm_context_t *spdm_context;
886 : libspdm_data_parameter_t parameter;
887 :
888 : void *data;
889 : size_t data_size;
890 : void *hash;
891 : size_t hash_size;
892 : const uint8_t *root_cert;
893 : uint8_t root_cert_buffer[LIBSPDM_MAX_CERT_CHAIN_SIZE];
894 : size_t root_cert_size;
895 :
896 : uint8_t root_cert_index;
897 :
898 1 : spdm_test_context = *state;
899 1 : spdm_context = spdm_test_context->spdm_context;
900 1 : spdm_test_context->case_id = 0x9;
901 :
902 : /* Loading Root certificate and saving its hash*/
903 1 : if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
904 : m_libspdm_use_asym_algo, &data,
905 : &data_size, &hash, &hash_size)) {
906 0 : assert(false);
907 : }
908 1 : if (!libspdm_x509_get_cert_from_cert_chain(
909 1 : (uint8_t *)data + sizeof(spdm_cert_chain_t) + hash_size,
910 1 : data_size - sizeof(spdm_cert_chain_t) - hash_size, 0, &root_cert, &root_cert_size)) {
911 0 : assert(false);
912 : }
913 1 : memcpy(root_cert_buffer, root_cert, root_cert_size);
914 :
915 : /*case: there is null root cert*/
916 11 : for (root_cert_index = 0; root_cert_index < LIBSPDM_MAX_ROOT_CERT_SUPPORT; root_cert_index++) {
917 10 : spdm_context->local_context.peer_root_cert_provision_size[root_cert_index] = 0;
918 10 : spdm_context->local_context.peer_root_cert_provision[root_cert_index] = NULL;
919 : }
920 1 : parameter.location = LIBSPDM_DATA_LOCATION_LOCAL;
921 1 : status = libspdm_set_data(spdm_context, LIBSPDM_DATA_PEER_PUBLIC_ROOT_CERT,
922 : ¶meter, root_cert_buffer, root_cert_size);
923 1 : assert_int_equal (status, LIBSPDM_STATUS_SUCCESS);
924 1 : assert_int_equal (spdm_context->local_context.peer_root_cert_provision_size[0], root_cert_size);
925 1 : assert_ptr_equal (spdm_context->local_context.peer_root_cert_provision[0], root_cert_buffer);
926 :
927 : /*case: there is full root cert*/
928 11 : for (root_cert_index = 0; root_cert_index < LIBSPDM_MAX_ROOT_CERT_SUPPORT; root_cert_index++) {
929 10 : spdm_context->local_context.peer_root_cert_provision_size[root_cert_index] = root_cert_size;
930 10 : spdm_context->local_context.peer_root_cert_provision[root_cert_index] = root_cert_buffer;
931 : }
932 1 : status = libspdm_set_data(spdm_context, LIBSPDM_DATA_PEER_PUBLIC_ROOT_CERT,
933 : ¶meter, root_cert_buffer, root_cert_size);
934 1 : assert_int_equal (status, LIBSPDM_STATUS_BUFFER_FULL);
935 :
936 1 : free(data);
937 1 : }
938 :
939 :
940 : /**
941 : * Test 10: There is no root cert.
942 : * Expected Behavior: Return true result.
943 : **/
944 1 : void libspdm_test_process_opaque_data_supported_version_data_case10(void **state)
945 : {
946 : libspdm_return_t status;
947 : libspdm_test_context_t *spdm_test_context;
948 : libspdm_context_t *spdm_context;
949 : size_t opaque_data_size;
950 : uint8_t element_num;
951 : spdm_version_number_t secured_message_version;
952 :
953 1 : spdm_test_context = *state;
954 1 : spdm_context = spdm_test_context->spdm_context;
955 1 : spdm_test_context->case_id = 0xA;
956 :
957 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_11 <<
958 : SPDM_VERSION_NUMBER_SHIFT_BIT;
959 :
960 1 : spdm_context->local_context.secured_message_version.secured_message_version_count = 1;
961 :
962 1 : element_num = 2;
963 1 : opaque_data_size =
964 1 : libspdm_get_multi_element_opaque_data_supported_version_data_size(
965 : spdm_context,
966 1 : spdm_context->local_context.secured_message_version.secured_message_version_count,
967 : element_num);
968 :
969 : uint8_t *opaque_data_ptr;
970 1 : opaque_data_ptr = malloc(opaque_data_size);
971 :
972 1 : libspdm_build_multi_element_opaque_data_supported_version_test(
973 : spdm_context, &opaque_data_size, opaque_data_ptr, element_num);
974 :
975 1 : status = libspdm_process_opaque_data_supported_version_data(spdm_context,
976 : opaque_data_size,
977 : opaque_data_ptr,
978 : &secured_message_version);
979 :
980 1 : assert_int_equal (status, LIBSPDM_STATUS_SUCCESS);
981 :
982 1 : free(opaque_data_ptr);
983 1 : }
984 :
985 1 : void libspdm_test_process_opaque_data_supported_version_data_case11(void **state)
986 : {
987 : libspdm_return_t status;
988 : libspdm_test_context_t *spdm_test_context;
989 : libspdm_context_t *spdm_context;
990 : size_t opaque_data_size;
991 : uint8_t element_num;
992 : spdm_version_number_t secured_message_version;
993 :
994 1 : spdm_test_context = *state;
995 1 : spdm_context = spdm_test_context->spdm_context;
996 1 : spdm_test_context->case_id = 0xB;
997 :
998 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_11 <<
999 : SPDM_VERSION_NUMBER_SHIFT_BIT;
1000 :
1001 1 : spdm_context->local_context.secured_message_version.secured_message_version_count = 1;
1002 :
1003 : /*make element id wrong*/
1004 1 : element_num = SPDM_REGISTRY_ID_MAX + 2;
1005 1 : opaque_data_size =
1006 1 : libspdm_get_multi_element_opaque_data_supported_version_data_size(
1007 : spdm_context,
1008 1 : spdm_context->local_context.secured_message_version.secured_message_version_count,
1009 : element_num);
1010 :
1011 : uint8_t *opaque_data_ptr;
1012 1 : opaque_data_ptr = malloc(opaque_data_size);
1013 :
1014 1 : libspdm_build_multi_element_opaque_data_supported_version_test(
1015 : spdm_context, &opaque_data_size, opaque_data_ptr, element_num);
1016 :
1017 1 : status = libspdm_process_opaque_data_supported_version_data(spdm_context,
1018 : opaque_data_size,
1019 : opaque_data_ptr,
1020 : &secured_message_version);
1021 :
1022 1 : assert_int_equal (status, LIBSPDM_STATUS_INVALID_MSG_FIELD);
1023 :
1024 1 : free(opaque_data_ptr);
1025 1 : }
1026 :
1027 1 : void libspdm_test_process_opaque_data_supported_version_data_case12(void **state)
1028 : {
1029 : libspdm_return_t status;
1030 : libspdm_test_context_t *spdm_test_context;
1031 : libspdm_context_t *spdm_context;
1032 : size_t opaque_data_size;
1033 : uint8_t element_num;
1034 : spdm_version_number_t secured_message_version;
1035 :
1036 1 : spdm_test_context = *state;
1037 1 : spdm_context = spdm_test_context->spdm_context;
1038 1 : spdm_test_context->case_id = 0xC;
1039 :
1040 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 <<
1041 : SPDM_VERSION_NUMBER_SHIFT_BIT;
1042 :
1043 1 : spdm_context->local_context.secured_message_version.secured_message_version_count = 1;
1044 :
1045 1 : element_num = 2;
1046 1 : opaque_data_size =
1047 1 : libspdm_get_multi_element_opaque_data_supported_version_data_size(
1048 : spdm_context,
1049 1 : spdm_context->local_context.secured_message_version.secured_message_version_count,
1050 : element_num);
1051 :
1052 : uint8_t *opaque_data_ptr;
1053 1 : opaque_data_ptr = malloc(opaque_data_size);
1054 :
1055 1 : libspdm_build_multi_element_opaque_data_supported_version_test(
1056 : spdm_context, &opaque_data_size, opaque_data_ptr, element_num);
1057 :
1058 1 : status = libspdm_process_opaque_data_supported_version_data(spdm_context,
1059 : opaque_data_size,
1060 : opaque_data_ptr,
1061 : &secured_message_version);
1062 :
1063 1 : assert_int_equal (status, LIBSPDM_STATUS_SUCCESS);
1064 :
1065 1 : free(opaque_data_ptr);
1066 1 : }
1067 :
1068 1 : void libspdm_test_process_opaque_data_supported_version_data_case13(void **state)
1069 : {
1070 : libspdm_return_t status;
1071 : libspdm_test_context_t *spdm_test_context;
1072 : libspdm_context_t *spdm_context;
1073 : size_t opaque_data_size;
1074 : uint8_t element_num;
1075 : spdm_version_number_t secured_message_version;
1076 :
1077 1 : spdm_test_context = *state;
1078 1 : spdm_context = spdm_test_context->spdm_context;
1079 1 : spdm_test_context->case_id = 0xD;
1080 :
1081 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 <<
1082 : SPDM_VERSION_NUMBER_SHIFT_BIT;
1083 :
1084 1 : spdm_context->local_context.secured_message_version.secured_message_version_count = 1;
1085 :
1086 : /*make element id wrong*/
1087 1 : element_num = SPDM_REGISTRY_ID_MAX + 2;
1088 1 : opaque_data_size =
1089 1 : libspdm_get_multi_element_opaque_data_supported_version_data_size(
1090 : spdm_context,
1091 1 : spdm_context->local_context.secured_message_version.secured_message_version_count,
1092 : element_num);
1093 :
1094 : uint8_t *opaque_data_ptr;
1095 1 : opaque_data_ptr = malloc(opaque_data_size);
1096 :
1097 1 : libspdm_build_multi_element_opaque_data_supported_version_test(
1098 : spdm_context, &opaque_data_size, opaque_data_ptr, element_num);
1099 :
1100 1 : status = libspdm_process_opaque_data_supported_version_data(spdm_context,
1101 : opaque_data_size,
1102 : opaque_data_ptr,
1103 : &secured_message_version);
1104 :
1105 1 : assert_int_equal (status, LIBSPDM_STATUS_INVALID_MSG_FIELD);
1106 :
1107 1 : free(opaque_data_ptr);
1108 1 : }
1109 :
1110 :
1111 1 : void libspdm_test_process_opaque_data_selection_version_data_case14(void **state)
1112 : {
1113 : libspdm_return_t status;
1114 : libspdm_test_context_t *spdm_test_context;
1115 : libspdm_context_t *spdm_context;
1116 : size_t opaque_data_size;
1117 : uint8_t element_num;
1118 : spdm_version_number_t secured_message_version;
1119 :
1120 1 : spdm_test_context = *state;
1121 1 : spdm_context = spdm_test_context->spdm_context;
1122 1 : spdm_test_context->case_id = 0xE;
1123 :
1124 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_11 <<
1125 : SPDM_VERSION_NUMBER_SHIFT_BIT;
1126 :
1127 1 : spdm_context->local_context.secured_message_version.secured_message_version_count = 1;
1128 1 : spdm_context->local_context.secured_message_version.secured_message_version[0] =
1129 : SECURED_SPDM_VERSION_11 << SPDM_VERSION_NUMBER_SHIFT_BIT;
1130 :
1131 1 : element_num = 2;
1132 1 : opaque_data_size =
1133 1 : libspdm_get_multi_element_opaque_data_version_selection_data_size(
1134 : spdm_context,
1135 : element_num);
1136 :
1137 : uint8_t *opaque_data_ptr;
1138 1 : opaque_data_ptr = malloc(opaque_data_size);
1139 :
1140 1 : libspdm_build_opaque_data_version_selection_data_test(
1141 : spdm_context, SECURED_SPDM_VERSION_11 << SPDM_VERSION_NUMBER_SHIFT_BIT, &opaque_data_size,
1142 : opaque_data_ptr, element_num);
1143 :
1144 1 : status = libspdm_process_opaque_data_version_selection_data(spdm_context,
1145 : opaque_data_size,
1146 : opaque_data_ptr,
1147 : &secured_message_version);
1148 :
1149 1 : assert_int_equal (status, LIBSPDM_STATUS_SUCCESS);
1150 1 : assert_int_equal (secured_message_version,
1151 : SECURED_SPDM_VERSION_11 << SPDM_VERSION_NUMBER_SHIFT_BIT);
1152 :
1153 1 : free(opaque_data_ptr);
1154 1 : }
1155 :
1156 :
1157 1 : void libspdm_test_process_opaque_data_selection_version_data_case15(void **state)
1158 : {
1159 : libspdm_return_t status;
1160 : libspdm_test_context_t *spdm_test_context;
1161 : libspdm_context_t *spdm_context;
1162 : size_t opaque_data_size;
1163 : uint8_t element_num;
1164 : spdm_version_number_t secured_message_version;
1165 :
1166 1 : spdm_test_context = *state;
1167 1 : spdm_context = spdm_test_context->spdm_context;
1168 1 : spdm_test_context->case_id = 0xF;
1169 :
1170 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_11 <<
1171 : SPDM_VERSION_NUMBER_SHIFT_BIT;
1172 :
1173 1 : spdm_context->local_context.secured_message_version.secured_message_version_count = 1;
1174 1 : spdm_context->local_context.secured_message_version.secured_message_version[0] =
1175 : SECURED_SPDM_VERSION_11 << SPDM_VERSION_NUMBER_SHIFT_BIT;
1176 :
1177 : /*make element id wrong*/
1178 1 : element_num = SPDM_REGISTRY_ID_MAX + 2;
1179 1 : opaque_data_size =
1180 1 : libspdm_get_multi_element_opaque_data_version_selection_data_size(
1181 : spdm_context,
1182 : element_num);
1183 :
1184 : uint8_t *opaque_data_ptr;
1185 1 : opaque_data_ptr = malloc(opaque_data_size);
1186 :
1187 1 : libspdm_build_opaque_data_version_selection_data_test(
1188 : spdm_context, SECURED_SPDM_VERSION_11 << SPDM_VERSION_NUMBER_SHIFT_BIT, &opaque_data_size,
1189 : opaque_data_ptr, element_num);
1190 :
1191 1 : status = libspdm_process_opaque_data_version_selection_data(spdm_context,
1192 : opaque_data_size,
1193 : opaque_data_ptr,
1194 : &secured_message_version);
1195 :
1196 1 : assert_int_equal (status, LIBSPDM_STATUS_INVALID_MSG_FIELD);
1197 :
1198 1 : free(opaque_data_ptr);
1199 1 : }
1200 :
1201 :
1202 1 : void libspdm_test_process_opaque_data_selection_version_data_case16(void **state)
1203 : {
1204 : libspdm_return_t status;
1205 : libspdm_test_context_t *spdm_test_context;
1206 : libspdm_context_t *spdm_context;
1207 : size_t opaque_data_size;
1208 : uint8_t element_num;
1209 : spdm_version_number_t secured_message_version;
1210 :
1211 1 : spdm_test_context = *state;
1212 1 : spdm_context = spdm_test_context->spdm_context;
1213 1 : spdm_test_context->case_id = 0x10;
1214 :
1215 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 <<
1216 : SPDM_VERSION_NUMBER_SHIFT_BIT;
1217 :
1218 1 : spdm_context->local_context.secured_message_version.secured_message_version_count = 1;
1219 1 : spdm_context->local_context.secured_message_version.secured_message_version[0] =
1220 : SECURED_SPDM_VERSION_11 << SPDM_VERSION_NUMBER_SHIFT_BIT;
1221 :
1222 1 : element_num = 2;
1223 1 : opaque_data_size = libspdm_get_multi_element_opaque_data_version_selection_data_size(
1224 : spdm_context, element_num);
1225 :
1226 : uint8_t *opaque_data_ptr;
1227 1 : opaque_data_ptr = malloc(opaque_data_size);
1228 :
1229 1 : libspdm_build_opaque_data_version_selection_data_test(
1230 : spdm_context, SECURED_SPDM_VERSION_11 << SPDM_VERSION_NUMBER_SHIFT_BIT, &opaque_data_size,
1231 : opaque_data_ptr, element_num);
1232 :
1233 1 : status = libspdm_process_opaque_data_version_selection_data(spdm_context,
1234 : opaque_data_size,
1235 : opaque_data_ptr,
1236 : &secured_message_version);
1237 :
1238 1 : assert_int_equal (status, LIBSPDM_STATUS_SUCCESS);
1239 :
1240 1 : free(opaque_data_ptr);
1241 1 : }
1242 :
1243 1 : void libspdm_test_process_opaque_data_selection_version_data_case17(void **state)
1244 : {
1245 : libspdm_return_t status;
1246 : libspdm_test_context_t *spdm_test_context;
1247 : libspdm_context_t *spdm_context;
1248 : size_t opaque_data_size;
1249 : uint8_t element_num;
1250 : spdm_version_number_t secured_message_version;
1251 :
1252 1 : spdm_test_context = *state;
1253 1 : spdm_context = spdm_test_context->spdm_context;
1254 1 : spdm_test_context->case_id = 0x11;
1255 :
1256 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 <<
1257 : SPDM_VERSION_NUMBER_SHIFT_BIT;
1258 :
1259 1 : spdm_context->local_context.secured_message_version.secured_message_version_count = 1;
1260 1 : spdm_context->local_context.secured_message_version.secured_message_version[0] =
1261 : SECURED_SPDM_VERSION_11 << SPDM_VERSION_NUMBER_SHIFT_BIT;
1262 :
1263 : /*make element id wrong*/
1264 1 : element_num = SPDM_REGISTRY_ID_MAX + 2;
1265 1 : opaque_data_size =
1266 1 : libspdm_get_multi_element_opaque_data_version_selection_data_size(
1267 : spdm_context,
1268 : element_num);
1269 :
1270 : uint8_t *opaque_data_ptr;
1271 1 : opaque_data_ptr = malloc(opaque_data_size);
1272 :
1273 1 : libspdm_build_opaque_data_version_selection_data_test(
1274 : spdm_context, SECURED_SPDM_VERSION_11 << SPDM_VERSION_NUMBER_SHIFT_BIT, &opaque_data_size,
1275 : opaque_data_ptr, element_num);
1276 :
1277 1 : status = libspdm_process_opaque_data_version_selection_data(spdm_context,
1278 : opaque_data_size,
1279 : opaque_data_ptr,
1280 : &secured_message_version);
1281 :
1282 1 : assert_int_equal (status, LIBSPDM_STATUS_INVALID_MSG_FIELD);
1283 :
1284 1 : free(opaque_data_ptr);
1285 1 : }
1286 :
1287 1 : void libspdm_test_secured_message_context_location_selection_case18(void **state)
1288 : {
1289 : libspdm_return_t status;
1290 : libspdm_test_context_t *spdm_test_context;
1291 : libspdm_context_t *spdm_context;
1292 : void *secured_message_contexts[LIBSPDM_MAX_SESSION_COUNT];
1293 : size_t index;
1294 :
1295 1 : spdm_test_context = *state;
1296 1 : spdm_test_context->case_id = 0x12;
1297 :
1298 1 : spdm_context = (libspdm_context_t *)malloc(libspdm_get_context_size_without_secured_context());
1299 :
1300 5 : for (index = 0; index < LIBSPDM_MAX_SESSION_COUNT; index++)
1301 : {
1302 4 : secured_message_contexts[index] =
1303 4 : (void *)malloc(libspdm_secured_message_get_context_size());
1304 : }
1305 :
1306 1 : status = libspdm_init_context_with_secured_context(spdm_context, secured_message_contexts,
1307 : LIBSPDM_MAX_SESSION_COUNT);
1308 1 : assert_int_equal (status, LIBSPDM_STATUS_SUCCESS);
1309 :
1310 5 : for (index = 0; index < LIBSPDM_MAX_SESSION_COUNT; index++)
1311 : {
1312 : /* Ensure the SPDM context points to the specified memory. */
1313 4 : assert_ptr_equal(spdm_context->session_info[index].secured_message_context,
1314 : secured_message_contexts[index]);
1315 : }
1316 :
1317 1 : free(spdm_context);
1318 5 : for (index = 0; index < LIBSPDM_MAX_SESSION_COUNT; index++)
1319 : {
1320 4 : free(secured_message_contexts[index]);
1321 : }
1322 1 : }
1323 :
1324 1 : static void libspdm_test_export_master_secret_case19(void **state)
1325 : {
1326 : uint8_t target_buffer[LIBSPDM_MAX_HASH_SIZE];
1327 : bool result;
1328 : libspdm_secured_message_context_t secured_message_context;
1329 : size_t export_master_secret_size;
1330 :
1331 : /* Get the entire EMS when the reported size of the target buffer is larger than the size of the
1332 : * EMS. */
1333 65 : for (int index = 0; index < LIBSPDM_MAX_HASH_SIZE; index++) {
1334 64 : secured_message_context.export_master_secret[index] = (uint8_t)index;
1335 64 : target_buffer[index] = 0x00;
1336 : }
1337 :
1338 1 : secured_message_context.hash_size = LIBSPDM_MAX_HASH_SIZE;
1339 1 : export_master_secret_size = LIBSPDM_MAX_HASH_SIZE + 0x100;
1340 :
1341 1 : result = libspdm_secured_message_export_master_secret(&secured_message_context,
1342 : &target_buffer,
1343 : &export_master_secret_size);
1344 1 : assert_int_equal(result, true);
1345 :
1346 1 : libspdm_secured_message_clear_export_master_secret(&secured_message_context);
1347 :
1348 65 : for (int index = 0; index < LIBSPDM_MAX_HASH_SIZE; index++) {
1349 64 : assert_int_equal(target_buffer[index], index);
1350 64 : assert_int_equal(secured_message_context.export_master_secret[index], 0x00);
1351 : }
1352 1 : assert_int_equal(export_master_secret_size, LIBSPDM_MAX_HASH_SIZE);
1353 :
1354 : /* Get the entire EMS when the size of the target buffer is the same size as the EMS. */
1355 65 : for (int index = 0; index < LIBSPDM_MAX_HASH_SIZE; index++) {
1356 64 : secured_message_context.export_master_secret[index] = (uint8_t)index;
1357 64 : target_buffer[index] = 0x00;
1358 : }
1359 :
1360 1 : secured_message_context.hash_size = LIBSPDM_MAX_HASH_SIZE;
1361 1 : export_master_secret_size = LIBSPDM_MAX_HASH_SIZE;
1362 :
1363 1 : result = libspdm_secured_message_export_master_secret(&secured_message_context,
1364 : &target_buffer,
1365 : &export_master_secret_size);
1366 1 : assert_int_equal(result, true);
1367 :
1368 65 : for (int index = 0; index < LIBSPDM_MAX_HASH_SIZE; index++) {
1369 64 : assert_int_equal(target_buffer[index], index);
1370 : }
1371 1 : assert_int_equal(export_master_secret_size, LIBSPDM_MAX_HASH_SIZE);
1372 :
1373 : /* Get the truncated EMS when the size of the target buffer is less than the size of the EMS. */
1374 65 : for (int index = 0; index < LIBSPDM_MAX_HASH_SIZE; index++) {
1375 64 : secured_message_context.export_master_secret[index] = (uint8_t)index;
1376 64 : target_buffer[index] = 0x00;
1377 : }
1378 :
1379 1 : secured_message_context.hash_size = LIBSPDM_MAX_HASH_SIZE;
1380 1 : export_master_secret_size = LIBSPDM_MAX_HASH_SIZE - 4;
1381 :
1382 1 : result = libspdm_secured_message_export_master_secret(&secured_message_context,
1383 : &target_buffer,
1384 : &export_master_secret_size);
1385 1 : assert_int_equal(result, true);
1386 :
1387 65 : for (int index = 0; index < LIBSPDM_MAX_HASH_SIZE; index++) {
1388 64 : if (index < LIBSPDM_MAX_HASH_SIZE - 4) {
1389 60 : assert_int_equal(target_buffer[index], index);
1390 : } else {
1391 4 : assert_int_equal(target_buffer[index], 0x00);
1392 : }
1393 : }
1394 1 : assert_int_equal(export_master_secret_size, LIBSPDM_MAX_HASH_SIZE - 4);
1395 1 : }
1396 :
1397 1 : static void libspdm_test_check_context_case20(void **state)
1398 : {
1399 : void *context;
1400 : bool result;
1401 :
1402 1 : context = (void *)malloc (libspdm_get_context_size());
1403 :
1404 1 : libspdm_init_context (context);
1405 :
1406 1 : result = libspdm_check_context (context);
1407 1 : assert_int_equal(false, result);
1408 :
1409 1 : libspdm_register_transport_layer_func(context,
1410 : LIBSPDM_MAX_SPDM_MSG_SIZE,
1411 : LIBSPDM_TEST_TRANSPORT_HEADER_SIZE,
1412 : LIBSPDM_TEST_TRANSPORT_TAIL_SIZE,
1413 : libspdm_transport_test_encode_message,
1414 : libspdm_transport_test_decode_message);
1415 :
1416 1 : libspdm_register_device_buffer_func(context,
1417 : LIBSPDM_MAX_SENDER_RECEIVER_BUFFER_SIZE,
1418 : LIBSPDM_MAX_SENDER_RECEIVER_BUFFER_SIZE,
1419 : spdm_device_acquire_sender_buffer,
1420 : spdm_device_release_sender_buffer,
1421 : spdm_device_acquire_receiver_buffer,
1422 : spdm_device_release_receiver_buffer);
1423 :
1424 1 : result = libspdm_check_context (context);
1425 1 : assert_int_equal(true, result);
1426 :
1427 1 : libspdm_register_transport_layer_func(context,
1428 : SPDM_MIN_DATA_TRANSFER_SIZE_VERSION_12,
1429 : LIBSPDM_TEST_TRANSPORT_HEADER_SIZE,
1430 : LIBSPDM_TEST_TRANSPORT_TAIL_SIZE,
1431 : libspdm_transport_test_encode_message,
1432 : libspdm_transport_test_decode_message);
1433 :
1434 1 : result = libspdm_check_context (context);
1435 1 : assert_int_equal(false, result);
1436 1 : }
1437 :
1438 1 : static void libspdm_test_max_session_count_case21(void **state)
1439 : {
1440 : libspdm_context_t *spdm_context;
1441 : libspdm_data_parameter_t parameter;
1442 : size_t index;
1443 : size_t round;
1444 : uint16_t req_id;
1445 : uint16_t rsp_id;
1446 : uint32_t session_id;
1447 : void *session_info;
1448 : uint32_t dhe_session_count;
1449 : uint32_t psk_session_count;
1450 :
1451 7 : for (round = 0; round <= 5; round++) {
1452 : /* prepare parameter */
1453 6 : switch (round) {
1454 1 : case 0:
1455 1 : dhe_session_count = 1;
1456 1 : psk_session_count = 1;
1457 1 : break;
1458 1 : case 1:
1459 1 : dhe_session_count = LIBSPDM_MAX_SESSION_COUNT / 2;
1460 1 : psk_session_count = LIBSPDM_MAX_SESSION_COUNT - dhe_session_count;
1461 1 : break;
1462 1 : case 2:
1463 1 : dhe_session_count = 1;
1464 1 : psk_session_count = LIBSPDM_MAX_SESSION_COUNT - 1;
1465 1 : break;
1466 1 : case 3:
1467 1 : dhe_session_count = LIBSPDM_MAX_SESSION_COUNT - 1;
1468 1 : psk_session_count = 1;
1469 1 : break;
1470 1 : case 4:
1471 1 : dhe_session_count = 0;
1472 1 : psk_session_count = LIBSPDM_MAX_SESSION_COUNT;
1473 1 : break;
1474 1 : case 5:
1475 1 : dhe_session_count = LIBSPDM_MAX_SESSION_COUNT;
1476 1 : psk_session_count = 0;
1477 1 : break;
1478 0 : default:
1479 0 : dhe_session_count = 0;
1480 0 : psk_session_count = 0;
1481 0 : break;
1482 : }
1483 :
1484 : /* test */
1485 6 : spdm_context = (libspdm_context_t *)malloc(libspdm_get_context_size());
1486 6 : libspdm_init_context (spdm_context);
1487 6 : spdm_context->connection_info.capability.flags =
1488 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_ENCRYPT_CAP |
1489 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MAC_CAP;
1490 6 : spdm_context->local_context.capability.flags =
1491 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_ENCRYPT_CAP |
1492 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MAC_CAP;
1493 6 : spdm_context->connection_info.algorithm.base_hash_algo =
1494 : SPDM_ALGORITHMS_BASE_HASH_ALGO_TPM_ALG_SHA_256;
1495 6 : spdm_context->connection_info.algorithm.dhe_named_group =
1496 : SPDM_ALGORITHMS_DHE_NAMED_GROUP_SECP_256_R1;
1497 6 : spdm_context->connection_info.algorithm.aead_cipher_suite =
1498 : SPDM_ALGORITHMS_AEAD_CIPHER_SUITE_AES_256_GCM;
1499 6 : spdm_context->connection_info.algorithm.key_schedule =
1500 : SPDM_ALGORITHMS_KEY_SCHEDULE_SPDM;
1501 :
1502 6 : libspdm_zero_mem(¶meter, sizeof(parameter));
1503 6 : parameter.location = LIBSPDM_DATA_LOCATION_LOCAL;
1504 6 : if (dhe_session_count != 0) {
1505 5 : libspdm_set_data (spdm_context, LIBSPDM_DATA_MAX_DHE_SESSION_COUNT, ¶meter,
1506 : &dhe_session_count, sizeof(dhe_session_count));
1507 : }
1508 6 : if (psk_session_count != 0) {
1509 5 : libspdm_set_data (spdm_context, LIBSPDM_DATA_MAX_PSK_SESSION_COUNT, ¶meter,
1510 : &psk_session_count, sizeof(psk_session_count));
1511 : }
1512 :
1513 6 : if (dhe_session_count != 0) {
1514 16 : for (index = 0; index < dhe_session_count; index++)
1515 : {
1516 11 : req_id = libspdm_allocate_req_session_id (spdm_context, false);
1517 11 : assert_int_not_equal (req_id, INVALID_SESSION_ID & 0xFFFF);
1518 :
1519 11 : rsp_id = libspdm_allocate_rsp_session_id (spdm_context, false);
1520 11 : assert_int_not_equal (rsp_id, (INVALID_SESSION_ID & 0xFFFF0000) >> 16);
1521 :
1522 11 : session_id = libspdm_generate_session_id (req_id, rsp_id);
1523 11 : session_info = libspdm_assign_session_id (spdm_context, session_id,
1524 : SECURED_SPDM_VERSION_11 <<
1525 : SPDM_VERSION_NUMBER_SHIFT_BIT,
1526 : false);
1527 11 : assert_ptr_not_equal (session_info, NULL);
1528 : }
1529 5 : req_id = libspdm_allocate_req_session_id (spdm_context, false);
1530 5 : assert_int_equal (req_id, INVALID_SESSION_ID & 0xFFFF);
1531 :
1532 5 : rsp_id = libspdm_allocate_rsp_session_id (spdm_context, false);
1533 5 : assert_int_equal (rsp_id, (INVALID_SESSION_ID & 0xFFFF0000) >> 16);
1534 : }
1535 :
1536 6 : if (psk_session_count != 0) {
1537 16 : for (index = 0; index < psk_session_count; index++)
1538 : {
1539 11 : req_id = libspdm_allocate_req_session_id (spdm_context, true);
1540 11 : assert_int_not_equal (req_id, INVALID_SESSION_ID & 0xFFFF);
1541 :
1542 11 : rsp_id = libspdm_allocate_rsp_session_id (spdm_context, true);
1543 11 : assert_int_not_equal (rsp_id, (INVALID_SESSION_ID & 0xFFFF0000) >> 16);
1544 :
1545 11 : session_id = libspdm_generate_session_id (req_id, rsp_id);
1546 11 : session_info = libspdm_assign_session_id (spdm_context, session_id,
1547 : SECURED_SPDM_VERSION_11 <<
1548 : SPDM_VERSION_NUMBER_SHIFT_BIT,
1549 : true);
1550 11 : assert_ptr_not_equal (session_info, NULL);
1551 : }
1552 5 : req_id = libspdm_allocate_req_session_id (spdm_context, true);
1553 5 : assert_int_equal (req_id, INVALID_SESSION_ID & 0xFFFF);
1554 :
1555 5 : rsp_id = libspdm_allocate_rsp_session_id (spdm_context, true);
1556 5 : assert_int_equal (rsp_id, (INVALID_SESSION_ID & 0xFFFF0000) >> 16);
1557 : }
1558 :
1559 6 : free(spdm_context);
1560 : }
1561 1 : }
1562 :
1563 : #pragma pack(1)
1564 :
1565 : typedef struct {
1566 : spdm_general_opaque_data_table_header_t opaque_header;
1567 : spdm_svh_iana_cbor_header_t cbor_header;
1568 : uint8_t cbor_vendor_id[10];
1569 : uint16_t cbor_opaque_len;
1570 : uint8_t cbor_opaque[10];
1571 : /* uint8_t cbor_align[]; */
1572 : spdm_svh_vesa_header_t vesa_header;
1573 : uint16_t vesa_opaque_len;
1574 : uint8_t vesa_opaque[9];
1575 : uint8_t vesa_align[3];
1576 : spdm_svh_jedec_header_t jedec_header;
1577 : uint16_t jedec_opaque_len;
1578 : uint8_t jedec_opaque[8];
1579 : uint8_t jedec_align[2];
1580 : spdm_svh_cxl_header_t cxl_header;
1581 : uint16_t cxl_opaque_len;
1582 : uint8_t cxl_opaque[7];
1583 : uint8_t cxl_align[3];
1584 : spdm_svh_mipi_header_t mipi_header;
1585 : uint16_t mipi_opaque_len;
1586 : uint8_t mipi_opaque[6];
1587 : /* uint8_t mipi_align[0]; */
1588 : spdm_svh_hdbaset_header_t hdbaset_header;
1589 : uint16_t hdbaset_opaque_len;
1590 : uint8_t hdbaset_opaque[5];
1591 : uint8_t hdbaset_align[3];
1592 : spdm_svh_iana_header_t iana_header;
1593 : uint16_t iana_opaque_len;
1594 : uint8_t iana_opaque[4];
1595 : /* uint8_t iana_align[0]; */
1596 : spdm_svh_pcisig_header_t pcisig_header;
1597 : uint16_t pcisig_opaque_len;
1598 : uint8_t pcisig_opaque[3];
1599 : uint8_t pcisig_align[3];
1600 : spdm_svh_usb_header_t usb_header;
1601 : uint16_t usb_opaque_len;
1602 : uint8_t usb_opaque[2];
1603 : /* uint8_t usb_align[0]; */
1604 : spdm_svh_tcg_header_t tcg_header;
1605 : uint16_t tcg_opaque_len;
1606 : uint8_t tcg_opaque[1];
1607 : uint8_t tcg_align[1];
1608 : spdm_svh_dmtf_dsp_header_t dmtf_dsp_header;
1609 : uint16_t dmtf_dsp_opaque_len;
1610 : uint8_t dmtf_dsp_opaque[11];
1611 : uint8_t dmtf_dsp_align[3];
1612 : spdm_svh_dmtf_header_t dmtf_sm_ver_sel_header;
1613 : uint16_t dmtf_sm_ver_sel_opaque_len;
1614 : secured_message_opaque_element_version_selection_t dmtf_sm_ver_sel_opaque;
1615 : /* uint8_t dmtf_sm_ver_sel_align[0]; */
1616 : spdm_svh_dmtf_header_t dmtf_sm_sup_ver_header;
1617 : uint16_t dmtf_sm_sup_ver_opaque_len;
1618 : secured_message_opaque_element_supported_version_t dmtf_sm_sup_ver_opaque;
1619 : spdm_version_number_t dmtf_sm_sup_ver_versions_list[3];
1620 : uint8_t dmtf_sm_sup_ver_align[3];
1621 : } test_spdm12_opaque_data_table_t;
1622 :
1623 : #pragma pack()
1624 :
1625 1 : static void libspdm_test_process_opaque_data_case22(void **state)
1626 : {
1627 : libspdm_return_t status;
1628 : libspdm_test_context_t *spdm_test_context;
1629 : libspdm_context_t *spdm_context;
1630 : const void *get_element_ptr;
1631 : size_t get_element_len;
1632 : size_t opaque_data_size;
1633 : uint8_t *opaque_data_ptr;
1634 : test_spdm12_opaque_data_table_t opaque_data;
1635 :
1636 1 : spdm_test_context = *state;
1637 1 : spdm_context = spdm_test_context->spdm_context;
1638 1 : spdm_test_context->case_id = 0x16;
1639 :
1640 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 <<
1641 : SPDM_VERSION_NUMBER_SHIFT_BIT;
1642 :
1643 1 : spdm_context->local_context.secured_message_version.secured_message_version_count = 1;
1644 :
1645 1 : libspdm_set_mem ((uint8_t *)&opaque_data, sizeof(opaque_data), 0xFF);
1646 1 : opaque_data.opaque_header.total_elements = SPDM_REGISTRY_ID_MAX + 2;
1647 1 : opaque_data.cbor_header.header.id = SPDM_REGISTRY_ID_IANA_CBOR;
1648 1 : opaque_data.cbor_header.header.vendor_id_len = sizeof(opaque_data.cbor_vendor_id);
1649 1 : opaque_data.cbor_opaque_len = sizeof(opaque_data.cbor_opaque);
1650 1 : opaque_data.vesa_header.header.id = SPDM_REGISTRY_ID_VESA;
1651 1 : opaque_data.vesa_header.header.vendor_id_len = 0;
1652 1 : opaque_data.vesa_opaque_len = sizeof(opaque_data.vesa_opaque);
1653 1 : opaque_data.jedec_header.header.id = SPDM_REGISTRY_ID_JEDEC;
1654 1 : opaque_data.jedec_header.header.vendor_id_len = sizeof(opaque_data.jedec_header.vendor_id);
1655 1 : opaque_data.jedec_opaque_len = sizeof(opaque_data.jedec_opaque);
1656 1 : opaque_data.cxl_header.header.id = SPDM_REGISTRY_ID_CXL;
1657 1 : opaque_data.cxl_header.header.vendor_id_len = sizeof(opaque_data.cxl_header.vendor_id);
1658 1 : opaque_data.cxl_opaque_len = sizeof(opaque_data.cxl_opaque);
1659 1 : opaque_data.mipi_header.header.id = SPDM_REGISTRY_ID_MIPI;
1660 1 : opaque_data.mipi_header.header.vendor_id_len = sizeof(opaque_data.mipi_header.vendor_id);
1661 1 : opaque_data.mipi_opaque_len = sizeof(opaque_data.mipi_opaque);
1662 1 : opaque_data.hdbaset_header.header.id = SPDM_REGISTRY_ID_HDBASET;
1663 1 : opaque_data.hdbaset_header.header.vendor_id_len = sizeof(opaque_data.hdbaset_header.vendor_id);
1664 1 : opaque_data.hdbaset_opaque_len = sizeof(opaque_data.hdbaset_opaque);
1665 1 : opaque_data.iana_header.header.id = SPDM_REGISTRY_ID_IANA;
1666 1 : opaque_data.iana_header.header.vendor_id_len = sizeof(opaque_data.iana_header.vendor_id);
1667 1 : opaque_data.iana_opaque_len = sizeof(opaque_data.iana_opaque);
1668 1 : opaque_data.pcisig_header.header.id = SPDM_REGISTRY_ID_PCISIG;
1669 1 : opaque_data.pcisig_header.header.vendor_id_len = sizeof(opaque_data.pcisig_header.vendor_id);
1670 1 : opaque_data.pcisig_opaque_len = sizeof(opaque_data.pcisig_opaque);
1671 1 : opaque_data.usb_header.header.id = SPDM_REGISTRY_ID_USB;
1672 1 : opaque_data.usb_header.header.vendor_id_len = sizeof(opaque_data.usb_header.vendor_id);
1673 1 : opaque_data.usb_opaque_len = sizeof(opaque_data.usb_opaque);
1674 1 : opaque_data.tcg_header.header.id = SPDM_REGISTRY_ID_TCG;
1675 1 : opaque_data.tcg_header.header.vendor_id_len = sizeof(opaque_data.tcg_header.vendor_id);
1676 1 : opaque_data.tcg_opaque_len = sizeof(opaque_data.tcg_opaque);
1677 1 : opaque_data.dmtf_dsp_header.header.id = SPDM_REGISTRY_ID_DMTF_DSP;
1678 1 : opaque_data.dmtf_dsp_header.header.vendor_id_len = sizeof(opaque_data.dmtf_dsp_header.vendor_id);
1679 1 : opaque_data.dmtf_dsp_opaque_len = sizeof(opaque_data.dmtf_dsp_opaque);
1680 1 : opaque_data.dmtf_sm_ver_sel_header.header.id = SPDM_REGISTRY_ID_DMTF;
1681 1 : opaque_data.dmtf_sm_ver_sel_header.header.vendor_id_len = 0;
1682 1 : opaque_data.dmtf_sm_ver_sel_opaque_len = sizeof(opaque_data.dmtf_sm_ver_sel_opaque);
1683 1 : opaque_data.dmtf_sm_ver_sel_opaque.sm_data_version =
1684 : SECURED_MESSAGE_OPAQUE_ELEMENT_SMDATA_DATA_VERSION;
1685 1 : opaque_data.dmtf_sm_ver_sel_opaque.sm_data_id =
1686 : SECURED_MESSAGE_OPAQUE_ELEMENT_SMDATA_ID_VERSION_SELECTION;
1687 1 : opaque_data.dmtf_sm_ver_sel_opaque.selected_version = SECURED_SPDM_VERSION_12 << 8;
1688 1 : opaque_data.dmtf_sm_sup_ver_header.header.id = SPDM_REGISTRY_ID_DMTF;
1689 1 : opaque_data.dmtf_sm_sup_ver_header.header.vendor_id_len = 0;
1690 1 : opaque_data.dmtf_sm_sup_ver_opaque_len = sizeof(opaque_data.dmtf_sm_sup_ver_opaque) +
1691 : sizeof(opaque_data.dmtf_sm_sup_ver_versions_list);
1692 1 : opaque_data.dmtf_sm_sup_ver_opaque.sm_data_version =
1693 : SECURED_MESSAGE_OPAQUE_ELEMENT_SMDATA_DATA_VERSION;
1694 1 : opaque_data.dmtf_sm_sup_ver_opaque.sm_data_id =
1695 : SECURED_MESSAGE_OPAQUE_ELEMENT_SMDATA_ID_SUPPORTED_VERSION;
1696 1 : opaque_data.dmtf_sm_sup_ver_opaque.version_count =
1697 : LIBSPDM_ARRAY_SIZE(opaque_data.dmtf_sm_sup_ver_versions_list);
1698 1 : opaque_data.dmtf_sm_sup_ver_versions_list[0] = SECURED_SPDM_VERSION_10 << 8;
1699 1 : opaque_data.dmtf_sm_sup_ver_versions_list[1] = SECURED_SPDM_VERSION_11 << 8;
1700 1 : opaque_data.dmtf_sm_sup_ver_versions_list[2] = SECURED_SPDM_VERSION_12 << 8;
1701 :
1702 1 : opaque_data_ptr = (uint8_t *)&opaque_data;
1703 1 : opaque_data_size = sizeof(opaque_data);
1704 1 : status = libspdm_get_sm_data_element_from_opaque_data(spdm_context,
1705 : opaque_data_size, opaque_data_ptr,
1706 : SECURED_MESSAGE_OPAQUE_ELEMENT_SMDATA_ID_VERSION_SELECTION,
1707 : &get_element_ptr, &get_element_len
1708 : );
1709 1 : assert_int_equal (status, true);
1710 1 : status = libspdm_get_sm_data_element_from_opaque_data(spdm_context,
1711 : opaque_data_size, opaque_data_ptr,
1712 : SECURED_MESSAGE_OPAQUE_ELEMENT_SMDATA_ID_SUPPORTED_VERSION,
1713 : &get_element_ptr, &get_element_len
1714 : );
1715 1 : assert_int_equal (status, true);
1716 1 : }
1717 :
1718 : #if !(LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT)
1719 : /**
1720 : * Test 23: libspdm_reset_context releases the peer leaf certificate public key.
1721 : * Expected Behavior: after a parsed leaf public key is stored for a slot,
1722 : * reset_context frees it and clears the slot, so it is not orphaned when the
1723 : * connection is re-established (reset_context runs on every GET_VERSION).
1724 : **/
1725 1 : static void libspdm_test_reset_context_leaf_key_case23(void **state)
1726 : {
1727 : libspdm_test_context_t *spdm_test_context;
1728 : libspdm_context_t *spdm_context;
1729 : void *data;
1730 : size_t data_size;
1731 : void *hash;
1732 : size_t hash_size;
1733 : bool result;
1734 :
1735 1 : spdm_test_context = *state;
1736 1 : spdm_context = spdm_test_context->spdm_context;
1737 1 : spdm_test_context->case_id = 0x17;
1738 :
1739 1 : spdm_context->local_context.is_requester = true;
1740 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
1741 1 : spdm_context->connection_info.algorithm.base_asym_algo = m_libspdm_use_asym_algo;
1742 :
1743 1 : if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
1744 : m_libspdm_use_asym_algo, &data,
1745 : &data_size, &hash, &hash_size)) {
1746 0 : assert(false);
1747 : }
1748 :
1749 1 : result = libspdm_get_leaf_cert_public_key_from_cert_chain(
1750 : m_libspdm_use_hash_algo, m_libspdm_use_asym_algo, data, data_size,
1751 : &spdm_context->connection_info.peer_used_cert_chain[0].leaf_cert_public_key);
1752 1 : assert_true(result);
1753 1 : assert_non_null(spdm_context->connection_info.peer_used_cert_chain[0].leaf_cert_public_key);
1754 :
1755 1 : libspdm_reset_context(spdm_context);
1756 :
1757 1 : assert_null(spdm_context->connection_info.peer_used_cert_chain[0].leaf_cert_public_key);
1758 :
1759 1 : free(data);
1760 1 : }
1761 : #endif /* !(LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT) */
1762 :
1763 : /* DSP0277 1.3 AEAD limit: build the supported-version opaque data then append AEADlimitOE, and
1764 : * verify the round-trip parse recovers the advertised exponent. */
1765 1 : static void libspdm_test_aead_limit_build_parse_case24(void **state)
1766 : {
1767 : libspdm_return_t status;
1768 : libspdm_test_context_t *spdm_test_context;
1769 : libspdm_context_t *spdm_context;
1770 : size_t opaque_data_size;
1771 : size_t element_size;
1772 : uint8_t *opaque_data_ptr;
1773 : uint8_t aead_limit_exponent;
1774 :
1775 1 : spdm_test_context = *state;
1776 1 : spdm_context = spdm_test_context->spdm_context;
1777 1 : spdm_test_context->case_id = 0x18;
1778 :
1779 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 <<
1780 : SPDM_VERSION_NUMBER_SHIFT_BIT;
1781 :
1782 : /* Local secured message version list includes 1.3, so AEADlimitOE is emitted. */
1783 1 : spdm_context->local_context.secured_message_version.secured_message_version_count = 4;
1784 1 : spdm_context->local_context.secured_message_version.secured_message_version[0] =
1785 : SECURED_SPDM_VERSION_10 << SPDM_VERSION_NUMBER_SHIFT_BIT;
1786 1 : spdm_context->local_context.secured_message_version.secured_message_version[1] =
1787 : SECURED_SPDM_VERSION_11 << SPDM_VERSION_NUMBER_SHIFT_BIT;
1788 1 : spdm_context->local_context.secured_message_version.secured_message_version[2] =
1789 : SECURED_SPDM_VERSION_12 << SPDM_VERSION_NUMBER_SHIFT_BIT;
1790 1 : spdm_context->local_context.secured_message_version.secured_message_version[3] =
1791 : SECURED_SPDM_VERSION_13 << SPDM_VERSION_NUMBER_SHIFT_BIT;
1792 :
1793 : /* Advertise a non-default exponent by setting the single-source-of-truth cap to 2^32 - 1, which
1794 : * the builder encodes as exponent 32. The cap is the maximum allowed sequence number =
1795 : * AeadLimit - 1 = 2^exponent - 1. */
1796 1 : spdm_context->max_spdm_session_sequence_number = (((uint64_t)1 << 32) - 1);
1797 :
1798 1 : element_size = libspdm_get_opaque_data_aead_limit_element_size(
1799 : spdm_context, SECURED_SPDM_VERSION_13 << SPDM_VERSION_NUMBER_SHIFT_BIT);
1800 1 : assert_int_not_equal(element_size, 0);
1801 :
1802 : /* The element size is 0 for a sub-1.3 version. */
1803 1 : assert_int_equal(libspdm_get_opaque_data_aead_limit_element_size(
1804 : spdm_context, SECURED_SPDM_VERSION_12 << SPDM_VERSION_NUMBER_SHIFT_BIT),
1805 : 0);
1806 :
1807 1 : opaque_data_size = libspdm_get_opaque_data_supported_version_data_size(spdm_context);
1808 1 : opaque_data_ptr = malloc(opaque_data_size + element_size);
1809 1 : assert_ptr_not_equal(opaque_data_ptr, NULL);
1810 :
1811 1 : libspdm_build_opaque_data_supported_version_data(spdm_context, &opaque_data_size,
1812 : opaque_data_ptr);
1813 : /* opaque_data_size now becomes the total buffer capacity for the append. */
1814 1 : opaque_data_size += element_size;
1815 1 : libspdm_build_opaque_data_aead_limit_element(
1816 : spdm_context, SECURED_SPDM_VERSION_13 << SPDM_VERSION_NUMBER_SHIFT_BIT,
1817 : &opaque_data_size, opaque_data_ptr);
1818 :
1819 1 : aead_limit_exponent = 0;
1820 1 : status = libspdm_process_opaque_data_aead_limit(
1821 : spdm_context, SECURED_SPDM_VERSION_13 << SPDM_VERSION_NUMBER_SHIFT_BIT,
1822 : opaque_data_size, opaque_data_ptr, &aead_limit_exponent);
1823 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
1824 1 : assert_int_equal(aead_limit_exponent, 32);
1825 :
1826 1 : free(opaque_data_ptr);
1827 1 : }
1828 :
1829 : /* DSP0277 1.3 AEAD limit: an exponent > 64 must be rejected, and an absent element must default to
1830 : * 64. */
1831 1 : static void libspdm_test_aead_limit_invalid_and_default_case25(void **state)
1832 : {
1833 : libspdm_return_t status;
1834 : libspdm_test_context_t *spdm_test_context;
1835 : libspdm_context_t *spdm_context;
1836 : size_t opaque_data_size;
1837 : size_t element_size;
1838 : uint8_t *opaque_data_ptr;
1839 : uint8_t aead_limit_exponent;
1840 : secured_message_opaque_element_aead_limit_t *aead_element;
1841 :
1842 1 : spdm_test_context = *state;
1843 1 : spdm_context = spdm_test_context->spdm_context;
1844 1 : spdm_test_context->case_id = 0x19;
1845 :
1846 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 <<
1847 : SPDM_VERSION_NUMBER_SHIFT_BIT;
1848 :
1849 1 : spdm_context->local_context.secured_message_version.secured_message_version_count = 4;
1850 1 : spdm_context->local_context.secured_message_version.secured_message_version[0] =
1851 : SECURED_SPDM_VERSION_10 << SPDM_VERSION_NUMBER_SHIFT_BIT;
1852 1 : spdm_context->local_context.secured_message_version.secured_message_version[1] =
1853 : SECURED_SPDM_VERSION_11 << SPDM_VERSION_NUMBER_SHIFT_BIT;
1854 1 : spdm_context->local_context.secured_message_version.secured_message_version[2] =
1855 : SECURED_SPDM_VERSION_12 << SPDM_VERSION_NUMBER_SHIFT_BIT;
1856 1 : spdm_context->local_context.secured_message_version.secured_message_version[3] =
1857 : SECURED_SPDM_VERSION_13 << SPDM_VERSION_NUMBER_SHIFT_BIT;
1858 : /* Default cap (all-ones) encodes the default exponent of 64. */
1859 1 : spdm_context->max_spdm_session_sequence_number = LIBSPDM_MAX_SPDM_SESSION_SEQUENCE_NUMBER;
1860 :
1861 1 : element_size = libspdm_get_opaque_data_aead_limit_element_size(
1862 : spdm_context, SECURED_SPDM_VERSION_13 << SPDM_VERSION_NUMBER_SHIFT_BIT);
1863 1 : assert_int_not_equal(element_size, 0);
1864 :
1865 : /* Build a valid blob with the AEADlimitOE present. */
1866 1 : opaque_data_size = libspdm_get_opaque_data_supported_version_data_size(spdm_context);
1867 1 : opaque_data_ptr = malloc(opaque_data_size + element_size);
1868 1 : assert_ptr_not_equal(opaque_data_ptr, NULL);
1869 :
1870 1 : libspdm_build_opaque_data_supported_version_data(spdm_context, &opaque_data_size,
1871 : opaque_data_ptr);
1872 : /* opaque_data_size now becomes the total buffer capacity for the append. */
1873 1 : opaque_data_size += element_size;
1874 1 : libspdm_build_opaque_data_aead_limit_element(
1875 : spdm_context, SECURED_SPDM_VERSION_13 << SPDM_VERSION_NUMBER_SHIFT_BIT,
1876 : &opaque_data_size, opaque_data_ptr);
1877 :
1878 : /* Corrupt the exponent so it exceeds the max (64). The AEADlimitOE element follows the
1879 : * element table header which is the last element in the blob. */
1880 1 : aead_element = (secured_message_opaque_element_aead_limit_t *)
1881 1 : (opaque_data_ptr + opaque_data_size -
1882 : sizeof(secured_message_opaque_element_aead_limit_t));
1883 : /* Account for the padding bytes (element_size rounds up to a multiple of 4). */
1884 1 : aead_element = (secured_message_opaque_element_aead_limit_t *)
1885 1 : ((uint8_t *)aead_element -
1886 : (element_size - (sizeof(secured_message_opaque_element_table_header_t) +
1887 : sizeof(secured_message_opaque_element_aead_limit_t))));
1888 1 : assert_int_equal(aead_element->sm_data_id,
1889 : SECURED_MESSAGE_OPAQUE_ELEMENT_SMDATA_ID_AEAD_LIMIT);
1890 1 : aead_element->aead_limit_exponent = SECURED_MESSAGE_AEAD_LIMIT_EXPONENT_MAX + 1;
1891 :
1892 1 : status = libspdm_process_opaque_data_aead_limit(
1893 : spdm_context, SECURED_SPDM_VERSION_13 << SPDM_VERSION_NUMBER_SHIFT_BIT,
1894 : opaque_data_size, opaque_data_ptr, &aead_limit_exponent);
1895 1 : assert_int_equal(status, LIBSPDM_STATUS_INVALID_MSG_FIELD);
1896 :
1897 1 : free(opaque_data_ptr);
1898 :
1899 : /* A blob without the AEADlimitOE element must default the exponent to 64. */
1900 1 : opaque_data_size = libspdm_get_opaque_data_supported_version_data_size(spdm_context);
1901 1 : opaque_data_ptr = malloc(opaque_data_size);
1902 1 : assert_ptr_not_equal(opaque_data_ptr, NULL);
1903 :
1904 1 : libspdm_build_opaque_data_supported_version_data(spdm_context, &opaque_data_size,
1905 : opaque_data_ptr);
1906 :
1907 1 : aead_limit_exponent = 0;
1908 1 : status = libspdm_process_opaque_data_aead_limit(
1909 : spdm_context, SECURED_SPDM_VERSION_13 << SPDM_VERSION_NUMBER_SHIFT_BIT,
1910 : opaque_data_size, opaque_data_ptr, &aead_limit_exponent);
1911 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
1912 1 : assert_int_equal(aead_limit_exponent, SECURED_MESSAGE_AEAD_LIMIT_EXPONENT_DEFAULT);
1913 :
1914 1 : free(opaque_data_ptr);
1915 1 : }
1916 :
1917 : /* DSP0277 1.3 AEAD limit: applying the limit to a session sets the session's max sequence number to
1918 : * min(local cap, peer AEAD limit), and the integrator's smaller pre-set cap is never raised. The
1919 : * local limit's single source of truth is max_spdm_session_sequence_number. */
1920 1 : static void libspdm_test_aead_limit_apply_to_session_case26(void **state)
1921 : {
1922 : libspdm_test_context_t *spdm_test_context;
1923 : libspdm_context_t *spdm_context;
1924 : libspdm_data_parameter_t parameter;
1925 : uint16_t req_id;
1926 : uint16_t rsp_id;
1927 : uint32_t session_id;
1928 : void *session_info;
1929 : uint64_t max_seq;
1930 : size_t data_size;
1931 :
1932 1 : spdm_test_context = *state;
1933 1 : spdm_context = spdm_test_context->spdm_context;
1934 1 : spdm_test_context->case_id = 0x1A;
1935 :
1936 1 : spdm_context->connection_info.capability.flags =
1937 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_ENCRYPT_CAP |
1938 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MAC_CAP;
1939 1 : spdm_context->local_context.capability.flags =
1940 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_ENCRYPT_CAP |
1941 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MAC_CAP;
1942 :
1943 : /* Local cap = 2^40 - 1 (encodes local exponent 40), peer exponent 30. The peer's maximum allowed
1944 : * sequence number is 2^30 - 1, so the effective session cap is min(2^40 - 1, 2^30 - 1) =
1945 : * 2^30 - 1. The cap is the maximum allowed sequence number = AeadLimit - 1 = 2^exponent - 1. */
1946 1 : spdm_context->max_spdm_session_sequence_number = (((uint64_t)1 << 40) - 1);
1947 :
1948 1 : req_id = libspdm_allocate_req_session_id(spdm_context, false);
1949 1 : rsp_id = libspdm_allocate_rsp_session_id(spdm_context, false);
1950 1 : session_id = libspdm_generate_session_id(req_id, rsp_id);
1951 1 : session_info = libspdm_assign_session_id(spdm_context, session_id,
1952 : SECURED_SPDM_VERSION_13 <<
1953 : SPDM_VERSION_NUMBER_SHIFT_BIT, false);
1954 1 : assert_ptr_not_equal(session_info, NULL);
1955 :
1956 1 : libspdm_zero_mem(¶meter, sizeof(parameter));
1957 1 : parameter.location = LIBSPDM_DATA_LOCATION_SESSION;
1958 1 : libspdm_copy_mem(parameter.additional_data, sizeof(parameter.additional_data),
1959 : &session_id, sizeof(session_id));
1960 :
1961 1 : libspdm_apply_aead_limit_to_session(spdm_context, session_info, 30);
1962 :
1963 : /* Read back the negotiated effective max sequence number per session via get_data. */
1964 1 : max_seq = 0;
1965 1 : data_size = sizeof(max_seq);
1966 1 : assert_int_equal(libspdm_get_data(spdm_context,
1967 : LIBSPDM_DATA_MAX_SPDM_SESSION_SEQUENCE_NUMBER,
1968 : ¶meter, &max_seq, &data_size),
1969 : LIBSPDM_STATUS_SUCCESS);
1970 1 : assert_int_equal(max_seq, (((uint64_t)1 << 30) - 1));
1971 :
1972 : /* A smaller local cap must never be raised by the peer's AEAD limit. With local cap 0xFFFF and
1973 : * peer exponent 30 (2^30), the effective cap stays 0xFFFF. */
1974 1 : spdm_context->max_spdm_session_sequence_number = 0xFFFF;
1975 1 : libspdm_apply_aead_limit_to_session(spdm_context, session_info, 30);
1976 1 : max_seq = 0;
1977 1 : data_size = sizeof(max_seq);
1978 1 : assert_int_equal(libspdm_get_data(spdm_context,
1979 : LIBSPDM_DATA_MAX_SPDM_SESSION_SEQUENCE_NUMBER,
1980 : ¶meter, &max_seq, &data_size),
1981 : LIBSPDM_STATUS_SUCCESS);
1982 1 : assert_int_equal(max_seq, 0xFFFF);
1983 :
1984 : /* A per-session set of the max sequence number is not allowed: the session cap is owned by the
1985 : * negotiated AEAD limit and must not be overridden. */
1986 1 : max_seq = 0x1000;
1987 1 : assert_int_not_equal(libspdm_set_data(spdm_context,
1988 : LIBSPDM_DATA_MAX_SPDM_SESSION_SEQUENCE_NUMBER,
1989 : ¶meter, &max_seq, sizeof(max_seq)),
1990 : LIBSPDM_STATUS_SUCCESS);
1991 :
1992 1 : libspdm_free_session_id(spdm_context, session_id);
1993 1 : }
1994 :
1995 : /* DSP0277 1.3 AEAD limit: the advertised AeadLimitExponent is derived from the single source of
1996 : * truth, max_spdm_session_sequence_number (= floor(log2(max + 1)), with the all-ones cap mapping
1997 : * to the default exponent 64 since max + 1 = 2^64 is not representable). */
1998 1 : static void libspdm_test_aead_limit_set_data_case27(void **state)
1999 : {
2000 : libspdm_return_t status;
2001 : libspdm_test_context_t *spdm_test_context;
2002 : libspdm_context_t *spdm_context;
2003 : size_t opaque_data_size;
2004 : size_t element_size;
2005 : uint8_t *opaque_data_ptr;
2006 : uint8_t aead_limit_exponent;
2007 :
2008 1 : spdm_test_context = *state;
2009 1 : spdm_context = spdm_test_context->spdm_context;
2010 1 : spdm_test_context->case_id = 0x1B;
2011 :
2012 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 <<
2013 : SPDM_VERSION_NUMBER_SHIFT_BIT;
2014 1 : spdm_context->local_context.secured_message_version.secured_message_version_count = 4;
2015 1 : spdm_context->local_context.secured_message_version.secured_message_version[0] =
2016 : SECURED_SPDM_VERSION_10 << SPDM_VERSION_NUMBER_SHIFT_BIT;
2017 1 : spdm_context->local_context.secured_message_version.secured_message_version[1] =
2018 : SECURED_SPDM_VERSION_11 << SPDM_VERSION_NUMBER_SHIFT_BIT;
2019 1 : spdm_context->local_context.secured_message_version.secured_message_version[2] =
2020 : SECURED_SPDM_VERSION_12 << SPDM_VERSION_NUMBER_SHIFT_BIT;
2021 1 : spdm_context->local_context.secured_message_version.secured_message_version[3] =
2022 : SECURED_SPDM_VERSION_13 << SPDM_VERSION_NUMBER_SHIFT_BIT;
2023 :
2024 1 : element_size = libspdm_get_opaque_data_aead_limit_element_size(
2025 : spdm_context, SECURED_SPDM_VERSION_13 << SPDM_VERSION_NUMBER_SHIFT_BIT);
2026 1 : assert_int_not_equal(element_size, 0);
2027 :
2028 : /* A cap that is not of the form 2^e - 1 (here 0xFFFFFE, i.e. 2^24 - 2) rounds down to the nearest
2029 : * representable AEAD limit 2^23, advertising exponent 23 (<= the configured cap, the safe
2030 : * direction). floor(log2(0xFFFFFE + 1)) = floor(log2(0xFFFFFF)) = 23. */
2031 1 : spdm_context->max_spdm_session_sequence_number = 0xFFFFFE;
2032 1 : opaque_data_size = libspdm_get_opaque_data_supported_version_data_size(spdm_context);
2033 1 : opaque_data_ptr = malloc(opaque_data_size + element_size);
2034 1 : assert_ptr_not_equal(opaque_data_ptr, NULL);
2035 1 : libspdm_build_opaque_data_supported_version_data(spdm_context, &opaque_data_size,
2036 : opaque_data_ptr);
2037 : /* opaque_data_size now becomes the total buffer capacity for the append. */
2038 1 : opaque_data_size += element_size;
2039 1 : libspdm_build_opaque_data_aead_limit_element(
2040 : spdm_context, SECURED_SPDM_VERSION_13 << SPDM_VERSION_NUMBER_SHIFT_BIT,
2041 : &opaque_data_size, opaque_data_ptr);
2042 1 : aead_limit_exponent = 0;
2043 1 : status = libspdm_process_opaque_data_aead_limit(
2044 : spdm_context, SECURED_SPDM_VERSION_13 << SPDM_VERSION_NUMBER_SHIFT_BIT,
2045 : opaque_data_size, opaque_data_ptr, &aead_limit_exponent);
2046 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
2047 1 : assert_int_equal(aead_limit_exponent, 23);
2048 1 : free(opaque_data_ptr);
2049 :
2050 : /* The all-ones default cap advertises the default exponent of 64. */
2051 1 : spdm_context->max_spdm_session_sequence_number = LIBSPDM_MAX_SPDM_SESSION_SEQUENCE_NUMBER;
2052 1 : opaque_data_size = libspdm_get_opaque_data_supported_version_data_size(spdm_context);
2053 1 : opaque_data_ptr = malloc(opaque_data_size + element_size);
2054 1 : assert_ptr_not_equal(opaque_data_ptr, NULL);
2055 1 : libspdm_build_opaque_data_supported_version_data(spdm_context, &opaque_data_size,
2056 : opaque_data_ptr);
2057 : /* opaque_data_size now becomes the total buffer capacity for the append. */
2058 1 : opaque_data_size += element_size;
2059 1 : libspdm_build_opaque_data_aead_limit_element(
2060 : spdm_context, SECURED_SPDM_VERSION_13 << SPDM_VERSION_NUMBER_SHIFT_BIT,
2061 : &opaque_data_size, opaque_data_ptr);
2062 1 : aead_limit_exponent = 0;
2063 1 : status = libspdm_process_opaque_data_aead_limit(
2064 : spdm_context, SECURED_SPDM_VERSION_13 << SPDM_VERSION_NUMBER_SHIFT_BIT,
2065 : opaque_data_size, opaque_data_ptr, &aead_limit_exponent);
2066 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
2067 1 : assert_int_equal(aead_limit_exponent, SECURED_MESSAGE_AEAD_LIMIT_EXPONENT_DEFAULT);
2068 1 : free(opaque_data_ptr);
2069 1 : }
2070 :
2071 : #pragma pack(1)
2072 : /* A general opaque data table (SPDM 1.2 format) with the AEADlimitOE element placed BEFORE the
2073 : * version-selection element, to exercise order-independent parsing. */
2074 : typedef struct {
2075 : spdm_general_opaque_data_table_header_t opaque_header;
2076 : secured_message_opaque_element_table_header_t aead_limit_header;
2077 : secured_message_opaque_element_aead_limit_t aead_limit_opaque;
2078 : uint8_t aead_limit_align[1];
2079 : secured_message_opaque_element_table_header_t ver_sel_header;
2080 : secured_message_opaque_element_version_selection_t ver_sel_opaque;
2081 : } test_aead_first_opaque_data_table_t;
2082 : #pragma pack()
2083 :
2084 : /* DSP0277 1.3 AEAD limit: opaque data elements may appear in any order. Verify that AEADlimitOE is
2085 : * still parsed correctly when it precedes the version-selection element, and that version-selection
2086 : * parsing is likewise unaffected by the ordering. */
2087 1 : static void libspdm_test_aead_limit_element_order_case28(void **state)
2088 : {
2089 : libspdm_return_t status;
2090 : libspdm_test_context_t *spdm_test_context;
2091 : libspdm_context_t *spdm_context;
2092 : test_aead_first_opaque_data_table_t opaque_data;
2093 : spdm_version_number_t secured_message_version;
2094 : uint8_t aead_limit_exponent;
2095 :
2096 1 : spdm_test_context = *state;
2097 1 : spdm_context = spdm_test_context->spdm_context;
2098 1 : spdm_test_context->case_id = 0x1C;
2099 :
2100 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 <<
2101 : SPDM_VERSION_NUMBER_SHIFT_BIT;
2102 1 : spdm_context->local_context.secured_message_version.secured_message_version_count = 4;
2103 1 : spdm_context->local_context.secured_message_version.secured_message_version[0] =
2104 : SECURED_SPDM_VERSION_10 << SPDM_VERSION_NUMBER_SHIFT_BIT;
2105 1 : spdm_context->local_context.secured_message_version.secured_message_version[1] =
2106 : SECURED_SPDM_VERSION_11 << SPDM_VERSION_NUMBER_SHIFT_BIT;
2107 1 : spdm_context->local_context.secured_message_version.secured_message_version[2] =
2108 : SECURED_SPDM_VERSION_12 << SPDM_VERSION_NUMBER_SHIFT_BIT;
2109 1 : spdm_context->local_context.secured_message_version.secured_message_version[3] =
2110 : SECURED_SPDM_VERSION_13 << SPDM_VERSION_NUMBER_SHIFT_BIT;
2111 :
2112 1 : libspdm_zero_mem(&opaque_data, sizeof(opaque_data));
2113 1 : opaque_data.opaque_header.total_elements = 2;
2114 :
2115 : /* Element 1: AEADlimitOE (placed first). */
2116 1 : opaque_data.aead_limit_header.id = SPDM_REGISTRY_ID_DMTF;
2117 1 : opaque_data.aead_limit_header.vendor_len = 0;
2118 1 : opaque_data.aead_limit_header.opaque_element_data_len =
2119 : sizeof(secured_message_opaque_element_aead_limit_t);
2120 1 : opaque_data.aead_limit_opaque.sm_data_version =
2121 : SECURED_MESSAGE_OPAQUE_ELEMENT_SMDATA_DATA_VERSION;
2122 1 : opaque_data.aead_limit_opaque.sm_data_id =
2123 : SECURED_MESSAGE_OPAQUE_ELEMENT_SMDATA_ID_AEAD_LIMIT;
2124 1 : opaque_data.aead_limit_opaque.aead_limit_exponent = 50;
2125 :
2126 : /* Element 2: version-selection (placed second). */
2127 1 : opaque_data.ver_sel_header.id = SPDM_REGISTRY_ID_DMTF;
2128 1 : opaque_data.ver_sel_header.vendor_len = 0;
2129 1 : opaque_data.ver_sel_header.opaque_element_data_len =
2130 : sizeof(secured_message_opaque_element_version_selection_t);
2131 1 : opaque_data.ver_sel_opaque.sm_data_version =
2132 : SECURED_MESSAGE_OPAQUE_ELEMENT_SMDATA_DATA_VERSION;
2133 1 : opaque_data.ver_sel_opaque.sm_data_id =
2134 : SECURED_MESSAGE_OPAQUE_ELEMENT_SMDATA_ID_VERSION_SELECTION;
2135 1 : opaque_data.ver_sel_opaque.selected_version =
2136 : SECURED_SPDM_VERSION_13 << SPDM_VERSION_NUMBER_SHIFT_BIT;
2137 :
2138 : /* AEADlimitOE is found even though it precedes version-selection (negotiated version 1.3). */
2139 1 : aead_limit_exponent = 0;
2140 1 : status = libspdm_process_opaque_data_aead_limit(
2141 : spdm_context, SECURED_SPDM_VERSION_13 << SPDM_VERSION_NUMBER_SHIFT_BIT,
2142 : sizeof(opaque_data), &opaque_data, &aead_limit_exponent);
2143 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
2144 1 : assert_int_equal(aead_limit_exponent, 50);
2145 :
2146 : /* The AEADlimitOE element is only defined for secured message version 1.3. With an older
2147 : * negotiated version (1.2) the element must be ignored and the default exponent (64) returned,
2148 : * even though the element is physically present. */
2149 1 : aead_limit_exponent = 0;
2150 1 : status = libspdm_process_opaque_data_aead_limit(
2151 : spdm_context, SECURED_SPDM_VERSION_12 << SPDM_VERSION_NUMBER_SHIFT_BIT,
2152 : sizeof(opaque_data), &opaque_data, &aead_limit_exponent);
2153 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
2154 1 : assert_int_equal(aead_limit_exponent, SECURED_MESSAGE_AEAD_LIMIT_EXPONENT_DEFAULT);
2155 :
2156 : /* version-selection is also found regardless of the AEADlimitOE ordering. */
2157 1 : secured_message_version = 0;
2158 1 : status = libspdm_process_opaque_data_version_selection_data(spdm_context, sizeof(opaque_data),
2159 : &opaque_data,
2160 : &secured_message_version);
2161 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
2162 1 : assert_int_equal(libspdm_get_version_from_version_number(secured_message_version),
2163 : SECURED_SPDM_VERSION_13);
2164 1 : }
2165 :
2166 : /* DSP0277 1.3 AEAD limit: peer-supports vs. peer-does-not-support, using a non-power-of-two local
2167 : * cap. With local cap 0xFF00FF:
2168 : * - peer does not support (absent element -> exponent 64): the session cap stays 0xFF00FF.
2169 : * - peer supports and advertises a tighter limit: the session cap is reduced to the peer's
2170 : * (rounded-down) AEAD limit, never raised. */
2171 1 : static void libspdm_test_aead_limit_peer_support_case29(void **state)
2172 : {
2173 : libspdm_test_context_t *spdm_test_context;
2174 : libspdm_context_t *spdm_context;
2175 : libspdm_data_parameter_t parameter;
2176 : uint16_t req_id;
2177 : uint16_t rsp_id;
2178 : uint32_t session_id;
2179 : void *session_info;
2180 : uint64_t max_seq;
2181 : size_t data_size;
2182 :
2183 1 : spdm_test_context = *state;
2184 1 : spdm_context = spdm_test_context->spdm_context;
2185 1 : spdm_test_context->case_id = 0x1D;
2186 :
2187 1 : spdm_context->connection_info.capability.flags =
2188 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_ENCRYPT_CAP |
2189 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MAC_CAP;
2190 1 : spdm_context->local_context.capability.flags =
2191 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_ENCRYPT_CAP |
2192 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MAC_CAP;
2193 :
2194 : /* Non-power-of-two local cap. */
2195 1 : spdm_context->max_spdm_session_sequence_number = 0xFF00FF;
2196 :
2197 1 : libspdm_zero_mem(¶meter, sizeof(parameter));
2198 1 : parameter.location = LIBSPDM_DATA_LOCATION_SESSION;
2199 :
2200 : /* Case 1: peer does NOT support AEAD limit. The message paths gate the apply on negotiated
2201 : * secured message version >= 1.3, so for an older session the apply is never called and the
2202 : * session cap is simply inherited from the context cap (0xFF00FF). */
2203 1 : req_id = libspdm_allocate_req_session_id(spdm_context, false);
2204 1 : rsp_id = libspdm_allocate_rsp_session_id(spdm_context, false);
2205 1 : session_id = libspdm_generate_session_id(req_id, rsp_id);
2206 1 : session_info = libspdm_assign_session_id(spdm_context, session_id,
2207 : SECURED_SPDM_VERSION_12 <<
2208 : SPDM_VERSION_NUMBER_SHIFT_BIT, false);
2209 1 : assert_ptr_not_equal(session_info, NULL);
2210 1 : libspdm_copy_mem(parameter.additional_data, sizeof(parameter.additional_data),
2211 : &session_id, sizeof(session_id));
2212 1 : max_seq = 0;
2213 1 : data_size = sizeof(max_seq);
2214 1 : assert_int_equal(libspdm_get_data(spdm_context,
2215 : LIBSPDM_DATA_MAX_SPDM_SESSION_SEQUENCE_NUMBER,
2216 : ¶meter, &max_seq, &data_size),
2217 : LIBSPDM_STATUS_SUCCESS);
2218 1 : assert_int_equal(max_seq, 0xFF00FF);
2219 1 : libspdm_free_session_id(spdm_context, session_id);
2220 :
2221 : /* Case 2: peer supports but advertises the default (absent element -> exponent 64). On a 1.3
2222 : * session this endpoint still enforces its own rounded-down advertised limit: the non-power-of-
2223 : * two cap 0xFF00FF advertises exponent floor(log2(0xFF00FF + 1)) = 23, so the local advertised
2224 : * max is 2^23 - 1 = 0x7FFFFF and the negotiated cap is min(0x7FFFFF, 2^64 - 1) = 0x7FFFFF. */
2225 1 : req_id = libspdm_allocate_req_session_id(spdm_context, false);
2226 1 : rsp_id = libspdm_allocate_rsp_session_id(spdm_context, false);
2227 1 : session_id = libspdm_generate_session_id(req_id, rsp_id);
2228 1 : session_info = libspdm_assign_session_id(spdm_context, session_id,
2229 : SECURED_SPDM_VERSION_13 <<
2230 : SPDM_VERSION_NUMBER_SHIFT_BIT, false);
2231 1 : assert_ptr_not_equal(session_info, NULL);
2232 1 : libspdm_copy_mem(parameter.additional_data, sizeof(parameter.additional_data),
2233 : &session_id, sizeof(session_id));
2234 1 : libspdm_apply_aead_limit_to_session(spdm_context, session_info,
2235 : SECURED_MESSAGE_AEAD_LIMIT_EXPONENT_DEFAULT);
2236 1 : max_seq = 0;
2237 1 : data_size = sizeof(max_seq);
2238 1 : assert_int_equal(libspdm_get_data(spdm_context,
2239 : LIBSPDM_DATA_MAX_SPDM_SESSION_SEQUENCE_NUMBER,
2240 : ¶meter, &max_seq, &data_size),
2241 : LIBSPDM_STATUS_SUCCESS);
2242 1 : assert_int_equal(max_seq, 0x7FFFFF);
2243 :
2244 : /* Case 3: peer supports and advertises a tighter limit (exponent 23 -> AeadLimit 2^23, max
2245 : * allowed sequence number 2^23 - 1 = 0x7FFFFF). The session cap is
2246 : * min(local 0x7FFFFF, peer 0x7FFFFF) = 0x7FFFFF. */
2247 1 : libspdm_apply_aead_limit_to_session(spdm_context, session_info, 23);
2248 1 : max_seq = 0;
2249 1 : data_size = sizeof(max_seq);
2250 1 : assert_int_equal(libspdm_get_data(spdm_context,
2251 : LIBSPDM_DATA_MAX_SPDM_SESSION_SEQUENCE_NUMBER,
2252 : ¶meter, &max_seq, &data_size),
2253 : LIBSPDM_STATUS_SUCCESS);
2254 1 : assert_int_equal(max_seq, 0x7FFFFF);
2255 1 : libspdm_free_session_id(spdm_context, session_id);
2256 1 : }
2257 :
2258 : /* DSP0277 1.3 AEAD limit: boundary semantics across exponents. AeadLimit = 2^AeadLimitExponent is
2259 : * the first sequence number that is NOT allowed, so the maximum allowed sequence number (which is
2260 : * what max_spdm_session_sequence_number stores) is AeadLimit - 1 = 2^exponent - 1:
2261 : * - exponent 0 -> AeadLimit 1 -> max 0 (only sequence number 0 is usable: one msg).
2262 : * - exponent 1 -> AeadLimit 2 -> max 1 (sequence numbers 0 and 1 are usable).
2263 : * - exponent 63 -> AeadLimit 2^63 -> max 2^63 - 1 (the largest exponent below the 2^64 clamp).
2264 : * - exponent 64 -> AeadLimit 2^64 -> max 2^64 - 1 (not representable as AeadLimit; the maximum
2265 : * allowed value is the all-ones cap, which is
2266 : * also the spec default).
2267 : * The exponent is also round-tripped through the builder. */
2268 1 : static void libspdm_test_aead_limit_small_exponent_case30(void **state)
2269 : {
2270 : libspdm_return_t status;
2271 : libspdm_test_context_t *spdm_test_context;
2272 : libspdm_context_t *spdm_context;
2273 : libspdm_data_parameter_t parameter;
2274 : uint16_t req_id;
2275 : uint16_t rsp_id;
2276 : uint32_t session_id;
2277 : void *session_info;
2278 : uint64_t max_seq;
2279 : size_t data_size;
2280 : size_t opaque_data_size;
2281 : size_t element_size;
2282 : uint8_t *opaque_data_ptr;
2283 : uint8_t aead_limit_exponent;
2284 : size_t index;
2285 : uint8_t exponent;
2286 : uint64_t expected_max;
2287 1 : const uint8_t test_exponents[] = {0, 1, 63, 64};
2288 :
2289 1 : spdm_test_context = *state;
2290 1 : spdm_context = spdm_test_context->spdm_context;
2291 1 : spdm_test_context->case_id = 0x1E;
2292 :
2293 1 : spdm_context->connection_info.capability.flags =
2294 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_ENCRYPT_CAP |
2295 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MAC_CAP;
2296 1 : spdm_context->local_context.capability.flags =
2297 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_ENCRYPT_CAP |
2298 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MAC_CAP;
2299 :
2300 : /* The local cap is the default (all-ones), so the effective session cap is driven entirely by
2301 : * the peer's advertised exponent: min(all-ones, 2^exponent) = 2^exponent. */
2302 1 : spdm_context->max_spdm_session_sequence_number = LIBSPDM_MAX_SPDM_SESSION_SEQUENCE_NUMBER;
2303 :
2304 1 : libspdm_zero_mem(¶meter, sizeof(parameter));
2305 1 : parameter.location = LIBSPDM_DATA_LOCATION_SESSION;
2306 :
2307 : /* Each exponent negotiates a session cap of exactly 2^exponent - 1 (the maximum allowed sequence
2308 : * number, one below the AEAD limit). */
2309 5 : for (index = 0; index < LIBSPDM_ARRAY_SIZE(test_exponents); index++) {
2310 4 : exponent = test_exponents[index];
2311 4 : req_id = libspdm_allocate_req_session_id(spdm_context, false);
2312 4 : rsp_id = libspdm_allocate_rsp_session_id(spdm_context, false);
2313 4 : session_id = libspdm_generate_session_id(req_id, rsp_id);
2314 4 : session_info = libspdm_assign_session_id(spdm_context, session_id,
2315 : SECURED_SPDM_VERSION_13 <<
2316 : SPDM_VERSION_NUMBER_SHIFT_BIT, false);
2317 4 : assert_ptr_not_equal(session_info, NULL);
2318 4 : libspdm_copy_mem(parameter.additional_data, sizeof(parameter.additional_data),
2319 : &session_id, sizeof(session_id));
2320 :
2321 4 : libspdm_apply_aead_limit_to_session(spdm_context, session_info, exponent);
2322 :
2323 : /* AeadLimit 2^64 is not representable; exponent 64's maximum allowed value is the all-ones
2324 : * cap. */
2325 4 : expected_max = (exponent >= 64) ? LIBSPDM_MAX_SPDM_SESSION_SEQUENCE_NUMBER :
2326 3 : (((uint64_t)1 << exponent) - 1);
2327 :
2328 4 : max_seq = 0;
2329 4 : data_size = sizeof(max_seq);
2330 4 : assert_int_equal(libspdm_get_data(spdm_context,
2331 : LIBSPDM_DATA_MAX_SPDM_SESSION_SEQUENCE_NUMBER,
2332 : ¶meter, &max_seq, &data_size),
2333 : LIBSPDM_STATUS_SUCCESS);
2334 4 : assert_int_equal(max_seq, expected_max);
2335 :
2336 4 : libspdm_free_session_id(spdm_context, session_id);
2337 : }
2338 :
2339 : /* Builder round-trip for small exponents: a local cap of 2^exponent must advertise exponent. */
2340 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 << SPDM_VERSION_NUMBER_SHIFT_BIT;
2341 1 : spdm_context->local_context.secured_message_version.secured_message_version_count = 4;
2342 1 : spdm_context->local_context.secured_message_version.secured_message_version[0] =
2343 : SECURED_SPDM_VERSION_10 << SPDM_VERSION_NUMBER_SHIFT_BIT;
2344 1 : spdm_context->local_context.secured_message_version.secured_message_version[1] =
2345 : SECURED_SPDM_VERSION_11 << SPDM_VERSION_NUMBER_SHIFT_BIT;
2346 1 : spdm_context->local_context.secured_message_version.secured_message_version[2] =
2347 : SECURED_SPDM_VERSION_12 << SPDM_VERSION_NUMBER_SHIFT_BIT;
2348 1 : spdm_context->local_context.secured_message_version.secured_message_version[3] =
2349 : SECURED_SPDM_VERSION_13 << SPDM_VERSION_NUMBER_SHIFT_BIT;
2350 :
2351 1 : element_size = libspdm_get_opaque_data_aead_limit_element_size(
2352 : spdm_context, SECURED_SPDM_VERSION_13 << SPDM_VERSION_NUMBER_SHIFT_BIT);
2353 1 : assert_int_not_equal(element_size, 0);
2354 :
2355 5 : for (index = 0; index < LIBSPDM_ARRAY_SIZE(test_exponents); index++) {
2356 4 : exponent = test_exponents[index];
2357 : /* A local cap of 2^exponent - 1 advertises exponent; exponent 64's limit (2^64) is
2358 : * represented by the all-ones cap. */
2359 4 : spdm_context->max_spdm_session_sequence_number =
2360 4 : (exponent >= 64) ? LIBSPDM_MAX_SPDM_SESSION_SEQUENCE_NUMBER :
2361 3 : (((uint64_t)1 << exponent) - 1);
2362 :
2363 4 : opaque_data_size = libspdm_get_opaque_data_supported_version_data_size(spdm_context);
2364 4 : opaque_data_ptr = malloc(opaque_data_size + element_size);
2365 4 : assert_ptr_not_equal(opaque_data_ptr, NULL);
2366 4 : libspdm_build_opaque_data_supported_version_data(spdm_context, &opaque_data_size,
2367 : opaque_data_ptr);
2368 : /* opaque_data_size now becomes the total buffer capacity for the append. */
2369 4 : opaque_data_size += element_size;
2370 4 : libspdm_build_opaque_data_aead_limit_element(
2371 : spdm_context, SECURED_SPDM_VERSION_13 << SPDM_VERSION_NUMBER_SHIFT_BIT,
2372 : &opaque_data_size, opaque_data_ptr);
2373 :
2374 4 : aead_limit_exponent = 0xFF;
2375 4 : status = libspdm_process_opaque_data_aead_limit(
2376 : spdm_context, SECURED_SPDM_VERSION_13 << SPDM_VERSION_NUMBER_SHIFT_BIT,
2377 : opaque_data_size, opaque_data_ptr, &aead_limit_exponent);
2378 4 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
2379 4 : assert_int_equal(aead_limit_exponent, exponent);
2380 :
2381 4 : free(opaque_data_ptr);
2382 : }
2383 1 : }
2384 :
2385 : static libspdm_test_context_t m_libspdm_common_context_data_test_context = {
2386 : LIBSPDM_TEST_CONTEXT_VERSION,
2387 : true,
2388 : NULL,
2389 : NULL,
2390 : };
2391 :
2392 1 : int libspdm_common_context_data_test_main(void)
2393 : {
2394 1 : const struct CMUnitTest spdm_common_context_data_tests[] = {
2395 : cmocka_unit_test(libspdm_test_common_context_data_case1),
2396 : cmocka_unit_test(libspdm_test_common_context_data_case2),
2397 : cmocka_unit_test(libspdm_test_common_context_data_case3),
2398 : cmocka_unit_test(libspdm_test_common_context_data_case4),
2399 :
2400 : cmocka_unit_test(libspdm_test_verify_peer_cert_chain_buffer_case5),
2401 : cmocka_unit_test(libspdm_test_verify_peer_cert_chain_buffer_case6),
2402 : cmocka_unit_test(libspdm_test_verify_peer_cert_chain_buffer_case7),
2403 : cmocka_unit_test(libspdm_test_verify_peer_cert_chain_buffer_case8),
2404 :
2405 : cmocka_unit_test(libspdm_test_set_data_case9),
2406 :
2407 : /* Successful response V1.1 for multi element opaque data supported version, element number is 2*/
2408 : cmocka_unit_test(libspdm_test_process_opaque_data_supported_version_data_case10),
2409 : /* Failed response V1.1 for multi element opaque data supported version, element id is wrong*/
2410 : cmocka_unit_test(libspdm_test_process_opaque_data_supported_version_data_case11),
2411 : /* Successful response V1.2 for multi element opaque data supported version, element number is 2*/
2412 : cmocka_unit_test(libspdm_test_process_opaque_data_supported_version_data_case12),
2413 : /* Failed response V1.2 for multi element opaque data supported version, element id is wrong*/
2414 : cmocka_unit_test(libspdm_test_process_opaque_data_supported_version_data_case13),
2415 : /* Successful response V1.1 for multi element opaque data selection version, element number is 2*/
2416 : cmocka_unit_test(libspdm_test_process_opaque_data_selection_version_data_case14),
2417 : /* Failed response V1.1 for multi element opaque data selection version, element number is wrong*/
2418 : cmocka_unit_test(libspdm_test_process_opaque_data_selection_version_data_case15),
2419 : /* Successful response V1.2 for multi element opaque data selection version, element number is 2*/
2420 : cmocka_unit_test(libspdm_test_process_opaque_data_selection_version_data_case16),
2421 : /* Failed response V1.2 for multi element opaque data selection version, element number is wrong*/
2422 : cmocka_unit_test(libspdm_test_process_opaque_data_selection_version_data_case17),
2423 :
2424 : /* Successful initialization and setting of secured message context location. */
2425 : cmocka_unit_test(libspdm_test_secured_message_context_location_selection_case18),
2426 :
2427 : /* Test that the Export Master Secret can be exported and cleared. */
2428 : cmocka_unit_test(libspdm_test_export_master_secret_case19),
2429 : cmocka_unit_test(libspdm_test_check_context_case20),
2430 :
2431 : /* Test the max DHE/PSK session count */
2432 : cmocka_unit_test(libspdm_test_max_session_count_case21),
2433 :
2434 : /* Successful response V1.2 for multi element */
2435 : cmocka_unit_test(libspdm_test_process_opaque_data_case22),
2436 :
2437 : #if !(LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT)
2438 : /* reset_context frees the stored peer leaf certificate public key */
2439 : cmocka_unit_test(libspdm_test_reset_context_leaf_key_case23),
2440 : #endif
2441 :
2442 : /* DSP0277 1.3 AEAD limit: build + append AEADlimitOE then parse it back. */
2443 : cmocka_unit_test(libspdm_test_aead_limit_build_parse_case24),
2444 : /* DSP0277 1.3 AEAD limit: reject exponent > 64, absent element defaults to 64. */
2445 : cmocka_unit_test(libspdm_test_aead_limit_invalid_and_default_case25),
2446 : /* DSP0277 1.3 AEAD limit: apply min(local, peer) limit to a session. */
2447 : cmocka_unit_test(libspdm_test_aead_limit_apply_to_session_case26),
2448 : /* DSP0277 1.3 AEAD limit: set_data validates the exponent. */
2449 : cmocka_unit_test(libspdm_test_aead_limit_set_data_case27),
2450 : /* DSP0277 1.3 AEAD limit: parse is order-independent (AEADlimitOE before version-sel). */
2451 : cmocka_unit_test(libspdm_test_aead_limit_element_order_case28),
2452 : /* DSP0277 1.3 AEAD limit: peer-supports vs peer-does-not-support with a non-pow2 cap. */
2453 : cmocka_unit_test(libspdm_test_aead_limit_peer_support_case29),
2454 : /* DSP0277 1.3 AEAD limit: exponent boundary semantics (exp 0, 1, 63, 64). */
2455 : cmocka_unit_test(libspdm_test_aead_limit_small_exponent_case30),
2456 : };
2457 :
2458 1 : libspdm_setup_test_context(&m_libspdm_common_context_data_test_context);
2459 :
2460 1 : return cmocka_run_group_tests(spdm_common_context_data_tests,
2461 : libspdm_unit_test_group_setup,
2462 : libspdm_unit_test_group_teardown);
2463 : }
|