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