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_responder_lib.h"
9 :
10 : #if LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP
11 :
12 : #define CHUNK_GET_RESPONDER_UNIT_TEST_DATA_TRANSFER_SIZE (44)
13 :
14 : /**
15 : * Test 1: Responder receives a CHUNK_GET request when it is not expecting it.
16 : * Responder does not have response CHUNK cap set.
17 : * Expected Behavior: Returns ERROR response message
18 : * with SPDM_ERROR_CODE_UNEXPECTED_REQUEST error code.
19 : **/
20 1 : void libspdm_test_responder_chunk_get_rsp_case1(void** state)
21 : {
22 : libspdm_return_t status;
23 : libspdm_test_context_t* spdm_test_context;
24 : libspdm_context_t* spdm_context;
25 : size_t response_size;
26 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
27 : spdm_error_response_t* spdm_response;
28 : spdm_chunk_get_request_t spdm_request;
29 :
30 1 : spdm_test_context = *state;
31 1 : spdm_context = spdm_test_context->spdm_context;
32 1 : spdm_test_context->case_id = 1;
33 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 <<
34 : SPDM_VERSION_NUMBER_SHIFT_BIT;
35 :
36 1 : spdm_context->connection_info.connection_state =
37 : LIBSPDM_CONNECTION_STATE_NEGOTIATED;
38 1 : spdm_context->connection_info.algorithm.base_hash_algo =
39 : m_libspdm_use_hash_algo;
40 :
41 1 : spdm_context->connection_info.capability.data_transfer_size =
42 : CHUNK_GET_RESPONDER_UNIT_TEST_DATA_TRANSFER_SIZE;
43 :
44 1 : libspdm_zero_mem(&spdm_request, sizeof(spdm_request));
45 1 : spdm_request.header.spdm_version = SPDM_MESSAGE_VERSION_12;
46 1 : spdm_request.header.request_response_code = SPDM_CHUNK_GET;
47 1 : spdm_request.header.param1 = 0;
48 1 : spdm_request.header.param2 = 0;
49 1 : spdm_request.chunk_seq_no = 0;
50 :
51 1 : response_size = sizeof(response);
52 1 : status = libspdm_get_response_chunk_get(
53 : spdm_context,
54 : sizeof(spdm_request), &spdm_request,
55 : &response_size, response);
56 :
57 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
58 1 : assert_int_equal(response_size, sizeof(spdm_error_response_t));
59 :
60 1 : spdm_response = (spdm_error_response_t*) response;
61 1 : assert_int_equal(spdm_response->header.spdm_version, SPDM_MESSAGE_VERSION_12);
62 1 : assert_int_equal(spdm_response->header.request_response_code, SPDM_ERROR);
63 1 : assert_int_equal(spdm_response->header.param1, SPDM_ERROR_CODE_UNEXPECTED_REQUEST);
64 1 : assert_int_equal(spdm_response->header.param2, 0);
65 1 : }
66 :
67 : /**
68 : * Test 2: Responder receives a CHUNK_GET request with bad response state.
69 : * Expected Behavior: Returns ERROR response message with an error code.
70 : **/
71 1 : void libspdm_test_responder_chunk_get_rsp_case2(void** state)
72 : {
73 : libspdm_return_t status;
74 : libspdm_test_context_t* spdm_test_context;
75 : libspdm_context_t* spdm_context;
76 : size_t response_size;
77 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
78 : spdm_error_response_t* spdm_response;
79 : spdm_chunk_get_request_t spdm_request;
80 :
81 1 : spdm_test_context = *state;
82 1 : spdm_context = spdm_test_context->spdm_context;
83 1 : spdm_test_context->case_id = 2;
84 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 <<
85 : SPDM_VERSION_NUMBER_SHIFT_BIT;
86 :
87 1 : spdm_context->connection_info.connection_state =
88 : LIBSPDM_CONNECTION_STATE_NEGOTIATED;
89 1 : spdm_context->connection_info.algorithm.base_hash_algo =
90 : m_libspdm_use_hash_algo;
91 :
92 1 : spdm_context->local_context.capability.data_transfer_size =
93 : CHUNK_GET_RESPONDER_UNIT_TEST_DATA_TRANSFER_SIZE;
94 :
95 1 : spdm_context->local_context.capability.flags |=
96 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHUNK_CAP;
97 1 : spdm_context->connection_info.capability.flags |=
98 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP;
99 :
100 : /* Set bad response state */
101 1 : spdm_context->response_state = LIBSPDM_RESPONSE_STATE_BUSY;
102 :
103 1 : libspdm_zero_mem(&spdm_request, sizeof(spdm_request));
104 1 : spdm_request.header.spdm_version = SPDM_MESSAGE_VERSION_12;
105 1 : spdm_request.header.request_response_code = SPDM_CHUNK_GET;
106 1 : spdm_request.header.param1 = 0;
107 1 : spdm_request.header.param2 = 0;
108 1 : spdm_request.chunk_seq_no = 0;
109 :
110 1 : response_size = sizeof(response);
111 1 : status = libspdm_get_response_chunk_get(
112 : spdm_context,
113 : sizeof(spdm_request), &spdm_request,
114 : &response_size, response);
115 :
116 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
117 1 : assert_int_equal(response_size, sizeof(spdm_error_response_t));
118 :
119 1 : spdm_response = (spdm_error_response_t*) response;
120 1 : assert_int_equal(spdm_response->header.spdm_version, SPDM_MESSAGE_VERSION_12);
121 1 : assert_int_equal(spdm_response->header.request_response_code, SPDM_ERROR);
122 1 : assert_int_equal(spdm_response->header.param1, SPDM_ERROR_CODE_BUSY);
123 1 : assert_int_equal(spdm_response->header.param2, 0);
124 1 : }
125 :
126 : /**
127 : * Test 3: Responder receives a CHUNK_GET request with bad connection state.
128 : * Expected Behavior: Returns ERROR response message
129 : * with SPDM_ERROR_CODE_UNEXPECTED_REQUEST error code.
130 : **/
131 1 : void libspdm_test_responder_chunk_get_rsp_case3(void** state)
132 : {
133 : libspdm_return_t status;
134 : libspdm_test_context_t* spdm_test_context;
135 : libspdm_context_t* spdm_context;
136 : size_t response_size;
137 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
138 : spdm_error_response_t* spdm_response;
139 : spdm_chunk_get_request_t spdm_request;
140 :
141 1 : spdm_test_context = *state;
142 1 : spdm_context = spdm_test_context->spdm_context;
143 1 : spdm_test_context->case_id = 3;
144 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 <<
145 : SPDM_VERSION_NUMBER_SHIFT_BIT;
146 :
147 : /* Set bad connection_state */
148 1 : spdm_context->connection_info.connection_state =
149 : LIBSPDM_CONNECTION_STATE_AFTER_CAPABILITIES - 1;
150 1 : spdm_context->connection_info.algorithm.base_hash_algo =
151 : m_libspdm_use_hash_algo;
152 :
153 1 : spdm_context->local_context.capability.data_transfer_size =
154 : CHUNK_GET_RESPONDER_UNIT_TEST_DATA_TRANSFER_SIZE;
155 1 : spdm_context->local_context.capability.flags |=
156 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHUNK_CAP;
157 1 : spdm_context->connection_info.capability.flags |=
158 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP;
159 1 : spdm_context->response_state = LIBSPDM_RESPONSE_STATE_NORMAL;
160 :
161 1 : libspdm_zero_mem(&spdm_request, sizeof(spdm_request));
162 1 : spdm_request.header.spdm_version = SPDM_MESSAGE_VERSION_12;
163 1 : spdm_request.header.request_response_code = SPDM_CHUNK_GET;
164 1 : spdm_request.header.param1 = 0;
165 1 : spdm_request.header.param2 = 0; /* Handle */
166 1 : spdm_request.chunk_seq_no = 0;
167 :
168 1 : response_size = sizeof(response);
169 1 : status = libspdm_get_response_chunk_get(
170 : spdm_context,
171 : sizeof(spdm_request), &spdm_request,
172 : &response_size, response);
173 :
174 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
175 1 : assert_int_equal(response_size, sizeof(spdm_error_response_t));
176 :
177 1 : spdm_response = (spdm_error_response_t*) response;
178 1 : assert_int_equal(spdm_response->header.spdm_version, SPDM_MESSAGE_VERSION_12);
179 1 : assert_int_equal(spdm_response->header.request_response_code, SPDM_ERROR);
180 1 : assert_int_equal(spdm_response->header.param1, SPDM_ERROR_CODE_UNEXPECTED_REQUEST);
181 1 : assert_int_equal(spdm_response->header.param2, 0);
182 1 : }
183 :
184 : /**
185 : * Test 4: Responder receives a CHUNK_GET request with bad size.
186 : * Expected Behavior: Returns ERROR response message
187 : * with SPDM_ERROR_CODE_INVALID_REQUEST error code.
188 : **/
189 1 : void libspdm_test_responder_chunk_get_rsp_case4(void** state)
190 : {
191 : libspdm_return_t status;
192 : libspdm_test_context_t* spdm_test_context;
193 : libspdm_context_t* spdm_context;
194 : size_t response_size;
195 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
196 : spdm_error_response_t* spdm_response;
197 : spdm_chunk_get_request_t spdm_request;
198 :
199 1 : spdm_test_context = *state;
200 1 : spdm_context = spdm_test_context->spdm_context;
201 1 : spdm_test_context->case_id = 4;
202 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 <<
203 : SPDM_VERSION_NUMBER_SHIFT_BIT;
204 :
205 1 : spdm_context->connection_info.connection_state =
206 : LIBSPDM_CONNECTION_STATE_AFTER_CAPABILITIES;
207 1 : spdm_context->connection_info.algorithm.base_hash_algo =
208 : m_libspdm_use_hash_algo;
209 :
210 1 : spdm_context->local_context.capability.data_transfer_size =
211 : CHUNK_GET_RESPONDER_UNIT_TEST_DATA_TRANSFER_SIZE;
212 :
213 1 : spdm_context->local_context.capability.flags |=
214 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHUNK_CAP;
215 1 : spdm_context->connection_info.capability.flags |=
216 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP;
217 :
218 1 : libspdm_zero_mem(&spdm_request, sizeof(spdm_request));
219 1 : spdm_request.header.spdm_version = SPDM_MESSAGE_VERSION_12;
220 1 : spdm_request.header.request_response_code = SPDM_CHUNK_GET;
221 1 : spdm_request.header.param1 = 0;
222 1 : spdm_request.header.param2 = 0;
223 1 : spdm_request.chunk_seq_no = 0;
224 :
225 1 : response_size = sizeof(response);
226 1 : status = libspdm_get_response_chunk_get(
227 : spdm_context,
228 : sizeof(spdm_request) - 1, &spdm_request, /* Bad request size */
229 : &response_size, response);
230 :
231 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
232 1 : assert_int_equal(response_size, sizeof(spdm_error_response_t));
233 :
234 1 : spdm_response = (spdm_error_response_t*) response;
235 1 : assert_int_equal(spdm_response->header.spdm_version, SPDM_MESSAGE_VERSION_12);
236 1 : assert_int_equal(spdm_response->header.request_response_code, SPDM_ERROR);
237 1 : assert_int_equal(spdm_response->header.param1, SPDM_ERROR_CODE_INVALID_REQUEST);
238 1 : assert_int_equal(spdm_response->header.param2, 0);
239 1 : }
240 :
241 : /**
242 : * Test 5: Responder receives a CHUNK_GET request with wrong SPDM version.
243 : * Expected Behavior: Returns ERROR response message
244 : * with SPDM_ERROR_CODE_VERSION_MISMATCH error code.
245 : **/
246 1 : void libspdm_test_responder_chunk_get_rsp_case5(void** state)
247 : {
248 : libspdm_return_t status;
249 : libspdm_test_context_t* spdm_test_context;
250 : libspdm_context_t* spdm_context;
251 : size_t response_size;
252 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
253 : spdm_error_response_t* spdm_response;
254 : spdm_chunk_get_request_t spdm_request;
255 :
256 1 : spdm_test_context = *state;
257 1 : spdm_context = spdm_test_context->spdm_context;
258 1 : spdm_test_context->case_id = 5;
259 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 <<
260 : SPDM_VERSION_NUMBER_SHIFT_BIT;
261 :
262 1 : spdm_context->connection_info.connection_state =
263 : LIBSPDM_CONNECTION_STATE_AFTER_CAPABILITIES;
264 1 : spdm_context->connection_info.algorithm.base_hash_algo =
265 : m_libspdm_use_hash_algo;
266 :
267 1 : spdm_context->local_context.capability.data_transfer_size =
268 : CHUNK_GET_RESPONDER_UNIT_TEST_DATA_TRANSFER_SIZE;
269 1 : spdm_context->local_context.capability.flags |=
270 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHUNK_CAP;
271 1 : spdm_context->connection_info.capability.flags |=
272 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP;
273 :
274 1 : libspdm_zero_mem(&spdm_request, sizeof(spdm_request));
275 1 : spdm_request.header.spdm_version = SPDM_MESSAGE_VERSION_11; /* Mismatching SPDM version */
276 1 : spdm_request.header.request_response_code = SPDM_CHUNK_GET;
277 1 : spdm_request.header.param1 = 0;
278 1 : spdm_request.header.param2 = 0;
279 1 : spdm_request.chunk_seq_no = 0;
280 :
281 1 : response_size = sizeof(response);
282 1 : status = libspdm_get_response_chunk_get(
283 : spdm_context,
284 : sizeof(spdm_request), &spdm_request,
285 : &response_size, response);
286 :
287 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
288 1 : assert_int_equal(response_size, sizeof(spdm_error_response_t));
289 :
290 1 : spdm_response = (spdm_error_response_t*) response;
291 1 : assert_int_equal(spdm_response->header.spdm_version, SPDM_MESSAGE_VERSION_12);
292 1 : assert_int_equal(spdm_response->header.request_response_code, SPDM_ERROR);
293 1 : assert_int_equal(spdm_response->header.param1, SPDM_ERROR_CODE_UNSUPPORTED_REQUEST);
294 1 : assert_int_equal(spdm_response->header.param2, SPDM_CHUNK_GET);
295 1 : }
296 :
297 : /**
298 : * Test 6: Responder has no chunk saved to get.
299 : **/
300 1 : void libspdm_test_responder_chunk_get_rsp_case6(void** state)
301 : {
302 : libspdm_return_t status;
303 : libspdm_test_context_t* spdm_test_context;
304 : libspdm_context_t* spdm_context;
305 : size_t response_size;
306 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
307 : spdm_error_response_t* spdm_response;
308 : spdm_chunk_get_request_t spdm_request;
309 :
310 1 : spdm_test_context = *state;
311 1 : spdm_context = spdm_test_context->spdm_context;
312 1 : spdm_test_context->case_id = 6;
313 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 <<
314 : SPDM_VERSION_NUMBER_SHIFT_BIT;
315 :
316 1 : spdm_context->connection_info.connection_state =
317 : LIBSPDM_CONNECTION_STATE_AFTER_CAPABILITIES;
318 1 : spdm_context->connection_info.algorithm.base_hash_algo =
319 : m_libspdm_use_hash_algo;
320 :
321 1 : spdm_context->local_context.capability.data_transfer_size =
322 : CHUNK_GET_RESPONDER_UNIT_TEST_DATA_TRANSFER_SIZE;
323 1 : spdm_context->local_context.capability.flags |=
324 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHUNK_CAP;
325 1 : spdm_context->connection_info.capability.flags |=
326 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP;
327 :
328 : /* Set no chunk saved */
329 1 : spdm_context->chunk_context.get.chunk_in_use = false;
330 :
331 1 : libspdm_zero_mem(&spdm_request, sizeof(spdm_request));
332 1 : spdm_request.header.spdm_version = SPDM_MESSAGE_VERSION_12;
333 1 : spdm_request.header.request_response_code = SPDM_CHUNK_GET;
334 1 : spdm_request.header.param1 = 0;
335 1 : spdm_request.header.param2 = 0;
336 1 : spdm_request.chunk_seq_no = 0;
337 :
338 1 : response_size = sizeof(response);
339 1 : status = libspdm_get_response_chunk_get(
340 : spdm_context,
341 : sizeof(spdm_request), &spdm_request,
342 : &response_size, response);
343 :
344 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
345 1 : assert_int_equal(response_size, sizeof(spdm_error_response_t));
346 :
347 1 : spdm_response = (spdm_error_response_t*) response;
348 1 : assert_int_equal(spdm_response->header.spdm_version, SPDM_MESSAGE_VERSION_12);
349 1 : assert_int_equal(spdm_response->header.request_response_code, SPDM_ERROR);
350 1 : assert_int_equal(spdm_response->header.param1, SPDM_ERROR_CODE_UNEXPECTED_REQUEST);
351 1 : assert_int_equal(spdm_response->header.param2, 0);
352 1 : }
353 :
354 : /**
355 : * Test 7: Responder has handle that does not match request.
356 : **/
357 1 : void libspdm_test_responder_chunk_get_rsp_case7(void** state)
358 : {
359 : libspdm_return_t status;
360 : libspdm_test_context_t* spdm_test_context;
361 : libspdm_context_t* spdm_context;
362 : size_t response_size;
363 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
364 : spdm_error_response_t* spdm_response;
365 : spdm_chunk_get_request_t spdm_request;
366 : void* scratch_buffer;
367 : size_t scratch_buffer_size;
368 :
369 : uint8_t chunk_handle;
370 :
371 1 : spdm_test_context = *state;
372 1 : spdm_context = spdm_test_context->spdm_context;
373 1 : spdm_test_context->case_id = 7;
374 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 <<
375 : SPDM_VERSION_NUMBER_SHIFT_BIT;
376 :
377 1 : spdm_context->connection_info.connection_state =
378 : LIBSPDM_CONNECTION_STATE_AFTER_CAPABILITIES;
379 1 : spdm_context->connection_info.algorithm.base_hash_algo =
380 : m_libspdm_use_hash_algo;
381 :
382 1 : spdm_context->local_context.capability.data_transfer_size =
383 : CHUNK_GET_RESPONDER_UNIT_TEST_DATA_TRANSFER_SIZE;
384 1 : spdm_context->local_context.capability.flags |=
385 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHUNK_CAP;
386 1 : spdm_context->connection_info.capability.flags |=
387 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP;
388 :
389 1 : libspdm_get_scratch_buffer(spdm_context, &scratch_buffer, &scratch_buffer_size);
390 :
391 2 : scratch_buffer = (uint8_t*)scratch_buffer +
392 1 : libspdm_get_scratch_buffer_large_message_offset(spdm_context);
393 2 : scratch_buffer_size = scratch_buffer_size -
394 1 : libspdm_get_scratch_buffer_large_message_offset(spdm_context);
395 1 : libspdm_zero_mem(scratch_buffer, scratch_buffer_size);
396 :
397 1 : chunk_handle = (uint8_t) spdm_test_context->case_id;
398 1 : spdm_context->chunk_context.get.chunk_in_use = true;
399 1 : spdm_context->chunk_context.get.chunk_handle = (uint8_t) spdm_test_context->case_id;
400 1 : spdm_context->chunk_context.get.chunk_seq_no = chunk_handle;
401 1 : spdm_context->chunk_context.get.large_message = scratch_buffer;
402 1 : spdm_context->chunk_context.get.large_message_size = scratch_buffer_size;
403 :
404 1 : libspdm_zero_mem(&spdm_request, sizeof(spdm_request));
405 1 : spdm_request.header.spdm_version = SPDM_MESSAGE_VERSION_12;
406 1 : spdm_request.header.request_response_code = SPDM_CHUNK_GET;
407 1 : spdm_request.header.param1 = 0;
408 1 : spdm_request.header.param2 = chunk_handle - 1; /* Bad chunk handle */
409 1 : spdm_request.chunk_seq_no = 0;
410 :
411 1 : response_size = sizeof(response);
412 1 : status = libspdm_get_response_chunk_get(
413 : spdm_context,
414 : sizeof(spdm_request), &spdm_request,
415 : &response_size, response);
416 :
417 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
418 1 : assert_int_equal(response_size, sizeof(spdm_error_response_t));
419 :
420 1 : spdm_response = (spdm_error_response_t*) response;
421 1 : assert_int_equal(spdm_response->header.spdm_version, SPDM_MESSAGE_VERSION_12);
422 1 : assert_int_equal(spdm_response->header.request_response_code, SPDM_ERROR);
423 1 : assert_int_equal(spdm_response->header.param1, SPDM_ERROR_CODE_INVALID_REQUEST);
424 1 : assert_int_equal(spdm_response->header.param2, 0);
425 1 : }
426 :
427 : /**
428 : * Test 8: Responder has earlier sequence number than request .
429 : **/
430 1 : void libspdm_test_responder_chunk_get_rsp_case8(void** state)
431 : {
432 : libspdm_return_t status;
433 : libspdm_test_context_t* spdm_test_context;
434 : libspdm_context_t* spdm_context;
435 : size_t response_size;
436 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
437 : spdm_error_response_t* spdm_response;
438 : spdm_chunk_get_request_t spdm_request;
439 : void* scratch_buffer;
440 : size_t scratch_buffer_size;
441 : uint8_t chunk_handle;
442 :
443 1 : spdm_test_context = *state;
444 1 : spdm_context = spdm_test_context->spdm_context;
445 1 : spdm_test_context->case_id = 8;
446 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 <<
447 : SPDM_VERSION_NUMBER_SHIFT_BIT;
448 :
449 1 : spdm_context->connection_info.connection_state =
450 : LIBSPDM_CONNECTION_STATE_NEGOTIATED;
451 1 : spdm_context->connection_info.algorithm.base_hash_algo =
452 : m_libspdm_use_hash_algo;
453 :
454 1 : spdm_context->local_context.capability.data_transfer_size =
455 : CHUNK_GET_RESPONDER_UNIT_TEST_DATA_TRANSFER_SIZE;
456 1 : spdm_context->local_context.capability.flags |=
457 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHUNK_CAP;
458 1 : spdm_context->connection_info.capability.flags |=
459 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP;
460 :
461 1 : libspdm_get_scratch_buffer(spdm_context, &scratch_buffer, &scratch_buffer_size);
462 :
463 2 : scratch_buffer = (uint8_t*)scratch_buffer +
464 1 : libspdm_get_scratch_buffer_large_message_offset(spdm_context);
465 2 : scratch_buffer_size = scratch_buffer_size -
466 1 : libspdm_get_scratch_buffer_large_message_offset(spdm_context);
467 1 : libspdm_zero_mem(scratch_buffer, scratch_buffer_size);
468 :
469 1 : chunk_handle = (uint8_t) spdm_test_context->case_id;
470 1 : spdm_context->chunk_context.get.chunk_in_use = true;
471 1 : spdm_context->chunk_context.get.chunk_handle = chunk_handle;
472 1 : spdm_context->chunk_context.get.chunk_seq_no = 0;
473 1 : spdm_context->chunk_context.get.large_message = scratch_buffer;
474 1 : spdm_context->chunk_context.get.large_message_size = scratch_buffer_size;
475 :
476 1 : libspdm_zero_mem(&spdm_request, sizeof(spdm_request));
477 1 : spdm_request.header.spdm_version = SPDM_MESSAGE_VERSION_12;
478 1 : spdm_request.header.request_response_code = SPDM_CHUNK_GET;
479 1 : spdm_request.header.param1 = 0;
480 1 : spdm_request.header.param2 = chunk_handle;
481 1 : spdm_request.chunk_seq_no = 1; /* Bad chunk seq no */
482 :
483 1 : response_size = sizeof(response);
484 1 : status = libspdm_get_response_chunk_get(
485 : spdm_context,
486 : sizeof(spdm_request), &spdm_request,
487 : &response_size, response);
488 :
489 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
490 1 : assert_int_equal(response_size, sizeof(spdm_error_response_t));
491 :
492 1 : spdm_response = (spdm_error_response_t*) response;
493 1 : assert_int_equal(spdm_response->header.spdm_version, SPDM_MESSAGE_VERSION_12);
494 1 : assert_int_equal(spdm_response->header.request_response_code, SPDM_ERROR);
495 1 : assert_int_equal(spdm_response->header.param1, SPDM_ERROR_CODE_INVALID_REQUEST);
496 1 : assert_int_equal(spdm_response->header.param2, 0);
497 1 : }
498 :
499 : /**
500 : * Test 9: Responder has later sequence number than request.
501 : **/
502 1 : void libspdm_test_responder_chunk_get_rsp_case9(void** state)
503 : {
504 : libspdm_return_t status;
505 : libspdm_test_context_t* spdm_test_context;
506 : libspdm_context_t* spdm_context;
507 : size_t response_size;
508 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
509 : spdm_error_response_t* spdm_response;
510 : spdm_chunk_get_request_t spdm_request;
511 : void* scratch_buffer;
512 : size_t scratch_buffer_size;
513 : uint8_t chunk_handle;
514 :
515 1 : spdm_test_context = *state;
516 1 : spdm_context = spdm_test_context->spdm_context;
517 1 : spdm_test_context->case_id = 9;
518 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 <<
519 : SPDM_VERSION_NUMBER_SHIFT_BIT;
520 :
521 1 : spdm_context->connection_info.connection_state =
522 : LIBSPDM_CONNECTION_STATE_NEGOTIATED;
523 1 : spdm_context->connection_info.algorithm.base_hash_algo =
524 : m_libspdm_use_hash_algo;
525 :
526 1 : spdm_context->local_context.capability.data_transfer_size =
527 : CHUNK_GET_RESPONDER_UNIT_TEST_DATA_TRANSFER_SIZE;
528 1 : spdm_context->local_context.capability.flags |=
529 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHUNK_CAP;
530 1 : spdm_context->connection_info.capability.flags |=
531 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP;
532 :
533 1 : libspdm_get_scratch_buffer(spdm_context, &scratch_buffer, &scratch_buffer_size);
534 :
535 2 : scratch_buffer = (uint8_t*)scratch_buffer +
536 1 : libspdm_get_scratch_buffer_large_message_offset(spdm_context);
537 2 : scratch_buffer_size = scratch_buffer_size -
538 1 : libspdm_get_scratch_buffer_large_message_offset(spdm_context);
539 1 : libspdm_zero_mem(scratch_buffer, scratch_buffer_size);
540 :
541 1 : chunk_handle = (uint8_t) spdm_test_context->case_id;
542 1 : spdm_context->chunk_context.get.chunk_in_use = true;
543 1 : spdm_context->chunk_context.get.chunk_handle = chunk_handle;
544 1 : spdm_context->chunk_context.get.chunk_seq_no = 0;
545 1 : spdm_context->chunk_context.get.large_message = scratch_buffer;
546 1 : spdm_context->chunk_context.get.large_message_size = scratch_buffer_size;
547 1 : spdm_context->chunk_context.get.chunk_bytes_transferred = 0;
548 :
549 1 : libspdm_zero_mem(&spdm_request, sizeof(spdm_request));
550 1 : spdm_request.header.spdm_version = SPDM_MESSAGE_VERSION_12;
551 1 : spdm_request.header.request_response_code = SPDM_CHUNK_GET;
552 1 : spdm_request.header.param1 = 0;
553 1 : spdm_request.header.param2 = chunk_handle;
554 1 : spdm_request.chunk_seq_no = 1; /* Bad chunk seq no */
555 :
556 1 : response_size = sizeof(response);
557 1 : status = libspdm_get_response_chunk_get(
558 : spdm_context,
559 : sizeof(spdm_request), &spdm_request,
560 : &response_size, response);
561 :
562 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
563 1 : assert_int_equal(response_size, sizeof(spdm_error_response_t));
564 :
565 1 : spdm_response = (spdm_error_response_t*) response;
566 1 : assert_int_equal(spdm_response->header.spdm_version, SPDM_MESSAGE_VERSION_12);
567 1 : assert_int_equal(spdm_response->header.request_response_code, SPDM_ERROR);
568 1 : assert_int_equal(spdm_response->header.param1, SPDM_ERROR_CODE_INVALID_REQUEST);
569 1 : assert_int_equal(spdm_response->header.param2, 0);
570 1 : }
571 :
572 : /**
573 : * Test 10: Successful request of first chunk.
574 : **/
575 1 : void libspdm_test_responder_chunk_get_rsp_case10(void** state)
576 : {
577 : libspdm_return_t status;
578 : libspdm_test_context_t* spdm_test_context;
579 : libspdm_context_t* spdm_context;
580 : size_t response_size;
581 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
582 : spdm_chunk_response_response_t* spdm_response;
583 : spdm_chunk_get_request_t spdm_request;
584 : void* scratch_buffer;
585 : size_t scratch_buffer_size;
586 :
587 : uint8_t chunk_handle;
588 : uint32_t data_transfer_size;
589 : uint32_t first_chunk_size;
590 : uint32_t second_chunk_size;
591 : uint32_t third_chunk_size;
592 : uint32_t total_chunk_size;
593 : uint32_t large_response;
594 : uint8_t* chunk_ptr;
595 : uint32_t i;
596 :
597 1 : spdm_test_context = *state;
598 1 : spdm_context = spdm_test_context->spdm_context;
599 1 : spdm_test_context->case_id = 10;
600 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 <<
601 : SPDM_VERSION_NUMBER_SHIFT_BIT;
602 :
603 1 : spdm_context->connection_info.connection_state =
604 : LIBSPDM_CONNECTION_STATE_NEGOTIATED;
605 1 : spdm_context->connection_info.algorithm.base_hash_algo =
606 : m_libspdm_use_hash_algo;
607 :
608 1 : data_transfer_size = CHUNK_GET_RESPONDER_UNIT_TEST_DATA_TRANSFER_SIZE;
609 1 : spdm_context->local_context.capability.data_transfer_size = data_transfer_size;
610 1 : spdm_context->local_context.capability.flags |=
611 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHUNK_CAP;
612 1 : spdm_context->connection_info.capability.flags |=
613 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP;
614 :
615 1 : libspdm_get_scratch_buffer(spdm_context, &scratch_buffer, &scratch_buffer_size);
616 :
617 2 : scratch_buffer = (uint8_t*)scratch_buffer +
618 1 : libspdm_get_scratch_buffer_large_message_offset(spdm_context);
619 2 : scratch_buffer_size = scratch_buffer_size -
620 1 : libspdm_get_scratch_buffer_large_message_offset(spdm_context);
621 1 : libspdm_zero_mem(scratch_buffer, scratch_buffer_size);
622 :
623 : /* Fill 1st chunk with 1, 2nd chunk with 2, 3rd chunk with 3 */
624 1 : first_chunk_size = data_transfer_size -
625 : (sizeof(spdm_chunk_response_response_t) + sizeof(uint32_t));
626 1 : second_chunk_size = data_transfer_size - sizeof(spdm_chunk_response_response_t);
627 1 : third_chunk_size = data_transfer_size - sizeof(spdm_chunk_response_response_t);
628 1 : total_chunk_size = first_chunk_size + second_chunk_size + third_chunk_size;
629 1 : LIBSPDM_ASSERT(total_chunk_size <= scratch_buffer_size);
630 :
631 1 : libspdm_set_mem(scratch_buffer, first_chunk_size, 1);
632 1 : libspdm_set_mem((uint8_t*)scratch_buffer + first_chunk_size, second_chunk_size, 2);
633 1 : libspdm_set_mem((uint8_t*) scratch_buffer + first_chunk_size + second_chunk_size,
634 : third_chunk_size, 3);
635 :
636 1 : chunk_handle = (uint8_t) spdm_test_context->case_id; /* Any number is fine */
637 1 : spdm_context->chunk_context.get.chunk_in_use = true;
638 1 : spdm_context->chunk_context.get.chunk_handle = chunk_handle;
639 1 : spdm_context->chunk_context.get.chunk_seq_no = 0;
640 1 : spdm_context->chunk_context.get.large_message = scratch_buffer;
641 1 : spdm_context->chunk_context.get.large_message_size = total_chunk_size;
642 1 : spdm_context->chunk_context.get.chunk_bytes_transferred = 0;
643 :
644 1 : libspdm_zero_mem(&spdm_request, sizeof(spdm_request));
645 1 : spdm_request.header.spdm_version = SPDM_MESSAGE_VERSION_12;
646 1 : spdm_request.header.request_response_code = SPDM_CHUNK_GET;
647 1 : spdm_request.header.param1 = 0;
648 1 : spdm_request.header.param2 = chunk_handle;
649 1 : spdm_request.chunk_seq_no = 0;
650 :
651 1 : response_size = sizeof(response);
652 1 : status = libspdm_get_response_chunk_get(
653 : spdm_context,
654 : sizeof(spdm_request), &spdm_request,
655 : &response_size, response);
656 :
657 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
658 1 : assert_int_equal(response_size, data_transfer_size);
659 :
660 1 : spdm_response = (spdm_chunk_response_response_t*) response;
661 1 : assert_int_equal(spdm_response->header.spdm_version, SPDM_MESSAGE_VERSION_12);
662 1 : assert_int_equal(spdm_response->header.request_response_code, SPDM_CHUNK_RESPONSE);
663 1 : assert_int_equal(spdm_response->header.param1, 0);
664 1 : assert_int_equal(spdm_response->header.param2, chunk_handle);
665 1 : assert_int_equal(spdm_response->chunk_seq_no, 0);
666 1 : assert_int_equal(spdm_response->chunk_size, first_chunk_size);
667 :
668 1 : large_response = *(uint32_t*) (spdm_response + 1);
669 1 : assert_int_equal(large_response, total_chunk_size);
670 :
671 : /* Verify the 1st chunk is filled with 1 */
672 1 : chunk_ptr = (uint8_t*)(((uint32_t*) (spdm_response + 1)) + 1);
673 29 : for (i = 0; i < spdm_response->chunk_size; i++) {
674 28 : assert_int_equal(chunk_ptr[i], 1);
675 : }
676 1 : }
677 :
678 : /**
679 : * Test 11: Successful request of middle chunk.
680 : **/
681 1 : void libspdm_test_responder_chunk_get_rsp_case11(void** state)
682 : {
683 : libspdm_return_t status;
684 : libspdm_test_context_t* spdm_test_context;
685 : libspdm_context_t* spdm_context;
686 : size_t response_size;
687 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
688 : spdm_chunk_response_response_t* spdm_response;
689 : spdm_chunk_get_request_t spdm_request;
690 : void* scratch_buffer;
691 : size_t scratch_buffer_size;
692 :
693 : uint8_t chunk_handle;
694 : uint16_t chunk_seq_no;
695 : uint32_t data_transfer_size;
696 : uint32_t first_chunk_size;
697 : uint32_t second_chunk_size;
698 : uint32_t third_chunk_size;
699 : uint32_t total_chunk_size;
700 : uint8_t* chunk_ptr;
701 : uint32_t i;
702 :
703 1 : spdm_test_context = *state;
704 1 : spdm_context = spdm_test_context->spdm_context;
705 1 : spdm_test_context->case_id = 11;
706 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 <<
707 : SPDM_VERSION_NUMBER_SHIFT_BIT;
708 :
709 1 : spdm_context->connection_info.connection_state =
710 : LIBSPDM_CONNECTION_STATE_NEGOTIATED;
711 1 : spdm_context->connection_info.algorithm.base_hash_algo =
712 : m_libspdm_use_hash_algo;
713 :
714 1 : data_transfer_size = CHUNK_GET_RESPONDER_UNIT_TEST_DATA_TRANSFER_SIZE;
715 1 : spdm_context->local_context.capability.data_transfer_size = data_transfer_size;
716 1 : spdm_context->local_context.capability.flags |=
717 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHUNK_CAP;
718 1 : spdm_context->connection_info.capability.flags |=
719 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP;
720 :
721 1 : libspdm_get_scratch_buffer(spdm_context, &scratch_buffer, &scratch_buffer_size);
722 :
723 2 : scratch_buffer = (uint8_t*)scratch_buffer +
724 1 : libspdm_get_scratch_buffer_large_message_offset(spdm_context);
725 2 : scratch_buffer_size = scratch_buffer_size -
726 1 : libspdm_get_scratch_buffer_large_message_offset(spdm_context);
727 1 : libspdm_zero_mem(scratch_buffer, scratch_buffer_size);
728 :
729 : /* Fill 1st chunk with 1, 2nd chunk with 2, 3rd chunk with 3 */
730 1 : first_chunk_size = data_transfer_size -
731 : (sizeof(spdm_chunk_response_response_t) + sizeof(uint32_t));
732 1 : second_chunk_size = data_transfer_size - sizeof(spdm_chunk_response_response_t);
733 1 : third_chunk_size = data_transfer_size - sizeof(spdm_chunk_response_response_t);
734 1 : total_chunk_size = first_chunk_size + second_chunk_size + third_chunk_size;
735 1 : LIBSPDM_ASSERT(total_chunk_size <= scratch_buffer_size);
736 :
737 1 : libspdm_set_mem(scratch_buffer, first_chunk_size, 1);
738 1 : libspdm_set_mem((uint8_t*) scratch_buffer + first_chunk_size, second_chunk_size, 2);
739 1 : libspdm_set_mem((uint8_t*) scratch_buffer + first_chunk_size + second_chunk_size,
740 : third_chunk_size, 3);
741 :
742 1 : chunk_handle = (uint8_t) spdm_test_context->case_id; /* Any number is fine */
743 1 : chunk_seq_no = 1; /* 1 == 2nd chunk */
744 1 : spdm_context->chunk_context.get.chunk_in_use = true;
745 1 : spdm_context->chunk_context.get.chunk_handle = chunk_handle;
746 1 : spdm_context->chunk_context.get.chunk_seq_no = chunk_seq_no;
747 1 : spdm_context->chunk_context.get.large_message = scratch_buffer;
748 1 : spdm_context->chunk_context.get.large_message_size = total_chunk_size;
749 1 : spdm_context->chunk_context.get.chunk_bytes_transferred = first_chunk_size;
750 :
751 1 : libspdm_zero_mem(&spdm_request, sizeof(spdm_request));
752 1 : spdm_request.header.spdm_version = SPDM_MESSAGE_VERSION_12;
753 1 : spdm_request.header.request_response_code = SPDM_CHUNK_GET;
754 1 : spdm_request.header.param1 = 0;
755 1 : spdm_request.header.param2 = chunk_handle;
756 1 : spdm_request.chunk_seq_no = chunk_seq_no;
757 :
758 1 : response_size = sizeof(response);
759 1 : status = libspdm_get_response_chunk_get(
760 : spdm_context,
761 : sizeof(spdm_request), &spdm_request,
762 : &response_size, response);
763 :
764 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
765 1 : assert_int_equal(response_size, data_transfer_size);
766 :
767 1 : spdm_response = (spdm_chunk_response_response_t*) response;
768 1 : assert_int_equal(spdm_response->header.spdm_version, SPDM_MESSAGE_VERSION_12);
769 1 : assert_int_equal(spdm_response->header.request_response_code, SPDM_CHUNK_RESPONSE);
770 1 : assert_int_equal(spdm_response->header.param1, 0);
771 1 : assert_int_equal(spdm_response->header.param2, chunk_handle);
772 1 : assert_int_equal(spdm_response->chunk_seq_no, chunk_seq_no);
773 1 : assert_int_equal(spdm_response->chunk_size, second_chunk_size);
774 :
775 : /* Verify the 2nd chunk is filled with 2 */
776 1 : chunk_ptr = (uint8_t*) (spdm_response + 1);
777 33 : for (i = 0; i < spdm_response->chunk_size; i++) {
778 32 : assert_int_equal(chunk_ptr[i], 2);
779 : }
780 1 : }
781 :
782 : /**
783 : * Test 12: Successful request of last chunk where size is exactly max chunk size
784 : **/
785 1 : void libspdm_test_responder_chunk_get_rsp_case12(void** state)
786 : {
787 : libspdm_return_t status;
788 : libspdm_test_context_t* spdm_test_context;
789 : libspdm_context_t* spdm_context;
790 : size_t response_size;
791 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
792 : spdm_chunk_response_response_t* spdm_response;
793 : spdm_chunk_get_request_t spdm_request;
794 : void* scratch_buffer;
795 : size_t scratch_buffer_size;
796 :
797 : uint8_t chunk_handle;
798 : uint16_t chunk_seq_no;
799 : uint32_t data_transfer_size;
800 : uint32_t first_chunk_size;
801 : uint32_t second_chunk_size;
802 : uint32_t third_chunk_size;
803 : uint32_t total_chunk_size;
804 : uint8_t* chunk_ptr;
805 : uint32_t i;
806 :
807 1 : spdm_test_context = *state;
808 1 : spdm_context = spdm_test_context->spdm_context;
809 1 : spdm_test_context->case_id = 12;
810 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 <<
811 : SPDM_VERSION_NUMBER_SHIFT_BIT;
812 :
813 1 : spdm_context->connection_info.connection_state =
814 : LIBSPDM_CONNECTION_STATE_NEGOTIATED;
815 1 : spdm_context->connection_info.algorithm.base_hash_algo =
816 : m_libspdm_use_hash_algo;
817 :
818 1 : data_transfer_size = CHUNK_GET_RESPONDER_UNIT_TEST_DATA_TRANSFER_SIZE;
819 1 : spdm_context->local_context.capability.data_transfer_size = data_transfer_size;
820 1 : spdm_context->local_context.capability.flags |=
821 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHUNK_CAP;
822 1 : spdm_context->connection_info.capability.flags |=
823 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP;
824 :
825 1 : libspdm_get_scratch_buffer(spdm_context, &scratch_buffer, &scratch_buffer_size);
826 :
827 2 : scratch_buffer = (uint8_t*)scratch_buffer +
828 1 : libspdm_get_scratch_buffer_large_message_offset(spdm_context);
829 2 : scratch_buffer_size = scratch_buffer_size -
830 1 : libspdm_get_scratch_buffer_large_message_offset(spdm_context);
831 1 : libspdm_zero_mem(scratch_buffer, scratch_buffer_size);
832 :
833 : /* Fill 1st chunk with 1, 2nd chunk with 2, 3rd chunk with 3 */
834 1 : first_chunk_size = data_transfer_size -
835 : (sizeof(spdm_chunk_response_response_t) + sizeof(uint32_t));
836 1 : second_chunk_size = data_transfer_size - sizeof(spdm_chunk_response_response_t);
837 1 : third_chunk_size = data_transfer_size - sizeof(spdm_chunk_response_response_t);
838 1 : total_chunk_size = first_chunk_size + second_chunk_size + third_chunk_size;
839 1 : LIBSPDM_ASSERT(total_chunk_size <= scratch_buffer_size);
840 :
841 1 : libspdm_set_mem(scratch_buffer, first_chunk_size, 1);
842 1 : libspdm_set_mem((uint8_t*) scratch_buffer + first_chunk_size, second_chunk_size, 2);
843 1 : libspdm_set_mem((uint8_t*) scratch_buffer + first_chunk_size + second_chunk_size,
844 : third_chunk_size, 3);
845 :
846 1 : chunk_handle = (uint8_t) spdm_test_context->case_id; /* Any number is fine */
847 1 : chunk_seq_no = 2; /* 2 == 3rd chunk */
848 1 : spdm_context->chunk_context.get.chunk_in_use = true;
849 1 : spdm_context->chunk_context.get.chunk_handle = chunk_handle;
850 1 : spdm_context->chunk_context.get.chunk_seq_no = chunk_seq_no;
851 1 : spdm_context->chunk_context.get.large_message = scratch_buffer;
852 1 : spdm_context->chunk_context.get.large_message_size = total_chunk_size;
853 1 : spdm_context->chunk_context.get.chunk_bytes_transferred = first_chunk_size + second_chunk_size;
854 :
855 1 : libspdm_zero_mem(&spdm_request, sizeof(spdm_request));
856 1 : spdm_request.header.spdm_version = SPDM_MESSAGE_VERSION_12;
857 1 : spdm_request.header.request_response_code = SPDM_CHUNK_GET;
858 1 : spdm_request.header.param1 = 0;
859 1 : spdm_request.header.param2 = chunk_handle;
860 1 : spdm_request.chunk_seq_no = chunk_seq_no;
861 :
862 1 : response_size = sizeof(response);
863 1 : status = libspdm_get_response_chunk_get(
864 : spdm_context,
865 : sizeof(spdm_request), &spdm_request,
866 : &response_size, response);
867 :
868 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
869 1 : assert_int_equal(response_size, data_transfer_size);
870 :
871 1 : spdm_response = (spdm_chunk_response_response_t*) response;
872 1 : assert_int_equal(spdm_response->header.spdm_version, SPDM_MESSAGE_VERSION_12);
873 1 : assert_int_equal(spdm_response->header.request_response_code, SPDM_CHUNK_RESPONSE);
874 1 : assert_int_equal(spdm_response->header.param1, SPDM_CHUNK_GET_RESPONSE_ATTRIBUTE_LAST_CHUNK);
875 1 : assert_int_equal(spdm_response->header.param2, chunk_handle);
876 1 : assert_int_equal(spdm_response->chunk_seq_no, chunk_seq_no);
877 1 : assert_int_equal(spdm_response->chunk_size, third_chunk_size);
878 :
879 : /* Verify the 3rd chunk is filled with 3 */
880 1 : chunk_ptr = (uint8_t*) (spdm_response + 1);
881 33 : for (i = 0; i < spdm_response->chunk_size; i++) {
882 32 : assert_int_equal(chunk_ptr[i], 3);
883 : }
884 1 : }
885 :
886 : /**
887 : * Test 13: Successful request of last chunk where size is exactly 1.
888 : **/
889 1 : void libspdm_test_responder_chunk_get_rsp_case13(void** state)
890 : {
891 : libspdm_return_t status;
892 : libspdm_test_context_t* spdm_test_context;
893 : libspdm_context_t* spdm_context;
894 : size_t response_size;
895 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
896 : spdm_chunk_response_response_t* spdm_response;
897 : spdm_chunk_get_request_t spdm_request;
898 : void* scratch_buffer;
899 : size_t scratch_buffer_size;
900 :
901 : uint8_t chunk_handle;
902 : uint16_t chunk_seq_no;
903 : uint32_t data_transfer_size;
904 : uint32_t first_chunk_size;
905 : uint32_t second_chunk_size;
906 : uint32_t third_chunk_size;
907 : uint32_t total_chunk_size;
908 : uint32_t fourth_chunk_size;
909 : uint32_t expected_response_size;
910 : uint8_t* chunk_ptr;
911 : uint32_t i;
912 :
913 1 : spdm_test_context = *state;
914 1 : spdm_context = spdm_test_context->spdm_context;
915 1 : spdm_test_context->case_id = 12;
916 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 <<
917 : SPDM_VERSION_NUMBER_SHIFT_BIT;
918 :
919 1 : spdm_context->connection_info.connection_state =
920 : LIBSPDM_CONNECTION_STATE_NEGOTIATED;
921 1 : spdm_context->connection_info.algorithm.base_hash_algo =
922 : m_libspdm_use_hash_algo;
923 :
924 1 : data_transfer_size = CHUNK_GET_RESPONDER_UNIT_TEST_DATA_TRANSFER_SIZE;
925 1 : spdm_context->local_context.capability.data_transfer_size = data_transfer_size;
926 1 : spdm_context->local_context.capability.flags |=
927 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHUNK_CAP;
928 1 : spdm_context->connection_info.capability.flags |=
929 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP;
930 :
931 1 : libspdm_get_scratch_buffer(spdm_context, &scratch_buffer, &scratch_buffer_size);
932 :
933 2 : scratch_buffer = (uint8_t*)scratch_buffer +
934 1 : libspdm_get_scratch_buffer_large_message_offset(spdm_context);
935 2 : scratch_buffer_size = scratch_buffer_size -
936 1 : libspdm_get_scratch_buffer_large_message_offset(spdm_context);
937 1 : libspdm_zero_mem(scratch_buffer, scratch_buffer_size);
938 :
939 : /* Fill 1st chunk with 1, 2nd chunk with 2, 3rd chunk with 3, 4th chunk with 4 */
940 1 : first_chunk_size = data_transfer_size -
941 : (sizeof(spdm_chunk_response_response_t) + sizeof(uint32_t));
942 1 : second_chunk_size = data_transfer_size - sizeof(spdm_chunk_response_response_t);
943 1 : third_chunk_size = data_transfer_size - sizeof(spdm_chunk_response_response_t);
944 1 : fourth_chunk_size = 1;
945 :
946 1 : total_chunk_size = first_chunk_size + second_chunk_size + third_chunk_size + fourth_chunk_size;
947 1 : expected_response_size = sizeof(spdm_chunk_response_response_t) + fourth_chunk_size;
948 1 : LIBSPDM_ASSERT(total_chunk_size <= scratch_buffer_size);
949 :
950 1 : libspdm_set_mem(scratch_buffer, first_chunk_size, 1);
951 1 : libspdm_set_mem((uint8_t*) scratch_buffer + first_chunk_size, second_chunk_size, 2);
952 1 : libspdm_set_mem((uint8_t*) scratch_buffer + first_chunk_size + second_chunk_size,
953 : third_chunk_size, 3);
954 1 : libspdm_set_mem((uint8_t*) scratch_buffer + first_chunk_size
955 1 : + second_chunk_size + third_chunk_size,
956 : fourth_chunk_size, 4);
957 :
958 1 : chunk_handle = (uint8_t) spdm_test_context->case_id; /* Any number is fine */
959 1 : chunk_seq_no = 3; /* 3 == 4th chunk */
960 1 : spdm_context->chunk_context.get.chunk_in_use = true;
961 1 : spdm_context->chunk_context.get.chunk_handle = chunk_handle;
962 1 : spdm_context->chunk_context.get.chunk_seq_no = chunk_seq_no;
963 1 : spdm_context->chunk_context.get.large_message = scratch_buffer;
964 1 : spdm_context->chunk_context.get.large_message_size = total_chunk_size;
965 1 : spdm_context->chunk_context.get.chunk_bytes_transferred =
966 1 : first_chunk_size + second_chunk_size + third_chunk_size;
967 :
968 1 : libspdm_zero_mem(&spdm_request, sizeof(spdm_request));
969 1 : spdm_request.header.spdm_version = SPDM_MESSAGE_VERSION_12;
970 1 : spdm_request.header.request_response_code = SPDM_CHUNK_GET;
971 1 : spdm_request.header.param1 = 0;
972 1 : spdm_request.header.param2 = chunk_handle;
973 1 : spdm_request.chunk_seq_no = chunk_seq_no;
974 :
975 1 : response_size = sizeof(response);
976 1 : status = libspdm_get_response_chunk_get(
977 : spdm_context,
978 : sizeof(spdm_request), &spdm_request,
979 : &response_size, response);
980 :
981 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
982 1 : assert_int_equal(response_size, expected_response_size);
983 :
984 1 : spdm_response = (spdm_chunk_response_response_t*) response;
985 1 : assert_int_equal(spdm_response->header.spdm_version, SPDM_MESSAGE_VERSION_12);
986 1 : assert_int_equal(spdm_response->header.request_response_code, SPDM_CHUNK_RESPONSE);
987 1 : assert_int_equal(spdm_response->header.param1, SPDM_CHUNK_GET_RESPONSE_ATTRIBUTE_LAST_CHUNK);
988 1 : assert_int_equal(spdm_response->header.param2, chunk_handle);
989 1 : assert_int_equal(spdm_response->chunk_seq_no, chunk_seq_no);
990 1 : assert_int_equal(spdm_response->chunk_size, fourth_chunk_size);
991 :
992 : /* Verify the 4th chunk is filled with 4 */
993 1 : chunk_ptr = (uint8_t*)(spdm_response + 1);
994 2 : for (i = 0; i < spdm_response->chunk_size; i++) {
995 1 : assert_int_equal(chunk_ptr[i], 4);
996 : }
997 1 : }
998 :
999 :
1000 : /**
1001 : * Test 14: Responder has response exceed chunk seq no
1002 : **/
1003 1 : void libspdm_test_responder_chunk_get_rsp_case14(void** state)
1004 : {
1005 : libspdm_return_t status;
1006 : libspdm_test_context_t* spdm_test_context;
1007 : libspdm_context_t* spdm_context;
1008 : size_t response_size;
1009 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
1010 : spdm_error_response_t* spdm_response;
1011 : spdm_chunk_get_request_t spdm_request;
1012 : void* scratch_buffer;
1013 : size_t scratch_buffer_size;
1014 :
1015 : uint8_t chunk_handle;
1016 : uint32_t data_transfer_size;
1017 : uint32_t total_chunk_size;
1018 :
1019 1 : spdm_test_context = *state;
1020 1 : spdm_context = spdm_test_context->spdm_context;
1021 1 : spdm_test_context->case_id = 10;
1022 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 <<
1023 : SPDM_VERSION_NUMBER_SHIFT_BIT;
1024 :
1025 1 : spdm_context->connection_info.connection_state =
1026 : LIBSPDM_CONNECTION_STATE_NEGOTIATED;
1027 1 : spdm_context->connection_info.algorithm.base_hash_algo =
1028 : m_libspdm_use_hash_algo;
1029 :
1030 1 : data_transfer_size = CHUNK_GET_RESPONDER_UNIT_TEST_DATA_TRANSFER_SIZE;
1031 1 : spdm_context->local_context.capability.data_transfer_size = data_transfer_size;
1032 1 : spdm_context->local_context.capability.flags |=
1033 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHUNK_CAP;
1034 1 : spdm_context->connection_info.capability.flags |=
1035 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP;
1036 :
1037 : /* large response need a large scratch buffer */
1038 1 : spdm_context->connection_info.capability.max_spdm_msg_size = data_transfer_size * 65536;
1039 1 : spdm_context->local_context.capability.max_spdm_msg_size = data_transfer_size * 65536;
1040 1 : spdm_test_context->scratch_buffer_size =
1041 1 : libspdm_get_sizeof_required_scratch_buffer(spdm_context);
1042 1 : spdm_test_context->scratch_buffer = (void *)malloc(spdm_test_context->scratch_buffer_size);
1043 1 : libspdm_set_scratch_buffer (spdm_context,
1044 : spdm_test_context->scratch_buffer,
1045 : spdm_test_context->scratch_buffer_size);
1046 :
1047 :
1048 1 : libspdm_get_scratch_buffer(spdm_context, &scratch_buffer, &scratch_buffer_size);
1049 :
1050 2 : scratch_buffer = (uint8_t*)scratch_buffer +
1051 1 : libspdm_get_scratch_buffer_large_message_offset(spdm_context);
1052 2 : scratch_buffer_size = scratch_buffer_size -
1053 1 : libspdm_get_scratch_buffer_large_message_offset(spdm_context);
1054 1 : libspdm_zero_mem(scratch_buffer, scratch_buffer_size);
1055 :
1056 : /* a huge chunk size to cause the chunk seq no wrap */
1057 1 : total_chunk_size = data_transfer_size * 65536;
1058 :
1059 1 : LIBSPDM_ASSERT(total_chunk_size <= scratch_buffer_size);
1060 :
1061 1 : chunk_handle = (uint8_t) spdm_test_context->case_id; /* Any number is fine */
1062 1 : spdm_context->chunk_context.get.chunk_in_use = true;
1063 1 : spdm_context->chunk_context.get.chunk_handle = chunk_handle;
1064 1 : spdm_context->chunk_context.get.chunk_seq_no = 0;
1065 1 : spdm_context->chunk_context.get.large_message = scratch_buffer;
1066 1 : spdm_context->chunk_context.get.large_message_size = total_chunk_size;
1067 1 : spdm_context->chunk_context.get.chunk_bytes_transferred = 0;
1068 :
1069 1 : libspdm_zero_mem(&spdm_request, sizeof(spdm_request));
1070 1 : spdm_request.header.spdm_version = SPDM_MESSAGE_VERSION_12;
1071 1 : spdm_request.header.request_response_code = SPDM_CHUNK_GET;
1072 1 : spdm_request.header.param1 = 0;
1073 1 : spdm_request.header.param2 = chunk_handle;
1074 1 : spdm_request.chunk_seq_no = 0;
1075 :
1076 1 : response_size = sizeof(response);
1077 1 : status = libspdm_get_response_chunk_get(
1078 : spdm_context,
1079 : sizeof(spdm_request), &spdm_request,
1080 : &response_size, response);
1081 :
1082 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
1083 1 : assert_int_equal(response_size, sizeof(spdm_error_response_t));
1084 :
1085 1 : spdm_response = (spdm_error_response_t*) response;
1086 :
1087 1 : assert_int_equal(spdm_response->header.spdm_version, SPDM_MESSAGE_VERSION_12);
1088 1 : assert_int_equal(spdm_response->header.request_response_code, SPDM_ERROR);
1089 1 : assert_int_equal(spdm_response->header.param1, SPDM_ERROR_CODE_RESPONSE_TOO_LARGE);
1090 1 : assert_int_equal(spdm_response->header.param2, 0);
1091 1 : }
1092 :
1093 :
1094 1 : int libspdm_responder_chunk_get_rsp_test_main(void)
1095 : {
1096 1 : const struct CMUnitTest spdm_responder_chunk_get_tests[] = {
1097 : /* Responder has no response flag chunk cap */
1098 : cmocka_unit_test(libspdm_test_responder_chunk_get_rsp_case1),
1099 : /* Responder has response state != NORMAL */
1100 : cmocka_unit_test(libspdm_test_responder_chunk_get_rsp_case2),
1101 : /* Responder has connection state <= NOT_START */
1102 : cmocka_unit_test(libspdm_test_responder_chunk_get_rsp_case3),
1103 : /* Request has wrong size */
1104 : cmocka_unit_test(libspdm_test_responder_chunk_get_rsp_case4),
1105 : /* Request has wrong SPDM version */
1106 : cmocka_unit_test(libspdm_test_responder_chunk_get_rsp_case5),
1107 : /* Responder has no chunk saved to get */
1108 : cmocka_unit_test(libspdm_test_responder_chunk_get_rsp_case6),
1109 : /* Responder has handle that does not match request */
1110 : cmocka_unit_test(libspdm_test_responder_chunk_get_rsp_case7),
1111 : /* Responder has earlier sequence number than request */
1112 : cmocka_unit_test(libspdm_test_responder_chunk_get_rsp_case8),
1113 : /* Responder has later sequence number than request*/
1114 : cmocka_unit_test(libspdm_test_responder_chunk_get_rsp_case9),
1115 : /* Successful request of first chunk */
1116 : cmocka_unit_test(libspdm_test_responder_chunk_get_rsp_case10),
1117 : /* Successful request of middle chunk */
1118 : cmocka_unit_test(libspdm_test_responder_chunk_get_rsp_case11),
1119 : /* Successful request of last chunk, where size is exactly max chunk size */
1120 : cmocka_unit_test(libspdm_test_responder_chunk_get_rsp_case12),
1121 : /* Successful request of last chunk where chunk size is exactly 1 byte */
1122 : cmocka_unit_test(libspdm_test_responder_chunk_get_rsp_case13),
1123 : /* Responder has response exceed chunk seq no */
1124 : cmocka_unit_test(libspdm_test_responder_chunk_get_rsp_case14),
1125 : };
1126 :
1127 1 : libspdm_test_context_t test_context = {
1128 : LIBSPDM_TEST_CONTEXT_VERSION,
1129 : false,
1130 : };
1131 :
1132 1 : libspdm_setup_test_context(&test_context);
1133 :
1134 1 : return cmocka_run_group_tests(spdm_responder_chunk_get_tests,
1135 : libspdm_unit_test_group_setup,
1136 : libspdm_unit_test_group_teardown);
1137 : }
1138 :
1139 : #endif /* LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP*/
|