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 : static void rsp_chunk_response_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 : static void rsp_chunk_response_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 : static void rsp_chunk_response_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 : static void rsp_chunk_response_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 : static void rsp_chunk_response_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 : static void rsp_chunk_response_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 : static void rsp_chunk_response_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 : static void rsp_chunk_response_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 : static void rsp_chunk_response_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 : static void rsp_chunk_response_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 : static void rsp_chunk_response_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 : static void rsp_chunk_response_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 : static void rsp_chunk_response_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 : static void rsp_chunk_response_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 : * Test 15: Successful request of first chunk, spdm 1.4.
1095 : **/
1096 1 : static void rsp_chunk_response_case15(void** state)
1097 : {
1098 : libspdm_return_t status;
1099 : libspdm_test_context_t* spdm_test_context;
1100 : libspdm_context_t* spdm_context;
1101 : size_t response_size;
1102 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
1103 : spdm_chunk_response_response_14_t* spdm_response;
1104 : spdm_chunk_get_request_14_t spdm_request;
1105 : void* scratch_buffer;
1106 : size_t scratch_buffer_size;
1107 :
1108 : uint8_t chunk_handle;
1109 : uint32_t data_transfer_size;
1110 : uint32_t first_chunk_size;
1111 : uint32_t second_chunk_size;
1112 : uint32_t third_chunk_size;
1113 : uint32_t total_chunk_size;
1114 : uint32_t large_response;
1115 : uint8_t* chunk_ptr;
1116 : uint32_t i;
1117 :
1118 1 : spdm_test_context = *state;
1119 1 : spdm_context = spdm_test_context->spdm_context;
1120 1 : spdm_test_context->case_id = 15;
1121 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_14 <<
1122 : SPDM_VERSION_NUMBER_SHIFT_BIT;
1123 :
1124 1 : spdm_context->connection_info.connection_state =
1125 : LIBSPDM_CONNECTION_STATE_NEGOTIATED;
1126 1 : spdm_context->connection_info.algorithm.base_hash_algo =
1127 : m_libspdm_use_hash_algo;
1128 :
1129 1 : data_transfer_size = CHUNK_GET_RESPONDER_UNIT_TEST_DATA_TRANSFER_SIZE;
1130 1 : spdm_context->local_context.capability.data_transfer_size = data_transfer_size;
1131 1 : spdm_context->local_context.capability.flags |=
1132 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHUNK_CAP;
1133 1 : spdm_context->connection_info.capability.flags |=
1134 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP;
1135 :
1136 1 : libspdm_get_scratch_buffer(spdm_context, &scratch_buffer, &scratch_buffer_size);
1137 :
1138 2 : scratch_buffer = (uint8_t*)scratch_buffer +
1139 1 : libspdm_get_scratch_buffer_large_message_offset(spdm_context);
1140 2 : scratch_buffer_size = scratch_buffer_size -
1141 1 : libspdm_get_scratch_buffer_large_message_offset(spdm_context);
1142 1 : libspdm_zero_mem(scratch_buffer, scratch_buffer_size);
1143 :
1144 : /* Fill 1st chunk with 1, 2nd chunk with 2, 3rd chunk with 3 */
1145 1 : first_chunk_size = data_transfer_size -
1146 : (sizeof(spdm_chunk_response_response_14_t) + sizeof(uint32_t));
1147 1 : second_chunk_size = data_transfer_size - sizeof(spdm_chunk_response_response_14_t);
1148 1 : third_chunk_size = data_transfer_size - sizeof(spdm_chunk_response_response_14_t);
1149 1 : total_chunk_size = first_chunk_size + second_chunk_size + third_chunk_size;
1150 1 : LIBSPDM_ASSERT(total_chunk_size <= scratch_buffer_size);
1151 :
1152 1 : libspdm_set_mem(scratch_buffer, first_chunk_size, 1);
1153 1 : libspdm_set_mem((uint8_t*)scratch_buffer + first_chunk_size, second_chunk_size, 2);
1154 1 : libspdm_set_mem((uint8_t*) scratch_buffer + first_chunk_size + second_chunk_size,
1155 : third_chunk_size, 3);
1156 :
1157 1 : chunk_handle = (uint8_t) spdm_test_context->case_id; /* Any number is fine */
1158 1 : spdm_context->chunk_context.get.chunk_in_use = true;
1159 1 : spdm_context->chunk_context.get.chunk_handle = chunk_handle;
1160 1 : spdm_context->chunk_context.get.chunk_seq_no = 0;
1161 1 : spdm_context->chunk_context.get.large_message = scratch_buffer;
1162 1 : spdm_context->chunk_context.get.large_message_size = total_chunk_size;
1163 1 : spdm_context->chunk_context.get.chunk_bytes_transferred = 0;
1164 :
1165 1 : libspdm_zero_mem(&spdm_request, sizeof(spdm_request));
1166 1 : spdm_request.header.spdm_version = SPDM_MESSAGE_VERSION_14;
1167 1 : spdm_request.header.request_response_code = SPDM_CHUNK_GET;
1168 1 : spdm_request.header.param1 = 0;
1169 1 : spdm_request.header.param2 = chunk_handle;
1170 1 : spdm_request.chunk_seq_no = 0;
1171 :
1172 1 : response_size = sizeof(response);
1173 1 : status = libspdm_get_response_chunk_get(
1174 : spdm_context,
1175 : sizeof(spdm_request), &spdm_request,
1176 : &response_size, response);
1177 :
1178 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
1179 1 : assert_int_equal(response_size, data_transfer_size);
1180 :
1181 1 : spdm_response = (spdm_chunk_response_response_14_t*) response;
1182 1 : assert_int_equal(spdm_response->header.spdm_version, SPDM_MESSAGE_VERSION_14);
1183 1 : assert_int_equal(spdm_response->header.request_response_code, SPDM_CHUNK_RESPONSE);
1184 1 : assert_int_equal(spdm_response->header.param1, 0);
1185 1 : assert_int_equal(spdm_response->header.param2, chunk_handle);
1186 1 : assert_int_equal(spdm_response->chunk_seq_no, 0);
1187 1 : assert_int_equal(spdm_response->chunk_size, first_chunk_size);
1188 :
1189 1 : large_response = *(uint32_t*) (spdm_response + 1);
1190 1 : assert_int_equal(large_response, total_chunk_size);
1191 :
1192 : /* Verify the 1st chunk is filled with 1 */
1193 1 : chunk_ptr = (uint8_t*)(((uint32_t*) (spdm_response + 1)) + 1);
1194 29 : for (i = 0; i < spdm_response->chunk_size; i++) {
1195 28 : assert_int_equal(chunk_ptr[i], 1);
1196 : }
1197 1 : }
1198 :
1199 : /**
1200 : * Test 16: Successful request of middle chunk, spdm 1.4.
1201 : **/
1202 1 : static void rsp_chunk_response_case16(void** state)
1203 : {
1204 : libspdm_return_t status;
1205 : libspdm_test_context_t* spdm_test_context;
1206 : libspdm_context_t* spdm_context;
1207 : size_t response_size;
1208 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
1209 : spdm_chunk_response_response_14_t* spdm_response;
1210 : spdm_chunk_get_request_14_t spdm_request;
1211 : void* scratch_buffer;
1212 : size_t scratch_buffer_size;
1213 :
1214 : uint8_t chunk_handle;
1215 : uint32_t chunk_seq_no;
1216 : uint32_t data_transfer_size;
1217 : uint32_t first_chunk_size;
1218 : uint32_t second_chunk_size;
1219 : uint32_t third_chunk_size;
1220 : uint32_t total_chunk_size;
1221 : uint8_t* chunk_ptr;
1222 : uint32_t i;
1223 :
1224 1 : spdm_test_context = *state;
1225 1 : spdm_context = spdm_test_context->spdm_context;
1226 1 : spdm_test_context->case_id = 16;
1227 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_14 <<
1228 : SPDM_VERSION_NUMBER_SHIFT_BIT;
1229 :
1230 1 : spdm_context->connection_info.connection_state =
1231 : LIBSPDM_CONNECTION_STATE_NEGOTIATED;
1232 1 : spdm_context->connection_info.algorithm.base_hash_algo =
1233 : m_libspdm_use_hash_algo;
1234 :
1235 1 : data_transfer_size = CHUNK_GET_RESPONDER_UNIT_TEST_DATA_TRANSFER_SIZE;
1236 1 : spdm_context->local_context.capability.data_transfer_size = data_transfer_size;
1237 1 : spdm_context->local_context.capability.flags |=
1238 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHUNK_CAP;
1239 1 : spdm_context->connection_info.capability.flags |=
1240 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP;
1241 :
1242 1 : libspdm_get_scratch_buffer(spdm_context, &scratch_buffer, &scratch_buffer_size);
1243 :
1244 2 : scratch_buffer = (uint8_t*)scratch_buffer +
1245 1 : libspdm_get_scratch_buffer_large_message_offset(spdm_context);
1246 2 : scratch_buffer_size = scratch_buffer_size -
1247 1 : libspdm_get_scratch_buffer_large_message_offset(spdm_context);
1248 1 : libspdm_zero_mem(scratch_buffer, scratch_buffer_size);
1249 :
1250 : /* Fill 1st chunk with 1, 2nd chunk with 2, 3rd chunk with 3 */
1251 1 : first_chunk_size = data_transfer_size -
1252 : (sizeof(spdm_chunk_response_response_14_t) + sizeof(uint32_t));
1253 1 : second_chunk_size = data_transfer_size - sizeof(spdm_chunk_response_response_14_t);
1254 1 : third_chunk_size = data_transfer_size - sizeof(spdm_chunk_response_response_14_t);
1255 1 : total_chunk_size = first_chunk_size + second_chunk_size + third_chunk_size;
1256 1 : LIBSPDM_ASSERT(total_chunk_size <= scratch_buffer_size);
1257 :
1258 1 : libspdm_set_mem(scratch_buffer, first_chunk_size, 1);
1259 1 : libspdm_set_mem((uint8_t*) scratch_buffer + first_chunk_size, second_chunk_size, 2);
1260 1 : libspdm_set_mem((uint8_t*) scratch_buffer + first_chunk_size + second_chunk_size,
1261 : third_chunk_size, 3);
1262 :
1263 1 : chunk_handle = (uint8_t) spdm_test_context->case_id; /* Any number is fine */
1264 1 : chunk_seq_no = 1; /* 1 == 2nd chunk */
1265 1 : spdm_context->chunk_context.get.chunk_in_use = true;
1266 1 : spdm_context->chunk_context.get.chunk_handle = chunk_handle;
1267 1 : spdm_context->chunk_context.get.chunk_seq_no = chunk_seq_no;
1268 1 : spdm_context->chunk_context.get.large_message = scratch_buffer;
1269 1 : spdm_context->chunk_context.get.large_message_size = total_chunk_size;
1270 1 : spdm_context->chunk_context.get.chunk_bytes_transferred = first_chunk_size;
1271 :
1272 1 : libspdm_zero_mem(&spdm_request, sizeof(spdm_request));
1273 1 : spdm_request.header.spdm_version = SPDM_MESSAGE_VERSION_14;
1274 1 : spdm_request.header.request_response_code = SPDM_CHUNK_GET;
1275 1 : spdm_request.header.param1 = 0;
1276 1 : spdm_request.header.param2 = chunk_handle;
1277 1 : spdm_request.chunk_seq_no = chunk_seq_no;
1278 :
1279 1 : response_size = sizeof(response);
1280 1 : status = libspdm_get_response_chunk_get(
1281 : spdm_context,
1282 : sizeof(spdm_request), &spdm_request,
1283 : &response_size, response);
1284 :
1285 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
1286 1 : assert_int_equal(response_size, data_transfer_size);
1287 :
1288 1 : spdm_response = (spdm_chunk_response_response_14_t*) response;
1289 1 : assert_int_equal(spdm_response->header.spdm_version, SPDM_MESSAGE_VERSION_14);
1290 1 : assert_int_equal(spdm_response->header.request_response_code, SPDM_CHUNK_RESPONSE);
1291 1 : assert_int_equal(spdm_response->header.param1, 0);
1292 1 : assert_int_equal(spdm_response->header.param2, chunk_handle);
1293 1 : assert_int_equal(spdm_response->chunk_seq_no, chunk_seq_no);
1294 1 : assert_int_equal(spdm_response->chunk_size, second_chunk_size);
1295 :
1296 : /* Verify the 2nd chunk is filled with 2 */
1297 1 : chunk_ptr = (uint8_t*) (spdm_response + 1);
1298 33 : for (i = 0; i < spdm_response->chunk_size; i++) {
1299 32 : assert_int_equal(chunk_ptr[i], 2);
1300 : }
1301 1 : }
1302 :
1303 : /**
1304 : * Test 17: Successful request of last chunk where size is exactly max chunk size
1305 : **/
1306 1 : static void rsp_chunk_response_case17(void** state)
1307 : {
1308 : libspdm_return_t status;
1309 : libspdm_test_context_t* spdm_test_context;
1310 : libspdm_context_t* spdm_context;
1311 : size_t response_size;
1312 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
1313 : spdm_chunk_response_response_14_t* spdm_response;
1314 : spdm_chunk_get_request_14_t spdm_request;
1315 : void* scratch_buffer;
1316 : size_t scratch_buffer_size;
1317 :
1318 : uint8_t chunk_handle;
1319 : uint32_t chunk_seq_no;
1320 : uint32_t data_transfer_size;
1321 : uint32_t first_chunk_size;
1322 : uint32_t second_chunk_size;
1323 : uint32_t third_chunk_size;
1324 : uint32_t total_chunk_size;
1325 : uint8_t* chunk_ptr;
1326 : uint32_t i;
1327 :
1328 1 : spdm_test_context = *state;
1329 1 : spdm_context = spdm_test_context->spdm_context;
1330 1 : spdm_test_context->case_id = 17;
1331 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_14 <<
1332 : SPDM_VERSION_NUMBER_SHIFT_BIT;
1333 :
1334 1 : spdm_context->connection_info.connection_state =
1335 : LIBSPDM_CONNECTION_STATE_NEGOTIATED;
1336 1 : spdm_context->connection_info.algorithm.base_hash_algo =
1337 : m_libspdm_use_hash_algo;
1338 :
1339 1 : data_transfer_size = CHUNK_GET_RESPONDER_UNIT_TEST_DATA_TRANSFER_SIZE;
1340 1 : spdm_context->local_context.capability.data_transfer_size = data_transfer_size;
1341 1 : spdm_context->local_context.capability.flags |=
1342 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHUNK_CAP;
1343 1 : spdm_context->connection_info.capability.flags |=
1344 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP;
1345 :
1346 1 : libspdm_get_scratch_buffer(spdm_context, &scratch_buffer, &scratch_buffer_size);
1347 :
1348 2 : scratch_buffer = (uint8_t*)scratch_buffer +
1349 1 : libspdm_get_scratch_buffer_large_message_offset(spdm_context);
1350 2 : scratch_buffer_size = scratch_buffer_size -
1351 1 : libspdm_get_scratch_buffer_large_message_offset(spdm_context);
1352 1 : libspdm_zero_mem(scratch_buffer, scratch_buffer_size);
1353 :
1354 : /* Fill 1st chunk with 1, 2nd chunk with 2, 3rd chunk with 3 */
1355 1 : first_chunk_size = data_transfer_size -
1356 : (sizeof(spdm_chunk_response_response_14_t) + sizeof(uint32_t));
1357 1 : second_chunk_size = data_transfer_size - sizeof(spdm_chunk_response_response_14_t);
1358 1 : third_chunk_size = data_transfer_size - sizeof(spdm_chunk_response_response_14_t);
1359 1 : total_chunk_size = first_chunk_size + second_chunk_size + third_chunk_size;
1360 1 : LIBSPDM_ASSERT(total_chunk_size <= scratch_buffer_size);
1361 :
1362 1 : libspdm_set_mem(scratch_buffer, first_chunk_size, 1);
1363 1 : libspdm_set_mem((uint8_t*) scratch_buffer + first_chunk_size, second_chunk_size, 2);
1364 1 : libspdm_set_mem((uint8_t*) scratch_buffer + first_chunk_size + second_chunk_size,
1365 : third_chunk_size, 3);
1366 :
1367 1 : chunk_handle = (uint8_t) spdm_test_context->case_id; /* Any number is fine */
1368 1 : chunk_seq_no = 2; /* 2 == 3rd chunk */
1369 1 : spdm_context->chunk_context.get.chunk_in_use = true;
1370 1 : spdm_context->chunk_context.get.chunk_handle = chunk_handle;
1371 1 : spdm_context->chunk_context.get.chunk_seq_no = chunk_seq_no;
1372 1 : spdm_context->chunk_context.get.large_message = scratch_buffer;
1373 1 : spdm_context->chunk_context.get.large_message_size = total_chunk_size;
1374 1 : spdm_context->chunk_context.get.chunk_bytes_transferred = first_chunk_size + second_chunk_size;
1375 :
1376 1 : libspdm_zero_mem(&spdm_request, sizeof(spdm_request));
1377 1 : spdm_request.header.spdm_version = SPDM_MESSAGE_VERSION_14;
1378 1 : spdm_request.header.request_response_code = SPDM_CHUNK_GET;
1379 1 : spdm_request.header.param1 = 0;
1380 1 : spdm_request.header.param2 = chunk_handle;
1381 1 : spdm_request.chunk_seq_no = chunk_seq_no;
1382 :
1383 1 : response_size = sizeof(response);
1384 1 : status = libspdm_get_response_chunk_get(
1385 : spdm_context,
1386 : sizeof(spdm_request), &spdm_request,
1387 : &response_size, response);
1388 :
1389 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
1390 1 : assert_int_equal(response_size, data_transfer_size);
1391 :
1392 1 : spdm_response = (spdm_chunk_response_response_14_t*) response;
1393 1 : assert_int_equal(spdm_response->header.spdm_version, SPDM_MESSAGE_VERSION_14);
1394 1 : assert_int_equal(spdm_response->header.request_response_code, SPDM_CHUNK_RESPONSE);
1395 1 : assert_int_equal(spdm_response->header.param1, SPDM_CHUNK_GET_RESPONSE_ATTRIBUTE_LAST_CHUNK);
1396 1 : assert_int_equal(spdm_response->header.param2, chunk_handle);
1397 1 : assert_int_equal(spdm_response->chunk_seq_no, chunk_seq_no);
1398 1 : assert_int_equal(spdm_response->chunk_size, third_chunk_size);
1399 :
1400 : /* Verify the 3rd chunk is filled with 3 */
1401 1 : chunk_ptr = (uint8_t*) (spdm_response + 1);
1402 33 : for (i = 0; i < spdm_response->chunk_size; i++) {
1403 32 : assert_int_equal(chunk_ptr[i], 3);
1404 : }
1405 1 : }
1406 :
1407 : /**
1408 : * Test 18: Successful request of last chunk where size is exactly 1.
1409 : **/
1410 1 : static void rsp_chunk_response_case18(void** state)
1411 : {
1412 : libspdm_return_t status;
1413 : libspdm_test_context_t* spdm_test_context;
1414 : libspdm_context_t* spdm_context;
1415 : size_t response_size;
1416 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
1417 : spdm_chunk_response_response_14_t* spdm_response;
1418 : spdm_chunk_get_request_14_t spdm_request;
1419 : void* scratch_buffer;
1420 : size_t scratch_buffer_size;
1421 :
1422 : uint8_t chunk_handle;
1423 : uint16_t chunk_seq_no;
1424 : uint32_t data_transfer_size;
1425 : uint32_t first_chunk_size;
1426 : uint32_t second_chunk_size;
1427 : uint32_t third_chunk_size;
1428 : uint32_t total_chunk_size;
1429 : uint32_t fourth_chunk_size;
1430 : uint32_t expected_response_size;
1431 : uint8_t* chunk_ptr;
1432 : uint32_t i;
1433 :
1434 1 : spdm_test_context = *state;
1435 1 : spdm_context = spdm_test_context->spdm_context;
1436 1 : spdm_test_context->case_id = 18;
1437 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_14 <<
1438 : SPDM_VERSION_NUMBER_SHIFT_BIT;
1439 :
1440 1 : spdm_context->connection_info.connection_state =
1441 : LIBSPDM_CONNECTION_STATE_NEGOTIATED;
1442 1 : spdm_context->connection_info.algorithm.base_hash_algo =
1443 : m_libspdm_use_hash_algo;
1444 :
1445 1 : data_transfer_size = CHUNK_GET_RESPONDER_UNIT_TEST_DATA_TRANSFER_SIZE;
1446 1 : spdm_context->local_context.capability.data_transfer_size = data_transfer_size;
1447 1 : spdm_context->local_context.capability.flags |=
1448 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHUNK_CAP;
1449 1 : spdm_context->connection_info.capability.flags |=
1450 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP;
1451 :
1452 1 : libspdm_get_scratch_buffer(spdm_context, &scratch_buffer, &scratch_buffer_size);
1453 :
1454 2 : scratch_buffer = (uint8_t*)scratch_buffer +
1455 1 : libspdm_get_scratch_buffer_large_message_offset(spdm_context);
1456 2 : scratch_buffer_size = scratch_buffer_size -
1457 1 : libspdm_get_scratch_buffer_large_message_offset(spdm_context);
1458 1 : libspdm_zero_mem(scratch_buffer, scratch_buffer_size);
1459 :
1460 : /* Fill 1st chunk with 1, 2nd chunk with 2, 3rd chunk with 3, 4th chunk with 4 */
1461 1 : first_chunk_size = data_transfer_size -
1462 : (sizeof(spdm_chunk_response_response_14_t) + sizeof(uint32_t));
1463 1 : second_chunk_size = data_transfer_size - sizeof(spdm_chunk_response_response_14_t);
1464 1 : third_chunk_size = data_transfer_size - sizeof(spdm_chunk_response_response_14_t);
1465 1 : fourth_chunk_size = 1;
1466 :
1467 1 : total_chunk_size = first_chunk_size + second_chunk_size + third_chunk_size + fourth_chunk_size;
1468 1 : expected_response_size = sizeof(spdm_chunk_response_response_14_t) + fourth_chunk_size;
1469 1 : LIBSPDM_ASSERT(total_chunk_size <= scratch_buffer_size);
1470 :
1471 1 : libspdm_set_mem(scratch_buffer, first_chunk_size, 1);
1472 1 : libspdm_set_mem((uint8_t*) scratch_buffer + first_chunk_size, second_chunk_size, 2);
1473 1 : libspdm_set_mem((uint8_t*) scratch_buffer + first_chunk_size + second_chunk_size,
1474 : third_chunk_size, 3);
1475 1 : libspdm_set_mem((uint8_t*) scratch_buffer + first_chunk_size
1476 1 : + second_chunk_size + third_chunk_size,
1477 : fourth_chunk_size, 4);
1478 :
1479 1 : chunk_handle = (uint8_t) spdm_test_context->case_id; /* Any number is fine */
1480 1 : chunk_seq_no = 3; /* 3 == 4th chunk */
1481 1 : spdm_context->chunk_context.get.chunk_in_use = true;
1482 1 : spdm_context->chunk_context.get.chunk_handle = chunk_handle;
1483 1 : spdm_context->chunk_context.get.chunk_seq_no = chunk_seq_no;
1484 1 : spdm_context->chunk_context.get.large_message = scratch_buffer;
1485 1 : spdm_context->chunk_context.get.large_message_size = total_chunk_size;
1486 1 : spdm_context->chunk_context.get.chunk_bytes_transferred =
1487 1 : first_chunk_size + second_chunk_size + third_chunk_size;
1488 :
1489 1 : libspdm_zero_mem(&spdm_request, sizeof(spdm_request));
1490 1 : spdm_request.header.spdm_version = SPDM_MESSAGE_VERSION_14;
1491 1 : spdm_request.header.request_response_code = SPDM_CHUNK_GET;
1492 1 : spdm_request.header.param1 = 0;
1493 1 : spdm_request.header.param2 = chunk_handle;
1494 1 : spdm_request.chunk_seq_no = chunk_seq_no;
1495 :
1496 1 : response_size = sizeof(response);
1497 1 : status = libspdm_get_response_chunk_get(
1498 : spdm_context,
1499 : sizeof(spdm_request), &spdm_request,
1500 : &response_size, response);
1501 :
1502 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
1503 1 : assert_int_equal(response_size, expected_response_size);
1504 :
1505 1 : spdm_response = (spdm_chunk_response_response_14_t*) response;
1506 1 : assert_int_equal(spdm_response->header.spdm_version, SPDM_MESSAGE_VERSION_14);
1507 1 : assert_int_equal(spdm_response->header.request_response_code, SPDM_CHUNK_RESPONSE);
1508 1 : assert_int_equal(spdm_response->header.param1, SPDM_CHUNK_GET_RESPONSE_ATTRIBUTE_LAST_CHUNK);
1509 1 : assert_int_equal(spdm_response->header.param2, chunk_handle);
1510 1 : assert_int_equal(spdm_response->chunk_seq_no, chunk_seq_no);
1511 1 : assert_int_equal(spdm_response->chunk_size, fourth_chunk_size);
1512 :
1513 : /* Verify the 4th chunk is filled with 4 */
1514 1 : chunk_ptr = (uint8_t*)(spdm_response + 1);
1515 2 : for (i = 0; i < spdm_response->chunk_size; i++) {
1516 1 : assert_int_equal(chunk_ptr[i], 4);
1517 : }
1518 1 : }
1519 :
1520 :
1521 1 : int libspdm_rsp_chunk_response_test(void)
1522 : {
1523 1 : const struct CMUnitTest test_cases[] = {
1524 : /* Responder has no response flag chunk cap */
1525 : cmocka_unit_test(rsp_chunk_response_case1),
1526 : /* Responder has response state != NORMAL */
1527 : cmocka_unit_test(rsp_chunk_response_case2),
1528 : /* Responder has connection state <= NOT_START */
1529 : cmocka_unit_test(rsp_chunk_response_case3),
1530 : /* Request has wrong size */
1531 : cmocka_unit_test(rsp_chunk_response_case4),
1532 : /* Request has wrong SPDM version */
1533 : cmocka_unit_test(rsp_chunk_response_case5),
1534 : /* Responder has no chunk saved to get */
1535 : cmocka_unit_test(rsp_chunk_response_case6),
1536 : /* Responder has handle that does not match request */
1537 : cmocka_unit_test(rsp_chunk_response_case7),
1538 : /* Responder has earlier sequence number than request */
1539 : cmocka_unit_test(rsp_chunk_response_case8),
1540 : /* Responder has later sequence number than request*/
1541 : cmocka_unit_test(rsp_chunk_response_case9),
1542 : /* Successful request of first chunk */
1543 : cmocka_unit_test(rsp_chunk_response_case10),
1544 : /* Successful request of middle chunk */
1545 : cmocka_unit_test(rsp_chunk_response_case11),
1546 : /* Successful request of last chunk, where size is exactly max chunk size */
1547 : cmocka_unit_test(rsp_chunk_response_case12),
1548 : /* Successful request of last chunk where chunk size is exactly 1 byte */
1549 : cmocka_unit_test(rsp_chunk_response_case13),
1550 : /* Responder has response exceed chunk seq no */
1551 : cmocka_unit_test(rsp_chunk_response_case14),
1552 : /* Successful request of first chunk, spdm 1.4*/
1553 : cmocka_unit_test(rsp_chunk_response_case15),
1554 : /* Successful request of middle chunk, spdm 1.4 */
1555 : cmocka_unit_test(rsp_chunk_response_case16),
1556 : /* Successful request of last chunk, where size is exactly max chunk size, spdm 1.4 */
1557 : cmocka_unit_test(rsp_chunk_response_case17),
1558 : /* Successful request of last chunk where chunk size is exactly 1 byte, spdm 1.4 */
1559 : cmocka_unit_test(rsp_chunk_response_case18),
1560 : };
1561 :
1562 1 : libspdm_test_context_t test_context = {
1563 : LIBSPDM_TEST_CONTEXT_VERSION,
1564 : false,
1565 : };
1566 :
1567 1 : libspdm_setup_test_context(&test_context);
1568 :
1569 1 : return cmocka_run_group_tests(test_cases,
1570 : libspdm_unit_test_group_setup,
1571 : libspdm_unit_test_group_teardown);
1572 : }
1573 :
1574 : #endif /* LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP*/
|