Line data Source code
1 : /**
2 : * Copyright Notice:
3 : * Copyright 2025-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_responder_lib.h"
9 :
10 : #if (LIBSPDM_ENABLE_CAPABILITY_ENCAP_CAP) && (LIBSPDM_ENABLE_CAPABILITY_EVENT_CAP)
11 :
12 : extern uint32_t g_event_count;
13 : extern size_t g_events_list_size;
14 :
15 : static uint8_t m_send_buffer[LIBSPDM_MAX_SPDM_MSG_SIZE];
16 : static uint8_t m_receive_buffer[LIBSPDM_MAX_SPDM_MSG_SIZE];
17 : static uint32_t m_session_id = 0xFFFFFFFF;
18 :
19 3 : static void set_standard_state(libspdm_context_t *spdm_context)
20 : {
21 : libspdm_session_info_t *session_info;
22 :
23 3 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_13 <<
24 : SPDM_VERSION_NUMBER_SHIFT_BIT;
25 3 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
26 :
27 3 : spdm_context->connection_info.capability.flags |=
28 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_ENCRYPT_CAP;
29 3 : spdm_context->connection_info.capability.flags |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MAC_CAP;
30 3 : spdm_context->connection_info.capability.flags |=
31 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_KEY_EX_CAP;
32 3 : spdm_context->connection_info.capability.flags |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_ENCAP_CAP;
33 :
34 3 : spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_EVENT_CAP;
35 3 : spdm_context->local_context.capability.flags |=
36 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_ENCRYPT_CAP;
37 3 : spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MAC_CAP;
38 3 : spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_KEY_EX_CAP;
39 3 : spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_ENCAP_CAP;
40 :
41 3 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
42 3 : spdm_context->connection_info.algorithm.base_asym_algo = m_libspdm_use_asym_algo;
43 3 : spdm_context->connection_info.algorithm.dhe_named_group = m_libspdm_use_dhe_algo;
44 3 : spdm_context->connection_info.algorithm.aead_cipher_suite = m_libspdm_use_aead_algo;
45 :
46 3 : spdm_context->latest_session_id = m_session_id;
47 3 : spdm_context->last_spdm_request_session_id_valid = true;
48 3 : spdm_context->last_spdm_request_session_id = m_session_id;
49 3 : session_info = &spdm_context->session_info[0];
50 3 : libspdm_session_info_init(spdm_context, session_info, m_session_id,
51 : SECURED_SPDM_VERSION_11 << SPDM_VERSION_NUMBER_SHIFT_BIT, true);
52 3 : libspdm_secured_message_set_session_state(
53 : session_info->secured_message_context,
54 : LIBSPDM_SESSION_STATE_ESTABLISHED);
55 3 : }
56 :
57 : /**
58 : * Test 1: Responder forms the expected SEND_EVENT request message with one event.
59 : **/
60 1 : static void rsp_encap_send_event_case1(void **state)
61 : {
62 : libspdm_return_t status;
63 : libspdm_test_context_t *spdm_test_context;
64 : libspdm_context_t *spdm_context;
65 1 : size_t request_buffer_size = sizeof(m_send_buffer);
66 : spdm_send_event_request_t *spdm_request;
67 :
68 1 : spdm_test_context = *state;
69 1 : spdm_context = spdm_test_context->spdm_context;
70 1 : spdm_test_context->case_id = 0x01;
71 :
72 1 : set_standard_state(spdm_context);
73 :
74 1 : g_event_count = 1;
75 :
76 1 : status = libspdm_get_encap_request_send_event(spdm_context, &request_buffer_size,
77 : m_send_buffer);
78 :
79 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
80 :
81 1 : spdm_request = (spdm_send_event_request_t *)m_send_buffer;
82 :
83 1 : assert_int_equal(spdm_request->header.spdm_version, SPDM_MESSAGE_VERSION_13);
84 1 : assert_int_equal(spdm_request->header.request_response_code, SPDM_SEND_EVENT);
85 1 : assert_int_equal(spdm_request->header.param1, 0);
86 1 : assert_int_equal(spdm_request->header.param1, 0);
87 1 : assert_int_equal(spdm_request->event_count, g_event_count);
88 :
89 1 : for (unsigned int index = 0;
90 4601 : index < request_buffer_size - sizeof(spdm_send_event_request_t);
91 4600 : index++) {
92 4600 : assert_int_equal((uint8_t)index, ((uint8_t *)(spdm_request + 1))[index]);
93 : }
94 1 : }
95 :
96 : /**
97 : * Test 2: encap_request_size is trimmed to the exact number of bytes written
98 : * by libspdm_generate_event_list.
99 : **/
100 1 : static void rsp_encap_send_event_case2(void **state)
101 : {
102 : libspdm_return_t status;
103 : libspdm_test_context_t *spdm_test_context;
104 : libspdm_context_t *spdm_context;
105 1 : size_t request_buffer_size = sizeof(m_send_buffer);
106 1 : const size_t actual_events_bytes = 32;
107 :
108 1 : spdm_test_context = *state;
109 1 : spdm_context = spdm_test_context->spdm_context;
110 1 : spdm_test_context->case_id = 0x02;
111 :
112 1 : set_standard_state(spdm_context);
113 :
114 1 : g_event_count = 1;
115 1 : g_events_list_size = actual_events_bytes;
116 :
117 1 : status = libspdm_get_encap_request_send_event(spdm_context, &request_buffer_size,
118 : m_send_buffer);
119 :
120 1 : g_events_list_size = 0;
121 :
122 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
123 1 : assert_int_equal(request_buffer_size,
124 : sizeof(spdm_send_event_request_t) + actual_events_bytes);
125 1 : }
126 :
127 : /**
128 : * Test 3: Responder processes the encapsulated EVENT_ACK response.
129 : **/
130 1 : static void rsp_encap_send_event_case3(void **state)
131 : {
132 : libspdm_return_t status;
133 : libspdm_test_context_t *spdm_test_context;
134 : libspdm_context_t *spdm_context;
135 : size_t response_size;
136 : spdm_event_ack_response_t *spdm_response;
137 : bool need_continue;
138 :
139 1 : spdm_test_context = *state;
140 1 : spdm_context = spdm_test_context->spdm_context;
141 1 : spdm_test_context->case_id = 0x03;
142 :
143 1 : set_standard_state(spdm_context);
144 :
145 1 : spdm_response = (spdm_event_ack_response_t *)m_receive_buffer;
146 1 : response_size = sizeof(spdm_event_ack_response_t);
147 :
148 1 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_13;
149 1 : spdm_response->header.request_response_code = SPDM_EVENT_ACK;
150 1 : spdm_response->header.param1 = 0;
151 1 : spdm_response->header.param2 = 0;
152 :
153 1 : status = libspdm_process_encap_response_event_ack(spdm_context, response_size, spdm_response,
154 : &need_continue);
155 :
156 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
157 1 : assert_false(need_continue);
158 1 : }
159 :
160 1 : int libspdm_rsp_encap_send_event_test(void)
161 : {
162 1 : const struct CMUnitTest test_cases[] = {
163 : cmocka_unit_test(rsp_encap_send_event_case1),
164 : cmocka_unit_test(rsp_encap_send_event_case2),
165 : cmocka_unit_test(rsp_encap_send_event_case3),
166 : };
167 :
168 1 : libspdm_test_context_t test_context = {
169 : LIBSPDM_TEST_CONTEXT_VERSION,
170 : false,
171 : };
172 :
173 1 : libspdm_setup_test_context(&test_context);
174 :
175 1 : return cmocka_run_group_tests(test_cases,
176 : libspdm_unit_test_group_setup,
177 : libspdm_unit_test_group_teardown);
178 : }
179 :
180 : #endif /* (LIBSPDM_ENABLE_CAPABILITY_ENCAP_CAP) && (LIBSPDM_ENABLE_CAPABILITY_EVENT_CAP) */
|