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 :
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 = SPDM_MESSAGE_VERSION_10;
170 0 : spdm_response->header.request_response_code = SPDM_ERROR;
171 0 : spdm_response->header.param1 = SPDM_ERROR_CODE_BUSY;
172 0 : spdm_response->header.param2 = 0;
173 :
174 0 : libspdm_transport_test_encode_message(
175 : spdm_context, NULL, false, false,
176 : spdm_response_size, spdm_response,
177 : response_size, response);
178 0 : } else if (sub_index1 == 1) {
179 : libspdm_version_response_mine_t *spdm_response;
180 : size_t spdm_response_size;
181 : size_t transport_header_size;
182 :
183 0 : spdm_response_size = sizeof(libspdm_version_response_mine_t);
184 0 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
185 0 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
186 :
187 0 : libspdm_zero_mem(spdm_response, spdm_response_size);
188 0 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_10;
189 0 : spdm_response->header.request_response_code = SPDM_VERSION;
190 0 : spdm_response->header.param1 = 0;
191 0 : spdm_response->header.param2 = 0;
192 0 : spdm_response->version_number_entry_count = 2;
193 0 : spdm_response->version_number_entry[0] = 0x10 << SPDM_VERSION_NUMBER_SHIFT_BIT;
194 0 : spdm_response->version_number_entry[1] = 0x11 << SPDM_VERSION_NUMBER_SHIFT_BIT;
195 :
196 0 : libspdm_transport_test_encode_message(
197 : spdm_context, NULL, false, false,
198 : spdm_response_size, spdm_response,
199 : response_size, response);
200 : }
201 0 : sub_index1++;
202 : }
203 0 : return LIBSPDM_STATUS_SUCCESS;
204 :
205 1 : case 0x7: {
206 : spdm_error_response_t *spdm_response;
207 : size_t spdm_response_size;
208 : size_t transport_header_size;
209 :
210 1 : spdm_response_size = sizeof(spdm_error_response_t);
211 1 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
212 1 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
213 :
214 1 : libspdm_zero_mem(spdm_response, spdm_response_size);
215 1 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_10;
216 1 : spdm_response->header.request_response_code = SPDM_ERROR;
217 1 : spdm_response->header.param1 = SPDM_ERROR_CODE_REQUEST_RESYNCH;
218 1 : spdm_response->header.param2 = 0;
219 :
220 1 : libspdm_transport_test_encode_message(spdm_context, NULL, false,
221 : false, spdm_response_size,
222 : spdm_response,
223 : response_size, response);
224 : }
225 1 : return LIBSPDM_STATUS_SUCCESS;
226 :
227 1 : case 0x8: {
228 : spdm_error_response_data_response_not_ready_t *spdm_response;
229 : size_t spdm_response_size;
230 : size_t transport_header_size;
231 :
232 1 : spdm_response_size = sizeof(spdm_error_response_data_response_not_ready_t);
233 1 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
234 1 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
235 :
236 1 : libspdm_zero_mem(spdm_response, spdm_response_size);
237 1 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_10;
238 1 : spdm_response->header.request_response_code = SPDM_ERROR;
239 1 : spdm_response->header.param1 = SPDM_ERROR_CODE_RESPONSE_NOT_READY;
240 1 : spdm_response->header.param2 = 0;
241 1 : spdm_response->extend_error_data.rd_exponent = 1;
242 1 : spdm_response->extend_error_data.rd_tm = 2;
243 1 : spdm_response->extend_error_data.request_code = SPDM_GET_VERSION;
244 1 : spdm_response->extend_error_data.token = 0;
245 :
246 1 : libspdm_transport_test_encode_message(spdm_context, NULL, false,
247 : false, spdm_response_size,
248 : spdm_response,
249 : response_size, response);
250 : }
251 1 : return LIBSPDM_STATUS_SUCCESS;
252 :
253 1 : case 0x9: {
254 : libspdm_version_response_mine_t *spdm_response;
255 : size_t spdm_response_size;
256 : size_t transport_header_size;
257 :
258 1 : spdm_response_size = sizeof(libspdm_version_response_mine_t);
259 1 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
260 1 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
261 :
262 1 : libspdm_zero_mem(spdm_response, spdm_response_size);
263 1 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_10;
264 1 : spdm_response->header.request_response_code = SPDM_VERSION;
265 1 : spdm_response->header.param1 = 0;
266 1 : spdm_response->header.param2 = 0;
267 1 : spdm_response->version_number_entry_count = 255;
268 1 : spdm_response->version_number_entry[0] = 0x10 << SPDM_VERSION_NUMBER_SHIFT_BIT;
269 1 : spdm_response->version_number_entry[1] = 0x11 << SPDM_VERSION_NUMBER_SHIFT_BIT;
270 1 : spdm_response->version_number_entry[2] = 0x12 << SPDM_VERSION_NUMBER_SHIFT_BIT;
271 :
272 1 : libspdm_transport_test_encode_message(spdm_context, NULL, false,
273 : false, spdm_response_size,
274 : spdm_response,
275 : response_size, response);
276 : }
277 1 : return LIBSPDM_STATUS_SUCCESS;
278 :
279 1 : case 0xA:
280 1 : return LIBSPDM_STATUS_RECEIVE_FAIL;
281 :
282 1 : case 0xB: {
283 : libspdm_version_response_mine_t *spdm_response;
284 : size_t spdm_response_size;
285 : size_t transport_header_size;
286 :
287 1 : spdm_response_size = sizeof(libspdm_version_response_mine_t);
288 1 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
289 1 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
290 :
291 1 : libspdm_zero_mem(spdm_response, spdm_response_size);
292 1 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_10;
293 1 : spdm_response->header.request_response_code = SPDM_VERSION;
294 1 : spdm_response->header.param1 = 0;
295 1 : spdm_response->header.param2 = 0;
296 1 : spdm_response->version_number_entry_count = 2;
297 1 : spdm_response->version_number_entry[0] = 0xA0 << SPDM_VERSION_NUMBER_SHIFT_BIT;
298 1 : spdm_response->version_number_entry[1] = 0xA1 << SPDM_VERSION_NUMBER_SHIFT_BIT;
299 :
300 1 : libspdm_transport_test_encode_message(spdm_context, NULL, false,
301 : false, spdm_response_size,
302 : spdm_response,
303 : response_size, response);
304 : }
305 1 : return LIBSPDM_STATUS_SUCCESS;
306 :
307 1 : case 0xC: {
308 : libspdm_version_response_mine_t *spdm_response;
309 : size_t spdm_response_size;
310 : size_t transport_header_size;
311 :
312 1 : spdm_response_size = sizeof(libspdm_version_response_mine_t);
313 1 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
314 1 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
315 :
316 1 : libspdm_zero_mem(spdm_response, spdm_response_size);
317 1 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_11;
318 1 : spdm_response->header.request_response_code = SPDM_VERSION;
319 1 : spdm_response->header.param1 = 0;
320 1 : spdm_response->header.param2 = 0;
321 1 : spdm_response->version_number_entry_count = 2;
322 1 : spdm_response->version_number_entry[0] = 0x10 << SPDM_VERSION_NUMBER_SHIFT_BIT;
323 1 : spdm_response->version_number_entry[1] = 0x11 << SPDM_VERSION_NUMBER_SHIFT_BIT;
324 :
325 1 : libspdm_transport_test_encode_message(spdm_context, NULL, false,
326 : false, spdm_response_size,
327 : spdm_response,
328 : response_size, response);
329 : }
330 1 : return LIBSPDM_STATUS_SUCCESS;
331 :
332 1 : case 0xD: {
333 : libspdm_version_response_mine_t *spdm_response;
334 : size_t spdm_response_size;
335 : size_t transport_header_size;
336 :
337 1 : spdm_response_size = sizeof(libspdm_version_response_mine_t);
338 1 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
339 1 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
340 :
341 1 : libspdm_zero_mem(spdm_response, spdm_response_size);
342 1 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_10;
343 1 : spdm_response->header.request_response_code = SPDM_GET_VERSION;
344 1 : spdm_response->header.param1 = 0;
345 1 : spdm_response->header.param2 = 0;
346 1 : spdm_response->version_number_entry_count = 2;
347 1 : spdm_response->version_number_entry[0] = 0x10 << SPDM_VERSION_NUMBER_SHIFT_BIT;
348 1 : spdm_response->version_number_entry[1] = 0x11 << SPDM_VERSION_NUMBER_SHIFT_BIT;
349 :
350 1 : libspdm_transport_test_encode_message(spdm_context, NULL, false,
351 : false, spdm_response_size,
352 : spdm_response,
353 : response_size, response);
354 : }
355 1 : return LIBSPDM_STATUS_SUCCESS;
356 :
357 18 : case 0xE:
358 : {
359 : static uint16_t error_code = LIBSPDM_ERROR_CODE_RESERVED_00;
360 :
361 : spdm_error_response_t *spdm_response;
362 : size_t spdm_response_size;
363 : size_t transport_header_size;
364 :
365 18 : spdm_response_size = sizeof(libspdm_version_response_mine_t);
366 18 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
367 18 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
368 :
369 18 : if(error_code <= 0xff) {
370 18 : libspdm_zero_mem (spdm_response, spdm_response_size);
371 18 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_10;
372 18 : spdm_response->header.request_response_code = SPDM_ERROR;
373 18 : spdm_response->header.param1 = (uint8_t) error_code;
374 :
375 18 : libspdm_transport_test_encode_message (spdm_context, NULL, false, false,
376 : spdm_response_size, spdm_response,
377 : response_size, response);
378 : }
379 :
380 18 : error_code++;
381 18 : if(error_code == SPDM_ERROR_CODE_BUSY) { /*busy is treated in cases 5 and 6*/
382 1 : error_code = SPDM_ERROR_CODE_UNEXPECTED_REQUEST;
383 : }
384 : /* skip some reserved error codes (0d to 3e) */
385 18 : if(error_code == LIBSPDM_ERROR_CODE_RESERVED_0D) {
386 1 : error_code = LIBSPDM_ERROR_CODE_RESERVED_3F;
387 : }
388 : /* skip response not ready, request resync, and some reserved codes (44 to fc) */
389 18 : if(error_code == SPDM_ERROR_CODE_RESPONSE_NOT_READY) {
390 1 : error_code = LIBSPDM_ERROR_CODE_RESERVED_FD;
391 : }
392 : }
393 18 : return LIBSPDM_STATUS_SUCCESS;
394 :
395 0 : case 0xF: {
396 : libspdm_version_response_mine_t *spdm_response;
397 : size_t spdm_response_size;
398 : size_t transport_header_size;
399 :
400 0 : spdm_response_size = sizeof(libspdm_version_response_mine_t);
401 0 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
402 0 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
403 :
404 0 : libspdm_zero_mem(spdm_response, spdm_response_size);
405 0 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_10;
406 0 : spdm_response->header.request_response_code = SPDM_VERSION;
407 0 : spdm_response->header.param1 = 0;
408 0 : spdm_response->header.param2 = 0;
409 0 : spdm_response->version_number_entry_count = 5;
410 0 : spdm_response->version_number_entry[0] = 0x42 << SPDM_VERSION_NUMBER_SHIFT_BIT;
411 0 : spdm_response->version_number_entry[1] = 0x52 << SPDM_VERSION_NUMBER_SHIFT_BIT;
412 0 : spdm_response->version_number_entry[2] = 0x12 << SPDM_VERSION_NUMBER_SHIFT_BIT;
413 0 : spdm_response->version_number_entry[3] = 0x11 << SPDM_VERSION_NUMBER_SHIFT_BIT;
414 0 : spdm_response->version_number_entry[4] = 0x10 << SPDM_VERSION_NUMBER_SHIFT_BIT;
415 :
416 0 : libspdm_transport_test_encode_message(spdm_context, NULL, false,
417 : false, spdm_response_size,
418 : spdm_response,
419 : response_size, response);
420 : }
421 0 : return LIBSPDM_STATUS_SUCCESS;
422 :
423 0 : case 0x10: {
424 : libspdm_version_response_mine_t *spdm_response;
425 : size_t spdm_response_size;
426 : size_t transport_header_size;
427 :
428 0 : spdm_response_size = sizeof(libspdm_version_response_mine_t);
429 0 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
430 0 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
431 :
432 0 : libspdm_zero_mem(spdm_response, spdm_response_size);
433 0 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_10;
434 0 : spdm_response->header.request_response_code = SPDM_VERSION;
435 0 : spdm_response->header.param1 = 0;
436 0 : spdm_response->header.param2 = 0;
437 0 : spdm_response->version_number_entry_count = 2;
438 0 : spdm_response->version_number_entry[0] = 0x10 << SPDM_VERSION_NUMBER_SHIFT_BIT;
439 0 : spdm_response->version_number_entry[1] = 0x11 << SPDM_VERSION_NUMBER_SHIFT_BIT;
440 :
441 0 : spdm_response_size = 10;
442 :
443 0 : libspdm_copy_mem(&m_libspdm_local_buffer[m_libspdm_local_buffer_size],
444 : sizeof(m_libspdm_local_buffer) - m_libspdm_local_buffer_size,
445 : (uint8_t *)spdm_response, spdm_response_size);
446 0 : m_libspdm_local_buffer_size += spdm_response_size;
447 :
448 0 : libspdm_transport_test_encode_message(spdm_context, NULL, false,
449 : false, spdm_response_size,
450 : spdm_response,
451 : response_size, response);
452 : }
453 0 : return LIBSPDM_STATUS_SUCCESS;
454 :
455 1 : case 0x11: {
456 : spdm_message_header_t *spdm_response;
457 : size_t spdm_response_size;
458 : size_t transport_header_size;
459 :
460 1 : spdm_response_size = sizeof(spdm_message_header_t);
461 1 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
462 1 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
463 :
464 1 : libspdm_zero_mem(spdm_response, spdm_response_size);
465 1 : spdm_response->spdm_version = SPDM_MESSAGE_VERSION_10;
466 1 : spdm_response->request_response_code = SPDM_VERSION;
467 1 : spdm_response->param1 = 0;
468 1 : spdm_response->param2 = 0;
469 :
470 1 : libspdm_transport_test_encode_message(spdm_context, NULL, false,
471 : false, spdm_response_size,
472 : spdm_response,
473 : response_size, response);
474 :
475 : }
476 1 : return LIBSPDM_STATUS_SUCCESS;
477 :
478 1 : case 0x12: {
479 : spdm_version_response_t *spdm_response;
480 : size_t spdm_response_size;
481 : size_t transport_header_size;
482 :
483 1 : spdm_response_size = sizeof(spdm_version_response_t);
484 1 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
485 1 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
486 :
487 1 : libspdm_zero_mem(spdm_response, spdm_response_size);
488 1 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_10;
489 1 : spdm_response->header.request_response_code = SPDM_VERSION;
490 1 : spdm_response->header.param1 = 0;
491 1 : spdm_response->header.param2 = 0;
492 1 : spdm_response->version_number_entry_count = LIBSPDM_MAX_VERSION_COUNT;
493 :
494 1 : libspdm_transport_test_encode_message(spdm_context, NULL, false,
495 : false, spdm_response_size,
496 : spdm_response,
497 : response_size, response);
498 :
499 : }
500 1 : return LIBSPDM_STATUS_SUCCESS;
501 :
502 0 : default:
503 0 : return LIBSPDM_STATUS_RECEIVE_FAIL;
504 : }
505 : }
506 :
507 : /**
508 : * Test 1: Unable to send the GET_VERSION request.
509 : * Expected behavior: returns a status of LIBSPDM_STATUS_SEND_FAIL.
510 : **/
511 1 : static void libspdm_test_requester_get_version_err_case1(void **state)
512 : {
513 : libspdm_return_t status;
514 : libspdm_test_context_t *spdm_test_context;
515 : libspdm_context_t *spdm_context;
516 :
517 1 : spdm_test_context = *state;
518 1 : spdm_context = spdm_test_context->spdm_context;
519 1 : spdm_test_context->case_id = 0x1;
520 :
521 1 : status = libspdm_get_version(spdm_context, NULL, NULL);
522 1 : assert_int_equal(status, LIBSPDM_STATUS_SEND_FAIL);
523 1 : }
524 :
525 : /**
526 : * Test 2: Requester is unable to acquire the sender buffer.
527 : * Expected behavior: returns with status LIBSPDM_STATUS_ACQUIRE_FAIL.
528 : **/
529 1 : static void libspdm_test_requester_get_version_err_case2(void **state)
530 : {
531 : libspdm_return_t status;
532 : libspdm_test_context_t *spdm_test_context;
533 : libspdm_context_t *spdm_context;
534 :
535 1 : spdm_test_context = *state;
536 1 : spdm_context = spdm_test_context->spdm_context;
537 1 : spdm_test_context->case_id = 0x2;
538 :
539 1 : libspdm_force_error (LIBSPDM_ERR_ACQUIRE_SENDER_BUFFER);
540 1 : status = libspdm_get_version(spdm_context, NULL, NULL);
541 1 : libspdm_release_error (LIBSPDM_ERR_ACQUIRE_SENDER_BUFFER);
542 :
543 1 : assert_int_equal(status, LIBSPDM_STATUS_ACQUIRE_FAIL);
544 1 : }
545 :
546 : /**
547 : * Test 3: receiving a correct VERSION message header, but with 0 versions available.
548 : * Expected behavior: client returns a status of LIBSPDM_STATUS_INVALID_MSG_FIELD.
549 : **/
550 1 : static void libspdm_test_requester_get_version_err_case3(void **state)
551 : {
552 : libspdm_return_t status;
553 : libspdm_test_context_t *spdm_test_context;
554 : libspdm_context_t *spdm_context;
555 :
556 1 : spdm_test_context = *state;
557 1 : spdm_context = spdm_test_context->spdm_context;
558 1 : spdm_test_context->case_id = 0x3;
559 :
560 1 : status = libspdm_get_version(spdm_context, NULL, NULL);
561 1 : assert_int_equal(status, LIBSPDM_STATUS_INVALID_MSG_FIELD);
562 1 : }
563 :
564 : /**
565 : * Test 4: receiving an InvalidRequest ERROR message from the responder.
566 : * Expected behavior: client returns a status of LIBSPDM_STATUS_ERROR_PEER.
567 : **/
568 1 : static void libspdm_test_requester_get_version_err_case4(void **state)
569 : {
570 : libspdm_return_t status;
571 : libspdm_test_context_t *spdm_test_context;
572 : libspdm_context_t *spdm_context;
573 :
574 1 : spdm_test_context = *state;
575 1 : spdm_context = spdm_test_context->spdm_context;
576 1 : spdm_test_context->case_id = 0x4;
577 :
578 1 : status = libspdm_get_version(spdm_context, NULL, NULL);
579 1 : assert_int_equal(status, LIBSPDM_STATUS_ERROR_PEER);
580 1 : }
581 :
582 : /**
583 : * Test 5: receiving a Busy ERROR message correct VERSION message from the responder.
584 : * Expected behavior: client returns a status of LIBSPDM_STATUS_BUSY_PEER.
585 : **/
586 1 : static void libspdm_test_requester_get_version_err_case5(void **state)
587 : {
588 : libspdm_return_t status;
589 : libspdm_test_context_t *spdm_test_context;
590 : libspdm_context_t *spdm_context;
591 :
592 1 : spdm_test_context = *state;
593 1 : spdm_context = spdm_test_context->spdm_context;
594 1 : spdm_test_context->case_id = 0x5;
595 :
596 1 : status = libspdm_get_version(spdm_context, NULL, NULL);
597 1 : assert_int_equal(status, LIBSPDM_STATUS_BUSY_PEER);
598 1 : }
599 :
600 : /**
601 : * Test 6: Requester is unable to acquire the receiver buffer.
602 : * Expected behavior: returns with status LIBSPDM_STATUS_ACQUIRE_FAIL.
603 : **/
604 1 : static void libspdm_test_requester_get_version_err_case6(void **state)
605 : {
606 : libspdm_return_t status;
607 : libspdm_test_context_t *spdm_test_context;
608 : libspdm_context_t *spdm_context;
609 :
610 1 : spdm_test_context = *state;
611 1 : spdm_context = spdm_test_context->spdm_context;
612 1 : spdm_test_context->case_id = 0x6;
613 :
614 1 : libspdm_force_error (LIBSPDM_ERR_ACQUIRE_RECEIVER_BUFFER);
615 1 : status = libspdm_get_version(spdm_context, NULL, NULL);
616 1 : libspdm_release_error (LIBSPDM_ERR_ACQUIRE_RECEIVER_BUFFER);
617 :
618 1 : assert_int_equal(status, LIBSPDM_STATUS_ACQUIRE_FAIL);
619 1 : }
620 :
621 : /**
622 : * Test 7: receiving a RequestResynch ERROR message from the responder.
623 : * Expected behavior: client returns a status of LIBSPDM_STATUS_RESYNCH_PEER, and the
624 : * internal state should be reset.
625 : **/
626 1 : static void libspdm_test_requester_get_version_err_case7(void **state)
627 : {
628 : libspdm_return_t status;
629 : libspdm_test_context_t *spdm_test_context;
630 : libspdm_context_t *spdm_context;
631 :
632 1 : spdm_test_context = *state;
633 1 : spdm_context = spdm_test_context->spdm_context;
634 1 : spdm_test_context->case_id = 0x7;
635 :
636 1 : status = libspdm_get_version(spdm_context, NULL, NULL);
637 1 : assert_int_equal(status, LIBSPDM_STATUS_RESYNCH_PEER);
638 1 : assert_int_equal(spdm_context->connection_info.connection_state,
639 : LIBSPDM_CONNECTION_STATE_NOT_STARTED);
640 1 : }
641 :
642 : /**
643 : * Test 8: receiving a ResponseNotReady ERROR message from the responder,
644 : * but Responder shall not respond to the GET_VERSION request message with ErrorCode=ResponseNotReady.
645 : * Expected behavior: client returns a status of LIBSPDM_STATUS_ERROR_PEER,
646 : * Received an unexpected error message.
647 : **/
648 1 : static void libspdm_test_requester_get_version_err_case8(void **state)
649 : {
650 : libspdm_return_t status;
651 : libspdm_test_context_t *spdm_test_context;
652 : libspdm_context_t *spdm_context;
653 :
654 1 : spdm_test_context = *state;
655 1 : spdm_context = spdm_test_context->spdm_context;
656 1 : spdm_test_context->case_id = 0x8;
657 :
658 1 : status = libspdm_get_version(spdm_context, NULL, NULL);
659 1 : assert_int_equal(status, LIBSPDM_STATUS_ERROR_PEER);
660 1 : }
661 :
662 : /**
663 : * Test 9: Number of version entries are larger than what the Requester can tolerate.
664 : * Expected behavior: returns a status of LIBSPDM_STATUS_INVALID_MSG_FIELD.
665 : **/
666 1 : static void libspdm_test_requester_get_version_err_case9(void **state)
667 : {
668 : libspdm_return_t status;
669 : libspdm_test_context_t *spdm_test_context;
670 : libspdm_context_t *spdm_context;
671 :
672 : LIBSPDM_ASSERT(LIBSPDM_MAX_VERSION_COUNT != 255);
673 :
674 1 : spdm_test_context = *state;
675 1 : spdm_context = spdm_test_context->spdm_context;
676 1 : spdm_test_context->case_id = 0x9;
677 :
678 1 : status = libspdm_get_version(spdm_context, NULL, NULL);
679 1 : assert_int_equal(status, LIBSPDM_STATUS_INVALID_MSG_FIELD);
680 1 : }
681 :
682 : /**
683 : * Test 10: Requester is unable to receive a VERSION response from the Responder.
684 : * Expected behavior: returns a status of LIBSPDM_STATUS_RECEIVE_FAIL.
685 : **/
686 1 : static void libspdm_test_requester_get_version_err_case10(void **state)
687 : {
688 : libspdm_return_t status;
689 : libspdm_test_context_t *spdm_test_context;
690 : libspdm_context_t *spdm_context;
691 :
692 1 : spdm_test_context = *state;
693 1 : spdm_context = spdm_test_context->spdm_context;
694 1 : spdm_test_context->case_id = 0xa;
695 :
696 1 : status = libspdm_get_version(spdm_context, NULL, NULL);
697 1 : assert_int_equal(status, LIBSPDM_STATUS_RECEIVE_FAIL);
698 1 : }
699 :
700 : /**
701 : * Test 11: receiving a correct VERSION message with available version 1.0 and 1.1, but
702 : * the requester do not have compatible versions with the responder.
703 : * Expected behavior: client returns a status of LIBSPDM_STATUS_NEGOTIATION_FAIL.
704 : **/
705 1 : static void libspdm_test_requester_get_version_err_case11(void **state)
706 : {
707 : libspdm_return_t status;
708 : libspdm_test_context_t *spdm_test_context;
709 : libspdm_context_t *spdm_context;
710 :
711 1 : spdm_test_context = *state;
712 1 : spdm_context = spdm_test_context->spdm_context;
713 1 : spdm_test_context->case_id = 0xB;
714 :
715 1 : status = libspdm_get_version(spdm_context, NULL, NULL);
716 1 : assert_int_equal(status, LIBSPDM_STATUS_NEGOTIATION_FAIL);
717 1 : }
718 :
719 : /**
720 : * Test 12: receiving a VERSION message in SPDM version 1.1 (in the header), but correct
721 : * 1.0-version format, with available version 1.0 and 1.1.
722 : * Expected behavior: client returns a status of LIBSPDM_STATUS_INVALID_MSG_FIELD.
723 : **/
724 1 : static void libspdm_test_requester_get_version_err_case12(void **state)
725 : {
726 : libspdm_return_t status;
727 : libspdm_test_context_t *spdm_test_context;
728 : libspdm_context_t *spdm_context;
729 :
730 1 : spdm_test_context = *state;
731 1 : spdm_context = spdm_test_context->spdm_context;
732 1 : spdm_test_context->case_id = 0xC;
733 :
734 1 : status = libspdm_get_version(spdm_context, NULL, NULL);
735 1 : assert_int_equal(status, LIBSPDM_STATUS_INVALID_MSG_FIELD);
736 1 : }
737 :
738 : /**
739 : * Test 13: receiving a VERSION message with wrong SPDM request_response_code (in this
740 : * case, GET_VERSION 0x84 instead of VERSION 0x04). The remaining data is a correct
741 : * VERSION message, with available version 1.0 and 1.1.
742 : * Expected behavior: client returns a status of LIBSPDM_STATUS_INVALID_MSG_FIELD.
743 : **/
744 1 : static void libspdm_test_requester_get_version_err_case13(void **state)
745 : {
746 : libspdm_return_t status;
747 : libspdm_test_context_t *spdm_test_context;
748 : libspdm_context_t *spdm_context;
749 :
750 1 : spdm_test_context = *state;
751 1 : spdm_context = spdm_test_context->spdm_context;
752 1 : spdm_test_context->case_id = 0xD;
753 :
754 1 : status = libspdm_get_version(spdm_context, NULL, NULL);
755 1 : assert_int_equal(status, LIBSPDM_STATUS_INVALID_MSG_FIELD);
756 1 : }
757 :
758 : /**
759 : * Test 14: receiving an unexpected ERROR message from the responder.
760 : * There are tests for all named codes, including some reserved ones
761 : * (namely, 0x00, 0x0b, 0x0c, 0x3f, 0xfd, 0xfe).
762 : * However, for having specific test cases, it is excluded from this case:
763 : * Busy (0x03), ResponseNotReady (0x42), and RequestResync (0x43).
764 : * Expected behavior: client returns a status of LIBSPDM_STATUS_ERROR_PEER.
765 : **/
766 1 : static void libspdm_test_requester_get_version_err_case14(void **state) {
767 : libspdm_return_t status;
768 : libspdm_test_context_t *spdm_test_context;
769 : libspdm_context_t *spdm_context;
770 : uint16_t error_code;
771 :
772 1 : spdm_test_context = *state;
773 1 : spdm_context = spdm_test_context->spdm_context;
774 1 : spdm_test_context->case_id = 0xE;
775 :
776 1 : error_code = LIBSPDM_ERROR_CODE_RESERVED_00;
777 19 : while(error_code <= 0xff) {
778 : /* no additional state control is necessary as a new GET_VERSION resets the state*/
779 18 : status = libspdm_get_version (spdm_context, NULL, NULL);
780 18 : LIBSPDM_ASSERT_INT_EQUAL_CASE (status, LIBSPDM_STATUS_ERROR_PEER, error_code);
781 :
782 18 : error_code++;
783 18 : if(error_code == SPDM_ERROR_CODE_BUSY) { /*busy is treated in cases 5 and 6*/
784 1 : error_code = SPDM_ERROR_CODE_UNEXPECTED_REQUEST;
785 : }
786 : /* skip some reserved error codes (0d to 3e) */
787 18 : if(error_code == LIBSPDM_ERROR_CODE_RESERVED_0D) {
788 1 : error_code = LIBSPDM_ERROR_CODE_RESERVED_3F;
789 : }
790 : /* skip response not ready, request resync, and some reserved codes (44 to fc) */
791 18 : if(error_code == SPDM_ERROR_CODE_RESPONSE_NOT_READY) {
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 : }
|