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 = *(uint32_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*)(((uint32_t*) (spdm_response + 1)) + 1);
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.chunk_bytes_transferred = first_chunk_size + second_chunk_size;
809 :
810 1 : libspdm_zero_mem(&spdm_request, sizeof(spdm_request));
811 1 : spdm_request.header.spdm_version = SPDM_MESSAGE_VERSION_12;
812 1 : spdm_request.header.request_response_code = SPDM_CHUNK_GET;
813 1 : spdm_request.header.param1 = 0;
814 1 : spdm_request.header.param2 = chunk_handle;
815 1 : spdm_request.chunk_seq_no = chunk_seq_no;
816 :
817 1 : response_size = sizeof(response);
818 1 : status = libspdm_get_response_chunk_get(
819 : spdm_context,
820 : sizeof(spdm_request), &spdm_request,
821 : &response_size, response);
822 :
823 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
824 1 : assert_int_equal(response_size, data_transfer_size);
825 :
826 1 : spdm_response = (spdm_chunk_response_response_t*) response;
827 1 : assert_int_equal(spdm_response->header.spdm_version, SPDM_MESSAGE_VERSION_12);
828 1 : assert_int_equal(spdm_response->header.request_response_code, SPDM_CHUNK_RESPONSE);
829 1 : assert_int_equal(spdm_response->header.param1, SPDM_CHUNK_GET_RESPONSE_ATTRIBUTE_LAST_CHUNK);
830 1 : assert_int_equal(spdm_response->header.param2, chunk_handle);
831 1 : assert_int_equal(spdm_response->chunk_seq_no, chunk_seq_no);
832 1 : assert_int_equal(spdm_response->chunk_size, third_chunk_size);
833 :
834 : /* Verify the 3rd chunk is filled with 3 */
835 1 : chunk_ptr = (uint8_t*) (spdm_response + 1);
836 33 : for (i = 0; i < spdm_response->chunk_size; i++) {
837 32 : assert_int_equal(chunk_ptr[i], 3);
838 : }
839 1 : }
840 :
841 : /**
842 : * Test 13: Successful request of last chunk where size is exactly 1.
843 : **/
844 1 : static void rsp_chunk_response_case13(void** state)
845 : {
846 : libspdm_return_t status;
847 : libspdm_test_context_t* spdm_test_context;
848 : libspdm_context_t* spdm_context;
849 : size_t response_size;
850 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
851 : spdm_chunk_response_response_t* spdm_response;
852 : spdm_chunk_get_request_t spdm_request;
853 : void* scratch_buffer;
854 : size_t scratch_buffer_size;
855 :
856 : uint8_t chunk_handle;
857 : uint16_t chunk_seq_no;
858 : uint32_t data_transfer_size;
859 : uint32_t first_chunk_size;
860 : uint32_t second_chunk_size;
861 : uint32_t third_chunk_size;
862 : uint32_t total_chunk_size;
863 : uint32_t fourth_chunk_size;
864 : uint32_t expected_response_size;
865 : uint8_t* chunk_ptr;
866 : uint32_t i;
867 :
868 1 : spdm_test_context = *state;
869 1 : spdm_context = spdm_test_context->spdm_context;
870 1 : spdm_test_context->case_id = 12;
871 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 <<
872 : SPDM_VERSION_NUMBER_SHIFT_BIT;
873 :
874 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
875 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
876 :
877 1 : data_transfer_size = CHUNK_GET_RESPONDER_UNIT_TEST_DATA_TRANSFER_SIZE;
878 1 : spdm_context->local_context.capability.data_transfer_size = data_transfer_size;
879 1 : spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHUNK_CAP;
880 1 : spdm_context->connection_info.capability.flags |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP;
881 :
882 1 : libspdm_get_scratch_buffer(spdm_context, &scratch_buffer, &scratch_buffer_size);
883 :
884 2 : scratch_buffer = (uint8_t*)scratch_buffer +
885 1 : libspdm_get_scratch_buffer_large_message_offset(spdm_context);
886 2 : scratch_buffer_size = scratch_buffer_size -
887 1 : libspdm_get_scratch_buffer_large_message_offset(spdm_context);
888 1 : libspdm_zero_mem(scratch_buffer, scratch_buffer_size);
889 :
890 : /* Fill 1st chunk with 1, 2nd chunk with 2, 3rd chunk with 3, 4th chunk with 4 */
891 1 : first_chunk_size = data_transfer_size -
892 : (sizeof(spdm_chunk_response_response_t) + sizeof(uint32_t));
893 1 : second_chunk_size = data_transfer_size - sizeof(spdm_chunk_response_response_t);
894 1 : third_chunk_size = data_transfer_size - sizeof(spdm_chunk_response_response_t);
895 1 : fourth_chunk_size = 1;
896 :
897 1 : total_chunk_size = first_chunk_size + second_chunk_size + third_chunk_size + fourth_chunk_size;
898 1 : expected_response_size = sizeof(spdm_chunk_response_response_t) + fourth_chunk_size;
899 1 : LIBSPDM_ASSERT(total_chunk_size <= scratch_buffer_size);
900 :
901 1 : libspdm_set_mem(scratch_buffer, first_chunk_size, 1);
902 1 : libspdm_set_mem((uint8_t*) scratch_buffer + first_chunk_size, second_chunk_size, 2);
903 1 : libspdm_set_mem((uint8_t*) scratch_buffer + first_chunk_size + second_chunk_size,
904 : third_chunk_size, 3);
905 1 : libspdm_set_mem((uint8_t*) scratch_buffer + first_chunk_size
906 1 : + second_chunk_size + third_chunk_size,
907 : fourth_chunk_size, 4);
908 :
909 1 : chunk_handle = (uint8_t) spdm_test_context->case_id; /* Any number is fine */
910 1 : chunk_seq_no = 3; /* 3 == 4th chunk */
911 1 : spdm_context->chunk_context.get.chunk_in_use = true;
912 1 : spdm_context->chunk_context.get.chunk_handle = chunk_handle;
913 1 : spdm_context->chunk_context.get.chunk_seq_no = chunk_seq_no;
914 1 : spdm_context->chunk_context.get.large_message = scratch_buffer;
915 1 : spdm_context->chunk_context.get.large_message_size = total_chunk_size;
916 1 : spdm_context->chunk_context.get.chunk_bytes_transferred =
917 1 : first_chunk_size + second_chunk_size + third_chunk_size;
918 :
919 1 : libspdm_zero_mem(&spdm_request, sizeof(spdm_request));
920 1 : spdm_request.header.spdm_version = SPDM_MESSAGE_VERSION_12;
921 1 : spdm_request.header.request_response_code = SPDM_CHUNK_GET;
922 1 : spdm_request.header.param1 = 0;
923 1 : spdm_request.header.param2 = chunk_handle;
924 1 : spdm_request.chunk_seq_no = chunk_seq_no;
925 :
926 1 : response_size = sizeof(response);
927 1 : status = libspdm_get_response_chunk_get(
928 : spdm_context,
929 : sizeof(spdm_request), &spdm_request,
930 : &response_size, response);
931 :
932 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
933 1 : assert_int_equal(response_size, expected_response_size);
934 :
935 1 : spdm_response = (spdm_chunk_response_response_t*) response;
936 1 : assert_int_equal(spdm_response->header.spdm_version, SPDM_MESSAGE_VERSION_12);
937 1 : assert_int_equal(spdm_response->header.request_response_code, SPDM_CHUNK_RESPONSE);
938 1 : assert_int_equal(spdm_response->header.param1, SPDM_CHUNK_GET_RESPONSE_ATTRIBUTE_LAST_CHUNK);
939 1 : assert_int_equal(spdm_response->header.param2, chunk_handle);
940 1 : assert_int_equal(spdm_response->chunk_seq_no, chunk_seq_no);
941 1 : assert_int_equal(spdm_response->chunk_size, fourth_chunk_size);
942 :
943 : /* Verify the 4th chunk is filled with 4 */
944 1 : chunk_ptr = (uint8_t*)(spdm_response + 1);
945 2 : for (i = 0; i < spdm_response->chunk_size; i++) {
946 1 : assert_int_equal(chunk_ptr[i], 4);
947 : }
948 1 : }
949 :
950 :
951 : /**
952 : * Test 14: Responder has response exceed chunk seq no
953 : **/
954 1 : static void rsp_chunk_response_case14(void** state)
955 : {
956 : libspdm_return_t status;
957 : libspdm_test_context_t* spdm_test_context;
958 : libspdm_context_t* spdm_context;
959 : size_t response_size;
960 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
961 : spdm_error_response_t* spdm_response;
962 : spdm_chunk_get_request_t spdm_request;
963 : void* scratch_buffer;
964 : size_t scratch_buffer_size;
965 :
966 : uint8_t chunk_handle;
967 : uint32_t data_transfer_size;
968 : uint32_t total_chunk_size;
969 :
970 1 : spdm_test_context = *state;
971 1 : spdm_context = spdm_test_context->spdm_context;
972 1 : spdm_test_context->case_id = 10;
973 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 <<
974 : SPDM_VERSION_NUMBER_SHIFT_BIT;
975 :
976 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
977 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
978 :
979 1 : data_transfer_size = CHUNK_GET_RESPONDER_UNIT_TEST_DATA_TRANSFER_SIZE;
980 1 : spdm_context->local_context.capability.data_transfer_size = data_transfer_size;
981 1 : spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHUNK_CAP;
982 1 : spdm_context->connection_info.capability.flags |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP;
983 :
984 : /* large response need a large scratch buffer */
985 1 : spdm_context->connection_info.capability.max_spdm_msg_size = data_transfer_size * 65536;
986 1 : spdm_context->local_context.capability.max_spdm_msg_size = data_transfer_size * 65536;
987 1 : spdm_test_context->scratch_buffer_size =
988 1 : libspdm_get_sizeof_required_scratch_buffer(spdm_context);
989 1 : spdm_test_context->scratch_buffer = (void *)malloc(spdm_test_context->scratch_buffer_size);
990 1 : libspdm_set_scratch_buffer (spdm_context,
991 : spdm_test_context->scratch_buffer,
992 : spdm_test_context->scratch_buffer_size);
993 :
994 :
995 1 : libspdm_get_scratch_buffer(spdm_context, &scratch_buffer, &scratch_buffer_size);
996 :
997 2 : scratch_buffer = (uint8_t*)scratch_buffer +
998 1 : libspdm_get_scratch_buffer_large_message_offset(spdm_context);
999 2 : scratch_buffer_size = scratch_buffer_size -
1000 1 : libspdm_get_scratch_buffer_large_message_offset(spdm_context);
1001 1 : libspdm_zero_mem(scratch_buffer, scratch_buffer_size);
1002 :
1003 : /* a huge chunk size to cause the chunk seq no wrap */
1004 1 : total_chunk_size = data_transfer_size * 65536;
1005 :
1006 1 : LIBSPDM_ASSERT(total_chunk_size <= scratch_buffer_size);
1007 :
1008 1 : chunk_handle = (uint8_t) spdm_test_context->case_id; /* Any number is fine */
1009 1 : spdm_context->chunk_context.get.chunk_in_use = true;
1010 1 : spdm_context->chunk_context.get.chunk_handle = chunk_handle;
1011 1 : spdm_context->chunk_context.get.chunk_seq_no = 0;
1012 1 : spdm_context->chunk_context.get.large_message = scratch_buffer;
1013 1 : spdm_context->chunk_context.get.large_message_size = total_chunk_size;
1014 1 : spdm_context->chunk_context.get.chunk_bytes_transferred = 0;
1015 :
1016 1 : libspdm_zero_mem(&spdm_request, sizeof(spdm_request));
1017 1 : spdm_request.header.spdm_version = SPDM_MESSAGE_VERSION_12;
1018 1 : spdm_request.header.request_response_code = SPDM_CHUNK_GET;
1019 1 : spdm_request.header.param1 = 0;
1020 1 : spdm_request.header.param2 = chunk_handle;
1021 1 : spdm_request.chunk_seq_no = 0;
1022 :
1023 1 : response_size = sizeof(response);
1024 1 : status = libspdm_get_response_chunk_get(
1025 : spdm_context,
1026 : sizeof(spdm_request), &spdm_request,
1027 : &response_size, response);
1028 :
1029 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
1030 1 : assert_int_equal(response_size, sizeof(spdm_error_response_t));
1031 :
1032 1 : spdm_response = (spdm_error_response_t*) response;
1033 :
1034 1 : assert_int_equal(spdm_response->header.spdm_version, SPDM_MESSAGE_VERSION_12);
1035 1 : assert_int_equal(spdm_response->header.request_response_code, SPDM_ERROR);
1036 1 : assert_int_equal(spdm_response->header.param1, SPDM_ERROR_CODE_RESPONSE_TOO_LARGE);
1037 1 : assert_int_equal(spdm_response->header.param2, 0);
1038 1 : }
1039 :
1040 : /**
1041 : * Test 15: Successful request of first chunk, spdm 1.4.
1042 : **/
1043 1 : static void rsp_chunk_response_case15(void** state)
1044 : {
1045 : libspdm_return_t status;
1046 : libspdm_test_context_t* spdm_test_context;
1047 : libspdm_context_t* spdm_context;
1048 : size_t response_size;
1049 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
1050 : spdm_chunk_response_response_14_t* spdm_response;
1051 : spdm_chunk_get_request_14_t spdm_request;
1052 : void* scratch_buffer;
1053 : size_t scratch_buffer_size;
1054 :
1055 : uint8_t chunk_handle;
1056 : uint32_t data_transfer_size;
1057 : uint32_t first_chunk_size;
1058 : uint32_t second_chunk_size;
1059 : uint32_t third_chunk_size;
1060 : uint32_t total_chunk_size;
1061 : uint32_t large_response;
1062 : uint8_t* chunk_ptr;
1063 : uint32_t i;
1064 :
1065 1 : spdm_test_context = *state;
1066 1 : spdm_context = spdm_test_context->spdm_context;
1067 1 : spdm_test_context->case_id = 15;
1068 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_14 <<
1069 : SPDM_VERSION_NUMBER_SHIFT_BIT;
1070 :
1071 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
1072 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
1073 :
1074 1 : data_transfer_size = CHUNK_GET_RESPONDER_UNIT_TEST_DATA_TRANSFER_SIZE;
1075 1 : spdm_context->local_context.capability.data_transfer_size = data_transfer_size;
1076 1 : spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHUNK_CAP;
1077 1 : spdm_context->connection_info.capability.flags |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP;
1078 :
1079 1 : libspdm_get_scratch_buffer(spdm_context, &scratch_buffer, &scratch_buffer_size);
1080 :
1081 2 : scratch_buffer = (uint8_t*)scratch_buffer +
1082 1 : libspdm_get_scratch_buffer_large_message_offset(spdm_context);
1083 2 : scratch_buffer_size = scratch_buffer_size -
1084 1 : libspdm_get_scratch_buffer_large_message_offset(spdm_context);
1085 1 : libspdm_zero_mem(scratch_buffer, scratch_buffer_size);
1086 :
1087 : /* Fill 1st chunk with 1, 2nd chunk with 2, 3rd chunk with 3 */
1088 1 : first_chunk_size = data_transfer_size -
1089 : (sizeof(spdm_chunk_response_response_14_t) + sizeof(uint32_t));
1090 1 : second_chunk_size = data_transfer_size - sizeof(spdm_chunk_response_response_14_t);
1091 1 : third_chunk_size = data_transfer_size - sizeof(spdm_chunk_response_response_14_t);
1092 1 : total_chunk_size = first_chunk_size + second_chunk_size + third_chunk_size;
1093 1 : LIBSPDM_ASSERT(total_chunk_size <= scratch_buffer_size);
1094 :
1095 1 : libspdm_set_mem(scratch_buffer, first_chunk_size, 1);
1096 1 : libspdm_set_mem((uint8_t*)scratch_buffer + first_chunk_size, second_chunk_size, 2);
1097 1 : libspdm_set_mem((uint8_t*) scratch_buffer + first_chunk_size + second_chunk_size,
1098 : third_chunk_size, 3);
1099 :
1100 1 : chunk_handle = (uint8_t) spdm_test_context->case_id; /* Any number is fine */
1101 1 : spdm_context->chunk_context.get.chunk_in_use = true;
1102 1 : spdm_context->chunk_context.get.chunk_handle = chunk_handle;
1103 1 : spdm_context->chunk_context.get.chunk_seq_no = 0;
1104 1 : spdm_context->chunk_context.get.large_message = scratch_buffer;
1105 1 : spdm_context->chunk_context.get.large_message_size = total_chunk_size;
1106 1 : spdm_context->chunk_context.get.chunk_bytes_transferred = 0;
1107 :
1108 1 : libspdm_zero_mem(&spdm_request, sizeof(spdm_request));
1109 1 : spdm_request.header.spdm_version = SPDM_MESSAGE_VERSION_14;
1110 1 : spdm_request.header.request_response_code = SPDM_CHUNK_GET;
1111 1 : spdm_request.header.param1 = 0;
1112 1 : spdm_request.header.param2 = chunk_handle;
1113 1 : spdm_request.chunk_seq_no = 0;
1114 :
1115 1 : response_size = sizeof(response);
1116 1 : status = libspdm_get_response_chunk_get(
1117 : spdm_context,
1118 : sizeof(spdm_request), &spdm_request,
1119 : &response_size, response);
1120 :
1121 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
1122 1 : assert_int_equal(response_size, data_transfer_size);
1123 :
1124 1 : spdm_response = (spdm_chunk_response_response_14_t*) response;
1125 1 : assert_int_equal(spdm_response->header.spdm_version, SPDM_MESSAGE_VERSION_14);
1126 1 : assert_int_equal(spdm_response->header.request_response_code, SPDM_CHUNK_RESPONSE);
1127 1 : assert_int_equal(spdm_response->header.param1, 0);
1128 1 : assert_int_equal(spdm_response->header.param2, chunk_handle);
1129 1 : assert_int_equal(spdm_response->chunk_seq_no, 0);
1130 1 : assert_int_equal(spdm_response->chunk_size, first_chunk_size);
1131 :
1132 1 : large_response = *(uint32_t*) (spdm_response + 1);
1133 1 : assert_int_equal(large_response, total_chunk_size);
1134 :
1135 : /* Verify the 1st chunk is filled with 1 */
1136 1 : chunk_ptr = (uint8_t*)(((uint32_t*) (spdm_response + 1)) + 1);
1137 29 : for (i = 0; i < spdm_response->chunk_size; i++) {
1138 28 : assert_int_equal(chunk_ptr[i], 1);
1139 : }
1140 1 : }
1141 :
1142 : /**
1143 : * Test 16: Successful request of middle chunk, spdm 1.4.
1144 : **/
1145 1 : static void rsp_chunk_response_case16(void** state)
1146 : {
1147 : libspdm_return_t status;
1148 : libspdm_test_context_t* spdm_test_context;
1149 : libspdm_context_t* spdm_context;
1150 : size_t response_size;
1151 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
1152 : spdm_chunk_response_response_14_t* spdm_response;
1153 : spdm_chunk_get_request_14_t spdm_request;
1154 : void* scratch_buffer;
1155 : size_t scratch_buffer_size;
1156 :
1157 : uint8_t chunk_handle;
1158 : uint32_t chunk_seq_no;
1159 : uint32_t data_transfer_size;
1160 : uint32_t first_chunk_size;
1161 : uint32_t second_chunk_size;
1162 : uint32_t third_chunk_size;
1163 : uint32_t total_chunk_size;
1164 : uint8_t* chunk_ptr;
1165 : uint32_t i;
1166 :
1167 1 : spdm_test_context = *state;
1168 1 : spdm_context = spdm_test_context->spdm_context;
1169 1 : spdm_test_context->case_id = 16;
1170 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_14 <<
1171 : SPDM_VERSION_NUMBER_SHIFT_BIT;
1172 :
1173 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
1174 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
1175 :
1176 1 : data_transfer_size = CHUNK_GET_RESPONDER_UNIT_TEST_DATA_TRANSFER_SIZE;
1177 1 : spdm_context->local_context.capability.data_transfer_size = data_transfer_size;
1178 1 : spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHUNK_CAP;
1179 1 : spdm_context->connection_info.capability.flags |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP;
1180 :
1181 1 : libspdm_get_scratch_buffer(spdm_context, &scratch_buffer, &scratch_buffer_size);
1182 :
1183 2 : scratch_buffer = (uint8_t*)scratch_buffer +
1184 1 : libspdm_get_scratch_buffer_large_message_offset(spdm_context);
1185 2 : scratch_buffer_size = scratch_buffer_size -
1186 1 : libspdm_get_scratch_buffer_large_message_offset(spdm_context);
1187 1 : libspdm_zero_mem(scratch_buffer, scratch_buffer_size);
1188 :
1189 : /* Fill 1st chunk with 1, 2nd chunk with 2, 3rd chunk with 3 */
1190 1 : first_chunk_size = data_transfer_size -
1191 : (sizeof(spdm_chunk_response_response_14_t) + sizeof(uint32_t));
1192 1 : second_chunk_size = data_transfer_size - sizeof(spdm_chunk_response_response_14_t);
1193 1 : third_chunk_size = data_transfer_size - sizeof(spdm_chunk_response_response_14_t);
1194 1 : total_chunk_size = first_chunk_size + second_chunk_size + third_chunk_size;
1195 1 : LIBSPDM_ASSERT(total_chunk_size <= scratch_buffer_size);
1196 :
1197 1 : libspdm_set_mem(scratch_buffer, first_chunk_size, 1);
1198 1 : libspdm_set_mem((uint8_t*) scratch_buffer + first_chunk_size, second_chunk_size, 2);
1199 1 : libspdm_set_mem((uint8_t*) scratch_buffer + first_chunk_size + second_chunk_size,
1200 : third_chunk_size, 3);
1201 :
1202 1 : chunk_handle = (uint8_t) spdm_test_context->case_id; /* Any number is fine */
1203 1 : chunk_seq_no = 1; /* 1 == 2nd chunk */
1204 1 : spdm_context->chunk_context.get.chunk_in_use = true;
1205 1 : spdm_context->chunk_context.get.chunk_handle = chunk_handle;
1206 1 : spdm_context->chunk_context.get.chunk_seq_no = chunk_seq_no;
1207 1 : spdm_context->chunk_context.get.large_message = scratch_buffer;
1208 1 : spdm_context->chunk_context.get.large_message_size = total_chunk_size;
1209 1 : spdm_context->chunk_context.get.chunk_bytes_transferred = first_chunk_size;
1210 :
1211 1 : libspdm_zero_mem(&spdm_request, sizeof(spdm_request));
1212 1 : spdm_request.header.spdm_version = SPDM_MESSAGE_VERSION_14;
1213 1 : spdm_request.header.request_response_code = SPDM_CHUNK_GET;
1214 1 : spdm_request.header.param1 = 0;
1215 1 : spdm_request.header.param2 = chunk_handle;
1216 1 : spdm_request.chunk_seq_no = chunk_seq_no;
1217 :
1218 1 : response_size = sizeof(response);
1219 1 : status = libspdm_get_response_chunk_get(
1220 : spdm_context,
1221 : sizeof(spdm_request), &spdm_request,
1222 : &response_size, response);
1223 :
1224 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
1225 1 : assert_int_equal(response_size, data_transfer_size);
1226 :
1227 1 : spdm_response = (spdm_chunk_response_response_14_t*) response;
1228 1 : assert_int_equal(spdm_response->header.spdm_version, SPDM_MESSAGE_VERSION_14);
1229 1 : assert_int_equal(spdm_response->header.request_response_code, SPDM_CHUNK_RESPONSE);
1230 1 : assert_int_equal(spdm_response->header.param1, 0);
1231 1 : assert_int_equal(spdm_response->header.param2, chunk_handle);
1232 1 : assert_int_equal(spdm_response->chunk_seq_no, chunk_seq_no);
1233 1 : assert_int_equal(spdm_response->chunk_size, second_chunk_size);
1234 :
1235 : /* Verify the 2nd chunk is filled with 2 */
1236 1 : chunk_ptr = (uint8_t*) (spdm_response + 1);
1237 33 : for (i = 0; i < spdm_response->chunk_size; i++) {
1238 32 : assert_int_equal(chunk_ptr[i], 2);
1239 : }
1240 1 : }
1241 :
1242 : /**
1243 : * Test 17: Successful request of last chunk where size is exactly max chunk size
1244 : **/
1245 1 : static void rsp_chunk_response_case17(void** state)
1246 : {
1247 : libspdm_return_t status;
1248 : libspdm_test_context_t* spdm_test_context;
1249 : libspdm_context_t* spdm_context;
1250 : size_t response_size;
1251 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
1252 : spdm_chunk_response_response_14_t* spdm_response;
1253 : spdm_chunk_get_request_14_t spdm_request;
1254 : void* scratch_buffer;
1255 : size_t scratch_buffer_size;
1256 :
1257 : uint8_t chunk_handle;
1258 : uint32_t chunk_seq_no;
1259 : uint32_t data_transfer_size;
1260 : uint32_t first_chunk_size;
1261 : uint32_t second_chunk_size;
1262 : uint32_t third_chunk_size;
1263 : uint32_t total_chunk_size;
1264 : uint8_t* chunk_ptr;
1265 : uint32_t i;
1266 :
1267 1 : spdm_test_context = *state;
1268 1 : spdm_context = spdm_test_context->spdm_context;
1269 1 : spdm_test_context->case_id = 17;
1270 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_14 <<
1271 : SPDM_VERSION_NUMBER_SHIFT_BIT;
1272 :
1273 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
1274 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
1275 :
1276 1 : data_transfer_size = CHUNK_GET_RESPONDER_UNIT_TEST_DATA_TRANSFER_SIZE;
1277 1 : spdm_context->local_context.capability.data_transfer_size = data_transfer_size;
1278 1 : spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHUNK_CAP;
1279 1 : spdm_context->connection_info.capability.flags |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP;
1280 :
1281 1 : libspdm_get_scratch_buffer(spdm_context, &scratch_buffer, &scratch_buffer_size);
1282 :
1283 2 : scratch_buffer = (uint8_t*)scratch_buffer +
1284 1 : libspdm_get_scratch_buffer_large_message_offset(spdm_context);
1285 2 : scratch_buffer_size = scratch_buffer_size -
1286 1 : libspdm_get_scratch_buffer_large_message_offset(spdm_context);
1287 1 : libspdm_zero_mem(scratch_buffer, scratch_buffer_size);
1288 :
1289 : /* Fill 1st chunk with 1, 2nd chunk with 2, 3rd chunk with 3 */
1290 1 : first_chunk_size = data_transfer_size -
1291 : (sizeof(spdm_chunk_response_response_14_t) + sizeof(uint32_t));
1292 1 : second_chunk_size = data_transfer_size - sizeof(spdm_chunk_response_response_14_t);
1293 1 : third_chunk_size = data_transfer_size - sizeof(spdm_chunk_response_response_14_t);
1294 1 : total_chunk_size = first_chunk_size + second_chunk_size + third_chunk_size;
1295 1 : LIBSPDM_ASSERT(total_chunk_size <= scratch_buffer_size);
1296 :
1297 1 : libspdm_set_mem(scratch_buffer, first_chunk_size, 1);
1298 1 : libspdm_set_mem((uint8_t*) scratch_buffer + first_chunk_size, second_chunk_size, 2);
1299 1 : libspdm_set_mem((uint8_t*) scratch_buffer + first_chunk_size + second_chunk_size,
1300 : third_chunk_size, 3);
1301 :
1302 1 : chunk_handle = (uint8_t) spdm_test_context->case_id; /* Any number is fine */
1303 1 : chunk_seq_no = 2; /* 2 == 3rd chunk */
1304 1 : spdm_context->chunk_context.get.chunk_in_use = true;
1305 1 : spdm_context->chunk_context.get.chunk_handle = chunk_handle;
1306 1 : spdm_context->chunk_context.get.chunk_seq_no = chunk_seq_no;
1307 1 : spdm_context->chunk_context.get.large_message = scratch_buffer;
1308 1 : spdm_context->chunk_context.get.large_message_size = total_chunk_size;
1309 1 : spdm_context->chunk_context.get.chunk_bytes_transferred = first_chunk_size + second_chunk_size;
1310 :
1311 1 : libspdm_zero_mem(&spdm_request, sizeof(spdm_request));
1312 1 : spdm_request.header.spdm_version = SPDM_MESSAGE_VERSION_14;
1313 1 : spdm_request.header.request_response_code = SPDM_CHUNK_GET;
1314 1 : spdm_request.header.param1 = 0;
1315 1 : spdm_request.header.param2 = chunk_handle;
1316 1 : spdm_request.chunk_seq_no = chunk_seq_no;
1317 :
1318 1 : response_size = sizeof(response);
1319 1 : status = libspdm_get_response_chunk_get(
1320 : spdm_context,
1321 : sizeof(spdm_request), &spdm_request,
1322 : &response_size, response);
1323 :
1324 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
1325 1 : assert_int_equal(response_size, data_transfer_size);
1326 :
1327 1 : spdm_response = (spdm_chunk_response_response_14_t*) response;
1328 1 : assert_int_equal(spdm_response->header.spdm_version, SPDM_MESSAGE_VERSION_14);
1329 1 : assert_int_equal(spdm_response->header.request_response_code, SPDM_CHUNK_RESPONSE);
1330 1 : assert_int_equal(spdm_response->header.param1, SPDM_CHUNK_GET_RESPONSE_ATTRIBUTE_LAST_CHUNK);
1331 1 : assert_int_equal(spdm_response->header.param2, chunk_handle);
1332 1 : assert_int_equal(spdm_response->chunk_seq_no, chunk_seq_no);
1333 1 : assert_int_equal(spdm_response->chunk_size, third_chunk_size);
1334 :
1335 : /* Verify the 3rd chunk is filled with 3 */
1336 1 : chunk_ptr = (uint8_t*) (spdm_response + 1);
1337 33 : for (i = 0; i < spdm_response->chunk_size; i++) {
1338 32 : assert_int_equal(chunk_ptr[i], 3);
1339 : }
1340 1 : }
1341 :
1342 : /**
1343 : * Test 18: Successful request of last chunk where size is exactly 1.
1344 : **/
1345 1 : static void rsp_chunk_response_case18(void** state)
1346 : {
1347 : libspdm_return_t status;
1348 : libspdm_test_context_t* spdm_test_context;
1349 : libspdm_context_t* spdm_context;
1350 : size_t response_size;
1351 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
1352 : spdm_chunk_response_response_14_t* spdm_response;
1353 : spdm_chunk_get_request_14_t spdm_request;
1354 : void* scratch_buffer;
1355 : size_t scratch_buffer_size;
1356 :
1357 : uint8_t chunk_handle;
1358 : uint16_t chunk_seq_no;
1359 : uint32_t data_transfer_size;
1360 : uint32_t first_chunk_size;
1361 : uint32_t second_chunk_size;
1362 : uint32_t third_chunk_size;
1363 : uint32_t total_chunk_size;
1364 : uint32_t fourth_chunk_size;
1365 : uint32_t expected_response_size;
1366 : uint8_t* chunk_ptr;
1367 : uint32_t i;
1368 :
1369 1 : spdm_test_context = *state;
1370 1 : spdm_context = spdm_test_context->spdm_context;
1371 1 : spdm_test_context->case_id = 18;
1372 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_14 <<
1373 : SPDM_VERSION_NUMBER_SHIFT_BIT;
1374 :
1375 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
1376 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
1377 :
1378 1 : data_transfer_size = CHUNK_GET_RESPONDER_UNIT_TEST_DATA_TRANSFER_SIZE;
1379 1 : spdm_context->local_context.capability.data_transfer_size = data_transfer_size;
1380 1 : spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHUNK_CAP;
1381 1 : spdm_context->connection_info.capability.flags |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP;
1382 :
1383 1 : libspdm_get_scratch_buffer(spdm_context, &scratch_buffer, &scratch_buffer_size);
1384 :
1385 2 : scratch_buffer = (uint8_t*)scratch_buffer +
1386 1 : libspdm_get_scratch_buffer_large_message_offset(spdm_context);
1387 2 : scratch_buffer_size = scratch_buffer_size -
1388 1 : libspdm_get_scratch_buffer_large_message_offset(spdm_context);
1389 1 : libspdm_zero_mem(scratch_buffer, scratch_buffer_size);
1390 :
1391 : /* Fill 1st chunk with 1, 2nd chunk with 2, 3rd chunk with 3, 4th chunk with 4 */
1392 1 : first_chunk_size = data_transfer_size -
1393 : (sizeof(spdm_chunk_response_response_14_t) + sizeof(uint32_t));
1394 1 : second_chunk_size = data_transfer_size - sizeof(spdm_chunk_response_response_14_t);
1395 1 : third_chunk_size = data_transfer_size - sizeof(spdm_chunk_response_response_14_t);
1396 1 : fourth_chunk_size = 1;
1397 :
1398 1 : total_chunk_size = first_chunk_size + second_chunk_size + third_chunk_size + fourth_chunk_size;
1399 1 : expected_response_size = sizeof(spdm_chunk_response_response_14_t) + fourth_chunk_size;
1400 1 : LIBSPDM_ASSERT(total_chunk_size <= scratch_buffer_size);
1401 :
1402 1 : libspdm_set_mem(scratch_buffer, first_chunk_size, 1);
1403 1 : libspdm_set_mem((uint8_t*) scratch_buffer + first_chunk_size, second_chunk_size, 2);
1404 1 : libspdm_set_mem((uint8_t*) scratch_buffer + first_chunk_size + second_chunk_size,
1405 : third_chunk_size, 3);
1406 1 : libspdm_set_mem((uint8_t*) scratch_buffer + first_chunk_size
1407 1 : + second_chunk_size + third_chunk_size,
1408 : fourth_chunk_size, 4);
1409 :
1410 1 : chunk_handle = (uint8_t) spdm_test_context->case_id; /* Any number is fine */
1411 1 : chunk_seq_no = 3; /* 3 == 4th chunk */
1412 1 : spdm_context->chunk_context.get.chunk_in_use = true;
1413 1 : spdm_context->chunk_context.get.chunk_handle = chunk_handle;
1414 1 : spdm_context->chunk_context.get.chunk_seq_no = chunk_seq_no;
1415 1 : spdm_context->chunk_context.get.large_message = scratch_buffer;
1416 1 : spdm_context->chunk_context.get.large_message_size = total_chunk_size;
1417 1 : spdm_context->chunk_context.get.chunk_bytes_transferred =
1418 1 : first_chunk_size + second_chunk_size + third_chunk_size;
1419 :
1420 1 : libspdm_zero_mem(&spdm_request, sizeof(spdm_request));
1421 1 : spdm_request.header.spdm_version = SPDM_MESSAGE_VERSION_14;
1422 1 : spdm_request.header.request_response_code = SPDM_CHUNK_GET;
1423 1 : spdm_request.header.param1 = 0;
1424 1 : spdm_request.header.param2 = chunk_handle;
1425 1 : spdm_request.chunk_seq_no = chunk_seq_no;
1426 :
1427 1 : response_size = sizeof(response);
1428 1 : status = libspdm_get_response_chunk_get(
1429 : spdm_context,
1430 : sizeof(spdm_request), &spdm_request,
1431 : &response_size, response);
1432 :
1433 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
1434 1 : assert_int_equal(response_size, expected_response_size);
1435 :
1436 1 : spdm_response = (spdm_chunk_response_response_14_t*) response;
1437 1 : assert_int_equal(spdm_response->header.spdm_version, SPDM_MESSAGE_VERSION_14);
1438 1 : assert_int_equal(spdm_response->header.request_response_code, SPDM_CHUNK_RESPONSE);
1439 1 : assert_int_equal(spdm_response->header.param1, SPDM_CHUNK_GET_RESPONSE_ATTRIBUTE_LAST_CHUNK);
1440 1 : assert_int_equal(spdm_response->header.param2, chunk_handle);
1441 1 : assert_int_equal(spdm_response->chunk_seq_no, chunk_seq_no);
1442 1 : assert_int_equal(spdm_response->chunk_size, fourth_chunk_size);
1443 :
1444 : /* Verify the 4th chunk is filled with 4 */
1445 1 : chunk_ptr = (uint8_t*)(spdm_response + 1);
1446 2 : for (i = 0; i < spdm_response->chunk_size; i++) {
1447 1 : assert_int_equal(chunk_ptr[i], 4);
1448 : }
1449 1 : }
1450 :
1451 :
1452 1 : int libspdm_rsp_chunk_response_test(void)
1453 : {
1454 1 : const struct CMUnitTest test_cases[] = {
1455 : /* Responder has no response flag chunk cap */
1456 : cmocka_unit_test(rsp_chunk_response_case1),
1457 : /* Responder has response state != NORMAL */
1458 : cmocka_unit_test(rsp_chunk_response_case2),
1459 : /* Responder has connection state <= NOT_START */
1460 : cmocka_unit_test(rsp_chunk_response_case3),
1461 : /* Request has wrong size */
1462 : cmocka_unit_test(rsp_chunk_response_case4),
1463 : /* Request has wrong SPDM version */
1464 : cmocka_unit_test(rsp_chunk_response_case5),
1465 : /* Responder has no chunk saved to get */
1466 : cmocka_unit_test(rsp_chunk_response_case6),
1467 : /* Responder has handle that does not match request */
1468 : cmocka_unit_test(rsp_chunk_response_case7),
1469 : /* Responder has earlier sequence number than request */
1470 : cmocka_unit_test(rsp_chunk_response_case8),
1471 : /* Responder has later sequence number than request*/
1472 : cmocka_unit_test(rsp_chunk_response_case9),
1473 : /* Successful request of first chunk */
1474 : cmocka_unit_test(rsp_chunk_response_case10),
1475 : /* Successful request of middle chunk */
1476 : cmocka_unit_test(rsp_chunk_response_case11),
1477 : /* Successful request of last chunk, where size is exactly max chunk size */
1478 : cmocka_unit_test(rsp_chunk_response_case12),
1479 : /* Successful request of last chunk where chunk size is exactly 1 byte */
1480 : cmocka_unit_test(rsp_chunk_response_case13),
1481 : /* Responder has response exceed chunk seq no */
1482 : cmocka_unit_test(rsp_chunk_response_case14),
1483 : /* Successful request of first chunk, spdm 1.4*/
1484 : cmocka_unit_test(rsp_chunk_response_case15),
1485 : /* Successful request of middle chunk, spdm 1.4 */
1486 : cmocka_unit_test(rsp_chunk_response_case16),
1487 : /* Successful request of last chunk, where size is exactly max chunk size, spdm 1.4 */
1488 : cmocka_unit_test(rsp_chunk_response_case17),
1489 : /* Successful request of last chunk where chunk size is exactly 1 byte, spdm 1.4 */
1490 : cmocka_unit_test(rsp_chunk_response_case18),
1491 : };
1492 :
1493 1 : libspdm_test_context_t test_context = {
1494 : LIBSPDM_TEST_CONTEXT_VERSION,
1495 : false,
1496 : };
1497 :
1498 1 : libspdm_setup_test_context(&test_context);
1499 :
1500 1 : return cmocka_run_group_tests(test_cases,
1501 : libspdm_unit_test_group_setup,
1502 : libspdm_unit_test_group_teardown);
1503 : }
1504 :
1505 : #endif /* LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP*/
|