Line data Source code
1 : /**
2 : * Copyright Notice:
3 : * Copyright 2021-2026 DMTF. All rights reserved.
4 : * License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/libspdm/blob/main/LICENSE.md
5 : **/
6 :
7 : #include "spdm_unit_test.h"
8 : #include "internal/libspdm_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 = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
37 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
38 :
39 1 : spdm_context->connection_info.capability.data_transfer_size =
40 : CHUNK_GET_RESPONDER_UNIT_TEST_DATA_TRANSFER_SIZE;
41 :
42 1 : libspdm_zero_mem(&spdm_request, sizeof(spdm_request));
43 1 : spdm_request.header.spdm_version = SPDM_MESSAGE_VERSION_12;
44 1 : spdm_request.header.request_response_code = SPDM_CHUNK_GET;
45 1 : spdm_request.header.param1 = 0;
46 1 : spdm_request.header.param2 = 0;
47 1 : spdm_request.chunk_seq_no = 0;
48 :
49 1 : response_size = sizeof(response);
50 1 : status = libspdm_get_response_chunk_get(
51 : spdm_context,
52 : sizeof(spdm_request), &spdm_request,
53 : &response_size, response);
54 :
55 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
56 1 : assert_int_equal(response_size, sizeof(spdm_error_response_t));
57 :
58 1 : spdm_response = (spdm_error_response_t*) response;
59 1 : assert_int_equal(spdm_response->header.spdm_version, SPDM_MESSAGE_VERSION_12);
60 1 : assert_int_equal(spdm_response->header.request_response_code, SPDM_ERROR);
61 1 : assert_int_equal(spdm_response->header.param1, SPDM_ERROR_CODE_UNEXPECTED_REQUEST);
62 1 : assert_int_equal(spdm_response->header.param2, 0);
63 1 : }
64 :
65 : /**
66 : * Test 2: Responder receives a CHUNK_GET request with bad response state.
67 : * Expected Behavior: Returns ERROR response message with an error code.
68 : **/
69 1 : static void rsp_chunk_response_case2(void** state)
70 : {
71 : libspdm_return_t status;
72 : libspdm_test_context_t* spdm_test_context;
73 : libspdm_context_t* spdm_context;
74 : size_t response_size;
75 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
76 : spdm_error_response_t* spdm_response;
77 : spdm_chunk_get_request_t spdm_request;
78 :
79 1 : spdm_test_context = *state;
80 1 : spdm_context = spdm_test_context->spdm_context;
81 1 : spdm_test_context->case_id = 2;
82 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 <<
83 : SPDM_VERSION_NUMBER_SHIFT_BIT;
84 :
85 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
86 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
87 :
88 1 : spdm_context->local_context.capability.data_transfer_size =
89 : CHUNK_GET_RESPONDER_UNIT_TEST_DATA_TRANSFER_SIZE;
90 :
91 1 : spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHUNK_CAP;
92 1 : spdm_context->connection_info.capability.flags |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP;
93 :
94 : /* Set bad response state */
95 1 : spdm_context->response_state = LIBSPDM_RESPONSE_STATE_BUSY;
96 :
97 1 : libspdm_zero_mem(&spdm_request, sizeof(spdm_request));
98 1 : spdm_request.header.spdm_version = SPDM_MESSAGE_VERSION_12;
99 1 : spdm_request.header.request_response_code = SPDM_CHUNK_GET;
100 1 : spdm_request.header.param1 = 0;
101 1 : spdm_request.header.param2 = 0;
102 1 : spdm_request.chunk_seq_no = 0;
103 :
104 1 : response_size = sizeof(response);
105 1 : status = libspdm_get_response_chunk_get(
106 : spdm_context,
107 : sizeof(spdm_request), &spdm_request,
108 : &response_size, response);
109 :
110 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
111 1 : assert_int_equal(response_size, sizeof(spdm_error_response_t));
112 :
113 1 : spdm_response = (spdm_error_response_t*) response;
114 1 : assert_int_equal(spdm_response->header.spdm_version, SPDM_MESSAGE_VERSION_12);
115 1 : assert_int_equal(spdm_response->header.request_response_code, SPDM_ERROR);
116 1 : assert_int_equal(spdm_response->header.param1, SPDM_ERROR_CODE_BUSY);
117 1 : assert_int_equal(spdm_response->header.param2, 0);
118 1 : }
119 :
120 : /**
121 : * Test 3: Responder receives a CHUNK_GET request with bad connection state.
122 : * Expected Behavior: Returns ERROR response message
123 : * with SPDM_ERROR_CODE_UNEXPECTED_REQUEST error code.
124 : **/
125 1 : static void rsp_chunk_response_case3(void** state)
126 : {
127 : libspdm_return_t status;
128 : libspdm_test_context_t* spdm_test_context;
129 : libspdm_context_t* spdm_context;
130 : size_t response_size;
131 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
132 : spdm_error_response_t* spdm_response;
133 : spdm_chunk_get_request_t spdm_request;
134 :
135 1 : spdm_test_context = *state;
136 1 : spdm_context = spdm_test_context->spdm_context;
137 1 : spdm_test_context->case_id = 3;
138 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 <<
139 : SPDM_VERSION_NUMBER_SHIFT_BIT;
140 :
141 : /* Set bad connection_state */
142 1 : spdm_context->connection_info.connection_state =
143 : LIBSPDM_CONNECTION_STATE_AFTER_CAPABILITIES - 1;
144 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
145 :
146 1 : spdm_context->local_context.capability.data_transfer_size =
147 : CHUNK_GET_RESPONDER_UNIT_TEST_DATA_TRANSFER_SIZE;
148 1 : spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHUNK_CAP;
149 1 : spdm_context->connection_info.capability.flags |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP;
150 1 : spdm_context->response_state = LIBSPDM_RESPONSE_STATE_NORMAL;
151 :
152 1 : libspdm_zero_mem(&spdm_request, sizeof(spdm_request));
153 1 : spdm_request.header.spdm_version = SPDM_MESSAGE_VERSION_12;
154 1 : spdm_request.header.request_response_code = SPDM_CHUNK_GET;
155 1 : spdm_request.header.param1 = 0;
156 1 : spdm_request.header.param2 = 0; /* Handle */
157 1 : spdm_request.chunk_seq_no = 0;
158 :
159 1 : response_size = sizeof(response);
160 1 : status = libspdm_get_response_chunk_get(
161 : spdm_context,
162 : sizeof(spdm_request), &spdm_request,
163 : &response_size, response);
164 :
165 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
166 1 : assert_int_equal(response_size, sizeof(spdm_error_response_t));
167 :
168 1 : spdm_response = (spdm_error_response_t*) response;
169 1 : assert_int_equal(spdm_response->header.spdm_version, SPDM_MESSAGE_VERSION_12);
170 1 : assert_int_equal(spdm_response->header.request_response_code, SPDM_ERROR);
171 1 : assert_int_equal(spdm_response->header.param1, SPDM_ERROR_CODE_UNEXPECTED_REQUEST);
172 1 : assert_int_equal(spdm_response->header.param2, 0);
173 1 : }
174 :
175 : /**
176 : * Test 4: Responder receives a CHUNK_GET request with bad size.
177 : * Expected Behavior: Returns ERROR response message
178 : * with SPDM_ERROR_CODE_INVALID_REQUEST error code.
179 : **/
180 1 : static void rsp_chunk_response_case4(void** state)
181 : {
182 : libspdm_return_t status;
183 : libspdm_test_context_t* spdm_test_context;
184 : libspdm_context_t* spdm_context;
185 : size_t response_size;
186 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
187 : spdm_error_response_t* spdm_response;
188 : spdm_chunk_get_request_t spdm_request;
189 :
190 1 : spdm_test_context = *state;
191 1 : spdm_context = spdm_test_context->spdm_context;
192 1 : spdm_test_context->case_id = 4;
193 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 <<
194 : SPDM_VERSION_NUMBER_SHIFT_BIT;
195 :
196 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_AFTER_CAPABILITIES;
197 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
198 :
199 1 : spdm_context->local_context.capability.data_transfer_size =
200 : CHUNK_GET_RESPONDER_UNIT_TEST_DATA_TRANSFER_SIZE;
201 :
202 1 : spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHUNK_CAP;
203 1 : spdm_context->connection_info.capability.flags |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP;
204 :
205 1 : libspdm_zero_mem(&spdm_request, sizeof(spdm_request));
206 1 : spdm_request.header.spdm_version = SPDM_MESSAGE_VERSION_12;
207 1 : spdm_request.header.request_response_code = SPDM_CHUNK_GET;
208 1 : spdm_request.header.param1 = 0;
209 1 : spdm_request.header.param2 = 0;
210 1 : spdm_request.chunk_seq_no = 0;
211 :
212 1 : response_size = sizeof(response);
213 1 : status = libspdm_get_response_chunk_get(
214 : spdm_context,
215 : sizeof(spdm_request) - 1, &spdm_request, /* Bad request size */
216 : &response_size, response);
217 :
218 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
219 1 : assert_int_equal(response_size, sizeof(spdm_error_response_t));
220 :
221 1 : spdm_response = (spdm_error_response_t*) response;
222 1 : assert_int_equal(spdm_response->header.spdm_version, SPDM_MESSAGE_VERSION_12);
223 1 : assert_int_equal(spdm_response->header.request_response_code, SPDM_ERROR);
224 1 : assert_int_equal(spdm_response->header.param1, SPDM_ERROR_CODE_INVALID_REQUEST);
225 1 : assert_int_equal(spdm_response->header.param2, 0);
226 1 : }
227 :
228 : /**
229 : * Test 5: Responder receives a CHUNK_GET request with wrong SPDM version.
230 : * Expected Behavior: Returns ERROR response message
231 : * with SPDM_ERROR_CODE_VERSION_MISMATCH error code.
232 : **/
233 1 : static void rsp_chunk_response_case5(void** state)
234 : {
235 : libspdm_return_t status;
236 : libspdm_test_context_t* spdm_test_context;
237 : libspdm_context_t* spdm_context;
238 : size_t response_size;
239 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
240 : spdm_error_response_t* spdm_response;
241 : spdm_chunk_get_request_t spdm_request;
242 :
243 1 : spdm_test_context = *state;
244 1 : spdm_context = spdm_test_context->spdm_context;
245 1 : spdm_test_context->case_id = 5;
246 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 <<
247 : SPDM_VERSION_NUMBER_SHIFT_BIT;
248 :
249 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_AFTER_CAPABILITIES;
250 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
251 :
252 1 : spdm_context->local_context.capability.data_transfer_size =
253 : CHUNK_GET_RESPONDER_UNIT_TEST_DATA_TRANSFER_SIZE;
254 1 : spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHUNK_CAP;
255 1 : spdm_context->connection_info.capability.flags |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP;
256 :
257 1 : libspdm_zero_mem(&spdm_request, sizeof(spdm_request));
258 1 : spdm_request.header.spdm_version = SPDM_MESSAGE_VERSION_11; /* Mismatching SPDM version */
259 1 : spdm_request.header.request_response_code = SPDM_CHUNK_GET;
260 1 : spdm_request.header.param1 = 0;
261 1 : spdm_request.header.param2 = 0;
262 1 : spdm_request.chunk_seq_no = 0;
263 :
264 1 : response_size = sizeof(response);
265 1 : status = libspdm_get_response_chunk_get(
266 : spdm_context,
267 : sizeof(spdm_request), &spdm_request,
268 : &response_size, response);
269 :
270 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
271 1 : assert_int_equal(response_size, sizeof(spdm_error_response_t));
272 :
273 1 : spdm_response = (spdm_error_response_t*) response;
274 1 : assert_int_equal(spdm_response->header.spdm_version, SPDM_MESSAGE_VERSION_12);
275 1 : assert_int_equal(spdm_response->header.request_response_code, SPDM_ERROR);
276 1 : assert_int_equal(spdm_response->header.param1, SPDM_ERROR_CODE_UNSUPPORTED_REQUEST);
277 1 : assert_int_equal(spdm_response->header.param2, SPDM_CHUNK_GET);
278 1 : }
279 :
280 : /**
281 : * Test 6: Responder has no chunk saved to get.
282 : **/
283 1 : static void rsp_chunk_response_case6(void** state)
284 : {
285 : libspdm_return_t status;
286 : libspdm_test_context_t* spdm_test_context;
287 : libspdm_context_t* spdm_context;
288 : size_t response_size;
289 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
290 : spdm_error_response_t* spdm_response;
291 : spdm_chunk_get_request_t spdm_request;
292 :
293 1 : spdm_test_context = *state;
294 1 : spdm_context = spdm_test_context->spdm_context;
295 1 : spdm_test_context->case_id = 6;
296 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 <<
297 : SPDM_VERSION_NUMBER_SHIFT_BIT;
298 :
299 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_AFTER_CAPABILITIES;
300 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
301 :
302 1 : spdm_context->local_context.capability.data_transfer_size =
303 : CHUNK_GET_RESPONDER_UNIT_TEST_DATA_TRANSFER_SIZE;
304 1 : spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHUNK_CAP;
305 1 : spdm_context->connection_info.capability.flags |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP;
306 :
307 : /* Set no chunk saved */
308 1 : spdm_context->chunk_context.get.chunk_in_use = false;
309 :
310 1 : libspdm_zero_mem(&spdm_request, sizeof(spdm_request));
311 1 : spdm_request.header.spdm_version = SPDM_MESSAGE_VERSION_12;
312 1 : spdm_request.header.request_response_code = SPDM_CHUNK_GET;
313 1 : spdm_request.header.param1 = 0;
314 1 : spdm_request.header.param2 = 0;
315 1 : spdm_request.chunk_seq_no = 0;
316 :
317 1 : response_size = sizeof(response);
318 1 : status = libspdm_get_response_chunk_get(
319 : spdm_context,
320 : sizeof(spdm_request), &spdm_request,
321 : &response_size, response);
322 :
323 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
324 1 : assert_int_equal(response_size, sizeof(spdm_error_response_t));
325 :
326 1 : spdm_response = (spdm_error_response_t*) response;
327 1 : assert_int_equal(spdm_response->header.spdm_version, SPDM_MESSAGE_VERSION_12);
328 1 : assert_int_equal(spdm_response->header.request_response_code, SPDM_ERROR);
329 1 : assert_int_equal(spdm_response->header.param1, SPDM_ERROR_CODE_UNEXPECTED_REQUEST);
330 1 : assert_int_equal(spdm_response->header.param2, 0);
331 1 : }
332 :
333 : /**
334 : * Test 7: Responder has handle that does not match request.
335 : **/
336 1 : static void rsp_chunk_response_case7(void** state)
337 : {
338 : libspdm_return_t status;
339 : libspdm_test_context_t* spdm_test_context;
340 : libspdm_context_t* spdm_context;
341 : size_t response_size;
342 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
343 : spdm_error_response_t* spdm_response;
344 : spdm_chunk_get_request_t spdm_request;
345 : void* scratch_buffer;
346 : size_t scratch_buffer_size;
347 :
348 : uint8_t chunk_handle;
349 :
350 1 : spdm_test_context = *state;
351 1 : spdm_context = spdm_test_context->spdm_context;
352 1 : spdm_test_context->case_id = 7;
353 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 <<
354 : SPDM_VERSION_NUMBER_SHIFT_BIT;
355 :
356 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_AFTER_CAPABILITIES;
357 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
358 :
359 1 : spdm_context->local_context.capability.data_transfer_size =
360 : CHUNK_GET_RESPONDER_UNIT_TEST_DATA_TRANSFER_SIZE;
361 1 : spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHUNK_CAP;
362 1 : spdm_context->connection_info.capability.flags |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP;
363 :
364 1 : libspdm_get_scratch_buffer(spdm_context, &scratch_buffer, &scratch_buffer_size);
365 :
366 2 : scratch_buffer = (uint8_t*)scratch_buffer +
367 1 : libspdm_get_scratch_buffer_large_message_offset(spdm_context);
368 2 : scratch_buffer_size = scratch_buffer_size -
369 1 : libspdm_get_scratch_buffer_large_message_offset(spdm_context);
370 1 : libspdm_zero_mem(scratch_buffer, scratch_buffer_size);
371 :
372 1 : chunk_handle = (uint8_t) spdm_test_context->case_id;
373 1 : spdm_context->chunk_context.get.chunk_in_use = true;
374 1 : spdm_context->chunk_context.get.chunk_handle = (uint8_t) spdm_test_context->case_id;
375 1 : spdm_context->chunk_context.get.chunk_seq_no = chunk_handle;
376 1 : spdm_context->chunk_context.get.large_message = scratch_buffer;
377 1 : spdm_context->chunk_context.get.large_message_size = scratch_buffer_size;
378 :
379 1 : libspdm_zero_mem(&spdm_request, sizeof(spdm_request));
380 1 : spdm_request.header.spdm_version = SPDM_MESSAGE_VERSION_12;
381 1 : spdm_request.header.request_response_code = SPDM_CHUNK_GET;
382 1 : spdm_request.header.param1 = 0;
383 1 : spdm_request.header.param2 = chunk_handle - 1; /* Bad chunk handle */
384 1 : spdm_request.chunk_seq_no = 0;
385 :
386 1 : response_size = sizeof(response);
387 1 : status = libspdm_get_response_chunk_get(
388 : spdm_context,
389 : sizeof(spdm_request), &spdm_request,
390 : &response_size, response);
391 :
392 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
393 1 : assert_int_equal(response_size, sizeof(spdm_error_response_t));
394 :
395 1 : spdm_response = (spdm_error_response_t*) response;
396 1 : assert_int_equal(spdm_response->header.spdm_version, SPDM_MESSAGE_VERSION_12);
397 1 : assert_int_equal(spdm_response->header.request_response_code, SPDM_ERROR);
398 1 : assert_int_equal(spdm_response->header.param1, SPDM_ERROR_CODE_INVALID_REQUEST);
399 1 : assert_int_equal(spdm_response->header.param2, 0);
400 1 : }
401 :
402 : /**
403 : * Test 8: Responder has earlier sequence number than request .
404 : **/
405 1 : static void rsp_chunk_response_case8(void** state)
406 : {
407 : libspdm_return_t status;
408 : libspdm_test_context_t* spdm_test_context;
409 : libspdm_context_t* spdm_context;
410 : size_t response_size;
411 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
412 : spdm_error_response_t* spdm_response;
413 : spdm_chunk_get_request_t spdm_request;
414 : void* scratch_buffer;
415 : size_t scratch_buffer_size;
416 : uint8_t chunk_handle;
417 :
418 1 : spdm_test_context = *state;
419 1 : spdm_context = spdm_test_context->spdm_context;
420 1 : spdm_test_context->case_id = 8;
421 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 <<
422 : SPDM_VERSION_NUMBER_SHIFT_BIT;
423 :
424 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
425 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
426 :
427 1 : spdm_context->local_context.capability.data_transfer_size =
428 : CHUNK_GET_RESPONDER_UNIT_TEST_DATA_TRANSFER_SIZE;
429 1 : spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHUNK_CAP;
430 1 : spdm_context->connection_info.capability.flags |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP;
431 :
432 1 : libspdm_get_scratch_buffer(spdm_context, &scratch_buffer, &scratch_buffer_size);
433 :
434 2 : scratch_buffer = (uint8_t*)scratch_buffer +
435 1 : libspdm_get_scratch_buffer_large_message_offset(spdm_context);
436 2 : scratch_buffer_size = scratch_buffer_size -
437 1 : libspdm_get_scratch_buffer_large_message_offset(spdm_context);
438 1 : libspdm_zero_mem(scratch_buffer, scratch_buffer_size);
439 :
440 1 : chunk_handle = (uint8_t) spdm_test_context->case_id;
441 1 : spdm_context->chunk_context.get.chunk_in_use = true;
442 1 : spdm_context->chunk_context.get.chunk_handle = chunk_handle;
443 1 : spdm_context->chunk_context.get.chunk_seq_no = 0;
444 1 : spdm_context->chunk_context.get.large_message = scratch_buffer;
445 1 : spdm_context->chunk_context.get.large_message_size = scratch_buffer_size;
446 :
447 1 : libspdm_zero_mem(&spdm_request, sizeof(spdm_request));
448 1 : spdm_request.header.spdm_version = SPDM_MESSAGE_VERSION_12;
449 1 : spdm_request.header.request_response_code = SPDM_CHUNK_GET;
450 1 : spdm_request.header.param1 = 0;
451 1 : spdm_request.header.param2 = chunk_handle;
452 1 : spdm_request.chunk_seq_no = 1; /* Bad chunk seq no */
453 :
454 1 : response_size = sizeof(response);
455 1 : status = libspdm_get_response_chunk_get(
456 : spdm_context,
457 : sizeof(spdm_request), &spdm_request,
458 : &response_size, response);
459 :
460 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
461 1 : assert_int_equal(response_size, sizeof(spdm_error_response_t));
462 :
463 1 : spdm_response = (spdm_error_response_t*) response;
464 1 : assert_int_equal(spdm_response->header.spdm_version, SPDM_MESSAGE_VERSION_12);
465 1 : assert_int_equal(spdm_response->header.request_response_code, SPDM_ERROR);
466 1 : assert_int_equal(spdm_response->header.param1, SPDM_ERROR_CODE_INVALID_REQUEST);
467 1 : assert_int_equal(spdm_response->header.param2, 0);
468 1 : }
469 :
470 : /**
471 : * Test 9: Responder has later sequence number than request.
472 : **/
473 1 : static void rsp_chunk_response_case9(void** state)
474 : {
475 : libspdm_return_t status;
476 : libspdm_test_context_t* spdm_test_context;
477 : libspdm_context_t* spdm_context;
478 : size_t response_size;
479 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
480 : spdm_error_response_t* spdm_response;
481 : spdm_chunk_get_request_t spdm_request;
482 : void* scratch_buffer;
483 : size_t scratch_buffer_size;
484 : uint8_t chunk_handle;
485 :
486 1 : spdm_test_context = *state;
487 1 : spdm_context = spdm_test_context->spdm_context;
488 1 : spdm_test_context->case_id = 9;
489 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 <<
490 : SPDM_VERSION_NUMBER_SHIFT_BIT;
491 :
492 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
493 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
494 :
495 1 : spdm_context->local_context.capability.data_transfer_size =
496 : CHUNK_GET_RESPONDER_UNIT_TEST_DATA_TRANSFER_SIZE;
497 1 : spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHUNK_CAP;
498 1 : spdm_context->connection_info.capability.flags |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP;
499 :
500 1 : libspdm_get_scratch_buffer(spdm_context, &scratch_buffer, &scratch_buffer_size);
501 :
502 2 : scratch_buffer = (uint8_t*)scratch_buffer +
503 1 : libspdm_get_scratch_buffer_large_message_offset(spdm_context);
504 2 : scratch_buffer_size = scratch_buffer_size -
505 1 : libspdm_get_scratch_buffer_large_message_offset(spdm_context);
506 1 : libspdm_zero_mem(scratch_buffer, scratch_buffer_size);
507 :
508 1 : chunk_handle = (uint8_t) spdm_test_context->case_id;
509 1 : spdm_context->chunk_context.get.chunk_in_use = true;
510 1 : spdm_context->chunk_context.get.chunk_handle = chunk_handle;
511 1 : spdm_context->chunk_context.get.chunk_seq_no = 0;
512 1 : spdm_context->chunk_context.get.large_message = scratch_buffer;
513 1 : spdm_context->chunk_context.get.large_message_size = scratch_buffer_size;
514 1 : spdm_context->chunk_context.get.chunk_bytes_transferred = 0;
515 :
516 1 : libspdm_zero_mem(&spdm_request, sizeof(spdm_request));
517 1 : spdm_request.header.spdm_version = SPDM_MESSAGE_VERSION_12;
518 1 : spdm_request.header.request_response_code = SPDM_CHUNK_GET;
519 1 : spdm_request.header.param1 = 0;
520 1 : spdm_request.header.param2 = chunk_handle;
521 1 : spdm_request.chunk_seq_no = 1; /* Bad chunk seq no */
522 :
523 1 : response_size = sizeof(response);
524 1 : status = libspdm_get_response_chunk_get(
525 : spdm_context,
526 : sizeof(spdm_request), &spdm_request,
527 : &response_size, response);
528 :
529 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
530 1 : assert_int_equal(response_size, sizeof(spdm_error_response_t));
531 :
532 1 : spdm_response = (spdm_error_response_t*) response;
533 1 : assert_int_equal(spdm_response->header.spdm_version, SPDM_MESSAGE_VERSION_12);
534 1 : assert_int_equal(spdm_response->header.request_response_code, SPDM_ERROR);
535 1 : assert_int_equal(spdm_response->header.param1, SPDM_ERROR_CODE_INVALID_REQUEST);
536 1 : assert_int_equal(spdm_response->header.param2, 0);
537 1 : }
538 :
539 : /**
540 : * Test 10: Successful request of first chunk.
541 : **/
542 1 : static void rsp_chunk_response_case10(void** state)
543 : {
544 : libspdm_return_t status;
545 : libspdm_test_context_t* spdm_test_context;
546 : libspdm_context_t* spdm_context;
547 : size_t response_size;
548 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
549 : spdm_chunk_response_response_t* spdm_response;
550 : spdm_chunk_get_request_t spdm_request;
551 : void* scratch_buffer;
552 : size_t scratch_buffer_size;
553 :
554 : uint8_t chunk_handle;
555 : uint32_t data_transfer_size;
556 : uint32_t first_chunk_size;
557 : uint32_t second_chunk_size;
558 : uint32_t third_chunk_size;
559 : uint32_t total_chunk_size;
560 : uint32_t large_response;
561 : uint8_t* chunk_ptr;
562 : uint32_t i;
563 :
564 1 : spdm_test_context = *state;
565 1 : spdm_context = spdm_test_context->spdm_context;
566 1 : spdm_test_context->case_id = 10;
567 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 <<
568 : SPDM_VERSION_NUMBER_SHIFT_BIT;
569 :
570 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
571 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
572 :
573 1 : data_transfer_size = CHUNK_GET_RESPONDER_UNIT_TEST_DATA_TRANSFER_SIZE;
574 1 : spdm_context->local_context.capability.data_transfer_size = data_transfer_size;
575 1 : spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHUNK_CAP;
576 1 : spdm_context->connection_info.capability.flags |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP;
577 :
578 1 : libspdm_get_scratch_buffer(spdm_context, &scratch_buffer, &scratch_buffer_size);
579 :
580 2 : scratch_buffer = (uint8_t*)scratch_buffer +
581 1 : libspdm_get_scratch_buffer_large_message_offset(spdm_context);
582 2 : scratch_buffer_size = scratch_buffer_size -
583 1 : libspdm_get_scratch_buffer_large_message_offset(spdm_context);
584 1 : libspdm_zero_mem(scratch_buffer, scratch_buffer_size);
585 :
586 : /* Fill 1st chunk with 1, 2nd chunk with 2, 3rd chunk with 3 */
587 1 : first_chunk_size = data_transfer_size -
588 : (sizeof(spdm_chunk_response_response_t) + sizeof(uint32_t));
589 1 : second_chunk_size = data_transfer_size - sizeof(spdm_chunk_response_response_t);
590 1 : third_chunk_size = data_transfer_size - sizeof(spdm_chunk_response_response_t);
591 1 : total_chunk_size = first_chunk_size + second_chunk_size + third_chunk_size;
592 1 : LIBSPDM_ASSERT(total_chunk_size <= scratch_buffer_size);
593 :
594 1 : libspdm_set_mem(scratch_buffer, first_chunk_size, 1);
595 1 : libspdm_set_mem((uint8_t*)scratch_buffer + first_chunk_size, second_chunk_size, 2);
596 1 : libspdm_set_mem((uint8_t*) scratch_buffer + first_chunk_size + second_chunk_size,
597 : third_chunk_size, 3);
598 :
599 1 : chunk_handle = (uint8_t) spdm_test_context->case_id; /* Any number is fine */
600 1 : spdm_context->chunk_context.get.chunk_in_use = true;
601 1 : spdm_context->chunk_context.get.chunk_handle = chunk_handle;
602 1 : spdm_context->chunk_context.get.chunk_seq_no = 0;
603 1 : spdm_context->chunk_context.get.large_message = scratch_buffer;
604 1 : spdm_context->chunk_context.get.large_message_size = total_chunk_size;
605 1 : spdm_context->chunk_context.get.chunk_bytes_transferred = 0;
606 :
607 1 : libspdm_zero_mem(&spdm_request, sizeof(spdm_request));
608 1 : spdm_request.header.spdm_version = SPDM_MESSAGE_VERSION_12;
609 1 : spdm_request.header.request_response_code = SPDM_CHUNK_GET;
610 1 : spdm_request.header.param1 = 0;
611 1 : spdm_request.header.param2 = chunk_handle;
612 1 : spdm_request.chunk_seq_no = 0;
613 :
614 1 : response_size = sizeof(response);
615 1 : status = libspdm_get_response_chunk_get(
616 : spdm_context,
617 : sizeof(spdm_request), &spdm_request,
618 : &response_size, response);
619 :
620 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
621 1 : assert_int_equal(response_size, data_transfer_size);
622 :
623 1 : spdm_response = (spdm_chunk_response_response_t*) response;
624 1 : assert_int_equal(spdm_response->header.spdm_version, SPDM_MESSAGE_VERSION_12);
625 1 : assert_int_equal(spdm_response->header.request_response_code, SPDM_CHUNK_RESPONSE);
626 1 : assert_int_equal(spdm_response->header.param1, 0);
627 1 : assert_int_equal(spdm_response->header.param2, chunk_handle);
628 1 : assert_int_equal(spdm_response->chunk_seq_no, 0);
629 1 : assert_int_equal(spdm_response->chunk_size, first_chunk_size);
630 :
631 1 : large_response = libspdm_read_uint32((const uint8_t *)(spdm_response + 1));
632 1 : assert_int_equal(large_response, total_chunk_size);
633 :
634 : /* Verify the 1st chunk is filled with 1 */
635 1 : chunk_ptr = (uint8_t *)(spdm_response + 1) + sizeof(uint32_t);
636 29 : for (i = 0; i < spdm_response->chunk_size; i++) {
637 28 : assert_int_equal(chunk_ptr[i], 1);
638 : }
639 1 : }
640 :
641 : /**
642 : * Test 11: Successful request of middle chunk.
643 : **/
644 1 : static void rsp_chunk_response_case11(void** state)
645 : {
646 : libspdm_return_t status;
647 : libspdm_test_context_t* spdm_test_context;
648 : libspdm_context_t* spdm_context;
649 : size_t response_size;
650 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
651 : spdm_chunk_response_response_t* spdm_response;
652 : spdm_chunk_get_request_t spdm_request;
653 : void* scratch_buffer;
654 : size_t scratch_buffer_size;
655 :
656 : uint8_t chunk_handle;
657 : uint16_t chunk_seq_no;
658 : uint32_t data_transfer_size;
659 : uint32_t first_chunk_size;
660 : uint32_t second_chunk_size;
661 : uint32_t third_chunk_size;
662 : uint32_t total_chunk_size;
663 : uint8_t* chunk_ptr;
664 : uint32_t i;
665 :
666 1 : spdm_test_context = *state;
667 1 : spdm_context = spdm_test_context->spdm_context;
668 1 : spdm_test_context->case_id = 11;
669 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 <<
670 : SPDM_VERSION_NUMBER_SHIFT_BIT;
671 :
672 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
673 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
674 :
675 1 : data_transfer_size = CHUNK_GET_RESPONDER_UNIT_TEST_DATA_TRANSFER_SIZE;
676 1 : spdm_context->local_context.capability.data_transfer_size = data_transfer_size;
677 1 : spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHUNK_CAP;
678 1 : spdm_context->connection_info.capability.flags |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP;
679 :
680 1 : libspdm_get_scratch_buffer(spdm_context, &scratch_buffer, &scratch_buffer_size);
681 :
682 2 : scratch_buffer = (uint8_t*)scratch_buffer +
683 1 : libspdm_get_scratch_buffer_large_message_offset(spdm_context);
684 2 : scratch_buffer_size = scratch_buffer_size -
685 1 : libspdm_get_scratch_buffer_large_message_offset(spdm_context);
686 1 : libspdm_zero_mem(scratch_buffer, scratch_buffer_size);
687 :
688 : /* Fill 1st chunk with 1, 2nd chunk with 2, 3rd chunk with 3 */
689 1 : first_chunk_size = data_transfer_size -
690 : (sizeof(spdm_chunk_response_response_t) + sizeof(uint32_t));
691 1 : second_chunk_size = data_transfer_size - sizeof(spdm_chunk_response_response_t);
692 1 : third_chunk_size = data_transfer_size - sizeof(spdm_chunk_response_response_t);
693 1 : total_chunk_size = first_chunk_size + second_chunk_size + third_chunk_size;
694 1 : LIBSPDM_ASSERT(total_chunk_size <= scratch_buffer_size);
695 :
696 1 : libspdm_set_mem(scratch_buffer, first_chunk_size, 1);
697 1 : libspdm_set_mem((uint8_t*) scratch_buffer + first_chunk_size, second_chunk_size, 2);
698 1 : libspdm_set_mem((uint8_t*) scratch_buffer + first_chunk_size + second_chunk_size,
699 : third_chunk_size, 3);
700 :
701 1 : chunk_handle = (uint8_t) spdm_test_context->case_id; /* Any number is fine */
702 1 : chunk_seq_no = 1; /* 1 == 2nd chunk */
703 1 : spdm_context->chunk_context.get.chunk_in_use = true;
704 1 : spdm_context->chunk_context.get.chunk_handle = chunk_handle;
705 1 : spdm_context->chunk_context.get.chunk_seq_no = chunk_seq_no;
706 1 : spdm_context->chunk_context.get.large_message = scratch_buffer;
707 1 : spdm_context->chunk_context.get.large_message_size = total_chunk_size;
708 1 : spdm_context->chunk_context.get.chunk_bytes_transferred = first_chunk_size;
709 :
710 1 : libspdm_zero_mem(&spdm_request, sizeof(spdm_request));
711 1 : spdm_request.header.spdm_version = SPDM_MESSAGE_VERSION_12;
712 1 : spdm_request.header.request_response_code = SPDM_CHUNK_GET;
713 1 : spdm_request.header.param1 = 0;
714 1 : spdm_request.header.param2 = chunk_handle;
715 1 : spdm_request.chunk_seq_no = chunk_seq_no;
716 :
717 1 : response_size = sizeof(response);
718 1 : status = libspdm_get_response_chunk_get(
719 : spdm_context,
720 : sizeof(spdm_request), &spdm_request,
721 : &response_size, response);
722 :
723 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
724 1 : assert_int_equal(response_size, data_transfer_size);
725 :
726 1 : spdm_response = (spdm_chunk_response_response_t*) response;
727 1 : assert_int_equal(spdm_response->header.spdm_version, SPDM_MESSAGE_VERSION_12);
728 1 : assert_int_equal(spdm_response->header.request_response_code, SPDM_CHUNK_RESPONSE);
729 1 : assert_int_equal(spdm_response->header.param1, 0);
730 1 : assert_int_equal(spdm_response->header.param2, chunk_handle);
731 1 : assert_int_equal(spdm_response->chunk_seq_no, chunk_seq_no);
732 1 : assert_int_equal(spdm_response->chunk_size, second_chunk_size);
733 :
734 : /* Verify the 2nd chunk is filled with 2 */
735 1 : chunk_ptr = (uint8_t*) (spdm_response + 1);
736 33 : for (i = 0; i < spdm_response->chunk_size; i++) {
737 32 : assert_int_equal(chunk_ptr[i], 2);
738 : }
739 1 : }
740 :
741 : /**
742 : * Test 12: Successful request of last chunk where size is exactly max chunk size
743 : **/
744 1 : static void rsp_chunk_response_case12(void** state)
745 : {
746 : libspdm_return_t status;
747 : libspdm_test_context_t* spdm_test_context;
748 : libspdm_context_t* spdm_context;
749 : size_t response_size;
750 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
751 : spdm_chunk_response_response_t* spdm_response;
752 : spdm_chunk_get_request_t spdm_request;
753 : void* scratch_buffer;
754 : size_t scratch_buffer_size;
755 :
756 : uint8_t chunk_handle;
757 : uint16_t chunk_seq_no;
758 : uint32_t data_transfer_size;
759 : uint32_t first_chunk_size;
760 : uint32_t second_chunk_size;
761 : uint32_t third_chunk_size;
762 : uint32_t total_chunk_size;
763 : uint8_t* chunk_ptr;
764 : uint32_t i;
765 :
766 1 : spdm_test_context = *state;
767 1 : spdm_context = spdm_test_context->spdm_context;
768 1 : spdm_test_context->case_id = 12;
769 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 <<
770 : SPDM_VERSION_NUMBER_SHIFT_BIT;
771 :
772 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
773 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
774 :
775 1 : data_transfer_size = CHUNK_GET_RESPONDER_UNIT_TEST_DATA_TRANSFER_SIZE;
776 1 : spdm_context->local_context.capability.data_transfer_size = data_transfer_size;
777 1 : spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHUNK_CAP;
778 1 : spdm_context->connection_info.capability.flags |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP;
779 :
780 1 : libspdm_get_scratch_buffer(spdm_context, &scratch_buffer, &scratch_buffer_size);
781 :
782 2 : scratch_buffer = (uint8_t*)scratch_buffer +
783 1 : libspdm_get_scratch_buffer_large_message_offset(spdm_context);
784 2 : scratch_buffer_size = scratch_buffer_size -
785 1 : libspdm_get_scratch_buffer_large_message_offset(spdm_context);
786 1 : libspdm_zero_mem(scratch_buffer, scratch_buffer_size);
787 :
788 : /* Fill 1st chunk with 1, 2nd chunk with 2, 3rd chunk with 3 */
789 1 : first_chunk_size = data_transfer_size -
790 : (sizeof(spdm_chunk_response_response_t) + sizeof(uint32_t));
791 1 : second_chunk_size = data_transfer_size - sizeof(spdm_chunk_response_response_t);
792 1 : third_chunk_size = data_transfer_size - sizeof(spdm_chunk_response_response_t);
793 1 : total_chunk_size = first_chunk_size + second_chunk_size + third_chunk_size;
794 1 : LIBSPDM_ASSERT(total_chunk_size <= scratch_buffer_size);
795 :
796 1 : libspdm_set_mem(scratch_buffer, first_chunk_size, 1);
797 1 : libspdm_set_mem((uint8_t*) scratch_buffer + first_chunk_size, second_chunk_size, 2);
798 1 : libspdm_set_mem((uint8_t*) scratch_buffer + first_chunk_size + second_chunk_size,
799 : third_chunk_size, 3);
800 :
801 1 : chunk_handle = (uint8_t) spdm_test_context->case_id; /* Any number is fine */
802 1 : chunk_seq_no = 2; /* 2 == 3rd chunk */
803 1 : spdm_context->chunk_context.get.chunk_in_use = true;
804 1 : spdm_context->chunk_context.get.chunk_handle = chunk_handle;
805 1 : spdm_context->chunk_context.get.chunk_seq_no = chunk_seq_no;
806 1 : spdm_context->chunk_context.get.large_message = scratch_buffer;
807 1 : spdm_context->chunk_context.get.large_message_size = total_chunk_size;
808 1 : spdm_context->chunk_context.get.large_message_capacity = scratch_buffer_size;
809 1 : spdm_context->chunk_context.get.chunk_bytes_transferred = first_chunk_size + second_chunk_size;
810 :
811 1 : libspdm_zero_mem(&spdm_request, sizeof(spdm_request));
812 1 : spdm_request.header.spdm_version = SPDM_MESSAGE_VERSION_12;
813 1 : spdm_request.header.request_response_code = SPDM_CHUNK_GET;
814 1 : spdm_request.header.param1 = 0;
815 1 : spdm_request.header.param2 = chunk_handle;
816 1 : spdm_request.chunk_seq_no = chunk_seq_no;
817 :
818 1 : response_size = sizeof(response);
819 1 : status = libspdm_get_response_chunk_get(
820 : spdm_context,
821 : sizeof(spdm_request), &spdm_request,
822 : &response_size, response);
823 :
824 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
825 1 : assert_int_equal(response_size, data_transfer_size);
826 :
827 1 : spdm_response = (spdm_chunk_response_response_t*) response;
828 1 : assert_int_equal(spdm_response->header.spdm_version, SPDM_MESSAGE_VERSION_12);
829 1 : assert_int_equal(spdm_response->header.request_response_code, SPDM_CHUNK_RESPONSE);
830 1 : assert_int_equal(spdm_response->header.param1, SPDM_CHUNK_GET_RESPONSE_ATTRIBUTE_LAST_CHUNK);
831 1 : assert_int_equal(spdm_response->header.param2, chunk_handle);
832 1 : assert_int_equal(spdm_response->chunk_seq_no, chunk_seq_no);
833 1 : assert_int_equal(spdm_response->chunk_size, third_chunk_size);
834 :
835 : /* Verify the 3rd chunk is filled with 3 */
836 1 : chunk_ptr = (uint8_t*) (spdm_response + 1);
837 33 : for (i = 0; i < spdm_response->chunk_size; i++) {
838 32 : assert_int_equal(chunk_ptr[i], 3);
839 : }
840 :
841 1 : assert_false(spdm_context->chunk_context.get.chunk_in_use);
842 1 : assert_int_equal(spdm_context->chunk_context.get.chunk_handle,
843 : (uint8_t)(chunk_handle + 1));
844 1 : assert_int_equal(spdm_context->chunk_context.get.chunk_seq_no, 0);
845 1 : assert_int_equal(spdm_context->chunk_context.get.chunk_bytes_transferred, 0);
846 1 : assert_null(spdm_context->chunk_context.get.large_message);
847 1 : assert_int_equal(spdm_context->chunk_context.get.large_message_size, 0);
848 1 : assert_int_equal(spdm_context->chunk_context.get.large_message_capacity, 0);
849 93 : for (i = 0; i < total_chunk_size; i++) {
850 92 : assert_int_equal(((uint8_t*)scratch_buffer)[i], 0);
851 : }
852 1 : }
853 :
854 : /**
855 : * Test 13: Successful request of last chunk where size is exactly 1.
856 : **/
857 1 : static void rsp_chunk_response_case13(void** state)
858 : {
859 : libspdm_return_t status;
860 : libspdm_test_context_t* spdm_test_context;
861 : libspdm_context_t* spdm_context;
862 : size_t response_size;
863 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
864 : spdm_chunk_response_response_t* spdm_response;
865 : spdm_chunk_get_request_t spdm_request;
866 : void* scratch_buffer;
867 : size_t scratch_buffer_size;
868 :
869 : uint8_t chunk_handle;
870 : uint16_t chunk_seq_no;
871 : uint32_t data_transfer_size;
872 : uint32_t first_chunk_size;
873 : uint32_t second_chunk_size;
874 : uint32_t third_chunk_size;
875 : uint32_t total_chunk_size;
876 : uint32_t fourth_chunk_size;
877 : uint32_t expected_response_size;
878 : uint8_t* chunk_ptr;
879 : uint32_t i;
880 :
881 1 : spdm_test_context = *state;
882 1 : spdm_context = spdm_test_context->spdm_context;
883 1 : spdm_test_context->case_id = 12;
884 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 <<
885 : SPDM_VERSION_NUMBER_SHIFT_BIT;
886 :
887 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
888 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
889 :
890 1 : data_transfer_size = CHUNK_GET_RESPONDER_UNIT_TEST_DATA_TRANSFER_SIZE;
891 1 : spdm_context->local_context.capability.data_transfer_size = data_transfer_size;
892 1 : spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHUNK_CAP;
893 1 : spdm_context->connection_info.capability.flags |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP;
894 :
895 1 : libspdm_get_scratch_buffer(spdm_context, &scratch_buffer, &scratch_buffer_size);
896 :
897 2 : scratch_buffer = (uint8_t*)scratch_buffer +
898 1 : libspdm_get_scratch_buffer_large_message_offset(spdm_context);
899 2 : scratch_buffer_size = scratch_buffer_size -
900 1 : libspdm_get_scratch_buffer_large_message_offset(spdm_context);
901 1 : libspdm_zero_mem(scratch_buffer, scratch_buffer_size);
902 :
903 : /* Fill 1st chunk with 1, 2nd chunk with 2, 3rd chunk with 3, 4th chunk with 4 */
904 1 : first_chunk_size = data_transfer_size -
905 : (sizeof(spdm_chunk_response_response_t) + sizeof(uint32_t));
906 1 : second_chunk_size = data_transfer_size - sizeof(spdm_chunk_response_response_t);
907 1 : third_chunk_size = data_transfer_size - sizeof(spdm_chunk_response_response_t);
908 1 : fourth_chunk_size = 1;
909 :
910 1 : total_chunk_size = first_chunk_size + second_chunk_size + third_chunk_size + fourth_chunk_size;
911 1 : expected_response_size = sizeof(spdm_chunk_response_response_t) + fourth_chunk_size;
912 1 : LIBSPDM_ASSERT(total_chunk_size <= scratch_buffer_size);
913 :
914 1 : libspdm_set_mem(scratch_buffer, first_chunk_size, 1);
915 1 : libspdm_set_mem((uint8_t*) scratch_buffer + first_chunk_size, second_chunk_size, 2);
916 1 : libspdm_set_mem((uint8_t*) scratch_buffer + first_chunk_size + second_chunk_size,
917 : third_chunk_size, 3);
918 1 : libspdm_set_mem((uint8_t*) scratch_buffer + first_chunk_size
919 1 : + second_chunk_size + third_chunk_size,
920 : fourth_chunk_size, 4);
921 :
922 1 : chunk_handle = (uint8_t) spdm_test_context->case_id; /* Any number is fine */
923 1 : chunk_seq_no = 3; /* 3 == 4th chunk */
924 1 : spdm_context->chunk_context.get.chunk_in_use = true;
925 1 : spdm_context->chunk_context.get.chunk_handle = chunk_handle;
926 1 : spdm_context->chunk_context.get.chunk_seq_no = chunk_seq_no;
927 1 : spdm_context->chunk_context.get.large_message = scratch_buffer;
928 1 : spdm_context->chunk_context.get.large_message_size = total_chunk_size;
929 1 : spdm_context->chunk_context.get.chunk_bytes_transferred =
930 1 : first_chunk_size + second_chunk_size + third_chunk_size;
931 :
932 1 : libspdm_zero_mem(&spdm_request, sizeof(spdm_request));
933 1 : spdm_request.header.spdm_version = SPDM_MESSAGE_VERSION_12;
934 1 : spdm_request.header.request_response_code = SPDM_CHUNK_GET;
935 1 : spdm_request.header.param1 = 0;
936 1 : spdm_request.header.param2 = chunk_handle;
937 1 : spdm_request.chunk_seq_no = chunk_seq_no;
938 :
939 1 : response_size = sizeof(response);
940 1 : status = libspdm_get_response_chunk_get(
941 : spdm_context,
942 : sizeof(spdm_request), &spdm_request,
943 : &response_size, response);
944 :
945 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
946 1 : assert_int_equal(response_size, expected_response_size);
947 :
948 1 : spdm_response = (spdm_chunk_response_response_t*) response;
949 1 : assert_int_equal(spdm_response->header.spdm_version, SPDM_MESSAGE_VERSION_12);
950 1 : assert_int_equal(spdm_response->header.request_response_code, SPDM_CHUNK_RESPONSE);
951 1 : assert_int_equal(spdm_response->header.param1, SPDM_CHUNK_GET_RESPONSE_ATTRIBUTE_LAST_CHUNK);
952 1 : assert_int_equal(spdm_response->header.param2, chunk_handle);
953 1 : assert_int_equal(spdm_response->chunk_seq_no, chunk_seq_no);
954 1 : assert_int_equal(spdm_response->chunk_size, fourth_chunk_size);
955 :
956 : /* Verify the 4th chunk is filled with 4 */
957 1 : chunk_ptr = (uint8_t*)(spdm_response + 1);
958 2 : for (i = 0; i < spdm_response->chunk_size; i++) {
959 1 : assert_int_equal(chunk_ptr[i], 4);
960 : }
961 1 : }
962 :
963 :
964 : /**
965 : * Test 14: Responder has response exceed chunk seq no
966 : **/
967 1 : static void rsp_chunk_response_case14(void** state)
968 : {
969 : libspdm_return_t status;
970 : libspdm_test_context_t* spdm_test_context;
971 : libspdm_context_t* spdm_context;
972 : size_t response_size;
973 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
974 : spdm_error_response_t* spdm_response;
975 : spdm_chunk_get_request_t spdm_request;
976 : void* scratch_buffer;
977 : size_t scratch_buffer_size;
978 :
979 : uint8_t chunk_handle;
980 : uint32_t data_transfer_size;
981 : uint32_t total_chunk_size;
982 :
983 1 : spdm_test_context = *state;
984 1 : spdm_context = spdm_test_context->spdm_context;
985 1 : spdm_test_context->case_id = 10;
986 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 <<
987 : SPDM_VERSION_NUMBER_SHIFT_BIT;
988 :
989 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
990 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
991 :
992 1 : data_transfer_size = CHUNK_GET_RESPONDER_UNIT_TEST_DATA_TRANSFER_SIZE;
993 1 : spdm_context->local_context.capability.data_transfer_size = data_transfer_size;
994 1 : spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHUNK_CAP;
995 1 : spdm_context->connection_info.capability.flags |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP;
996 :
997 : /* large response need a large scratch buffer */
998 1 : spdm_context->connection_info.capability.max_spdm_msg_size = data_transfer_size * 65536;
999 1 : spdm_context->local_context.capability.max_spdm_msg_size = data_transfer_size * 65536;
1000 1 : spdm_test_context->scratch_buffer_size =
1001 1 : libspdm_get_sizeof_required_scratch_buffer(spdm_context);
1002 1 : spdm_test_context->scratch_buffer = (void *)malloc(spdm_test_context->scratch_buffer_size);
1003 1 : libspdm_set_scratch_buffer (spdm_context,
1004 : spdm_test_context->scratch_buffer,
1005 : spdm_test_context->scratch_buffer_size);
1006 :
1007 :
1008 1 : libspdm_get_scratch_buffer(spdm_context, &scratch_buffer, &scratch_buffer_size);
1009 :
1010 2 : scratch_buffer = (uint8_t*)scratch_buffer +
1011 1 : libspdm_get_scratch_buffer_large_message_offset(spdm_context);
1012 2 : scratch_buffer_size = scratch_buffer_size -
1013 1 : libspdm_get_scratch_buffer_large_message_offset(spdm_context);
1014 1 : libspdm_zero_mem(scratch_buffer, scratch_buffer_size);
1015 :
1016 : /* a huge chunk size to cause the chunk seq no wrap */
1017 1 : total_chunk_size = data_transfer_size * 65536;
1018 :
1019 1 : LIBSPDM_ASSERT(total_chunk_size <= scratch_buffer_size);
1020 :
1021 1 : chunk_handle = (uint8_t) spdm_test_context->case_id; /* Any number is fine */
1022 1 : spdm_context->chunk_context.get.chunk_in_use = true;
1023 1 : spdm_context->chunk_context.get.chunk_handle = chunk_handle;
1024 1 : spdm_context->chunk_context.get.chunk_seq_no = 0;
1025 1 : spdm_context->chunk_context.get.large_message = scratch_buffer;
1026 1 : spdm_context->chunk_context.get.large_message_size = total_chunk_size;
1027 1 : spdm_context->chunk_context.get.chunk_bytes_transferred = 0;
1028 :
1029 1 : libspdm_zero_mem(&spdm_request, sizeof(spdm_request));
1030 1 : spdm_request.header.spdm_version = SPDM_MESSAGE_VERSION_12;
1031 1 : spdm_request.header.request_response_code = SPDM_CHUNK_GET;
1032 1 : spdm_request.header.param1 = 0;
1033 1 : spdm_request.header.param2 = chunk_handle;
1034 1 : spdm_request.chunk_seq_no = 0;
1035 :
1036 1 : response_size = sizeof(response);
1037 1 : status = libspdm_get_response_chunk_get(
1038 : spdm_context,
1039 : sizeof(spdm_request), &spdm_request,
1040 : &response_size, response);
1041 :
1042 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
1043 1 : assert_int_equal(response_size, sizeof(spdm_error_response_t));
1044 :
1045 1 : spdm_response = (spdm_error_response_t*) response;
1046 :
1047 1 : assert_int_equal(spdm_response->header.spdm_version, SPDM_MESSAGE_VERSION_12);
1048 1 : assert_int_equal(spdm_response->header.request_response_code, SPDM_ERROR);
1049 1 : assert_int_equal(spdm_response->header.param1, SPDM_ERROR_CODE_RESPONSE_TOO_LARGE);
1050 1 : assert_int_equal(spdm_response->header.param2, 0);
1051 1 : }
1052 :
1053 : /**
1054 : * Test 15: Successful request of first chunk, spdm 1.4.
1055 : **/
1056 1 : static void rsp_chunk_response_case15(void** state)
1057 : {
1058 : libspdm_return_t status;
1059 : libspdm_test_context_t* spdm_test_context;
1060 : libspdm_context_t* spdm_context;
1061 : size_t response_size;
1062 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
1063 : spdm_chunk_response_response_14_t* spdm_response;
1064 : spdm_chunk_get_request_14_t spdm_request;
1065 : void* scratch_buffer;
1066 : size_t scratch_buffer_size;
1067 :
1068 : uint8_t chunk_handle;
1069 : uint32_t data_transfer_size;
1070 : uint32_t first_chunk_size;
1071 : uint32_t second_chunk_size;
1072 : uint32_t third_chunk_size;
1073 : uint32_t total_chunk_size;
1074 : uint32_t large_response;
1075 : uint8_t* chunk_ptr;
1076 : uint32_t i;
1077 :
1078 1 : spdm_test_context = *state;
1079 1 : spdm_context = spdm_test_context->spdm_context;
1080 1 : spdm_test_context->case_id = 15;
1081 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_14 <<
1082 : SPDM_VERSION_NUMBER_SHIFT_BIT;
1083 :
1084 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
1085 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
1086 :
1087 1 : data_transfer_size = CHUNK_GET_RESPONDER_UNIT_TEST_DATA_TRANSFER_SIZE;
1088 1 : spdm_context->local_context.capability.data_transfer_size = data_transfer_size;
1089 1 : spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHUNK_CAP;
1090 1 : spdm_context->connection_info.capability.flags |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP;
1091 :
1092 1 : libspdm_get_scratch_buffer(spdm_context, &scratch_buffer, &scratch_buffer_size);
1093 :
1094 2 : scratch_buffer = (uint8_t*)scratch_buffer +
1095 1 : libspdm_get_scratch_buffer_large_message_offset(spdm_context);
1096 2 : scratch_buffer_size = scratch_buffer_size -
1097 1 : libspdm_get_scratch_buffer_large_message_offset(spdm_context);
1098 1 : libspdm_zero_mem(scratch_buffer, scratch_buffer_size);
1099 :
1100 : /* Fill 1st chunk with 1, 2nd chunk with 2, 3rd chunk with 3 */
1101 1 : first_chunk_size = data_transfer_size -
1102 : (sizeof(spdm_chunk_response_response_14_t) + sizeof(uint32_t));
1103 1 : second_chunk_size = data_transfer_size - sizeof(spdm_chunk_response_response_14_t);
1104 1 : third_chunk_size = data_transfer_size - sizeof(spdm_chunk_response_response_14_t);
1105 1 : total_chunk_size = first_chunk_size + second_chunk_size + third_chunk_size;
1106 1 : LIBSPDM_ASSERT(total_chunk_size <= scratch_buffer_size);
1107 :
1108 1 : libspdm_set_mem(scratch_buffer, first_chunk_size, 1);
1109 1 : libspdm_set_mem((uint8_t*)scratch_buffer + first_chunk_size, second_chunk_size, 2);
1110 1 : libspdm_set_mem((uint8_t*) scratch_buffer + first_chunk_size + second_chunk_size,
1111 : third_chunk_size, 3);
1112 :
1113 1 : chunk_handle = (uint8_t) spdm_test_context->case_id; /* Any number is fine */
1114 1 : spdm_context->chunk_context.get.chunk_in_use = true;
1115 1 : spdm_context->chunk_context.get.chunk_handle = chunk_handle;
1116 1 : spdm_context->chunk_context.get.chunk_seq_no = 0;
1117 1 : spdm_context->chunk_context.get.large_message = scratch_buffer;
1118 1 : spdm_context->chunk_context.get.large_message_size = total_chunk_size;
1119 1 : spdm_context->chunk_context.get.chunk_bytes_transferred = 0;
1120 :
1121 1 : libspdm_zero_mem(&spdm_request, sizeof(spdm_request));
1122 1 : spdm_request.header.spdm_version = SPDM_MESSAGE_VERSION_14;
1123 1 : spdm_request.header.request_response_code = SPDM_CHUNK_GET;
1124 1 : spdm_request.header.param1 = 0;
1125 1 : spdm_request.header.param2 = chunk_handle;
1126 1 : spdm_request.chunk_seq_no = 0;
1127 :
1128 1 : response_size = sizeof(response);
1129 1 : status = libspdm_get_response_chunk_get(
1130 : spdm_context,
1131 : sizeof(spdm_request), &spdm_request,
1132 : &response_size, response);
1133 :
1134 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
1135 1 : assert_int_equal(response_size, data_transfer_size);
1136 :
1137 1 : spdm_response = (spdm_chunk_response_response_14_t*) response;
1138 1 : assert_int_equal(spdm_response->header.spdm_version, SPDM_MESSAGE_VERSION_14);
1139 1 : assert_int_equal(spdm_response->header.request_response_code, SPDM_CHUNK_RESPONSE);
1140 1 : assert_int_equal(spdm_response->header.param1, 0);
1141 1 : assert_int_equal(spdm_response->header.param2, chunk_handle);
1142 1 : assert_int_equal(spdm_response->chunk_seq_no, 0);
1143 1 : assert_int_equal(spdm_response->chunk_size, first_chunk_size);
1144 :
1145 1 : large_response = libspdm_read_uint32((const uint8_t *)(spdm_response + 1));
1146 1 : assert_int_equal(large_response, total_chunk_size);
1147 :
1148 : /* Verify the 1st chunk is filled with 1 */
1149 1 : chunk_ptr = (uint8_t *)(spdm_response + 1) + sizeof(uint32_t);
1150 29 : for (i = 0; i < spdm_response->chunk_size; i++) {
1151 28 : assert_int_equal(chunk_ptr[i], 1);
1152 : }
1153 1 : }
1154 :
1155 : /**
1156 : * Test 16: Successful request of middle chunk, spdm 1.4.
1157 : **/
1158 1 : static void rsp_chunk_response_case16(void** state)
1159 : {
1160 : libspdm_return_t status;
1161 : libspdm_test_context_t* spdm_test_context;
1162 : libspdm_context_t* spdm_context;
1163 : size_t response_size;
1164 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
1165 : spdm_chunk_response_response_14_t* spdm_response;
1166 : spdm_chunk_get_request_14_t spdm_request;
1167 : void* scratch_buffer;
1168 : size_t scratch_buffer_size;
1169 :
1170 : uint8_t chunk_handle;
1171 : uint32_t chunk_seq_no;
1172 : uint32_t data_transfer_size;
1173 : uint32_t first_chunk_size;
1174 : uint32_t second_chunk_size;
1175 : uint32_t third_chunk_size;
1176 : uint32_t total_chunk_size;
1177 : uint8_t* chunk_ptr;
1178 : uint32_t i;
1179 :
1180 1 : spdm_test_context = *state;
1181 1 : spdm_context = spdm_test_context->spdm_context;
1182 1 : spdm_test_context->case_id = 16;
1183 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_14 <<
1184 : SPDM_VERSION_NUMBER_SHIFT_BIT;
1185 :
1186 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
1187 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
1188 :
1189 1 : data_transfer_size = CHUNK_GET_RESPONDER_UNIT_TEST_DATA_TRANSFER_SIZE;
1190 1 : spdm_context->local_context.capability.data_transfer_size = data_transfer_size;
1191 1 : spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHUNK_CAP;
1192 1 : spdm_context->connection_info.capability.flags |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP;
1193 :
1194 1 : libspdm_get_scratch_buffer(spdm_context, &scratch_buffer, &scratch_buffer_size);
1195 :
1196 2 : scratch_buffer = (uint8_t*)scratch_buffer +
1197 1 : libspdm_get_scratch_buffer_large_message_offset(spdm_context);
1198 2 : scratch_buffer_size = scratch_buffer_size -
1199 1 : libspdm_get_scratch_buffer_large_message_offset(spdm_context);
1200 1 : libspdm_zero_mem(scratch_buffer, scratch_buffer_size);
1201 :
1202 : /* Fill 1st chunk with 1, 2nd chunk with 2, 3rd chunk with 3 */
1203 1 : first_chunk_size = data_transfer_size -
1204 : (sizeof(spdm_chunk_response_response_14_t) + sizeof(uint32_t));
1205 1 : second_chunk_size = data_transfer_size - sizeof(spdm_chunk_response_response_14_t);
1206 1 : third_chunk_size = data_transfer_size - sizeof(spdm_chunk_response_response_14_t);
1207 1 : total_chunk_size = first_chunk_size + second_chunk_size + third_chunk_size;
1208 1 : LIBSPDM_ASSERT(total_chunk_size <= scratch_buffer_size);
1209 :
1210 1 : libspdm_set_mem(scratch_buffer, first_chunk_size, 1);
1211 1 : libspdm_set_mem((uint8_t*) scratch_buffer + first_chunk_size, second_chunk_size, 2);
1212 1 : libspdm_set_mem((uint8_t*) scratch_buffer + first_chunk_size + second_chunk_size,
1213 : third_chunk_size, 3);
1214 :
1215 1 : chunk_handle = (uint8_t) spdm_test_context->case_id; /* Any number is fine */
1216 1 : chunk_seq_no = 1; /* 1 == 2nd chunk */
1217 1 : spdm_context->chunk_context.get.chunk_in_use = true;
1218 1 : spdm_context->chunk_context.get.chunk_handle = chunk_handle;
1219 1 : spdm_context->chunk_context.get.chunk_seq_no = chunk_seq_no;
1220 1 : spdm_context->chunk_context.get.large_message = scratch_buffer;
1221 1 : spdm_context->chunk_context.get.large_message_size = total_chunk_size;
1222 1 : spdm_context->chunk_context.get.chunk_bytes_transferred = first_chunk_size;
1223 :
1224 1 : libspdm_zero_mem(&spdm_request, sizeof(spdm_request));
1225 1 : spdm_request.header.spdm_version = SPDM_MESSAGE_VERSION_14;
1226 1 : spdm_request.header.request_response_code = SPDM_CHUNK_GET;
1227 1 : spdm_request.header.param1 = 0;
1228 1 : spdm_request.header.param2 = chunk_handle;
1229 1 : spdm_request.chunk_seq_no = chunk_seq_no;
1230 :
1231 1 : response_size = sizeof(response);
1232 1 : status = libspdm_get_response_chunk_get(
1233 : spdm_context,
1234 : sizeof(spdm_request), &spdm_request,
1235 : &response_size, response);
1236 :
1237 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
1238 1 : assert_int_equal(response_size, data_transfer_size);
1239 :
1240 1 : spdm_response = (spdm_chunk_response_response_14_t*) response;
1241 1 : assert_int_equal(spdm_response->header.spdm_version, SPDM_MESSAGE_VERSION_14);
1242 1 : assert_int_equal(spdm_response->header.request_response_code, SPDM_CHUNK_RESPONSE);
1243 1 : assert_int_equal(spdm_response->header.param1, 0);
1244 1 : assert_int_equal(spdm_response->header.param2, chunk_handle);
1245 1 : assert_int_equal(spdm_response->chunk_seq_no, chunk_seq_no);
1246 1 : assert_int_equal(spdm_response->chunk_size, second_chunk_size);
1247 :
1248 : /* Verify the 2nd chunk is filled with 2 */
1249 1 : chunk_ptr = (uint8_t*) (spdm_response + 1);
1250 33 : for (i = 0; i < spdm_response->chunk_size; i++) {
1251 32 : assert_int_equal(chunk_ptr[i], 2);
1252 : }
1253 1 : }
1254 :
1255 : /**
1256 : * Test 17: Successful request of last chunk where size is exactly max chunk size
1257 : **/
1258 1 : static void rsp_chunk_response_case17(void** state)
1259 : {
1260 : libspdm_return_t status;
1261 : libspdm_test_context_t* spdm_test_context;
1262 : libspdm_context_t* spdm_context;
1263 : size_t response_size;
1264 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
1265 : spdm_chunk_response_response_14_t* spdm_response;
1266 : spdm_chunk_get_request_14_t spdm_request;
1267 : void* scratch_buffer;
1268 : size_t scratch_buffer_size;
1269 :
1270 : uint8_t chunk_handle;
1271 : uint32_t chunk_seq_no;
1272 : uint32_t data_transfer_size;
1273 : uint32_t first_chunk_size;
1274 : uint32_t second_chunk_size;
1275 : uint32_t third_chunk_size;
1276 : uint32_t total_chunk_size;
1277 : uint8_t* chunk_ptr;
1278 : uint32_t i;
1279 :
1280 1 : spdm_test_context = *state;
1281 1 : spdm_context = spdm_test_context->spdm_context;
1282 1 : spdm_test_context->case_id = 17;
1283 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_14 <<
1284 : SPDM_VERSION_NUMBER_SHIFT_BIT;
1285 :
1286 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
1287 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
1288 :
1289 1 : data_transfer_size = CHUNK_GET_RESPONDER_UNIT_TEST_DATA_TRANSFER_SIZE;
1290 1 : spdm_context->local_context.capability.data_transfer_size = data_transfer_size;
1291 1 : spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHUNK_CAP;
1292 1 : spdm_context->connection_info.capability.flags |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP;
1293 :
1294 1 : libspdm_get_scratch_buffer(spdm_context, &scratch_buffer, &scratch_buffer_size);
1295 :
1296 2 : scratch_buffer = (uint8_t*)scratch_buffer +
1297 1 : libspdm_get_scratch_buffer_large_message_offset(spdm_context);
1298 2 : scratch_buffer_size = scratch_buffer_size -
1299 1 : libspdm_get_scratch_buffer_large_message_offset(spdm_context);
1300 1 : libspdm_zero_mem(scratch_buffer, scratch_buffer_size);
1301 :
1302 : /* Fill 1st chunk with 1, 2nd chunk with 2, 3rd chunk with 3 */
1303 1 : first_chunk_size = data_transfer_size -
1304 : (sizeof(spdm_chunk_response_response_14_t) + sizeof(uint32_t));
1305 1 : second_chunk_size = data_transfer_size - sizeof(spdm_chunk_response_response_14_t);
1306 1 : third_chunk_size = data_transfer_size - sizeof(spdm_chunk_response_response_14_t);
1307 1 : total_chunk_size = first_chunk_size + second_chunk_size + third_chunk_size;
1308 1 : LIBSPDM_ASSERT(total_chunk_size <= scratch_buffer_size);
1309 :
1310 1 : libspdm_set_mem(scratch_buffer, first_chunk_size, 1);
1311 1 : libspdm_set_mem((uint8_t*) scratch_buffer + first_chunk_size, second_chunk_size, 2);
1312 1 : libspdm_set_mem((uint8_t*) scratch_buffer + first_chunk_size + second_chunk_size,
1313 : third_chunk_size, 3);
1314 :
1315 1 : chunk_handle = (uint8_t) spdm_test_context->case_id; /* Any number is fine */
1316 1 : chunk_seq_no = 2; /* 2 == 3rd chunk */
1317 1 : spdm_context->chunk_context.get.chunk_in_use = true;
1318 1 : spdm_context->chunk_context.get.chunk_handle = chunk_handle;
1319 1 : spdm_context->chunk_context.get.chunk_seq_no = chunk_seq_no;
1320 1 : spdm_context->chunk_context.get.large_message = scratch_buffer;
1321 1 : spdm_context->chunk_context.get.large_message_size = total_chunk_size;
1322 1 : spdm_context->chunk_context.get.chunk_bytes_transferred = first_chunk_size + second_chunk_size;
1323 :
1324 1 : libspdm_zero_mem(&spdm_request, sizeof(spdm_request));
1325 1 : spdm_request.header.spdm_version = SPDM_MESSAGE_VERSION_14;
1326 1 : spdm_request.header.request_response_code = SPDM_CHUNK_GET;
1327 1 : spdm_request.header.param1 = 0;
1328 1 : spdm_request.header.param2 = chunk_handle;
1329 1 : spdm_request.chunk_seq_no = chunk_seq_no;
1330 :
1331 1 : response_size = sizeof(response);
1332 1 : status = libspdm_get_response_chunk_get(
1333 : spdm_context,
1334 : sizeof(spdm_request), &spdm_request,
1335 : &response_size, response);
1336 :
1337 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
1338 1 : assert_int_equal(response_size, data_transfer_size);
1339 :
1340 1 : spdm_response = (spdm_chunk_response_response_14_t*) response;
1341 1 : assert_int_equal(spdm_response->header.spdm_version, SPDM_MESSAGE_VERSION_14);
1342 1 : assert_int_equal(spdm_response->header.request_response_code, SPDM_CHUNK_RESPONSE);
1343 1 : assert_int_equal(spdm_response->header.param1, SPDM_CHUNK_GET_RESPONSE_ATTRIBUTE_LAST_CHUNK);
1344 1 : assert_int_equal(spdm_response->header.param2, chunk_handle);
1345 1 : assert_int_equal(spdm_response->chunk_seq_no, chunk_seq_no);
1346 1 : assert_int_equal(spdm_response->chunk_size, third_chunk_size);
1347 :
1348 : /* Verify the 3rd chunk is filled with 3 */
1349 1 : chunk_ptr = (uint8_t*) (spdm_response + 1);
1350 33 : for (i = 0; i < spdm_response->chunk_size; i++) {
1351 32 : assert_int_equal(chunk_ptr[i], 3);
1352 : }
1353 1 : }
1354 :
1355 : /**
1356 : * Test 18: Successful request of last chunk where size is exactly 1.
1357 : **/
1358 1 : static void rsp_chunk_response_case18(void** state)
1359 : {
1360 : libspdm_return_t status;
1361 : libspdm_test_context_t* spdm_test_context;
1362 : libspdm_context_t* spdm_context;
1363 : size_t response_size;
1364 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
1365 : spdm_chunk_response_response_14_t* spdm_response;
1366 : spdm_chunk_get_request_14_t spdm_request;
1367 : void* scratch_buffer;
1368 : size_t scratch_buffer_size;
1369 :
1370 : uint8_t chunk_handle;
1371 : uint16_t chunk_seq_no;
1372 : uint32_t data_transfer_size;
1373 : uint32_t first_chunk_size;
1374 : uint32_t second_chunk_size;
1375 : uint32_t third_chunk_size;
1376 : uint32_t total_chunk_size;
1377 : uint32_t fourth_chunk_size;
1378 : uint32_t expected_response_size;
1379 : uint8_t* chunk_ptr;
1380 : uint32_t i;
1381 :
1382 1 : spdm_test_context = *state;
1383 1 : spdm_context = spdm_test_context->spdm_context;
1384 1 : spdm_test_context->case_id = 18;
1385 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_14 <<
1386 : SPDM_VERSION_NUMBER_SHIFT_BIT;
1387 :
1388 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
1389 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
1390 :
1391 1 : data_transfer_size = CHUNK_GET_RESPONDER_UNIT_TEST_DATA_TRANSFER_SIZE;
1392 1 : spdm_context->local_context.capability.data_transfer_size = data_transfer_size;
1393 1 : spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHUNK_CAP;
1394 1 : spdm_context->connection_info.capability.flags |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP;
1395 :
1396 1 : libspdm_get_scratch_buffer(spdm_context, &scratch_buffer, &scratch_buffer_size);
1397 :
1398 2 : scratch_buffer = (uint8_t*)scratch_buffer +
1399 1 : libspdm_get_scratch_buffer_large_message_offset(spdm_context);
1400 2 : scratch_buffer_size = scratch_buffer_size -
1401 1 : libspdm_get_scratch_buffer_large_message_offset(spdm_context);
1402 1 : libspdm_zero_mem(scratch_buffer, scratch_buffer_size);
1403 :
1404 : /* Fill 1st chunk with 1, 2nd chunk with 2, 3rd chunk with 3, 4th chunk with 4 */
1405 1 : first_chunk_size = data_transfer_size -
1406 : (sizeof(spdm_chunk_response_response_14_t) + sizeof(uint32_t));
1407 1 : second_chunk_size = data_transfer_size - sizeof(spdm_chunk_response_response_14_t);
1408 1 : third_chunk_size = data_transfer_size - sizeof(spdm_chunk_response_response_14_t);
1409 1 : fourth_chunk_size = 1;
1410 :
1411 1 : total_chunk_size = first_chunk_size + second_chunk_size + third_chunk_size + fourth_chunk_size;
1412 1 : expected_response_size = sizeof(spdm_chunk_response_response_14_t) + fourth_chunk_size;
1413 1 : LIBSPDM_ASSERT(total_chunk_size <= scratch_buffer_size);
1414 :
1415 1 : libspdm_set_mem(scratch_buffer, first_chunk_size, 1);
1416 1 : libspdm_set_mem((uint8_t*) scratch_buffer + first_chunk_size, second_chunk_size, 2);
1417 1 : libspdm_set_mem((uint8_t*) scratch_buffer + first_chunk_size + second_chunk_size,
1418 : third_chunk_size, 3);
1419 1 : libspdm_set_mem((uint8_t*) scratch_buffer + first_chunk_size
1420 1 : + second_chunk_size + third_chunk_size,
1421 : fourth_chunk_size, 4);
1422 :
1423 1 : chunk_handle = (uint8_t) spdm_test_context->case_id; /* Any number is fine */
1424 1 : chunk_seq_no = 3; /* 3 == 4th chunk */
1425 1 : spdm_context->chunk_context.get.chunk_in_use = true;
1426 1 : spdm_context->chunk_context.get.chunk_handle = chunk_handle;
1427 1 : spdm_context->chunk_context.get.chunk_seq_no = chunk_seq_no;
1428 1 : spdm_context->chunk_context.get.large_message = scratch_buffer;
1429 1 : spdm_context->chunk_context.get.large_message_size = total_chunk_size;
1430 1 : spdm_context->chunk_context.get.chunk_bytes_transferred =
1431 1 : first_chunk_size + second_chunk_size + third_chunk_size;
1432 :
1433 1 : libspdm_zero_mem(&spdm_request, sizeof(spdm_request));
1434 1 : spdm_request.header.spdm_version = SPDM_MESSAGE_VERSION_14;
1435 1 : spdm_request.header.request_response_code = SPDM_CHUNK_GET;
1436 1 : spdm_request.header.param1 = 0;
1437 1 : spdm_request.header.param2 = chunk_handle;
1438 1 : spdm_request.chunk_seq_no = chunk_seq_no;
1439 :
1440 1 : response_size = sizeof(response);
1441 1 : status = libspdm_get_response_chunk_get(
1442 : spdm_context,
1443 : sizeof(spdm_request), &spdm_request,
1444 : &response_size, response);
1445 :
1446 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
1447 1 : assert_int_equal(response_size, expected_response_size);
1448 :
1449 1 : spdm_response = (spdm_chunk_response_response_14_t*) response;
1450 1 : assert_int_equal(spdm_response->header.spdm_version, SPDM_MESSAGE_VERSION_14);
1451 1 : assert_int_equal(spdm_response->header.request_response_code, SPDM_CHUNK_RESPONSE);
1452 1 : assert_int_equal(spdm_response->header.param1, SPDM_CHUNK_GET_RESPONSE_ATTRIBUTE_LAST_CHUNK);
1453 1 : assert_int_equal(spdm_response->header.param2, chunk_handle);
1454 1 : assert_int_equal(spdm_response->chunk_seq_no, chunk_seq_no);
1455 1 : assert_int_equal(spdm_response->chunk_size, fourth_chunk_size);
1456 :
1457 : /* Verify the 4th chunk is filled with 4 */
1458 1 : chunk_ptr = (uint8_t*)(spdm_response + 1);
1459 2 : for (i = 0; i < spdm_response->chunk_size; i++) {
1460 1 : assert_int_equal(chunk_ptr[i], 4);
1461 : }
1462 1 : }
1463 :
1464 :
1465 1 : int libspdm_rsp_chunk_response_test(void)
1466 : {
1467 1 : const struct CMUnitTest test_cases[] = {
1468 : /* Responder has no response flag chunk cap */
1469 : cmocka_unit_test(rsp_chunk_response_case1),
1470 : /* Responder has response state != NORMAL */
1471 : cmocka_unit_test(rsp_chunk_response_case2),
1472 : /* Responder has connection state <= NOT_START */
1473 : cmocka_unit_test(rsp_chunk_response_case3),
1474 : /* Request has wrong size */
1475 : cmocka_unit_test(rsp_chunk_response_case4),
1476 : /* Request has wrong SPDM version */
1477 : cmocka_unit_test(rsp_chunk_response_case5),
1478 : /* Responder has no chunk saved to get */
1479 : cmocka_unit_test(rsp_chunk_response_case6),
1480 : /* Responder has handle that does not match request */
1481 : cmocka_unit_test(rsp_chunk_response_case7),
1482 : /* Responder has earlier sequence number than request */
1483 : cmocka_unit_test(rsp_chunk_response_case8),
1484 : /* Responder has later sequence number than request*/
1485 : cmocka_unit_test(rsp_chunk_response_case9),
1486 : /* Successful request of first chunk */
1487 : cmocka_unit_test(rsp_chunk_response_case10),
1488 : /* Successful request of middle chunk */
1489 : cmocka_unit_test(rsp_chunk_response_case11),
1490 : /* Successful request of last chunk, where size is exactly max chunk size */
1491 : cmocka_unit_test(rsp_chunk_response_case12),
1492 : /* Successful request of last chunk where chunk size is exactly 1 byte */
1493 : cmocka_unit_test(rsp_chunk_response_case13),
1494 : /* Responder has response exceed chunk seq no */
1495 : cmocka_unit_test(rsp_chunk_response_case14),
1496 : /* Successful request of first chunk, spdm 1.4*/
1497 : cmocka_unit_test(rsp_chunk_response_case15),
1498 : /* Successful request of middle chunk, spdm 1.4 */
1499 : cmocka_unit_test(rsp_chunk_response_case16),
1500 : /* Successful request of last chunk, where size is exactly max chunk size, spdm 1.4 */
1501 : cmocka_unit_test(rsp_chunk_response_case17),
1502 : /* Successful request of last chunk where chunk size is exactly 1 byte, spdm 1.4 */
1503 : cmocka_unit_test(rsp_chunk_response_case18),
1504 : };
1505 :
1506 1 : libspdm_test_context_t test_context = {
1507 : LIBSPDM_TEST_CONTEXT_VERSION,
1508 : false,
1509 : };
1510 :
1511 1 : libspdm_setup_test_context(&test_context);
1512 :
1513 1 : return cmocka_run_group_tests(test_cases,
1514 : libspdm_unit_test_group_setup,
1515 : libspdm_unit_test_group_teardown);
1516 : }
1517 :
1518 : #endif /* LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP*/
|