Line data Source code
1 : /**
2 : * Copyright Notice:
3 : * Copyright 2021-2022 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 : #define LIBSPDM_DEFAULT_SPDM_VERSION_ENTRY_COUNT SPDM_MAX_VERSION_COUNT
11 :
12 : #pragma pack(1)
13 : typedef struct {
14 : spdm_message_header_t header;
15 : uint8_t reserved;
16 : uint8_t version_number_entry_count;
17 : spdm_version_number_t version_number_entry[LIBSPDM_MAX_VERSION_COUNT];
18 : } libspdm_version_response_mine_t;
19 : #pragma pack()
20 :
21 : spdm_get_version_request_t m_libspdm_get_version_request1 = {
22 : {
23 : SPDM_MESSAGE_VERSION_10,
24 : SPDM_GET_VERSION,
25 : },
26 : };
27 : size_t m_libspdm_get_version_request1_size = sizeof(m_libspdm_get_version_request1);
28 :
29 : spdm_get_version_request_t m_libspdm_get_version_request3 = {
30 : {
31 : SPDM_MESSAGE_VERSION_11,
32 : SPDM_GET_VERSION,
33 : },
34 : };
35 : size_t m_libspdm_get_version_request3_size = sizeof(m_libspdm_get_version_request3);
36 :
37 : spdm_get_version_request_t m_libspdm_get_version_request4 = {
38 : {
39 : SPDM_MESSAGE_VERSION_10,
40 : SPDM_VERSION,
41 : },
42 : };
43 : size_t m_libspdm_get_version_request4_size = sizeof(m_libspdm_get_version_request4);
44 :
45 : /**
46 : * Test 1: receiving a correct GET_VERSION from the requester.
47 : * Expected behavior: the responder accepts the request, produces a valid VERSION
48 : * response message, and then resets the connection state.
49 : **/
50 1 : void libspdm_test_responder_version_case1(void **state)
51 : {
52 : libspdm_return_t status;
53 : libspdm_test_context_t *spdm_test_context;
54 : libspdm_context_t *spdm_context;
55 : size_t response_size;
56 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
57 : spdm_version_response_t *spdm_response;
58 :
59 1 : spdm_test_context = *state;
60 1 : spdm_context = spdm_test_context->spdm_context;
61 1 : spdm_test_context->case_id = 0x1;
62 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NOT_STARTED;
63 :
64 1 : response_size = sizeof(response);
65 1 : status = libspdm_get_response_version(spdm_context,
66 : m_libspdm_get_version_request1_size,
67 : &m_libspdm_get_version_request1,
68 : &response_size, response);
69 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
70 1 : assert_int_equal(response_size,
71 : sizeof(spdm_version_response_t) +
72 : LIBSPDM_DEFAULT_SPDM_VERSION_ENTRY_COUNT *
73 : sizeof(spdm_version_number_t));
74 1 : spdm_response = (void *)response;
75 1 : assert_int_equal(spdm_response->header.request_response_code,
76 : SPDM_VERSION);
77 1 : assert_int_equal(spdm_context->connection_info.connection_state,
78 : LIBSPDM_CONNECTION_STATE_AFTER_VERSION);
79 1 : }
80 :
81 : /**
82 : * Test 2:
83 : * Expected behavior:
84 : **/
85 1 : void libspdm_test_responder_version_case2(void **state)
86 : {
87 1 : }
88 :
89 : /**
90 : * Test 3: receiving a correct GET_VERSION from the requester, but the responder is in
91 : * a Busy state.
92 : * Expected behavior: the responder accepts the request, but produces an ERROR message
93 : * indicating the Buse state.
94 : **/
95 1 : void libspdm_test_responder_version_case3(void **state)
96 : {
97 : libspdm_return_t status;
98 : libspdm_test_context_t *spdm_test_context;
99 : libspdm_context_t *spdm_context;
100 : size_t response_size;
101 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
102 : spdm_version_response_t *spdm_response;
103 :
104 1 : spdm_test_context = *state;
105 1 : spdm_context = spdm_test_context->spdm_context;
106 1 : spdm_test_context->case_id = 0x3;
107 1 : spdm_context->response_state = LIBSPDM_RESPONSE_STATE_BUSY;
108 :
109 1 : response_size = sizeof(response);
110 1 : status = libspdm_get_response_version(spdm_context,
111 : m_libspdm_get_version_request1_size,
112 : &m_libspdm_get_version_request1,
113 : &response_size, response);
114 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
115 1 : assert_int_equal(response_size, sizeof(spdm_error_response_t));
116 1 : spdm_response = (void *)response;
117 1 : assert_int_equal(spdm_response->header.request_response_code,
118 : SPDM_ERROR);
119 1 : assert_int_equal(spdm_response->header.param1, SPDM_ERROR_CODE_BUSY);
120 1 : assert_int_equal(spdm_response->header.param2, 0);
121 1 : assert_int_equal(spdm_context->response_state,
122 : LIBSPDM_RESPONSE_STATE_BUSY);
123 1 : }
124 :
125 : /**
126 : * Test 4: receiving a correct GET_VERSION from the requester, but the responder requires
127 : * resynchronization with the requester.
128 : * Expected behavior: the requester resets the communication upon receiving the GET_VERSION
129 : * message, fulfilling the resynchronization. A valid VERSION message is produced.
130 : **/
131 1 : void libspdm_test_responder_version_case4(void **state)
132 : {
133 : libspdm_return_t status;
134 : libspdm_test_context_t *spdm_test_context;
135 : libspdm_context_t *spdm_context;
136 : size_t response_size;
137 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
138 : spdm_version_response_t *spdm_response;
139 :
140 1 : spdm_test_context = *state;
141 1 : spdm_context = spdm_test_context->spdm_context;
142 1 : spdm_test_context->case_id = 0x4;
143 1 : spdm_context->response_state = LIBSPDM_RESPONSE_STATE_NEED_RESYNC;
144 :
145 1 : response_size = sizeof(response);
146 1 : status = libspdm_get_response_version(spdm_context,
147 : m_libspdm_get_version_request1_size,
148 : &m_libspdm_get_version_request1,
149 : &response_size, response);
150 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
151 1 : assert_int_equal(response_size,
152 : sizeof(spdm_version_response_t) +
153 : LIBSPDM_DEFAULT_SPDM_VERSION_ENTRY_COUNT *
154 : sizeof(spdm_version_number_t));
155 1 : spdm_response = (void *)response;
156 1 : assert_int_equal(spdm_response->header.request_response_code,
157 : SPDM_VERSION);
158 1 : assert_int_equal(spdm_context->response_state,
159 : LIBSPDM_RESPONSE_STATE_NORMAL);
160 1 : }
161 :
162 : /**
163 : * Test 6: receiving a GET_VERSION message in SPDM version 1.1 (in the header), but correct
164 : * 1.0-version format.
165 : * Expected behavior: the responder refuses the GET_VERSION message, produces an
166 : * ERROR message indicating the VersionMismatch, and will not reset the connection state.
167 : **/
168 1 : void libspdm_test_responder_version_case6(void **state)
169 : {
170 : libspdm_return_t status;
171 : libspdm_test_context_t *spdm_test_context;
172 : libspdm_context_t *spdm_context;
173 : size_t response_size;
174 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
175 : spdm_version_response_t *spdm_response;
176 :
177 1 : spdm_test_context = *state;
178 1 : spdm_context = spdm_test_context->spdm_context;
179 1 : spdm_test_context->case_id = 0x6;
180 1 : spdm_context->response_state = LIBSPDM_RESPONSE_STATE_NORMAL;
181 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_AUTHENTICATED;
182 :
183 1 : response_size = sizeof(response);
184 1 : status = libspdm_get_response_version(spdm_context,
185 : m_libspdm_get_version_request3_size,
186 : &m_libspdm_get_version_request3,
187 : &response_size, response);
188 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
189 1 : assert_int_equal(response_size, sizeof(spdm_error_response_t));
190 1 : spdm_response = (void *)response;
191 1 : assert_int_equal(spdm_response->header.spdm_version, SPDM_MESSAGE_VERSION_10);
192 1 : assert_int_equal(spdm_response->header.request_response_code, SPDM_ERROR);
193 1 : assert_int_equal(spdm_response->header.param1, SPDM_ERROR_CODE_VERSION_MISMATCH);
194 1 : assert_int_equal(spdm_response->header.param2, 0);
195 1 : assert_int_equal(spdm_context->connection_info.connection_state,
196 : LIBSPDM_CONNECTION_STATE_AUTHENTICATED);
197 1 : }
198 :
199 : /**
200 : * Test 7: can be populated with new test.
201 : **/
202 1 : void libspdm_test_responder_version_case7(void **state)
203 : {
204 1 : }
205 :
206 : /**
207 : * Test 8: receiving a correct GET_VERSION from the requester. Buffers A, B and C
208 : * already have arbitrary data.
209 : * Expected behavior: the responder accepts the request and produces a valid VERSION
210 : * response message, buffers A, B and C should be first reset, and then buffer A
211 : * receives only the exchanged GET_VERSION and VERSION messages.
212 : **/
213 1 : void libspdm_test_responder_version_case8(void **state)
214 : {
215 : libspdm_return_t status;
216 : libspdm_test_context_t *spdm_test_context;
217 : libspdm_context_t *spdm_context;
218 : size_t response_size;
219 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
220 : spdm_version_response_t *spdm_response;
221 :
222 1 : spdm_test_context = *state;
223 1 : spdm_context = spdm_test_context->spdm_context;
224 1 : spdm_test_context->case_id = 0x8;
225 :
226 : /*filling buffers with arbitrary data*/
227 1 : libspdm_set_mem(spdm_context->transcript.message_a.buffer, 10, (uint8_t) 0xFF);
228 1 : spdm_context->transcript.message_a.buffer_size = 10;
229 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
230 : libspdm_set_mem(spdm_context->transcript.message_b.buffer, 8, (uint8_t) 0xEE);
231 : spdm_context->transcript.message_b.buffer_size = 8;
232 : libspdm_set_mem(spdm_context->transcript.message_c.buffer, 12, (uint8_t) 0xDD);
233 : spdm_context->transcript.message_c.buffer_size = 12;
234 : #endif
235 :
236 1 : response_size = sizeof(response);
237 1 : status = libspdm_get_response_version(
238 : spdm_context, m_libspdm_get_version_request1_size, &m_libspdm_get_version_request1,
239 : &response_size, response);
240 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
241 1 : assert_int_equal(response_size, sizeof(spdm_version_response_t) +
242 : LIBSPDM_DEFAULT_SPDM_VERSION_ENTRY_COUNT * sizeof(spdm_version_number_t));
243 1 : spdm_response = (void *)response;
244 1 : assert_int_equal(spdm_response->header.request_response_code, SPDM_VERSION);
245 :
246 1 : assert_int_equal(spdm_context->transcript.message_a.buffer_size,
247 : m_libspdm_get_version_request1_size + response_size);
248 1 : assert_memory_equal(spdm_context->transcript.message_a.buffer,
249 : &m_libspdm_get_version_request1, m_libspdm_get_version_request1_size);
250 1 : assert_memory_equal(
251 : spdm_context->transcript.message_a.buffer + m_libspdm_get_version_request1_size,
252 : response, response_size);
253 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
254 : assert_int_equal(spdm_context->transcript.message_b.buffer_size, 0);
255 : assert_int_equal(spdm_context->transcript.message_c.buffer_size, 0);
256 : #endif
257 1 : }
258 :
259 1 : int libspdm_responder_version_test_main(void)
260 : {
261 1 : const struct CMUnitTest spdm_responder_version_tests[] = {
262 : cmocka_unit_test(libspdm_test_responder_version_case1),
263 : /* Invalid request*/
264 : cmocka_unit_test(libspdm_test_responder_version_case2),
265 : /* response_state: SPDM_RESPONSE_STATE_BUSY*/
266 : cmocka_unit_test(libspdm_test_responder_version_case3),
267 : /* response_state: SPDM_RESPONSE_STATE_NEED_RESYNC*/
268 : cmocka_unit_test(libspdm_test_responder_version_case4),
269 : /* Invalid request*/
270 : cmocka_unit_test(libspdm_test_responder_version_case6),
271 : /* Invalid request*/
272 : cmocka_unit_test(libspdm_test_responder_version_case7),
273 : /* Buffer verification*/
274 : cmocka_unit_test(libspdm_test_responder_version_case8),
275 : };
276 :
277 1 : libspdm_test_context_t test_context = {
278 : LIBSPDM_TEST_CONTEXT_VERSION,
279 : false,
280 : };
281 :
282 1 : libspdm_setup_test_context(&test_context);
283 :
284 1 : return cmocka_run_group_tests(spdm_responder_version_tests,
285 : libspdm_unit_test_group_setup,
286 : libspdm_unit_test_group_teardown);
287 : }
|