Line data Source code
1 : /**
2 : * Copyright Notice:
3 : * Copyright 2021-2025 DMTF. All rights reserved.
4 : * License: BSD 3-Clause License. For full text see link: https://github.com/DMTF/libspdm/blob/main/LICENSE.md
5 : **/
6 :
7 : #include "spdm_unit_test.h"
8 : #include "internal/libspdm_requester_lib.h"
9 : #include "internal/libspdm_secured_message_lib.h"
10 :
11 : #if LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP
12 :
13 : static bool m_libspdm_chunk_send_last_chunk = false;
14 : static uint8_t m_libspdm_chunk_send_chunk_handle = 0;
15 : static uint16_t m_libspdm_chunk_send_chunk_seq_no = 0;
16 :
17 : /* Override the LIBSPDM_DATA_TRANSFER_SIZE just for the unit tests in this file.
18 : * All other unit tests have the default data transfer size due to the specific
19 : * unit tests requests and responses hardcode for each test case. */
20 : #define CHUNK_SEND_REQUESTER_UNIT_TEST_DATA_TRANSFER_SIZE (42)
21 :
22 3 : void libspdm_requester_chunk_send_test_case1_build_algorithms_response(
23 : void* context, void* response, size_t* response_size)
24 : {
25 : spdm_algorithms_response_t* spdm_response;
26 :
27 3 : *response_size = sizeof(spdm_algorithms_response_t);
28 3 : spdm_response = (spdm_algorithms_response_t*) response;
29 :
30 3 : libspdm_zero_mem(spdm_response, *response_size);
31 3 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_12;
32 3 : spdm_response->header.request_response_code = SPDM_ALGORITHMS;
33 3 : spdm_response->header.param1 = 0;
34 3 : spdm_response->header.param2 = 0;
35 3 : spdm_response->length = sizeof(spdm_algorithms_response_t);
36 3 : spdm_response->measurement_specification_sel =
37 : SPDM_MEASUREMENT_SPECIFICATION_DMTF;
38 3 : spdm_response->measurement_hash_algo =
39 : m_libspdm_use_measurement_hash_algo;
40 3 : spdm_response->base_asym_sel = m_libspdm_use_asym_algo;
41 3 : spdm_response->base_hash_sel = m_libspdm_use_hash_algo;
42 3 : spdm_response->ext_asym_sel_count = 0;
43 3 : spdm_response->ext_hash_sel_count = 0;
44 3 : }
45 :
46 :
47 14 : libspdm_return_t libspdm_requester_chunk_send_test_send_message(
48 : void* spdm_context, size_t request_size, const void* request,
49 : uint64_t timeout)
50 : {
51 : libspdm_test_context_t* spdm_test_context;
52 : const spdm_chunk_send_request_t* chunk_send;
53 :
54 14 : spdm_test_context = libspdm_get_test_context();
55 :
56 14 : chunk_send = (const spdm_chunk_send_request_t*)
57 : ((const uint8_t*) request + sizeof(libspdm_test_message_header_t));
58 :
59 14 : m_libspdm_chunk_send_chunk_handle = chunk_send->header.param2;
60 14 : m_libspdm_chunk_send_chunk_seq_no = chunk_send->chunk_seq_no;
61 :
62 14 : if (chunk_send->header.param1 & SPDM_CHUNK_SEND_REQUEST_ATTRIBUTE_LAST_CHUNK) {
63 2 : m_libspdm_chunk_send_last_chunk = true;
64 : }
65 :
66 14 : if (spdm_test_context->case_id == 1) {
67 2 : return LIBSPDM_STATUS_SUCCESS;
68 : }
69 12 : if (spdm_test_context->case_id == 2) {
70 1 : return LIBSPDM_STATUS_SEND_FAIL;
71 : }
72 11 : if (spdm_test_context->case_id == 3) {
73 1 : return LIBSPDM_STATUS_SUCCESS;
74 : }
75 10 : if (spdm_test_context->case_id == 4) {
76 1 : return LIBSPDM_STATUS_SUCCESS;
77 : }
78 9 : if (spdm_test_context->case_id == 5) {
79 1 : return LIBSPDM_STATUS_SUCCESS;
80 : }
81 8 : if (spdm_test_context->case_id == 6) {
82 1 : return LIBSPDM_STATUS_SUCCESS;
83 : }
84 7 : if (spdm_test_context->case_id == 7) {
85 1 : return LIBSPDM_STATUS_SUCCESS;
86 : }
87 6 : if (spdm_test_context->case_id == 8) {
88 1 : return LIBSPDM_STATUS_SUCCESS;
89 : }
90 5 : if (spdm_test_context->case_id == 9) {
91 1 : return LIBSPDM_STATUS_SUCCESS;
92 : }
93 4 : if (spdm_test_context->case_id == 10) {
94 2 : if (chunk_send->header.request_response_code == SPDM_CHUNK_SEND) {
95 2 : return LIBSPDM_STATUS_SUCCESS;
96 : }
97 0 : return LIBSPDM_STATUS_SEND_FAIL;
98 : }
99 2 : if (spdm_test_context->case_id == 11) {
100 0 : return LIBSPDM_STATUS_SUCCESS;
101 : }
102 2 : if (spdm_test_context->case_id == 12) {
103 : /* Here the send request message should always be SPDM_CHUNK_SEND,
104 : * if not then something is wrong. */
105 1 : LIBSPDM_ASSERT(chunk_send->header.request_response_code == SPDM_CHUNK_SEND);
106 1 : return LIBSPDM_STATUS_SUCCESS;
107 : }
108 1 : if (spdm_test_context->case_id == 13) {
109 : /* Should never reach here since the test case is meant to fail before send */
110 0 : LIBSPDM_ASSERT(0);
111 : }
112 1 : if (spdm_test_context->case_id == 14) {
113 1 : return LIBSPDM_STATUS_SUCCESS;
114 : }
115 0 : return LIBSPDM_STATUS_SEND_FAIL;
116 : }
117 :
118 13 : libspdm_return_t libspdm_requester_chunk_send_test_receive_message(
119 : void *context, size_t *response_size,
120 : void **response, uint64_t timeout)
121 : {
122 : libspdm_test_context_t *spdm_test_context;
123 : libspdm_context_t *spdm_context;
124 : spdm_chunk_send_ack_response_t *chunk_send_ack_rsp;
125 : spdm_error_response_t *error_response;
126 : size_t chunk_rsp_size;
127 : uint8_t *chunk_copy_to;
128 : size_t chunk_size;
129 :
130 13 : spdm_test_context = libspdm_get_test_context();
131 13 : spdm_context = context;
132 :
133 13 : if ((spdm_test_context->case_id == 1) || (spdm_test_context->case_id == 10) ||
134 9 : (spdm_test_context->case_id == 11)) {
135 : /* Successful chunk send of algorithms request */
136 : chunk_send_ack_rsp
137 4 : = (void*) ((uint8_t*) *response + sizeof(libspdm_test_message_header_t));
138 :
139 4 : chunk_send_ack_rsp->header.spdm_version = SPDM_MESSAGE_VERSION_12;
140 4 : chunk_send_ack_rsp->header.request_response_code = SPDM_CHUNK_SEND_ACK;
141 4 : chunk_send_ack_rsp->header.param1 = 0;
142 4 : chunk_send_ack_rsp->header.param2 = m_libspdm_chunk_send_chunk_handle;
143 4 : chunk_send_ack_rsp->chunk_seq_no = m_libspdm_chunk_send_chunk_seq_no;
144 :
145 4 : if (m_libspdm_chunk_send_last_chunk) {
146 :
147 3 : chunk_copy_to = (uint8_t*) (chunk_send_ack_rsp + 1);
148 3 : chunk_size = *response_size - (chunk_copy_to - (uint8_t*) *response);
149 :
150 3 : libspdm_requester_chunk_send_test_case1_build_algorithms_response(
151 : spdm_context, chunk_copy_to, &chunk_size);
152 3 : chunk_rsp_size = sizeof(spdm_chunk_send_ack_response_t) + chunk_size;
153 :
154 3 : libspdm_transport_test_encode_message(
155 : spdm_context, NULL, false, false,
156 : chunk_rsp_size, chunk_send_ack_rsp,
157 : response_size, response);
158 : } else {
159 1 : chunk_rsp_size = sizeof(spdm_chunk_send_ack_response_t);
160 1 : libspdm_transport_test_encode_message(
161 : spdm_context, NULL, false, false,
162 : chunk_rsp_size, chunk_send_ack_rsp,
163 : response_size, response);
164 : }
165 4 : return LIBSPDM_STATUS_SUCCESS;
166 : }
167 9 : if (spdm_test_context->case_id == 2) {
168 : /* Request fail send
169 : * Should never reach here since the test case is meant to fail at send */
170 0 : LIBSPDM_ASSERT(0);
171 0 : return LIBSPDM_STATUS_RECEIVE_FAIL;
172 : }
173 9 : if (spdm_test_context->case_id == 3) {
174 : /* Response fail receive */
175 1 : return LIBSPDM_STATUS_RECEIVE_FAIL;
176 : }
177 8 : if (spdm_test_context->case_id == 4) {
178 : /* Response has bad SPDM version */
179 : chunk_send_ack_rsp
180 1 : = (void*) ((uint8_t*) *response + sizeof(libspdm_test_message_header_t));
181 :
182 1 : chunk_send_ack_rsp->header.spdm_version = SPDM_MESSAGE_VERSION_11; /* Bad SPDM version */
183 1 : chunk_send_ack_rsp->header.request_response_code = SPDM_CHUNK_SEND_ACK;
184 1 : chunk_send_ack_rsp->header.param1 = 0;
185 1 : chunk_send_ack_rsp->header.param2 = m_libspdm_chunk_send_chunk_handle;
186 1 : chunk_send_ack_rsp->chunk_seq_no = m_libspdm_chunk_send_chunk_seq_no;
187 :
188 1 : chunk_rsp_size = sizeof(spdm_chunk_send_ack_response_t);
189 1 : libspdm_transport_test_encode_message(
190 : spdm_context, NULL, false, false,
191 : chunk_rsp_size, chunk_send_ack_rsp,
192 : response_size, response);
193 :
194 1 : return LIBSPDM_STATUS_SUCCESS;
195 : }
196 7 : if (spdm_test_context->case_id == 5) {
197 : /* Response has bad request response code */
198 : chunk_send_ack_rsp
199 1 : = (void*) ((uint8_t*) *response + sizeof(libspdm_test_message_header_t));
200 :
201 1 : chunk_send_ack_rsp->header.spdm_version = SPDM_MESSAGE_VERSION_12;
202 1 : chunk_send_ack_rsp->header.request_response_code = SPDM_ERROR; /* Bad response code */
203 1 : chunk_send_ack_rsp->header.param1 = 0;
204 1 : chunk_send_ack_rsp->header.param2 = 0;
205 :
206 1 : chunk_rsp_size = sizeof(spdm_chunk_send_ack_response_t);
207 1 : libspdm_transport_test_encode_message(
208 : spdm_context, NULL, false, false,
209 : chunk_rsp_size, chunk_send_ack_rsp,
210 : response_size, response);
211 :
212 1 : return LIBSPDM_STATUS_SUCCESS;
213 : }
214 6 : if (spdm_test_context->case_id == 6) {
215 : /* Response has bad response size */
216 : chunk_send_ack_rsp
217 1 : = (void*) ((uint8_t*) *response + sizeof(libspdm_test_message_header_t));
218 :
219 1 : chunk_send_ack_rsp->header.spdm_version = SPDM_MESSAGE_VERSION_12;
220 1 : chunk_send_ack_rsp->header.request_response_code = SPDM_CHUNK_SEND_ACK;
221 1 : chunk_send_ack_rsp->header.param1 = 0;
222 1 : chunk_send_ack_rsp->header.param2 = m_libspdm_chunk_send_chunk_handle;
223 1 : chunk_send_ack_rsp->chunk_seq_no = m_libspdm_chunk_send_chunk_seq_no;
224 :
225 1 : chunk_rsp_size = 4; /* Bad response size */
226 :
227 1 : libspdm_transport_test_encode_message(
228 : spdm_context, NULL, false, false,
229 : chunk_rsp_size, chunk_send_ack_rsp,
230 : response_size, response);
231 :
232 :
233 1 : return LIBSPDM_STATUS_SUCCESS;
234 : }
235 5 : if (spdm_test_context->case_id == 7) {
236 : /* Response has early error detected */
237 : chunk_send_ack_rsp
238 1 : = (void*) ((uint8_t*) *response + sizeof(libspdm_test_message_header_t));
239 :
240 1 : chunk_send_ack_rsp->header.spdm_version = SPDM_MESSAGE_VERSION_12;
241 1 : chunk_send_ack_rsp->header.request_response_code = SPDM_CHUNK_SEND_ACK;
242 : chunk_send_ack_rsp->header.param1
243 1 : = SPDM_CHUNK_SEND_ACK_RESPONSE_ATTRIBUTE_EARLY_ERROR_DETECTED;
244 1 : chunk_send_ack_rsp->header.param2 = m_libspdm_chunk_send_chunk_handle;
245 1 : chunk_send_ack_rsp->chunk_seq_no = m_libspdm_chunk_send_chunk_seq_no;
246 :
247 1 : error_response = (void*) (chunk_send_ack_rsp + 1);
248 1 : error_response->header.spdm_version = SPDM_MESSAGE_VERSION_12;
249 1 : error_response->header.request_response_code = SPDM_ERROR;
250 1 : error_response->header.param1 = SPDM_ERROR_CODE_UNSPECIFIED;
251 1 : error_response->header.param2 = 0;
252 :
253 1 : chunk_rsp_size = sizeof(spdm_chunk_send_ack_response_t) + sizeof(spdm_error_response_t);
254 1 : libspdm_transport_test_encode_message(
255 : spdm_context, NULL, false, false,
256 : chunk_rsp_size, chunk_send_ack_rsp,
257 : response_size, response);
258 :
259 1 : return LIBSPDM_STATUS_SUCCESS;
260 : }
261 4 : if (spdm_test_context->case_id == 8) {
262 : /* Response has bad chunk handle */
263 : chunk_send_ack_rsp
264 1 : = (void*) ((uint8_t*) *response + sizeof(libspdm_test_message_header_t));
265 :
266 1 : chunk_send_ack_rsp->header.spdm_version = SPDM_MESSAGE_VERSION_12;
267 1 : chunk_send_ack_rsp->header.request_response_code = SPDM_CHUNK_SEND_ACK;
268 1 : chunk_send_ack_rsp->header.param1 = 0;
269 :
270 : /* Bad chunk handle */
271 1 : chunk_send_ack_rsp->header.param2 = m_libspdm_chunk_send_chunk_handle - 1;
272 1 : chunk_send_ack_rsp->chunk_seq_no = m_libspdm_chunk_send_chunk_seq_no;
273 :
274 1 : chunk_rsp_size = sizeof(spdm_chunk_send_ack_response_t);
275 1 : libspdm_transport_test_encode_message(
276 : spdm_context, NULL, false, false,
277 : chunk_rsp_size, chunk_send_ack_rsp,
278 : response_size, response);
279 :
280 1 : return LIBSPDM_STATUS_SUCCESS;
281 : }
282 3 : if (spdm_test_context->case_id == 9) {
283 : /* Response has bad chunk seq no */
284 : chunk_send_ack_rsp
285 1 : = (void*) ((uint8_t*) *response + sizeof(libspdm_test_message_header_t));
286 :
287 1 : chunk_send_ack_rsp->header.spdm_version = SPDM_MESSAGE_VERSION_12;
288 1 : chunk_send_ack_rsp->header.request_response_code = SPDM_CHUNK_SEND_ACK;
289 1 : chunk_send_ack_rsp->header.param1 = 0;
290 1 : chunk_send_ack_rsp->header.param2 = m_libspdm_chunk_send_chunk_handle;
291 :
292 : /* Bad Chunk Seq No */
293 1 : chunk_send_ack_rsp->chunk_seq_no = m_libspdm_chunk_send_chunk_seq_no - 1;
294 :
295 1 : chunk_rsp_size = sizeof(spdm_chunk_send_ack_response_t);
296 1 : libspdm_transport_test_encode_message(
297 : spdm_context, NULL, false, false,
298 : chunk_rsp_size, chunk_send_ack_rsp,
299 : response_size, response);
300 :
301 1 : return LIBSPDM_STATUS_SUCCESS;
302 : }
303 2 : if (spdm_test_context->case_id == 12) {
304 : /* ErrorCode == LargeResponse shall not be allowed in ResponseToLargeRequest */
305 : chunk_send_ack_rsp
306 1 : = (void*) ((uint8_t*) *response + sizeof(libspdm_test_message_header_t));
307 :
308 1 : chunk_send_ack_rsp->header.spdm_version = SPDM_MESSAGE_VERSION_12;
309 1 : chunk_send_ack_rsp->header.request_response_code = SPDM_CHUNK_SEND_ACK;
310 : chunk_send_ack_rsp->header.param1
311 1 : = SPDM_CHUNK_SEND_ACK_RESPONSE_ATTRIBUTE_EARLY_ERROR_DETECTED;
312 1 : chunk_send_ack_rsp->header.param2 = m_libspdm_chunk_send_chunk_handle;
313 1 : chunk_send_ack_rsp->chunk_seq_no = m_libspdm_chunk_send_chunk_seq_no;
314 :
315 1 : error_response = (void*) (chunk_send_ack_rsp + 1);
316 1 : error_response->header.spdm_version = SPDM_MESSAGE_VERSION_12;
317 1 : error_response->header.request_response_code = SPDM_ERROR;
318 :
319 : /* ErrorCode == LargeResponse in ResponseToLargeRequest */
320 1 : error_response->header.param1 = SPDM_ERROR_CODE_LARGE_RESPONSE;
321 1 : error_response->header.param2 = 0;
322 1 : *((uint8_t*) (error_response + 1)) = 0;
323 :
324 1 : chunk_rsp_size = sizeof(spdm_chunk_send_ack_response_t) + sizeof(spdm_error_response_t) +
325 : sizeof(uint8_t);
326 1 : libspdm_transport_test_encode_message(
327 : spdm_context, NULL, false, false,
328 : chunk_rsp_size, chunk_send_ack_rsp,
329 : response_size, response);
330 :
331 1 : return LIBSPDM_STATUS_SUCCESS;
332 : }
333 1 : if (spdm_test_context->case_id == 13) {
334 : /* Should never reach here since the test case is meant to fail before send */
335 0 : LIBSPDM_ASSERT(0);
336 : }
337 1 : if (spdm_test_context->case_id == 14) {
338 : /* Response an arror response with RequestResynch */
339 1 : error_response = (void*) ((uint8_t*) *response + sizeof(libspdm_test_message_header_t));
340 1 : error_response->header.spdm_version = SPDM_MESSAGE_VERSION_10;
341 1 : error_response->header.request_response_code = SPDM_ERROR;
342 1 : error_response->header.param1 = SPDM_ERROR_CODE_REQUEST_RESYNCH;
343 1 : error_response->header.param2 = 0;
344 :
345 1 : libspdm_transport_test_encode_message(
346 : spdm_context, NULL, false, false,
347 : sizeof(spdm_error_response_t), error_response,
348 : response_size, response);
349 :
350 1 : return LIBSPDM_STATUS_SUCCESS;
351 : }
352 0 : return LIBSPDM_STATUS_RECEIVE_FAIL;
353 : }
354 :
355 13 : libspdm_return_t libspdm_test_requester_chunk_send_generic_test_case(
356 : void** state, uint32_t case_id)
357 : {
358 : /* Copied from Neg. Algorithms test case 2 */
359 : libspdm_return_t status;
360 : libspdm_test_context_t* spdm_test_context;
361 : libspdm_context_t* spdm_context;
362 :
363 13 : spdm_test_context = *state;
364 13 : spdm_context = spdm_test_context->spdm_context;
365 13 : spdm_test_context->case_id = case_id;
366 13 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 <<
367 : SPDM_VERSION_NUMBER_SHIFT_BIT;
368 13 : spdm_context->connection_info.capability.max_spdm_msg_size = LIBSPDM_MAX_SPDM_MSG_SIZE;
369 13 : spdm_context->connection_info.connection_state =
370 : LIBSPDM_CONNECTION_STATE_AFTER_CAPABILITIES;
371 13 : spdm_context->connection_info.capability.flags |=
372 : (SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP
373 : | SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHUNK_CAP);
374 13 : if (case_id != 10) {
375 : spdm_context->connection_info.capability.data_transfer_size
376 12 : = CHUNK_SEND_REQUESTER_UNIT_TEST_DATA_TRANSFER_SIZE;
377 : spdm_context->local_context.capability.sender_data_transfer_size
378 12 : = LIBSPDM_DATA_TRANSFER_SIZE;
379 : } else {
380 : spdm_context->connection_info.capability.data_transfer_size
381 1 : = LIBSPDM_DATA_TRANSFER_SIZE;
382 : spdm_context->local_context.capability.sender_data_transfer_size
383 1 : = CHUNK_SEND_REQUESTER_UNIT_TEST_DATA_TRANSFER_SIZE;
384 : }
385 :
386 13 : if (case_id == 11) {
387 1 : spdm_context->connection_info.capability.max_spdm_msg_size = 42;
388 : }
389 :
390 13 : spdm_context->local_context.capability.flags |=
391 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHUNK_CAP;
392 13 : spdm_context->connection_info.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP;
393 13 : spdm_context->local_context.algorithm.measurement_spec = SPDM_MEASUREMENT_SPECIFICATION_DMTF;
394 :
395 13 : spdm_context->local_context.algorithm.measurement_hash_algo =
396 : m_libspdm_use_measurement_hash_algo;
397 13 : spdm_context->local_context.algorithm.base_asym_algo = m_libspdm_use_asym_algo;
398 13 : spdm_context->local_context.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
399 13 : spdm_context->local_context.algorithm.dhe_named_group = m_libspdm_use_dhe_algo;
400 13 : spdm_context->local_context.algorithm.aead_cipher_suite = m_libspdm_use_aead_algo;
401 13 : spdm_context->local_context.algorithm.req_base_asym_alg = m_libspdm_use_req_asym_algo;
402 13 : spdm_context->local_context.algorithm.key_schedule = m_libspdm_use_key_schedule_algo;
403 13 : libspdm_reset_message_a(spdm_context);
404 :
405 13 : status = libspdm_negotiate_algorithms(spdm_context);
406 13 : return status;
407 : }
408 :
409 1 : libspdm_return_t libspdm_test_requester_chunk_send_vendor_specific_test_case(
410 : void** state, uint32_t case_id)
411 : {
412 : /* Use vendor specific request to generate a large request. */
413 : libspdm_return_t status;
414 : libspdm_test_context_t* spdm_test_context;
415 : libspdm_context_t* spdm_context;
416 :
417 1 : uint16_t standard_id = 6;
418 1 : uint8_t vendor_id_len = 2;
419 1 : uint8_t vendor_id[SPDM_MAX_VENDOR_ID_LENGTH] = {0xAA, 0xAA};
420 1 : uint16_t data_len = 65535;
421 1 : uint8_t data[65535] = {0};
422 :
423 1 : spdm_test_context = *state;
424 1 : spdm_context = spdm_test_context->spdm_context;
425 1 : spdm_test_context->case_id = case_id;
426 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 <<
427 : SPDM_VERSION_NUMBER_SHIFT_BIT;
428 : /* Large request need a large scratch buffer. */
429 1 : spdm_context->connection_info.capability.max_spdm_msg_size = 0x12000;
430 1 : spdm_context->local_context.capability.max_spdm_msg_size = 0x12000;
431 1 : spdm_context->connection_info.connection_state =
432 : LIBSPDM_CONNECTION_STATE_NEGOTIATED;
433 1 : spdm_context->connection_info.capability.flags |=
434 : (SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP
435 : | SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHUNK_CAP);
436 : spdm_context->connection_info.capability.data_transfer_size
437 1 : = sizeof(spdm_chunk_send_request_t) + 1;
438 : spdm_context->local_context.capability.sender_data_transfer_size
439 1 : = CHUNK_SEND_REQUESTER_UNIT_TEST_DATA_TRANSFER_SIZE;
440 1 : spdm_context->local_context.is_requester = true;
441 :
442 1 : spdm_test_context->scratch_buffer_size =
443 1 : libspdm_get_sizeof_required_scratch_buffer(spdm_context);
444 1 : spdm_test_context->scratch_buffer = (void *)malloc(spdm_test_context->scratch_buffer_size);
445 1 : libspdm_set_scratch_buffer (spdm_context,
446 : spdm_test_context->scratch_buffer,
447 : spdm_test_context->scratch_buffer_size);
448 :
449 1 : libspdm_reset_message_a(spdm_context);
450 :
451 1 : status = libspdm_vendor_send_request_receive_response(spdm_context, NULL,
452 : standard_id, vendor_id_len, vendor_id,
453 : data_len, data,
454 : &standard_id, &vendor_id_len, vendor_id,
455 : &data_len, data);
456 1 : return status;
457 : }
458 :
459 1 : void libspdm_test_requester_chunk_send_case1(void** state)
460 : {
461 : libspdm_return_t status;
462 :
463 1 : status = libspdm_test_requester_chunk_send_generic_test_case(state, 1);
464 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
465 1 : }
466 :
467 1 : void libspdm_test_requester_chunk_send_case2(void** state)
468 : {
469 : libspdm_return_t status;
470 1 : status = libspdm_test_requester_chunk_send_generic_test_case(state, 2);
471 1 : assert_int_equal(status, LIBSPDM_STATUS_SEND_FAIL);
472 1 : }
473 :
474 1 : void libspdm_test_requester_chunk_send_case3(void** state)
475 : {
476 : libspdm_return_t status;
477 1 : status = libspdm_test_requester_chunk_send_generic_test_case(state, 3);
478 1 : assert_int_equal(status, LIBSPDM_STATUS_RECEIVE_FAIL);
479 1 : }
480 :
481 1 : void libspdm_test_requester_chunk_send_case4(void** state)
482 : {
483 : libspdm_return_t status;
484 1 : status = libspdm_test_requester_chunk_send_generic_test_case(state, 4);
485 1 : assert_int_equal(status, LIBSPDM_STATUS_INVALID_MSG_FIELD);
486 1 : }
487 :
488 1 : void libspdm_test_requester_chunk_send_case5(void** state)
489 : {
490 : libspdm_return_t status;
491 1 : status = libspdm_test_requester_chunk_send_generic_test_case(state, 5);
492 1 : assert_int_equal(status, LIBSPDM_STATUS_ERROR_PEER);
493 1 : }
494 :
495 1 : void libspdm_test_requester_chunk_send_case6(void** state)
496 : {
497 : libspdm_return_t status;
498 1 : status = libspdm_test_requester_chunk_send_generic_test_case(state, 6);
499 1 : assert_int_equal(status, LIBSPDM_STATUS_INVALID_MSG_SIZE);
500 1 : }
501 :
502 1 : void libspdm_test_requester_chunk_send_case7(void** state)
503 : {
504 : libspdm_return_t status;
505 1 : status = libspdm_test_requester_chunk_send_generic_test_case(state, 7);
506 1 : assert_int_equal(status, LIBSPDM_STATUS_ERROR_PEER);
507 1 : }
508 :
509 1 : void libspdm_test_requester_chunk_send_case8(void** state)
510 : {
511 : libspdm_return_t status;
512 1 : status = libspdm_test_requester_chunk_send_generic_test_case(state, 8);
513 1 : assert_int_equal(status, LIBSPDM_STATUS_INVALID_MSG_FIELD);
514 1 : }
515 :
516 1 : void libspdm_test_requester_chunk_send_case9(void** state)
517 : {
518 : libspdm_return_t status;
519 1 : status = libspdm_test_requester_chunk_send_generic_test_case(state, 9);
520 1 : assert_int_equal(status, LIBSPDM_STATUS_INVALID_MSG_FIELD);
521 1 : }
522 :
523 1 : void libspdm_test_requester_chunk_send_case10(void** state)
524 : {
525 : libspdm_return_t status;
526 1 : status = libspdm_test_requester_chunk_send_generic_test_case(state, 10);
527 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
528 1 : }
529 :
530 1 : void libspdm_test_requester_chunk_send_case11(void** state)
531 : {
532 : libspdm_return_t status;
533 :
534 1 : status = libspdm_test_requester_chunk_send_generic_test_case(state, 11);
535 1 : assert_int_equal(status, LIBSPDM_STATUS_PEER_BUFFER_TOO_SMALL);
536 1 : }
537 :
538 : /**
539 : * Test 12: ErrorCode == LargeResponse shall not be allowed in ResponseToLargeRequest.
540 : * Expected behavior: returns a status of LIBSPDM_STATUS_ERROR_PEER,
541 : * Received an unexpected error message.
542 : **/
543 1 : void libspdm_test_requester_chunk_send_case12(void** state)
544 : {
545 : libspdm_return_t status;
546 :
547 1 : status = libspdm_test_requester_chunk_send_generic_test_case(state, 12);
548 1 : assert_int_equal(status, LIBSPDM_STATUS_ERROR_PEER);
549 1 : }
550 :
551 : #if LIBSPDM_ENABLE_VENDOR_DEFINED_MESSAGES
552 : /**
553 : * Test 13: Request size shall not exceed max supported transfer size.
554 : * Expected behavior: returns a status of LIBSPDM_STATUS_SEND_FAIL,
555 : **/
556 1 : void libspdm_test_requester_chunk_send_case13(void** state)
557 : {
558 : libspdm_return_t status;
559 :
560 1 : status = libspdm_test_requester_chunk_send_vendor_specific_test_case(state, 13);
561 1 : assert_int_equal(status, LIBSPDM_STATUS_SEND_FAIL);
562 1 : }
563 : #endif
564 :
565 : /**
566 : * Test 14: the requester is sending CHUNK_SEND, but receives an
567 : * ERROR message indicating the RequestResynch status of the responder
568 : * Expected behavior: client returns a Status of RETURN_DEVICE_ERROR, and the
569 : * communication is reset to expect a new GET_VERSION message.
570 : **/
571 1 : void libspdm_test_requester_chunk_send_case14(void** state)
572 : {
573 : libspdm_return_t status;
574 : libspdm_test_context_t* spdm_test_context;
575 : libspdm_context_t* spdm_context;
576 :
577 1 : spdm_test_context = *state;
578 1 : spdm_context = spdm_test_context->spdm_context;
579 :
580 1 : status = libspdm_test_requester_chunk_send_generic_test_case(state, 14);
581 1 : assert_int_equal(status, LIBSPDM_STATUS_RESYNCH_PEER);
582 1 : assert_int_equal(spdm_context->connection_info.connection_state,
583 : LIBSPDM_CONNECTION_STATE_NOT_STARTED);
584 1 : }
585 :
586 1 : int libspdm_requester_chunk_send_test_main(void)
587 : {
588 : /* Test the CHUNK_SEND handlers in various requester handlers */
589 1 : const struct CMUnitTest spdm_requester_chunk_send_tests[] = {
590 : /* Request Algorithms successfully sent in chunks. */
591 : cmocka_unit_test(libspdm_test_requester_chunk_send_case1),
592 : /* Chunk Request fail send */
593 : cmocka_unit_test(libspdm_test_requester_chunk_send_case2),
594 : /* Chunk Response fail receive */
595 : cmocka_unit_test(libspdm_test_requester_chunk_send_case3),
596 : /* Chunk Response has bad SPDM version */
597 : cmocka_unit_test(libspdm_test_requester_chunk_send_case4),
598 : /* Chunk Response has bad request response code */
599 : cmocka_unit_test(libspdm_test_requester_chunk_send_case5),
600 : /* Chunk Response has bad response size */
601 : cmocka_unit_test(libspdm_test_requester_chunk_send_case6),
602 : /* Chunk Response has early error detected */
603 : cmocka_unit_test(libspdm_test_requester_chunk_send_case7),
604 : /* Chunk Response has bad chunk handle */
605 : cmocka_unit_test(libspdm_test_requester_chunk_send_case8),
606 : /* Chunk Response has bad chunk seq no */
607 : cmocka_unit_test(libspdm_test_requester_chunk_send_case9),
608 : /* sent in chunks due to greater than the sending transmit buffer size. */
609 : cmocka_unit_test(libspdm_test_requester_chunk_send_case10),
610 : /* requester message size greater than the responder max_spdm_msg_size, return LIBSPDM_STATUS_PEER_BUFFER_TOO_SMALL */
611 : cmocka_unit_test(libspdm_test_requester_chunk_send_case11),
612 : /* ErrorCode == LargeResponse shall not be allowed in ResponseToLargeRequest */
613 : cmocka_unit_test(libspdm_test_requester_chunk_send_case12),
614 : #if LIBSPDM_ENABLE_VENDOR_DEFINED_MESSAGES
615 : /* Request size exceed max chunks */
616 : cmocka_unit_test(libspdm_test_requester_chunk_send_case13),
617 : #endif
618 : /* Recieved and error message indicating RequestResynch */
619 : cmocka_unit_test(libspdm_test_requester_chunk_send_case14),
620 : };
621 :
622 1 : libspdm_test_context_t test_context = {
623 : LIBSPDM_TEST_CONTEXT_VERSION,
624 : true,
625 : libspdm_requester_chunk_send_test_send_message,
626 : libspdm_requester_chunk_send_test_receive_message,
627 : };
628 :
629 1 : libspdm_setup_test_context(&test_context);
630 :
631 1 : return cmocka_run_group_tests(spdm_requester_chunk_send_tests,
632 : libspdm_unit_test_group_setup,
633 : libspdm_unit_test_group_teardown);
634 : }
635 :
636 : #endif /* LIBSPDM_ENABLE_CAPABILITY_CHUNK_CAP*/
|