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_requester_lib.h"
9 : #include "internal/libspdm_secured_message_lib.h"
10 :
11 : #if LIBSPDM_ENABLE_CAPABILITY_CSR_CAP
12 :
13 : #define LIBSPDM_MAX_CSR_SIZE 0x1000
14 :
15 : /*refer to https://github.com/Mbed-TLS/mbedtls/blob/3048c8c90654eb116a6b17c0d2d27c3ccbe6782c/programs/x509/cert_req.c#L119-L129*/
16 : #define LIBSPDM_MAX_REQ_INFO_BUFFER_SIZE 4096
17 :
18 : uint8_t csr_pointer[LIBSPDM_MAX_CSR_SIZE] = {0};
19 : uint8_t *csr_data_pointer = csr_pointer;
20 : size_t global_csr_len;
21 :
22 : uint8_t m_csr_opaque_data[8] = "libspdm";
23 : uint16_t m_csr_opaque_data_size = sizeof(m_csr_opaque_data);
24 :
25 : /*ECC 256 req_info(include right req_info attribute)*/
26 : uint8_t req_info_sequence[] = {0x30, 0x81, 0xBF,};
27 : uint8_t req_info_version[] = {0x02, 0x01, 0x00,};
28 : uint8_t req_info_subject[] = {
29 : 0x30, 0x45, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x41, 0x55, 0x31,
30 : 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0C, 0x0A, 0x53, 0x6F, 0x6D, 0x65, 0x2D, 0x53,
31 : 0x74, 0x61, 0x74, 0x65, 0x31, 0x21, 0x30, 0x1F, 0x06, 0x03, 0x55, 0x04, 0x0A, 0x0C, 0x18, 0x49,
32 : 0x6E, 0x74, 0x65, 0x72, 0x6E, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67, 0x69, 0x74, 0x73, 0x20,
33 : 0x50, 0x74, 0x79, 0x20, 0x4C, 0x74, 0x64,
34 : };
35 : uint8_t req_info_right_attributes[] = {
36 : /*[0]: attributes*/
37 : 0xA0, 0x18, 0x30, 0x16,
38 : /*OID*/
39 : 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x09, 0x07,
40 : /*attributes*/
41 : 0x31, 0x09, 0x0C, 0x07, 0x74, 0x65, 0x73, 0x74, 0x31, 0x32, 0x33
42 : };
43 :
44 : /*the unique attribute from right_req_info*/
45 : char right_req_info_string[] = {0x74, 0x65, 0x73, 0x74, 0x31, 0x32, 0x33};
46 :
47 : static uint8_t right_req_info[LIBSPDM_MAX_REQ_INFO_BUFFER_SIZE];
48 : static uint16_t right_req_info_size;
49 :
50 : /*gen right_req_info*/
51 1 : void libspdm_gen_req_info() {
52 : uint8_t *req_info_p;
53 : void *req_info_pkinfo;
54 : size_t req_info_pkinfo_len;
55 :
56 1 : libspdm_zero_mem(right_req_info, sizeof(right_req_info));
57 :
58 1 : req_info_p = right_req_info;
59 1 : right_req_info_size = sizeof(right_req_info);
60 :
61 1 : libspdm_read_responder_public_key(m_libspdm_use_asym_algo,
62 : &req_info_pkinfo, &req_info_pkinfo_len);
63 :
64 : /*concat right_req_info*/
65 1 : libspdm_copy_mem(req_info_p, right_req_info_size, req_info_sequence, sizeof(req_info_sequence));
66 1 : req_info_p += sizeof(req_info_sequence);
67 1 : right_req_info_size -= sizeof(req_info_sequence);
68 :
69 1 : libspdm_copy_mem(req_info_p, right_req_info_size, req_info_version, sizeof(req_info_version));
70 1 : req_info_p += sizeof(req_info_version);
71 1 : right_req_info_size -= sizeof(req_info_version);
72 :
73 1 : libspdm_copy_mem(req_info_p, right_req_info_size, req_info_subject, sizeof(req_info_subject));
74 1 : req_info_p += sizeof(req_info_subject);
75 1 : right_req_info_size -= sizeof(req_info_subject);
76 :
77 1 : libspdm_copy_mem(req_info_p, right_req_info_size, req_info_pkinfo, req_info_pkinfo_len);
78 1 : req_info_p += req_info_pkinfo_len;
79 1 : right_req_info_size = (uint16_t)(right_req_info_size - req_info_pkinfo_len);
80 :
81 1 : libspdm_copy_mem(req_info_p, right_req_info_size,
82 : req_info_right_attributes, sizeof(req_info_right_attributes));
83 1 : req_info_p += sizeof(req_info_right_attributes);
84 1 : right_req_info_size -= sizeof(req_info_right_attributes);
85 :
86 1 : right_req_info_size = sizeof(right_req_info) - right_req_info_size;
87 :
88 1 : free(req_info_pkinfo);
89 1 : }
90 :
91 5 : bool libspdm_read_requester_gen_csr(void **csr_data, size_t *csr_len)
92 : {
93 : char *file;
94 : bool res;
95 :
96 5 : file = "test_csr/cached.csr";
97 5 : res = libspdm_read_input_file(file, csr_data, csr_len);
98 5 : if (!res) {
99 0 : return res;
100 : }
101 :
102 5 : return res;
103 : }
104 :
105 : /*ensure that cached.csr exists in test_csr at the beginning*/
106 1 : void libspdm_clear_cached_csr()
107 : {
108 1 : char *new_name = "test_csr/cached.csr";
109 1 : char *file_name = "test_csr/cached.staging";
110 :
111 1 : rename(file_name, new_name);
112 1 : }
113 :
114 7 : static libspdm_return_t send_message(
115 : void *spdm_context, size_t request_size, const void *request, uint64_t timeout)
116 : {
117 : libspdm_test_context_t *spdm_test_context;
118 :
119 7 : spdm_test_context = libspdm_get_test_context();
120 7 : switch (spdm_test_context->case_id) {
121 1 : case 0x1:
122 1 : return LIBSPDM_STATUS_SEND_FAIL;
123 1 : case 0x2:
124 1 : return LIBSPDM_STATUS_SUCCESS;
125 2 : case 0x3:
126 2 : return LIBSPDM_STATUS_SUCCESS;
127 1 : case 0x4: {
128 : const spdm_get_csr_request_t *spdm_request;
129 : uint16_t requester_info_length;
130 : uint16_t opaque_data_length;
131 : uint8_t *opaque_data;
132 : uint8_t *requester_info;
133 :
134 : /* Obtain the real spdm_request */
135 1 : spdm_request =
136 : (const spdm_get_csr_request_t *)((const uint8_t *)request +
137 : sizeof(libspdm_test_message_header_t));
138 :
139 1 : requester_info_length = spdm_request->requester_info_length;
140 1 : opaque_data_length = spdm_request->opaque_data_length;
141 :
142 1 : requester_info = (void*)((size_t)(spdm_request + 1));
143 1 : assert_memory_equal(requester_info, right_req_info, requester_info_length);
144 1 : opaque_data = (void *)(requester_info + requester_info_length);
145 1 : assert_memory_equal(opaque_data, m_csr_opaque_data, opaque_data_length);
146 1 : return LIBSPDM_STATUS_SUCCESS;
147 : }
148 1 : case 0x5:
149 1 : return LIBSPDM_STATUS_SUCCESS;
150 1 : case 0x6:
151 1 : return LIBSPDM_STATUS_SUCCESS;
152 0 : case 0x7:
153 0 : assert_true(false);
154 0 : return LIBSPDM_STATUS_SUCCESS;
155 0 : default:
156 0 : return LIBSPDM_STATUS_SEND_FAIL;
157 : }
158 : }
159 :
160 6 : static libspdm_return_t receive_message(
161 : void *spdm_context, size_t *response_size, void **response, uint64_t timeout)
162 : {
163 : libspdm_test_context_t *spdm_test_context;
164 : libspdm_context_t *context;
165 :
166 6 : spdm_test_context = libspdm_get_test_context();
167 6 : switch (spdm_test_context->case_id) {
168 0 : case 0x1:
169 0 : return LIBSPDM_STATUS_RECEIVE_FAIL;
170 :
171 1 : case 0x2: {
172 : spdm_csr_response_t *spdm_response;
173 : size_t spdm_response_size;
174 : size_t transport_header_size;
175 :
176 1 : libspdm_read_requester_gen_csr((void *)&csr_data_pointer, &global_csr_len);
177 :
178 1 : spdm_response_size = sizeof(spdm_csr_response_t) + global_csr_len;
179 1 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
180 1 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
181 :
182 1 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_12;
183 1 : spdm_response->header.request_response_code = SPDM_CSR;
184 1 : spdm_response->header.param1 = 0;
185 1 : spdm_response->header.param2 = 0;
186 1 : spdm_response->csr_length = (uint16_t)global_csr_len;
187 1 : spdm_response->reserved = 0;
188 :
189 1 : libspdm_copy_mem(spdm_response + 1, global_csr_len, csr_data_pointer, global_csr_len);
190 :
191 1 : libspdm_transport_test_encode_message(spdm_context, NULL, false,
192 : false, spdm_response_size,
193 : spdm_response, response_size,
194 : response);
195 : }
196 1 : return LIBSPDM_STATUS_SUCCESS;
197 :
198 2 : case 0x3: {
199 : spdm_csr_response_t *spdm_response;
200 : size_t spdm_response_size;
201 : size_t transport_header_size;
202 :
203 2 : libspdm_read_requester_gen_csr((void *)&csr_data_pointer, &global_csr_len);
204 :
205 2 : spdm_response_size = sizeof(spdm_csr_response_t) + global_csr_len;
206 2 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
207 2 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
208 :
209 2 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_12;
210 2 : spdm_response->header.param2 = 0;
211 2 : spdm_response->csr_length = (uint16_t)global_csr_len;
212 2 : spdm_response->reserved = 0;
213 :
214 2 : context = spdm_context;
215 :
216 2 : if (context->connection_info.capability.flags &
217 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_INSTALL_RESET_CAP) {
218 1 : spdm_response->header.request_response_code = SPDM_ERROR;
219 1 : spdm_response->header.param1 = SPDM_ERROR_CODE_RESET_REQUIRED;
220 : } else {
221 1 : spdm_response->header.request_response_code = SPDM_CSR;
222 1 : spdm_response->header.param1 = 0;
223 :
224 1 : libspdm_copy_mem(spdm_response + 1, global_csr_len, csr_data_pointer, global_csr_len);
225 : }
226 :
227 2 : libspdm_transport_test_encode_message(spdm_context, NULL, false,
228 : false, spdm_response_size,
229 : spdm_response, response_size,
230 : response);
231 : }
232 2 : return LIBSPDM_STATUS_SUCCESS;
233 1 : case 0x4: {
234 : spdm_csr_response_t *spdm_response;
235 : size_t spdm_response_size;
236 : size_t transport_header_size;
237 :
238 1 : libspdm_read_requester_gen_csr((void *)&csr_data_pointer, &global_csr_len);
239 1 : spdm_response_size = sizeof(spdm_csr_response_t) + global_csr_len;
240 1 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
241 1 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
242 :
243 1 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_12;
244 1 : spdm_response->header.request_response_code = SPDM_CSR;
245 1 : spdm_response->header.param1 = 0;
246 1 : spdm_response->header.param2 = 0;
247 1 : spdm_response->csr_length = (uint16_t)global_csr_len;
248 1 : spdm_response->reserved = 0;
249 1 : libspdm_copy_mem(spdm_response + 1, global_csr_len, csr_data_pointer, global_csr_len);
250 :
251 1 : libspdm_transport_test_encode_message(spdm_context, NULL, false,
252 : false, spdm_response_size,
253 : spdm_response, response_size,
254 : response);
255 : }
256 1 : return LIBSPDM_STATUS_SUCCESS;
257 1 : case 0x5: {
258 : spdm_csr_response_t *spdm_response;
259 : size_t spdm_response_size;
260 : size_t transport_header_size;
261 :
262 1 : libspdm_read_requester_gen_csr((void *)&csr_data_pointer, &global_csr_len);
263 :
264 1 : spdm_response_size = sizeof(spdm_csr_response_t) + global_csr_len;
265 1 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
266 1 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
267 :
268 1 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_13;
269 1 : spdm_response->header.request_response_code = SPDM_ERROR;
270 1 : spdm_response->header.param1 = SPDM_ERROR_CODE_RESET_REQUIRED;
271 1 : spdm_response->header.param2 = 1;
272 1 : spdm_response->csr_length = (uint16_t)global_csr_len;
273 1 : spdm_response->reserved = 0;
274 :
275 1 : libspdm_transport_test_encode_message(spdm_context, NULL, false,
276 : false, spdm_response_size,
277 : spdm_response, response_size,
278 : response);
279 : }
280 1 : return LIBSPDM_STATUS_SUCCESS;
281 1 : case 0x6: {
282 : spdm_error_response_t *spdm_response;
283 : size_t spdm_response_size;
284 : size_t transport_header_size;
285 :
286 1 : spdm_response_size = sizeof(spdm_error_response_t);
287 1 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
288 1 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
289 :
290 1 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_13;
291 1 : spdm_response->header.request_response_code = SPDM_ERROR;
292 1 : spdm_response->header.param1 = SPDM_ERROR_CODE_RESET_REQUIRED;
293 1 : spdm_response->header.param2 = 1;
294 :
295 1 : libspdm_transport_test_encode_message(spdm_context, NULL, false,
296 : false, spdm_response_size,
297 : spdm_response, response_size,
298 : response);
299 : }
300 1 : return LIBSPDM_STATUS_SUCCESS;
301 0 : case 0x7:
302 0 : assert_true(false);
303 0 : return LIBSPDM_STATUS_SUCCESS;
304 0 : default:
305 0 : return LIBSPDM_STATUS_RECEIVE_FAIL;
306 : }
307 : }
308 :
309 : /**
310 : * Test 1: message could not be sent
311 : * Expected Behavior: get a RETURN_DEVICE_ERROR return code
312 : **/
313 1 : static void req_get_csr_case1(void **state)
314 : {
315 : libspdm_return_t status;
316 : libspdm_test_context_t *spdm_test_context;
317 : libspdm_context_t *spdm_context;
318 :
319 1 : uint8_t csr_form_get[LIBSPDM_MAX_CSR_SIZE] = {0};
320 : size_t csr_len;
321 :
322 1 : csr_len = LIBSPDM_MAX_CSR_SIZE;
323 :
324 1 : spdm_test_context = *state;
325 1 : spdm_context = spdm_test_context->spdm_context;
326 1 : spdm_test_context->case_id = 0x1;
327 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 <<
328 : SPDM_VERSION_NUMBER_SHIFT_BIT;
329 :
330 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
331 1 : spdm_context->connection_info.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CSR_CAP;
332 :
333 : /*init req_info*/
334 1 : libspdm_gen_req_info();
335 :
336 1 : status = libspdm_get_csr(spdm_context, NULL, NULL, 0, NULL, 0, (void *)&csr_form_get, &csr_len);
337 :
338 1 : assert_int_equal(status, LIBSPDM_STATUS_SEND_FAIL);
339 1 : }
340 :
341 : /**
342 : * Test 2: Successful response to get csr
343 : * Expected Behavior: get a LIBSPDM_STATUS_SUCCESS return code
344 : **/
345 1 : static void req_get_csr_case2(void **state)
346 : {
347 : libspdm_return_t status;
348 : libspdm_test_context_t *spdm_test_context;
349 : libspdm_context_t *spdm_context;
350 :
351 1 : uint8_t csr_form_get[LIBSPDM_MAX_CSR_SIZE] = {0};
352 : size_t csr_len;
353 :
354 1 : csr_len = LIBSPDM_MAX_CSR_SIZE;
355 :
356 1 : spdm_test_context = *state;
357 1 : spdm_context = spdm_test_context->spdm_context;
358 1 : spdm_test_context->case_id = 0x2;
359 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 <<
360 : SPDM_VERSION_NUMBER_SHIFT_BIT;
361 :
362 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
363 1 : spdm_context->connection_info.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CSR_CAP;
364 :
365 1 : status = libspdm_get_csr(spdm_context, NULL, NULL, 0, NULL, 0, (void *)&csr_form_get, &csr_len);
366 :
367 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
368 1 : assert_int_equal(csr_len, global_csr_len);
369 1 : assert_memory_equal(csr_form_get, csr_data_pointer, global_csr_len);
370 1 : }
371 :
372 : /**
373 : * Test 3: Successful response to get csr,
374 : * with a reset required
375 : * Expected Behavior: get a LIBSPDM_STATUS_SUCCESS return code
376 : **/
377 1 : static void req_get_csr_case3(void **state)
378 : {
379 : libspdm_return_t status;
380 : libspdm_test_context_t *spdm_test_context;
381 : libspdm_context_t *spdm_context;
382 :
383 1 : uint8_t csr_form_get[LIBSPDM_MAX_CSR_SIZE] = {0};
384 : size_t csr_len;
385 :
386 1 : csr_len = LIBSPDM_MAX_CSR_SIZE;
387 :
388 1 : spdm_test_context = *state;
389 1 : spdm_context = spdm_test_context->spdm_context;
390 1 : spdm_test_context->case_id = 0x3;
391 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 <<
392 : SPDM_VERSION_NUMBER_SHIFT_BIT;
393 :
394 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
395 1 : spdm_context->connection_info.capability.flags |=
396 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CSR_CAP |
397 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_INSTALL_RESET_CAP;
398 :
399 1 : status = libspdm_get_csr(spdm_context, NULL, NULL, 0, NULL, 0, (void *)&csr_form_get, &csr_len);
400 :
401 1 : assert_int_equal(status, LIBSPDM_STATUS_RESET_REQUIRED_PEER);
402 :
403 : /* Let's reset the responder and send the request again */
404 1 : spdm_context->connection_info.capability.flags &=
405 : ~SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_INSTALL_RESET_CAP;
406 :
407 1 : status = libspdm_get_csr(spdm_context, NULL, NULL, 0, NULL, 0, (void *)&csr_form_get, &csr_len);
408 :
409 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
410 1 : assert_int_equal(csr_len, global_csr_len);
411 1 : assert_memory_equal(csr_form_get, csr_data_pointer, global_csr_len);
412 1 : }
413 :
414 : /**
415 : * Test 4: Send correct req_info and opaque_data
416 : * Expected Behavior: get a LIBSPDM_STATUS_SUCCESS return code and determine if req_info and opaque_data are correct
417 : **/
418 1 : static void req_get_csr_case4(void **state)
419 : {
420 : libspdm_return_t status;
421 : libspdm_test_context_t *spdm_test_context;
422 : libspdm_context_t *spdm_context;
423 :
424 1 : uint8_t csr_form_get[LIBSPDM_MAX_CSR_SIZE] = {0};
425 : size_t csr_len;
426 :
427 1 : csr_len = LIBSPDM_MAX_CSR_SIZE;
428 :
429 1 : spdm_test_context = *state;
430 1 : spdm_context = spdm_test_context->spdm_context;
431 1 : spdm_test_context->case_id = 0x4;
432 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 <<
433 : SPDM_VERSION_NUMBER_SHIFT_BIT;
434 :
435 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
436 1 : spdm_context->local_context.capability.flags = 0;
437 1 : spdm_context->connection_info.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CSR_CAP;
438 :
439 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
440 1 : spdm_context->connection_info.algorithm.base_asym_algo = m_libspdm_use_asym_algo;
441 :
442 1 : spdm_context->connection_info.algorithm.other_params_support =
443 : SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_0;
444 :
445 1 : status = libspdm_get_csr(spdm_context, NULL,
446 : right_req_info, right_req_info_size,
447 : m_csr_opaque_data, m_csr_opaque_data_size,
448 : (void *)&csr_form_get, &csr_len);
449 :
450 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
451 1 : assert_int_equal(csr_len, global_csr_len);
452 1 : assert_memory_equal(csr_form_get, csr_data_pointer, global_csr_len);
453 1 : }
454 :
455 : /**
456 : * Test 5: Successful response to libspdm_get_csr_ex,
457 : * with a reset required
458 : * Expected Behavior: get a LIBSPDM_STATUS_RESET_REQUIRED_PEER return code and available csr_tracking_tag
459 : **/
460 1 : static void req_get_csr_case5(void **state)
461 : {
462 : libspdm_test_context_t *spdm_test_context;
463 : libspdm_context_t *spdm_context;
464 : #if LIBSPDM_ENABLE_CAPABILITY_CSR_CAP_EX
465 : libspdm_return_t status;
466 1 : uint8_t csr_form_get[LIBSPDM_MAX_CSR_SIZE] = {0};
467 : size_t csr_len;
468 : uint8_t reset_csr_tracking_tag;
469 :
470 1 : csr_len = LIBSPDM_MAX_CSR_SIZE;
471 1 : reset_csr_tracking_tag = 0;
472 : #endif /* LIBSPDM_ENABLE_CAPABILITY_CSR_CAP_EX*/
473 1 : spdm_test_context = *state;
474 1 : spdm_context = spdm_test_context->spdm_context;
475 1 : spdm_test_context->case_id = 0x5;
476 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_13 <<
477 : SPDM_VERSION_NUMBER_SHIFT_BIT;
478 :
479 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
480 1 : spdm_context->connection_info.capability.flags |=
481 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CSR_CAP |
482 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_INSTALL_RESET_CAP;
483 :
484 : #if LIBSPDM_ENABLE_CAPABILITY_CSR_CAP_EX
485 1 : status = libspdm_get_csr_ex(spdm_context, NULL, NULL, 0, NULL, 0, (void *)&csr_form_get,
486 : &csr_len, 0, 0, &reset_csr_tracking_tag);
487 :
488 1 : assert_int_equal(status, LIBSPDM_STATUS_RESET_REQUIRED_PEER);
489 1 : assert_int_equal(reset_csr_tracking_tag, 1);
490 : #endif /*LIBSPDM_ENABLE_CAPABILITY_CSR_CAP_EX*/
491 1 : }
492 :
493 : /**
494 : * Test 6: A 1.3 Responder returns ResetRequired when its CERT_INSTALL_RESET_CAP is 0.
495 : * Expected Behavior: libspdm returns LIBSPDM_STATUS_ERROR_PEER since Responder should
496 : * not produce that error message unless CERT_INSTALL_RESET_CAP is 1.
497 : **/
498 1 : static void req_get_csr_case6(void **state)
499 : {
500 : libspdm_return_t status;
501 : libspdm_test_context_t *spdm_test_context;
502 : libspdm_context_t *spdm_context;
503 :
504 1 : uint8_t csr_form_get[LIBSPDM_MAX_CSR_SIZE] = {0};
505 : size_t csr_len;
506 :
507 1 : csr_len = LIBSPDM_MAX_CSR_SIZE;
508 :
509 1 : spdm_test_context = *state;
510 1 : spdm_context = spdm_test_context->spdm_context;
511 1 : spdm_test_context->case_id = 0x6;
512 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_13 <<
513 : SPDM_VERSION_NUMBER_SHIFT_BIT;
514 :
515 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
516 1 : spdm_context->local_context.capability.flags = 0;
517 : /* Don't set CERT_INSTALL_RESET_CAP. */
518 1 : spdm_context->connection_info.capability.flags = SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CSR_CAP;
519 :
520 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
521 1 : spdm_context->connection_info.algorithm.base_asym_algo = m_libspdm_use_asym_algo;
522 :
523 1 : spdm_context->connection_info.algorithm.other_params_support =
524 : SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_0;
525 :
526 1 : status = libspdm_get_csr(spdm_context, NULL,
527 : right_req_info, right_req_info_size,
528 : m_csr_opaque_data, m_csr_opaque_data_size,
529 : (void *)&csr_form_get, &csr_len);
530 :
531 1 : assert_int_equal(status, LIBSPDM_STATUS_ERROR_PEER);
532 1 : }
533 :
534 : /**
535 : * Test 7: Illegal combination of MULTI_KEY_CONN_RSP = true and CSRCertModel = 0.
536 : * Expected Behavior: returns LIBSPDM_STATUS_INVALID_PARAMETER.
537 : **/
538 1 : static void req_get_csr_case7(void **state)
539 : {
540 : #if LIBSPDM_ENABLE_CAPABILITY_CSR_CAP_EX
541 : libspdm_return_t status;
542 : libspdm_test_context_t *spdm_test_context;
543 : libspdm_context_t *spdm_context;
544 :
545 1 : uint8_t csr_form_get[LIBSPDM_MAX_CSR_SIZE] = {0};
546 : size_t csr_len;
547 : uint8_t tracking_tag;
548 :
549 1 : csr_len = LIBSPDM_MAX_CSR_SIZE;
550 :
551 1 : spdm_test_context = *state;
552 1 : spdm_context = spdm_test_context->spdm_context;
553 1 : spdm_test_context->case_id = 0x7;
554 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_13 <<
555 : SPDM_VERSION_NUMBER_SHIFT_BIT;
556 :
557 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
558 1 : spdm_context->local_context.capability.flags = 0;
559 1 : spdm_context->connection_info.capability.flags = SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CSR_CAP;
560 1 : spdm_context->connection_info.multi_key_conn_rsp = true;
561 :
562 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
563 1 : spdm_context->connection_info.algorithm.base_asym_algo = m_libspdm_use_asym_algo;
564 :
565 1 : spdm_context->connection_info.algorithm.other_params_support =
566 : SPDM_ALGORITHMS_OPAQUE_DATA_FORMAT_0;
567 :
568 1 : status = libspdm_get_csr_ex(spdm_context, NULL, NULL, 0, NULL, 0, (void *)&csr_form_get,
569 : &csr_len, SPDM_CERTIFICATE_INFO_CERT_MODEL_NONE, 1, &tracking_tag);
570 :
571 1 : assert_int_equal(status, LIBSPDM_STATUS_INVALID_PARAMETER);
572 : #endif /* LIBSPDM_ENABLE_CAPABILITY_CSR_CAP_EX */
573 1 : }
574 :
575 1 : int libspdm_req_get_csr_test(void)
576 : {
577 1 : const struct CMUnitTest test_cases[] = {
578 : /* SendRequest failed*/
579 : cmocka_unit_test(req_get_csr_case1),
580 : /* Successful response to get csr*/
581 : cmocka_unit_test(req_get_csr_case2),
582 : /* Successful response to get csr with a reset required */
583 : cmocka_unit_test(req_get_csr_case3),
584 : /* Send req_info and opaque_data Successful response to get csr */
585 : cmocka_unit_test(req_get_csr_case4),
586 : /* Successful response to libspdm_get_csr_ex with a reset required */
587 : cmocka_unit_test(req_get_csr_case5),
588 : /* Illegal ResetRequired error response. */
589 : cmocka_unit_test(req_get_csr_case6),
590 : cmocka_unit_test(req_get_csr_case7),
591 : };
592 :
593 1 : libspdm_test_context_t test_context = {
594 : LIBSPDM_TEST_CONTEXT_VERSION,
595 : true,
596 : send_message,
597 : receive_message,
598 : };
599 :
600 1 : libspdm_setup_test_context(&test_context);
601 :
602 : /*ensure that cached.csr exists in test_csr at the beginning*/
603 1 : libspdm_clear_cached_csr();
604 :
605 1 : return cmocka_run_group_tests(test_cases,
606 : libspdm_unit_test_group_setup,
607 : libspdm_unit_test_group_teardown);
608 : }
609 :
610 : #endif /*LIBSPDM_ENABLE_CAPABILITY_CSR_CAP*/
|