Line data Source code
1 : /**
2 : * Copyright Notice:
3 : * Copyright 2021-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 :
10 : #pragma pack(1)
11 : typedef struct {
12 : spdm_message_header_t header;
13 : uint8_t reserved;
14 : uint8_t version_number_entry_count;
15 : spdm_version_number_t version_number_entry[LIBSPDM_MAX_VERSION_COUNT];
16 : } libspdm_version_response_mine_t;
17 : #pragma pack()
18 :
19 : static size_t m_libspdm_local_buffer_size;
20 : static uint8_t m_libspdm_local_buffer[LIBSPDM_MAX_MESSAGE_VCA_BUFFER_SIZE];
21 :
22 32 : static libspdm_return_t send_message(
23 : void *spdm_context, size_t request_size, const void *request, uint64_t timeout)
24 : {
25 : libspdm_test_context_t *spdm_test_context;
26 :
27 32 : spdm_test_context = libspdm_get_test_context();
28 32 : switch (spdm_test_context->case_id) {
29 1 : case 0x1:
30 1 : return LIBSPDM_STATUS_SEND_FAIL;
31 0 : case 0x2:
32 0 : return LIBSPDM_STATUS_SUCCESS;
33 1 : case 0x3:
34 1 : return LIBSPDM_STATUS_SUCCESS;
35 1 : case 0x4:
36 1 : return LIBSPDM_STATUS_SUCCESS;
37 1 : case 0x5:
38 1 : return LIBSPDM_STATUS_SUCCESS;
39 1 : case 0x6:
40 1 : return LIBSPDM_STATUS_SUCCESS;
41 1 : case 0x7:
42 1 : return LIBSPDM_STATUS_SUCCESS;
43 1 : case 0x8:
44 1 : return LIBSPDM_STATUS_SUCCESS;
45 1 : case 0x9:
46 1 : return LIBSPDM_STATUS_SUCCESS;
47 1 : case 0xA:
48 1 : return LIBSPDM_STATUS_SUCCESS;
49 1 : case 0xB:
50 1 : return LIBSPDM_STATUS_SUCCESS;
51 1 : case 0xC:
52 1 : return LIBSPDM_STATUS_SUCCESS;
53 1 : case 0xD:
54 1 : return LIBSPDM_STATUS_SUCCESS;
55 18 : case 0xE:
56 18 : return LIBSPDM_STATUS_SUCCESS;
57 0 : case 0xF:
58 0 : return LIBSPDM_STATUS_SUCCESS;
59 0 : case 0x10: {
60 0 : const uint8_t *ptr = (const uint8_t *)request;
61 :
62 0 : m_libspdm_local_buffer_size = 0;
63 0 : libspdm_copy_mem(m_libspdm_local_buffer, sizeof(m_libspdm_local_buffer),
64 0 : &ptr[1], request_size - 1);
65 0 : m_libspdm_local_buffer_size += (request_size - 1);
66 : }
67 0 : return LIBSPDM_STATUS_SUCCESS;
68 1 : case 0x11:
69 1 : return LIBSPDM_STATUS_SUCCESS;
70 1 : case 0x12:
71 1 : return LIBSPDM_STATUS_SUCCESS;
72 0 : default:
73 0 : return LIBSPDM_STATUS_SEND_FAIL;
74 : }
75 : }
76 :
77 30 : static libspdm_return_t receive_message(
78 : void *spdm_context, size_t *response_size, void **response, uint64_t timeout)
79 : {
80 : libspdm_test_context_t *spdm_test_context;
81 :
82 30 : spdm_test_context = libspdm_get_test_context();
83 30 : switch (spdm_test_context->case_id) {
84 0 : case 0x1:
85 0 : return LIBSPDM_STATUS_RECEIVE_FAIL;
86 :
87 0 : case 0x2:
88 0 : return LIBSPDM_STATUS_SUCCESS;
89 :
90 1 : case 0x3: {
91 : spdm_version_response_t *spdm_response;
92 : size_t spdm_response_size;
93 : size_t transport_header_size;
94 :
95 1 : spdm_response_size = sizeof(spdm_version_response_t);
96 1 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
97 1 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
98 :
99 1 : libspdm_zero_mem(spdm_response, spdm_response_size);
100 1 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_10;
101 1 : spdm_response->header.request_response_code = SPDM_VERSION;
102 1 : spdm_response->header.param1 = 0;
103 1 : spdm_response->header.param2 = 0;
104 1 : spdm_response->version_number_entry_count = 0;
105 :
106 1 : libspdm_transport_test_encode_message(spdm_context, NULL, false,
107 : false, spdm_response_size,
108 : spdm_response,
109 : response_size, response);
110 : }
111 1 : return LIBSPDM_STATUS_SUCCESS;
112 :
113 1 : case 0x4: {
114 : spdm_error_response_t *spdm_response;
115 : size_t spdm_response_size;
116 : size_t transport_header_size;
117 :
118 1 : spdm_response_size = sizeof(spdm_error_response_t);
119 1 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
120 1 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
121 :
122 1 : libspdm_zero_mem(spdm_response, spdm_response_size);
123 1 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_10;
124 1 : spdm_response->header.request_response_code = SPDM_ERROR;
125 1 : spdm_response->header.param1 = SPDM_ERROR_CODE_INVALID_REQUEST;
126 1 : spdm_response->header.param2 = 0;
127 :
128 1 : libspdm_transport_test_encode_message(spdm_context, NULL, false,
129 : false, spdm_response_size,
130 : spdm_response,
131 : response_size, response);
132 : }
133 1 : return LIBSPDM_STATUS_SUCCESS;
134 :
135 1 : case 0x5: {
136 : spdm_error_response_t *spdm_response;
137 : size_t spdm_response_size;
138 : size_t transport_header_size;
139 :
140 1 : spdm_response_size = sizeof(spdm_error_response_t);
141 1 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
142 1 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
143 :
144 1 : libspdm_zero_mem(spdm_response, spdm_response_size);
145 1 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_10;
146 1 : spdm_response->header.request_response_code = SPDM_ERROR;
147 1 : spdm_response->header.param1 = SPDM_ERROR_CODE_BUSY;
148 1 : spdm_response->header.param2 = 0;
149 :
150 1 : libspdm_transport_test_encode_message(spdm_context, NULL, false,
151 : false, spdm_response_size,
152 : spdm_response,
153 : response_size, response);
154 : }
155 1 : return LIBSPDM_STATUS_SUCCESS;
156 :
157 0 : case 0x6: {
158 : static size_t sub_index1 = 0;
159 0 : if (sub_index1 == 0) {
160 : spdm_error_response_t *spdm_response;
161 : size_t spdm_response_size;
162 : size_t transport_header_size;
163 :
164 0 : spdm_response_size = sizeof(spdm_error_response_t);
165 0 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
166 0 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
167 :
168 0 : libspdm_zero_mem(spdm_response, spdm_response_size);
169 0 : spdm_response->header.spdm_version =
170 : SPDM_MESSAGE_VERSION_10;
171 0 : spdm_response->header.request_response_code = SPDM_ERROR;
172 0 : spdm_response->header.param1 = SPDM_ERROR_CODE_BUSY;
173 0 : spdm_response->header.param2 = 0;
174 :
175 0 : libspdm_transport_test_encode_message(
176 : spdm_context, NULL, false, false,
177 : spdm_response_size, spdm_response,
178 : response_size, response);
179 0 : } else if (sub_index1 == 1) {
180 : libspdm_version_response_mine_t *spdm_response;
181 : size_t spdm_response_size;
182 : size_t transport_header_size;
183 :
184 0 : spdm_response_size = sizeof(libspdm_version_response_mine_t);
185 0 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
186 0 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
187 :
188 0 : libspdm_zero_mem(spdm_response, spdm_response_size);
189 0 : spdm_response->header.spdm_version =
190 : SPDM_MESSAGE_VERSION_10;
191 0 : spdm_response->header.request_response_code =
192 : SPDM_VERSION;
193 0 : spdm_response->header.param1 = 0;
194 0 : spdm_response->header.param2 = 0;
195 0 : spdm_response->version_number_entry_count = 2;
196 0 : spdm_response->version_number_entry[0] = 0x10 << SPDM_VERSION_NUMBER_SHIFT_BIT;
197 0 : spdm_response->version_number_entry[1] = 0x11 << SPDM_VERSION_NUMBER_SHIFT_BIT;
198 :
199 0 : libspdm_transport_test_encode_message(
200 : spdm_context, NULL, false, false,
201 : spdm_response_size, spdm_response,
202 : response_size, response);
203 : }
204 0 : sub_index1++;
205 : }
206 0 : return LIBSPDM_STATUS_SUCCESS;
207 :
208 1 : case 0x7: {
209 : spdm_error_response_t *spdm_response;
210 : size_t spdm_response_size;
211 : size_t transport_header_size;
212 :
213 1 : spdm_response_size = sizeof(spdm_error_response_t);
214 1 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
215 1 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
216 :
217 1 : libspdm_zero_mem(spdm_response, spdm_response_size);
218 1 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_10;
219 1 : spdm_response->header.request_response_code = SPDM_ERROR;
220 1 : spdm_response->header.param1 = SPDM_ERROR_CODE_REQUEST_RESYNCH;
221 1 : spdm_response->header.param2 = 0;
222 :
223 1 : libspdm_transport_test_encode_message(spdm_context, NULL, false,
224 : false, spdm_response_size,
225 : spdm_response,
226 : response_size, response);
227 : }
228 1 : return LIBSPDM_STATUS_SUCCESS;
229 :
230 1 : case 0x8: {
231 : spdm_error_response_data_response_not_ready_t *spdm_response;
232 : size_t spdm_response_size;
233 : size_t transport_header_size;
234 :
235 1 : spdm_response_size = sizeof(spdm_error_response_data_response_not_ready_t);
236 1 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
237 1 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
238 :
239 1 : libspdm_zero_mem(spdm_response, spdm_response_size);
240 1 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_10;
241 1 : spdm_response->header.request_response_code = SPDM_ERROR;
242 1 : spdm_response->header.param1 =
243 : SPDM_ERROR_CODE_RESPONSE_NOT_READY;
244 1 : spdm_response->header.param2 = 0;
245 1 : spdm_response->extend_error_data.rd_exponent = 1;
246 1 : spdm_response->extend_error_data.rd_tm = 2;
247 1 : spdm_response->extend_error_data.request_code = SPDM_GET_VERSION;
248 1 : spdm_response->extend_error_data.token = 0;
249 :
250 1 : libspdm_transport_test_encode_message(spdm_context, NULL, false,
251 : false, spdm_response_size,
252 : spdm_response,
253 : response_size, response);
254 : }
255 1 : return LIBSPDM_STATUS_SUCCESS;
256 :
257 1 : case 0x9: {
258 : libspdm_version_response_mine_t *spdm_response;
259 : size_t spdm_response_size;
260 : size_t transport_header_size;
261 :
262 1 : spdm_response_size = sizeof(libspdm_version_response_mine_t);
263 1 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
264 1 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
265 :
266 1 : libspdm_zero_mem(spdm_response, spdm_response_size);
267 1 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_10;
268 1 : spdm_response->header.request_response_code = SPDM_VERSION;
269 1 : spdm_response->header.param1 = 0;
270 1 : spdm_response->header.param2 = 0;
271 1 : spdm_response->version_number_entry_count = 255;
272 1 : spdm_response->version_number_entry[0] = 0x10 << SPDM_VERSION_NUMBER_SHIFT_BIT;
273 1 : spdm_response->version_number_entry[1] = 0x11 << SPDM_VERSION_NUMBER_SHIFT_BIT;
274 1 : spdm_response->version_number_entry[2] = 0x12 << SPDM_VERSION_NUMBER_SHIFT_BIT;
275 :
276 1 : libspdm_transport_test_encode_message(spdm_context, NULL, false,
277 : false, spdm_response_size,
278 : spdm_response,
279 : response_size, response);
280 : }
281 1 : return LIBSPDM_STATUS_SUCCESS;
282 :
283 1 : case 0xA:
284 1 : return LIBSPDM_STATUS_RECEIVE_FAIL;
285 :
286 1 : case 0xB: {
287 : libspdm_version_response_mine_t *spdm_response;
288 : size_t spdm_response_size;
289 : size_t transport_header_size;
290 :
291 1 : spdm_response_size = sizeof(libspdm_version_response_mine_t);
292 1 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
293 1 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
294 :
295 1 : libspdm_zero_mem(spdm_response, spdm_response_size);
296 1 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_10;
297 1 : spdm_response->header.request_response_code = SPDM_VERSION;
298 1 : spdm_response->header.param1 = 0;
299 1 : spdm_response->header.param2 = 0;
300 1 : spdm_response->version_number_entry_count = 2;
301 1 : spdm_response->version_number_entry[0] = 0xA0 << SPDM_VERSION_NUMBER_SHIFT_BIT;
302 1 : spdm_response->version_number_entry[1] = 0xA1 << SPDM_VERSION_NUMBER_SHIFT_BIT;
303 :
304 1 : libspdm_transport_test_encode_message(spdm_context, NULL, false,
305 : false, spdm_response_size,
306 : spdm_response,
307 : response_size, response);
308 : }
309 1 : return LIBSPDM_STATUS_SUCCESS;
310 :
311 1 : case 0xC: {
312 : libspdm_version_response_mine_t *spdm_response;
313 : size_t spdm_response_size;
314 : size_t transport_header_size;
315 :
316 1 : spdm_response_size = sizeof(libspdm_version_response_mine_t);
317 1 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
318 1 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
319 :
320 1 : libspdm_zero_mem(spdm_response, spdm_response_size);
321 1 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_11;
322 1 : spdm_response->header.request_response_code = SPDM_VERSION;
323 1 : spdm_response->header.param1 = 0;
324 1 : spdm_response->header.param2 = 0;
325 1 : spdm_response->version_number_entry_count = 2;
326 1 : spdm_response->version_number_entry[0] = 0x10 << SPDM_VERSION_NUMBER_SHIFT_BIT;
327 1 : spdm_response->version_number_entry[1] = 0x11 << SPDM_VERSION_NUMBER_SHIFT_BIT;
328 :
329 1 : libspdm_transport_test_encode_message(spdm_context, NULL, false,
330 : false, spdm_response_size,
331 : spdm_response,
332 : response_size, response);
333 : }
334 1 : return LIBSPDM_STATUS_SUCCESS;
335 :
336 1 : case 0xD: {
337 : libspdm_version_response_mine_t *spdm_response;
338 : size_t spdm_response_size;
339 : size_t transport_header_size;
340 :
341 1 : spdm_response_size = sizeof(libspdm_version_response_mine_t);
342 1 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
343 1 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
344 :
345 1 : libspdm_zero_mem(spdm_response, spdm_response_size);
346 1 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_10;
347 1 : spdm_response->header.request_response_code = SPDM_GET_VERSION;
348 1 : spdm_response->header.param1 = 0;
349 1 : spdm_response->header.param2 = 0;
350 1 : spdm_response->version_number_entry_count = 2;
351 1 : spdm_response->version_number_entry[0] = 0x10 << SPDM_VERSION_NUMBER_SHIFT_BIT;
352 1 : spdm_response->version_number_entry[1] = 0x11 << SPDM_VERSION_NUMBER_SHIFT_BIT;
353 :
354 1 : libspdm_transport_test_encode_message(spdm_context, NULL, false,
355 : false, spdm_response_size,
356 : spdm_response,
357 : response_size, response);
358 : }
359 1 : return LIBSPDM_STATUS_SUCCESS;
360 :
361 18 : case 0xE:
362 : {
363 : static uint16_t error_code = LIBSPDM_ERROR_CODE_RESERVED_00;
364 :
365 : spdm_error_response_t *spdm_response;
366 : size_t spdm_response_size;
367 : size_t transport_header_size;
368 :
369 18 : spdm_response_size = sizeof(libspdm_version_response_mine_t);
370 18 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
371 18 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
372 :
373 18 : if(error_code <= 0xff) {
374 18 : libspdm_zero_mem (spdm_response, spdm_response_size);
375 18 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_10;
376 18 : spdm_response->header.request_response_code = SPDM_ERROR;
377 18 : spdm_response->header.param1 = (uint8_t) error_code;
378 :
379 18 : libspdm_transport_test_encode_message (spdm_context, NULL, false, false,
380 : spdm_response_size, spdm_response,
381 : response_size, response);
382 : }
383 :
384 18 : error_code++;
385 18 : if(error_code == SPDM_ERROR_CODE_BUSY) { /*busy is treated in cases 5 and 6*/
386 1 : error_code = SPDM_ERROR_CODE_UNEXPECTED_REQUEST;
387 : }
388 18 : if(error_code == LIBSPDM_ERROR_CODE_RESERVED_0D) { /*skip some reserved error codes (0d to 3e)*/
389 1 : error_code = LIBSPDM_ERROR_CODE_RESERVED_3F;
390 : }
391 18 : if(error_code == SPDM_ERROR_CODE_RESPONSE_NOT_READY) { /*skip response not ready, request resync, and some reserved codes (44 to fc)*/
392 1 : error_code = LIBSPDM_ERROR_CODE_RESERVED_FD;
393 : }
394 : }
395 18 : return LIBSPDM_STATUS_SUCCESS;
396 :
397 0 : case 0xF: {
398 : libspdm_version_response_mine_t *spdm_response;
399 : size_t spdm_response_size;
400 : size_t transport_header_size;
401 :
402 0 : spdm_response_size = sizeof(libspdm_version_response_mine_t);
403 0 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
404 0 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
405 :
406 0 : libspdm_zero_mem(spdm_response, spdm_response_size);
407 0 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_10;
408 0 : spdm_response->header.request_response_code = SPDM_VERSION;
409 0 : spdm_response->header.param1 = 0;
410 0 : spdm_response->header.param2 = 0;
411 0 : spdm_response->version_number_entry_count = 5;
412 0 : spdm_response->version_number_entry[0] = 0x42 << SPDM_VERSION_NUMBER_SHIFT_BIT;
413 0 : spdm_response->version_number_entry[1] = 0x52 << SPDM_VERSION_NUMBER_SHIFT_BIT;
414 0 : spdm_response->version_number_entry[2] = 0x12 << SPDM_VERSION_NUMBER_SHIFT_BIT;
415 0 : spdm_response->version_number_entry[3] = 0x11 << SPDM_VERSION_NUMBER_SHIFT_BIT;
416 0 : spdm_response->version_number_entry[4] = 0x10 << SPDM_VERSION_NUMBER_SHIFT_BIT;
417 :
418 0 : libspdm_transport_test_encode_message(spdm_context, NULL, false,
419 : false, spdm_response_size,
420 : spdm_response,
421 : response_size, response);
422 : }
423 0 : return LIBSPDM_STATUS_SUCCESS;
424 :
425 0 : case 0x10: {
426 : libspdm_version_response_mine_t *spdm_response;
427 : size_t spdm_response_size;
428 : size_t transport_header_size;
429 :
430 0 : spdm_response_size = sizeof(libspdm_version_response_mine_t);
431 0 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
432 0 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
433 :
434 0 : libspdm_zero_mem(spdm_response, spdm_response_size);
435 0 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_10;
436 0 : spdm_response->header.request_response_code = SPDM_VERSION;
437 0 : spdm_response->header.param1 = 0;
438 0 : spdm_response->header.param2 = 0;
439 0 : spdm_response->version_number_entry_count = 2;
440 0 : spdm_response->version_number_entry[0] = 0x10 << SPDM_VERSION_NUMBER_SHIFT_BIT;
441 0 : spdm_response->version_number_entry[1] = 0x11 << SPDM_VERSION_NUMBER_SHIFT_BIT;
442 :
443 0 : spdm_response_size = 10;
444 :
445 0 : libspdm_copy_mem(&m_libspdm_local_buffer[m_libspdm_local_buffer_size],
446 : sizeof(m_libspdm_local_buffer) - m_libspdm_local_buffer_size,
447 : (uint8_t *)spdm_response, spdm_response_size);
448 0 : m_libspdm_local_buffer_size += spdm_response_size;
449 :
450 0 : libspdm_transport_test_encode_message(spdm_context, NULL, false,
451 : false, spdm_response_size,
452 : spdm_response,
453 : response_size, response);
454 : }
455 0 : return LIBSPDM_STATUS_SUCCESS;
456 :
457 1 : case 0x11: {
458 : spdm_message_header_t *spdm_response;
459 : size_t spdm_response_size;
460 : size_t transport_header_size;
461 :
462 1 : spdm_response_size = sizeof(spdm_message_header_t);
463 1 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
464 1 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
465 :
466 1 : libspdm_zero_mem(spdm_response, spdm_response_size);
467 1 : spdm_response->spdm_version = SPDM_MESSAGE_VERSION_10;
468 1 : spdm_response->request_response_code = SPDM_VERSION;
469 1 : spdm_response->param1 = 0;
470 1 : spdm_response->param2 = 0;
471 :
472 1 : libspdm_transport_test_encode_message(spdm_context, NULL, false,
473 : false, spdm_response_size,
474 : spdm_response,
475 : response_size, response);
476 :
477 : }
478 1 : return LIBSPDM_STATUS_SUCCESS;
479 :
480 1 : case 0x12: {
481 : spdm_version_response_t *spdm_response;
482 : size_t spdm_response_size;
483 : size_t transport_header_size;
484 :
485 1 : spdm_response_size = sizeof(spdm_version_response_t);
486 1 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
487 1 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
488 :
489 1 : libspdm_zero_mem(spdm_response, spdm_response_size);
490 1 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_10;
491 1 : spdm_response->header.request_response_code = SPDM_VERSION;
492 1 : spdm_response->header.param1 = 0;
493 1 : spdm_response->header.param2 = 0;
494 1 : spdm_response->version_number_entry_count = LIBSPDM_MAX_VERSION_COUNT;
495 :
496 1 : libspdm_transport_test_encode_message(spdm_context, NULL, false,
497 : false, spdm_response_size,
498 : spdm_response,
499 : response_size, response);
500 :
501 : }
502 1 : return LIBSPDM_STATUS_SUCCESS;
503 :
504 0 : default:
505 0 : return LIBSPDM_STATUS_RECEIVE_FAIL;
506 : }
507 : }
508 :
509 : /**
510 : * Test 1: Unable to send the GET_VERSION request.
511 : * Expected behavior: returns a status of LIBSPDM_STATUS_SEND_FAIL.
512 : **/
513 1 : static void libspdm_test_requester_get_version_err_case1(void **state)
514 : {
515 : libspdm_return_t status;
516 : libspdm_test_context_t *spdm_test_context;
517 : libspdm_context_t *spdm_context;
518 :
519 1 : spdm_test_context = *state;
520 1 : spdm_context = spdm_test_context->spdm_context;
521 1 : spdm_test_context->case_id = 0x1;
522 :
523 1 : status = libspdm_get_version(spdm_context, NULL, NULL);
524 1 : assert_int_equal(status, LIBSPDM_STATUS_SEND_FAIL);
525 1 : }
526 :
527 : /**
528 : * Test 2: Requester is unable to acquire the sender buffer.
529 : * Expected behavior: returns with status LIBSPDM_STATUS_ACQUIRE_FAIL.
530 : **/
531 1 : static void libspdm_test_requester_get_version_err_case2(void **state)
532 : {
533 : libspdm_return_t status;
534 : libspdm_test_context_t *spdm_test_context;
535 : libspdm_context_t *spdm_context;
536 :
537 1 : spdm_test_context = *state;
538 1 : spdm_context = spdm_test_context->spdm_context;
539 1 : spdm_test_context->case_id = 0x2;
540 :
541 1 : libspdm_force_error (LIBSPDM_ERR_ACQUIRE_SENDER_BUFFER);
542 1 : status = libspdm_get_version(spdm_context, NULL, NULL);
543 1 : libspdm_release_error (LIBSPDM_ERR_ACQUIRE_SENDER_BUFFER);
544 :
545 1 : assert_int_equal(status, LIBSPDM_STATUS_ACQUIRE_FAIL);
546 1 : }
547 :
548 : /**
549 : * Test 3: receiving a correct VERSION message header, but with 0 versions available.
550 : * Expected behavior: client returns a status of LIBSPDM_STATUS_INVALID_MSG_FIELD.
551 : **/
552 1 : static void libspdm_test_requester_get_version_err_case3(void **state)
553 : {
554 : libspdm_return_t status;
555 : libspdm_test_context_t *spdm_test_context;
556 : libspdm_context_t *spdm_context;
557 :
558 1 : spdm_test_context = *state;
559 1 : spdm_context = spdm_test_context->spdm_context;
560 1 : spdm_test_context->case_id = 0x3;
561 :
562 1 : status = libspdm_get_version(spdm_context, NULL, NULL);
563 1 : assert_int_equal(status, LIBSPDM_STATUS_INVALID_MSG_FIELD);
564 1 : }
565 :
566 : /**
567 : * Test 4: receiving an InvalidRequest ERROR message from the responder.
568 : * Expected behavior: client returns a status of LIBSPDM_STATUS_ERROR_PEER.
569 : **/
570 1 : static void libspdm_test_requester_get_version_err_case4(void **state)
571 : {
572 : libspdm_return_t status;
573 : libspdm_test_context_t *spdm_test_context;
574 : libspdm_context_t *spdm_context;
575 :
576 1 : spdm_test_context = *state;
577 1 : spdm_context = spdm_test_context->spdm_context;
578 1 : spdm_test_context->case_id = 0x4;
579 :
580 1 : status = libspdm_get_version(spdm_context, NULL, NULL);
581 1 : assert_int_equal(status, LIBSPDM_STATUS_ERROR_PEER);
582 1 : }
583 :
584 : /**
585 : * Test 5: receiving a Busy ERROR message correct VERSION message from the responder.
586 : * Expected behavior: client returns a status of LIBSPDM_STATUS_BUSY_PEER.
587 : **/
588 1 : static void libspdm_test_requester_get_version_err_case5(void **state)
589 : {
590 : libspdm_return_t status;
591 : libspdm_test_context_t *spdm_test_context;
592 : libspdm_context_t *spdm_context;
593 :
594 1 : spdm_test_context = *state;
595 1 : spdm_context = spdm_test_context->spdm_context;
596 1 : spdm_test_context->case_id = 0x5;
597 :
598 1 : status = libspdm_get_version(spdm_context, NULL, NULL);
599 1 : assert_int_equal(status, LIBSPDM_STATUS_BUSY_PEER);
600 1 : }
601 :
602 : /**
603 : * Test 6: Requester is unable to acquire the receiver buffer.
604 : * Expected behavior: returns with status LIBSPDM_STATUS_ACQUIRE_FAIL.
605 : **/
606 1 : static void libspdm_test_requester_get_version_err_case6(void **state)
607 : {
608 : libspdm_return_t status;
609 : libspdm_test_context_t *spdm_test_context;
610 : libspdm_context_t *spdm_context;
611 :
612 1 : spdm_test_context = *state;
613 1 : spdm_context = spdm_test_context->spdm_context;
614 1 : spdm_test_context->case_id = 0x6;
615 :
616 1 : libspdm_force_error (LIBSPDM_ERR_ACQUIRE_RECEIVER_BUFFER);
617 1 : status = libspdm_get_version(spdm_context, NULL, NULL);
618 1 : libspdm_release_error (LIBSPDM_ERR_ACQUIRE_RECEIVER_BUFFER);
619 :
620 1 : assert_int_equal(status, LIBSPDM_STATUS_ACQUIRE_FAIL);
621 1 : }
622 :
623 : /**
624 : * Test 7: receiving a RequestResynch ERROR message from the responder.
625 : * Expected behavior: client returns a status of LIBSPDM_STATUS_RESYNCH_PEER, and the
626 : * internal state should be reset.
627 : **/
628 1 : static void libspdm_test_requester_get_version_err_case7(void **state)
629 : {
630 : libspdm_return_t status;
631 : libspdm_test_context_t *spdm_test_context;
632 : libspdm_context_t *spdm_context;
633 :
634 1 : spdm_test_context = *state;
635 1 : spdm_context = spdm_test_context->spdm_context;
636 1 : spdm_test_context->case_id = 0x7;
637 :
638 1 : status = libspdm_get_version(spdm_context, NULL, NULL);
639 1 : assert_int_equal(status, LIBSPDM_STATUS_RESYNCH_PEER);
640 1 : assert_int_equal(spdm_context->connection_info.connection_state,
641 : LIBSPDM_CONNECTION_STATE_NOT_STARTED);
642 1 : }
643 :
644 : /**
645 : * Test 8: receiving a ResponseNotReady ERROR message from the responder,
646 : * but Responder shall not respond to the GET_VERSION request message with ErrorCode=ResponseNotReady.
647 : * Expected behavior: client returns a status of LIBSPDM_STATUS_ERROR_PEER,
648 : * Received an unexpected error message.
649 : **/
650 1 : static void libspdm_test_requester_get_version_err_case8(void **state)
651 : {
652 : libspdm_return_t status;
653 : libspdm_test_context_t *spdm_test_context;
654 : libspdm_context_t *spdm_context;
655 :
656 1 : spdm_test_context = *state;
657 1 : spdm_context = spdm_test_context->spdm_context;
658 1 : spdm_test_context->case_id = 0x8;
659 :
660 1 : status = libspdm_get_version(spdm_context, NULL, NULL);
661 1 : assert_int_equal(status, LIBSPDM_STATUS_ERROR_PEER);
662 1 : }
663 :
664 : /**
665 : * Test 9: Number of version entries are larger than what the Requester can tolerate.
666 : * Expected behavior: returns a status of LIBSPDM_STATUS_INVALID_MSG_FIELD.
667 : **/
668 1 : static void libspdm_test_requester_get_version_err_case9(void **state)
669 : {
670 : libspdm_return_t status;
671 : libspdm_test_context_t *spdm_test_context;
672 : libspdm_context_t *spdm_context;
673 :
674 : LIBSPDM_ASSERT(LIBSPDM_MAX_VERSION_COUNT != 255);
675 :
676 1 : spdm_test_context = *state;
677 1 : spdm_context = spdm_test_context->spdm_context;
678 1 : spdm_test_context->case_id = 0x9;
679 :
680 1 : status = libspdm_get_version(spdm_context, NULL, NULL);
681 1 : assert_int_equal(status, LIBSPDM_STATUS_INVALID_MSG_FIELD);
682 1 : }
683 :
684 : /**
685 : * Test 10: Requester is unable to receive a VERSION response from the Responder.
686 : * Expected behavior: returns a status of LIBSPDM_STATUS_RECEIVE_FAIL.
687 : **/
688 1 : static void libspdm_test_requester_get_version_err_case10(void **state)
689 : {
690 : libspdm_return_t status;
691 : libspdm_test_context_t *spdm_test_context;
692 : libspdm_context_t *spdm_context;
693 :
694 1 : spdm_test_context = *state;
695 1 : spdm_context = spdm_test_context->spdm_context;
696 1 : spdm_test_context->case_id = 0xa;
697 :
698 1 : status = libspdm_get_version(spdm_context, NULL, NULL);
699 1 : assert_int_equal(status, LIBSPDM_STATUS_RECEIVE_FAIL);
700 1 : }
701 :
702 : /**
703 : * Test 11: receiving a correct VERSION message with available version 1.0 and 1.1, but
704 : * the requester do not have compatible versions with the responder.
705 : * Expected behavior: client returns a status of LIBSPDM_STATUS_NEGOTIATION_FAIL.
706 : **/
707 1 : static void libspdm_test_requester_get_version_err_case11(void **state)
708 : {
709 : libspdm_return_t status;
710 : libspdm_test_context_t *spdm_test_context;
711 : libspdm_context_t *spdm_context;
712 :
713 1 : spdm_test_context = *state;
714 1 : spdm_context = spdm_test_context->spdm_context;
715 1 : spdm_test_context->case_id = 0xB;
716 :
717 1 : status = libspdm_get_version(spdm_context, NULL, NULL);
718 1 : assert_int_equal(status, LIBSPDM_STATUS_NEGOTIATION_FAIL);
719 1 : }
720 :
721 : /**
722 : * Test 12: receiving a VERSION message in SPDM version 1.1 (in the header), but correct
723 : * 1.0-version format, with available version 1.0 and 1.1.
724 : * Expected behavior: client returns a status of LIBSPDM_STATUS_INVALID_MSG_FIELD.
725 : **/
726 1 : static void libspdm_test_requester_get_version_err_case12(void **state)
727 : {
728 : libspdm_return_t status;
729 : libspdm_test_context_t *spdm_test_context;
730 : libspdm_context_t *spdm_context;
731 :
732 1 : spdm_test_context = *state;
733 1 : spdm_context = spdm_test_context->spdm_context;
734 1 : spdm_test_context->case_id = 0xC;
735 :
736 1 : status = libspdm_get_version(spdm_context, NULL, NULL);
737 1 : assert_int_equal(status, LIBSPDM_STATUS_INVALID_MSG_FIELD);
738 1 : }
739 :
740 : /**
741 : * Test 13: receiving a VERSION message with wrong SPDM request_response_code (in this
742 : * case, GET_VERSION 0x84 instead of VERSION 0x04). The remaining data is a correct
743 : * VERSION message, with available version 1.0 and 1.1.
744 : * Expected behavior: client returns a status of LIBSPDM_STATUS_INVALID_MSG_FIELD.
745 : **/
746 1 : static void libspdm_test_requester_get_version_err_case13(void **state)
747 : {
748 : libspdm_return_t status;
749 : libspdm_test_context_t *spdm_test_context;
750 : libspdm_context_t *spdm_context;
751 :
752 1 : spdm_test_context = *state;
753 1 : spdm_context = spdm_test_context->spdm_context;
754 1 : spdm_test_context->case_id = 0xD;
755 :
756 1 : status = libspdm_get_version(spdm_context, NULL, NULL);
757 1 : assert_int_equal(status, LIBSPDM_STATUS_INVALID_MSG_FIELD);
758 1 : }
759 :
760 : /**
761 : * Test 14: receiving an unexpected ERROR message from the responder.
762 : * There are tests for all named codes, including some reserved ones
763 : * (namely, 0x00, 0x0b, 0x0c, 0x3f, 0xfd, 0xfe).
764 : * However, for having specific test cases, it is excluded from this case:
765 : * Busy (0x03), ResponseNotReady (0x42), and RequestResync (0x43).
766 : * Expected behavior: client returns a status of LIBSPDM_STATUS_ERROR_PEER.
767 : **/
768 1 : static void libspdm_test_requester_get_version_err_case14(void **state) {
769 : libspdm_return_t status;
770 : libspdm_test_context_t *spdm_test_context;
771 : libspdm_context_t *spdm_context;
772 : uint16_t error_code;
773 :
774 1 : spdm_test_context = *state;
775 1 : spdm_context = spdm_test_context->spdm_context;
776 1 : spdm_test_context->case_id = 0xE;
777 :
778 1 : error_code = LIBSPDM_ERROR_CODE_RESERVED_00;
779 19 : while(error_code <= 0xff) {
780 : /* no additional state control is necessary as a new GET_VERSION resets the state*/
781 18 : status = libspdm_get_version (spdm_context, NULL, NULL);
782 18 : LIBSPDM_ASSERT_INT_EQUAL_CASE (status, LIBSPDM_STATUS_ERROR_PEER, error_code);
783 :
784 18 : error_code++;
785 18 : if(error_code == SPDM_ERROR_CODE_BUSY) { /*busy is treated in cases 5 and 6*/
786 1 : error_code = SPDM_ERROR_CODE_UNEXPECTED_REQUEST;
787 : }
788 18 : if(error_code == LIBSPDM_ERROR_CODE_RESERVED_0D) { /*skip some reserved error codes (0d to 3e)*/
789 1 : error_code = LIBSPDM_ERROR_CODE_RESERVED_3F;
790 : }
791 18 : if(error_code == SPDM_ERROR_CODE_RESPONSE_NOT_READY) { /*skip response not ready, request resync, and some reserved codes (44 to fc)*/
792 1 : error_code = LIBSPDM_ERROR_CODE_RESERVED_FD;
793 : }
794 : }
795 1 : }
796 :
797 : /*
798 : * static void libspdm_test_requester_get_version_err_case15(void **state)
799 : * {
800 : * }
801 : */
802 :
803 : /*
804 : * static void libspdm_test_requester_get_version_err_case16(void **state)
805 : * {
806 : * }
807 : */
808 :
809 : /**
810 : * Test 17: when no VERSION message is received, and the client returns a device error.
811 : * Expected behavior: client returns a status of LIBSPDM_STATUS_INVALID_MSG_FIELD.
812 : **/
813 1 : static void libspdm_test_requester_get_version_err_case17(void **state)
814 : {
815 : libspdm_return_t status;
816 : libspdm_test_context_t *spdm_test_context;
817 : libspdm_context_t *spdm_context;
818 :
819 1 : spdm_test_context = *state;
820 1 : spdm_context = spdm_test_context->spdm_context;
821 1 : spdm_test_context->case_id = 0x11;
822 :
823 1 : status = libspdm_get_version(spdm_context, NULL, NULL);
824 1 : assert_int_equal(status, LIBSPDM_STATUS_INVALID_MSG_SIZE);
825 1 : }
826 :
827 : /**
828 : * Test 18: when no VERSION message is received, and the client returns a device error.
829 : * Expected behavior: client returns a status of LIBSPDM_STATUS_INVALID_MSG_FIELD.
830 : **/
831 1 : static void libspdm_test_requester_get_version_err_case18(void **state)
832 : {
833 : libspdm_return_t status;
834 : libspdm_test_context_t *spdm_test_context;
835 : libspdm_context_t *spdm_context;
836 :
837 1 : spdm_test_context = *state;
838 1 : spdm_context = spdm_test_context->spdm_context;
839 1 : spdm_test_context->case_id = 0x12;
840 :
841 1 : status = libspdm_get_version(spdm_context, NULL, NULL);
842 1 : assert_int_equal(status, LIBSPDM_STATUS_INVALID_MSG_SIZE);
843 1 : }
844 :
845 1 : int libspdm_req_get_version_error_test(void)
846 : {
847 1 : const struct CMUnitTest test_cases[] = {
848 : cmocka_unit_test(libspdm_test_requester_get_version_err_case1),
849 : cmocka_unit_test(libspdm_test_requester_get_version_err_case2),
850 : cmocka_unit_test(libspdm_test_requester_get_version_err_case3),
851 : cmocka_unit_test(libspdm_test_requester_get_version_err_case4),
852 : cmocka_unit_test(libspdm_test_requester_get_version_err_case5),
853 : cmocka_unit_test(libspdm_test_requester_get_version_err_case6),
854 : cmocka_unit_test(libspdm_test_requester_get_version_err_case7),
855 : cmocka_unit_test(libspdm_test_requester_get_version_err_case8),
856 : cmocka_unit_test(libspdm_test_requester_get_version_err_case9),
857 : cmocka_unit_test(libspdm_test_requester_get_version_err_case10),
858 : cmocka_unit_test(libspdm_test_requester_get_version_err_case11),
859 : cmocka_unit_test(libspdm_test_requester_get_version_err_case12),
860 : cmocka_unit_test(libspdm_test_requester_get_version_err_case13),
861 : cmocka_unit_test(libspdm_test_requester_get_version_err_case14),
862 : /* cmocka_unit_test(libspdm_test_requester_get_version_err_case15),
863 : * cmocka_unit_test(libspdm_test_requester_get_version_err_case16), */
864 : cmocka_unit_test(libspdm_test_requester_get_version_err_case17),
865 : cmocka_unit_test(libspdm_test_requester_get_version_err_case18),
866 : };
867 :
868 1 : libspdm_test_context_t test_context = {
869 : LIBSPDM_TEST_CONTEXT_VERSION,
870 : true,
871 : send_message,
872 : receive_message,
873 : };
874 :
875 1 : libspdm_setup_test_context(&test_context);
876 :
877 1 : return cmocka_run_group_tests(test_cases,
878 : libspdm_unit_test_group_setup,
879 : libspdm_unit_test_group_teardown);
880 : }
|