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