Line data Source code
1 : /**
2 : * Copyright Notice:
3 : * Copyright 2025 DMTF. All rights reserved.
4 : * License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/libspdm/blob/main/LICENSE.md
5 : **/
6 :
7 : #include "spdm_unit_test.h"
8 : #include "internal/libspdm_requester_lib.h"
9 : #include "internal/libspdm_secured_message_lib.h"
10 :
11 : #if LIBSPDM_ENABLE_CAPABILITY_EVENT_CAP
12 :
13 : static uint32_t m_session_id = 0xffffffff;
14 : static uint8_t m_spdm_request_buffer[0x1000];
15 :
16 : static struct m_test_params {
17 : uint32_t event_count;
18 : size_t events_list_size;
19 : uint8_t events_list[0x1000];
20 : } m_test_params;
21 :
22 1 : static libspdm_return_t send_message(
23 : void *spdm_context, size_t request_size, const void *request, uint64_t timeout)
24 : {
25 : libspdm_return_t status;
26 : uint32_t session_id;
27 : uint32_t *message_session_id;
28 : spdm_send_event_request_t *spdm_message;
29 : bool is_app_message;
30 : void *spdm_request_buffer;
31 : size_t spdm_request_size;
32 : libspdm_session_info_t *session_info;
33 : uint8_t request_buffer[0x1000];
34 :
35 : /* Workaround request being const. */
36 1 : libspdm_copy_mem(request_buffer, sizeof(request_buffer), request, request_size);
37 :
38 1 : session_id = m_session_id;
39 1 : session_info = libspdm_get_session_info_via_session_id(spdm_context, session_id);
40 1 : LIBSPDM_ASSERT(session_info != NULL);
41 :
42 1 : ((libspdm_secured_message_context_t *)(session_info->secured_message_context))->
43 1 : application_secret.request_data_sequence_number--;
44 :
45 1 : spdm_request_buffer = m_spdm_request_buffer;
46 1 : spdm_request_size = sizeof(m_spdm_request_buffer);
47 :
48 1 : status = libspdm_transport_test_decode_message(spdm_context, &message_session_id,
49 : &is_app_message, true,
50 : request_size, request_buffer,
51 : &spdm_request_size, &spdm_request_buffer);
52 :
53 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
54 :
55 1 : spdm_message = spdm_request_buffer;
56 :
57 1 : assert_int_equal(spdm_request_size,
58 : sizeof(spdm_send_event_request_t) + m_test_params.events_list_size);
59 1 : assert_int_equal(spdm_message->header.spdm_version, SPDM_MESSAGE_VERSION_13);
60 1 : assert_int_equal(spdm_message->header.request_response_code, SPDM_SEND_EVENT);
61 1 : assert_int_equal(spdm_message->header.param1, 0);
62 1 : assert_int_equal(spdm_message->header.param2, 0);
63 1 : assert_int_equal(spdm_message->event_count, m_test_params.event_count);
64 :
65 101 : for (unsigned int index = 0; index < m_test_params.events_list_size; index++) {
66 100 : assert_int_equal(((uint8_t *)(spdm_message + 1))[index], (uint8_t)index);
67 : }
68 :
69 1 : return LIBSPDM_STATUS_SUCCESS;
70 : }
71 :
72 1 : static libspdm_return_t receive_message(
73 : void *spdm_context, size_t *response_size, void **response, uint64_t timeout)
74 : {
75 : spdm_event_ack_response_t *spdm_response;
76 : size_t spdm_response_size;
77 : size_t transport_header_size;
78 : uint32_t session_id;
79 : libspdm_session_info_t *session_info;
80 : uint8_t *scratch_buffer;
81 : size_t scratch_buffer_size;
82 :
83 1 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
84 1 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
85 :
86 1 : session_id = m_session_id;
87 1 : session_info = libspdm_get_session_info_via_session_id(spdm_context, session_id);
88 1 : LIBSPDM_ASSERT((session_info != NULL));
89 :
90 1 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
91 1 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
92 :
93 1 : spdm_response_size = sizeof(spdm_event_ack_response_t);
94 1 : libspdm_zero_mem(spdm_response, spdm_response_size);
95 :
96 1 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_13;
97 1 : spdm_response->header.request_response_code = SPDM_EVENT_ACK;
98 1 : spdm_response->header.param1 = 0;
99 1 : spdm_response->header.param2 = 0;
100 :
101 : /* For secure message, message is in sender buffer, we need copy it to scratch buffer.
102 : * transport_message is always in sender buffer. */
103 1 : libspdm_get_scratch_buffer(spdm_context, (void **)&scratch_buffer, &scratch_buffer_size);
104 1 : libspdm_copy_mem(scratch_buffer + transport_header_size,
105 : scratch_buffer_size - transport_header_size,
106 : spdm_response, spdm_response_size);
107 :
108 1 : spdm_response = (void *)(scratch_buffer + transport_header_size);
109 :
110 1 : libspdm_transport_test_encode_message(spdm_context, &session_id,
111 : false, false, spdm_response_size,
112 : spdm_response, response_size, response);
113 :
114 : /* Workaround: Use single context to encode message and then decode message. */
115 1 : ((libspdm_secured_message_context_t *)(session_info->secured_message_context))->
116 1 : application_secret.response_data_sequence_number--;
117 :
118 1 : return LIBSPDM_STATUS_SUCCESS;
119 : }
120 :
121 1 : static void set_standard_state(libspdm_context_t *spdm_context)
122 : {
123 : libspdm_session_info_t *session_info;
124 :
125 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_13 <<
126 : SPDM_VERSION_NUMBER_SHIFT_BIT;
127 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
128 :
129 1 : spdm_context->connection_info.capability.flags |=
130 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_ENCRYPT_CAP;
131 1 : spdm_context->connection_info.capability.flags |=
132 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MAC_CAP;
133 1 : spdm_context->connection_info.capability.flags |=
134 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_KEY_EX_CAP;
135 1 : spdm_context->connection_info.capability.flags |=
136 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_ENCAP_CAP;
137 :
138 1 : spdm_context->local_context.capability.flags |=
139 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_ENCRYPT_CAP;
140 1 : spdm_context->local_context.capability.flags |=
141 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MAC_CAP;
142 1 : spdm_context->local_context.capability.flags |=
143 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_KEY_EX_CAP;
144 1 : spdm_context->local_context.capability.flags |=
145 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_ENCAP_CAP;
146 1 : spdm_context->local_context.capability.flags |=
147 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_EVENT_CAP;
148 :
149 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
150 1 : spdm_context->connection_info.algorithm.base_asym_algo = m_libspdm_use_asym_algo;
151 1 : spdm_context->connection_info.algorithm.dhe_named_group = m_libspdm_use_dhe_algo;
152 1 : spdm_context->connection_info.algorithm.aead_cipher_suite = m_libspdm_use_aead_algo;
153 :
154 1 : spdm_context->latest_session_id = m_session_id;
155 1 : spdm_context->last_spdm_request_session_id_valid = true;
156 1 : spdm_context->last_spdm_request_session_id = m_session_id;
157 1 : session_info = &spdm_context->session_info[0];
158 1 : libspdm_session_info_init(spdm_context, session_info, m_session_id,
159 : SECURED_SPDM_VERSION_11 << SPDM_VERSION_NUMBER_SHIFT_BIT, true);
160 1 : libspdm_secured_message_set_session_state(
161 : session_info->secured_message_context,
162 : LIBSPDM_SESSION_STATE_ESTABLISHED);
163 1 : }
164 :
165 : /**
166 : * Test 1: Successfully send a SEND_EVENT message.
167 : * Expected behavior: returns with LIBSPDM_STATUS_SUCCESS.
168 : **/
169 1 : static void req_send_event_case1(void **state)
170 : {
171 : libspdm_test_context_t *spdm_test_context;
172 : libspdm_context_t *spdm_context;
173 : libspdm_return_t status;
174 :
175 1 : spdm_test_context = *state;
176 1 : spdm_context = spdm_test_context->spdm_context;
177 1 : spdm_test_context->case_id = 0x1;
178 :
179 1 : set_standard_state(spdm_context);
180 :
181 1 : m_test_params.event_count = 3;
182 1 : m_test_params.events_list_size = 100;
183 :
184 101 : for (int unsigned index = 0; index < m_test_params.events_list_size; index++) {
185 100 : m_test_params.events_list[index] = (uint8_t)index;
186 : }
187 :
188 1 : status = libspdm_send_event(spdm_context, m_session_id, m_test_params.event_count,
189 : m_test_params.events_list_size, m_test_params.events_list);
190 :
191 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
192 1 : }
193 :
194 1 : int libspdm_req_send_event_test(void)
195 : {
196 1 : const struct CMUnitTest test_cases[] = {
197 : cmocka_unit_test(req_send_event_case1),
198 : };
199 :
200 1 : libspdm_test_context_t test_context = {
201 : LIBSPDM_TEST_CONTEXT_VERSION,
202 : true,
203 : send_message,
204 : receive_message,
205 : };
206 :
207 1 : libspdm_setup_test_context(&test_context);
208 :
209 1 : return cmocka_run_group_tests(test_cases,
210 : libspdm_unit_test_group_setup,
211 : libspdm_unit_test_group_teardown);
212 : }
213 :
214 : #endif /* LIBSPDM_ENABLE_CAPABILITY_EVENT_CAP */
|