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_SET_CERT_CAP
12 :
13 6 : static libspdm_return_t send_message(
14 : void *spdm_context, size_t request_size, const void *request, uint64_t timeout)
15 : {
16 : libspdm_test_context_t *spdm_test_context;
17 : uint32_t *session_id;
18 : libspdm_session_info_t *session_info;
19 : bool is_app_message;
20 : uint8_t *app_message;
21 : size_t app_message_size;
22 : uint8_t message_buffer[LIBSPDM_SENDER_BUFFER_SIZE];
23 : spdm_set_certificate_request_t *spdm_request;
24 :
25 6 : memcpy(message_buffer, request, request_size);
26 6 : libspdm_transport_test_decode_message(spdm_context, &session_id, &is_app_message, true,
27 : request_size, message_buffer, &app_message_size,
28 : (void **)&app_message);
29 :
30 6 : spdm_test_context = libspdm_get_test_context();
31 6 : switch (spdm_test_context->case_id) {
32 1 : case 0x1:
33 1 : return LIBSPDM_STATUS_SEND_FAIL;
34 1 : case 0x2:
35 1 : spdm_request = (spdm_set_certificate_request_t *)app_message;
36 :
37 1 : assert_int_equal(spdm_request->header.spdm_version, SPDM_MESSAGE_VERSION_12);
38 1 : assert_int_equal(spdm_request->header.request_response_code, SPDM_SET_CERTIFICATE);
39 1 : assert_int_equal(spdm_request->header.param1 & SPDM_SET_CERTIFICATE_REQUEST_SLOT_ID_MASK,
40 : 0);
41 1 : assert_int_equal(spdm_request->header.param2, 0);
42 :
43 1 : return LIBSPDM_STATUS_SUCCESS;
44 0 : case 0x3:
45 0 : assert_true(false);
46 :
47 0 : return LIBSPDM_STATUS_SUCCESS;
48 0 : case 0x4:
49 0 : return LIBSPDM_STATUS_SUCCESS;
50 1 : case 0x5:
51 1 : session_id = NULL;
52 1 : session_info = libspdm_get_session_info_via_session_id(spdm_context, 0xFFFFFFFF);
53 1 : if (session_info == NULL) {
54 0 : return LIBSPDM_STATUS_SEND_FAIL;
55 : }
56 1 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "Request (0x%zx):\n", request_size));
57 1 : libspdm_dump_hex(request, request_size);
58 :
59 1 : libspdm_get_scratch_buffer (spdm_context, (void **)&app_message, &app_message_size);
60 1 : libspdm_transport_test_decode_message(
61 : spdm_context, &session_id, &is_app_message,
62 : false, request_size, message_buffer,
63 : &app_message_size, (void **)&app_message);
64 :
65 : /* WALKAROUND: If just use single context to encode
66 : * message and then decode message */
67 : ((libspdm_secured_message_context_t
68 1 : *)(session_info->secured_message_context))
69 1 : ->application_secret.request_data_sequence_number--;
70 :
71 1 : return LIBSPDM_STATUS_SUCCESS;
72 1 : case 0x6:
73 1 : spdm_request = (spdm_set_certificate_request_t *)app_message;
74 :
75 1 : assert_int_equal(spdm_request->header.spdm_version, SPDM_MESSAGE_VERSION_12);
76 1 : assert_int_equal(spdm_request->header.request_response_code, SPDM_SET_CERTIFICATE);
77 1 : assert_int_equal(spdm_request->header.param1 & SPDM_SET_CERTIFICATE_REQUEST_SLOT_ID_MASK,
78 : 0);
79 1 : assert_int_equal(spdm_request->header.param2, 0);
80 :
81 1 : return LIBSPDM_STATUS_SUCCESS;
82 1 : case 0x7:
83 1 : spdm_request = (spdm_set_certificate_request_t *)app_message;
84 :
85 1 : assert_int_equal(spdm_request->header.spdm_version, SPDM_MESSAGE_VERSION_13);
86 1 : assert_int_equal(spdm_request->header.request_response_code, SPDM_SET_CERTIFICATE);
87 1 : assert_int_equal(spdm_request->header.param1 & SPDM_SET_CERTIFICATE_REQUEST_SLOT_ID_MASK,
88 : 0);
89 1 : assert_int_equal((spdm_request->header.param1 &
90 : SPDM_SET_CERTIFICATE_REQUEST_ATTRIBUTES_CERT_MODEL_MASK) >>
91 : SPDM_SET_CERTIFICATE_REQUEST_ATTRIBUTES_CERT_MODEL_OFFSET,
92 : SPDM_CERTIFICATE_INFO_CERT_MODEL_NONE);
93 1 : assert_int_equal(spdm_request->header.param1 &
94 : SPDM_SET_CERTIFICATE_REQUEST_ATTRIBUTES_ERASE,
95 : SPDM_SET_CERTIFICATE_REQUEST_ATTRIBUTES_ERASE);
96 1 : assert_int_equal(spdm_request->header.param2, 0);
97 :
98 1 : return LIBSPDM_STATUS_SUCCESS;
99 0 : case 0x8:
100 0 : assert_true(false);
101 0 : return LIBSPDM_STATUS_SEND_FAIL;
102 1 : case 0x9:
103 1 : spdm_request = (spdm_set_certificate_request_t *)app_message;
104 :
105 1 : assert_int_equal(spdm_request->header.spdm_version, SPDM_MESSAGE_VERSION_13);
106 1 : assert_int_equal(spdm_request->header.request_response_code, SPDM_SET_CERTIFICATE);
107 1 : assert_int_equal(spdm_request->header.param1 & SPDM_SET_CERTIFICATE_REQUEST_SLOT_ID_MASK,
108 : 3);
109 1 : assert_int_equal((spdm_request->header.param1 &
110 : SPDM_SET_CERTIFICATE_REQUEST_ATTRIBUTES_CERT_MODEL_MASK) >>
111 : SPDM_SET_CERTIFICATE_REQUEST_ATTRIBUTES_CERT_MODEL_OFFSET,
112 : SPDM_CERTIFICATE_INFO_CERT_MODEL_DEVICE_CERT);
113 1 : assert_int_equal(spdm_request->header.param2, 1);
114 :
115 1 : return LIBSPDM_STATUS_SUCCESS;
116 :
117 0 : default:
118 0 : return LIBSPDM_STATUS_SEND_FAIL;
119 : }
120 : }
121 :
122 5 : static libspdm_return_t receive_message(
123 : void *spdm_context, size_t *response_size, void **response, uint64_t timeout)
124 : {
125 : libspdm_test_context_t *spdm_test_context;
126 :
127 5 : spdm_test_context = libspdm_get_test_context();
128 5 : switch (spdm_test_context->case_id) {
129 0 : case 0x1:
130 0 : return LIBSPDM_STATUS_RECEIVE_FAIL;
131 :
132 1 : case 0x2: {
133 : spdm_set_certificate_response_t *spdm_response;
134 : size_t spdm_response_size;
135 : size_t transport_header_size;
136 :
137 1 : spdm_response_size = sizeof(spdm_set_certificate_response_t);
138 1 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
139 1 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
140 :
141 1 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_12;
142 1 : spdm_response->header.request_response_code = SPDM_SET_CERTIFICATE_RSP;
143 1 : spdm_response->header.param1 = 0;
144 1 : spdm_response->header.param2 = 0;
145 :
146 1 : libspdm_transport_test_encode_message(spdm_context, NULL, false,
147 : false, spdm_response_size,
148 : spdm_response, response_size,
149 : response);
150 : }
151 1 : return LIBSPDM_STATUS_SUCCESS;
152 :
153 0 : case 0x3: {
154 : spdm_set_certificate_response_t *spdm_response;
155 : size_t spdm_response_size;
156 : size_t transport_header_size;
157 :
158 0 : spdm_response_size = sizeof(spdm_set_certificate_response_t);
159 0 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
160 0 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
161 :
162 0 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_12;
163 0 : spdm_response->header.request_response_code = SPDM_SET_CERTIFICATE_RSP;
164 0 : spdm_response->header.param1 = 0;
165 0 : spdm_response->header.param2 = 0;
166 :
167 0 : libspdm_transport_test_encode_message(spdm_context, NULL, false,
168 : false, spdm_response_size,
169 : spdm_response, response_size,
170 : response);
171 : }
172 0 : return LIBSPDM_STATUS_SUCCESS;
173 :
174 0 : case 0x4: {
175 : spdm_set_certificate_response_t *spdm_response;
176 : size_t spdm_response_size;
177 : size_t transport_header_size;
178 :
179 0 : spdm_response_size = sizeof(spdm_set_certificate_response_t);
180 0 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
181 0 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
182 :
183 0 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_12;
184 0 : spdm_response->header.request_response_code = SPDM_SET_CERTIFICATE_RSP;
185 0 : spdm_response->header.param1 = 1;
186 0 : spdm_response->header.param2 = 0;
187 :
188 0 : libspdm_transport_test_encode_message(spdm_context, NULL, false,
189 : false, spdm_response_size,
190 : spdm_response, response_size,
191 : response);
192 : }
193 0 : return LIBSPDM_STATUS_SUCCESS;
194 :
195 1 : case 0x05: {
196 : spdm_set_certificate_response_t *spdm_response;
197 : size_t spdm_response_size;
198 : size_t transport_header_size;
199 : uint32_t session_id;
200 : libspdm_session_info_t *session_info;
201 : uint8_t *scratch_buffer;
202 : size_t scratch_buffer_size;
203 :
204 1 : session_id = 0xFFFFFFFF;
205 :
206 1 : spdm_response_size = sizeof(spdm_set_certificate_response_t);
207 1 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
208 1 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
209 :
210 1 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_12;
211 1 : spdm_response->header.request_response_code = SPDM_SET_CERTIFICATE_RSP;
212 : /*slot id is 1*/
213 1 : spdm_response->header.param1 = 1;
214 1 : spdm_response->header.param2 = 0;
215 :
216 : /* For secure message, message is in sender buffer, we need copy it to scratch buffer.
217 : * transport_message is always in sender buffer. */
218 1 : libspdm_get_scratch_buffer (spdm_context, (void **)&scratch_buffer, &scratch_buffer_size);
219 1 : libspdm_copy_mem (scratch_buffer + transport_header_size,
220 : scratch_buffer_size - transport_header_size,
221 : spdm_response, spdm_response_size);
222 1 : spdm_response = (void *)(scratch_buffer + transport_header_size);
223 1 : libspdm_transport_test_encode_message(spdm_context, &session_id, false,
224 : false, spdm_response_size,
225 : spdm_response, response_size,
226 : response);
227 1 : session_info = libspdm_get_session_info_via_session_id( spdm_context, session_id);
228 1 : if (session_info == NULL) {
229 0 : return LIBSPDM_STATUS_RECEIVE_FAIL;
230 : }
231 : /* WALKAROUND: If just use single context to encode message and then decode message */
232 : ((libspdm_secured_message_context_t
233 1 : *)(session_info->secured_message_context))
234 1 : ->application_secret.response_data_sequence_number--;
235 : }
236 1 : return LIBSPDM_STATUS_SUCCESS;
237 :
238 1 : case 0x6: {
239 : spdm_set_certificate_response_t *spdm_response;
240 : size_t spdm_response_size;
241 : size_t transport_header_size;
242 :
243 1 : spdm_response_size = sizeof(spdm_set_certificate_response_t);
244 1 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
245 1 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
246 :
247 1 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_12;
248 1 : spdm_response->header.request_response_code = SPDM_ERROR;
249 1 : spdm_response->header.param1 = SPDM_ERROR_CODE_RESET_REQUIRED;
250 1 : spdm_response->header.param2 = 0;
251 :
252 1 : libspdm_transport_test_encode_message(spdm_context, NULL, false,
253 : false, spdm_response_size,
254 : spdm_response, response_size,
255 : response);
256 : }
257 1 : return LIBSPDM_STATUS_SUCCESS;
258 :
259 1 : case 0x7: {
260 : spdm_set_certificate_response_t *spdm_response;
261 : size_t spdm_response_size;
262 : size_t transport_header_size;
263 :
264 1 : spdm_response_size = sizeof(spdm_set_certificate_response_t);
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_SET_CERTIFICATE_RSP;
270 1 : spdm_response->header.param1 = 0;
271 1 : spdm_response->header.param2 = 0;
272 :
273 1 : libspdm_transport_test_encode_message(spdm_context, NULL, false,
274 : false, spdm_response_size,
275 : spdm_response, response_size,
276 : response);
277 : }
278 1 : return LIBSPDM_STATUS_SUCCESS;
279 :
280 0 : case 0x8:
281 0 : assert_true(false);
282 0 : return LIBSPDM_STATUS_RECEIVE_FAIL;
283 :
284 1 : case 0x9: {
285 : spdm_set_certificate_response_t *spdm_response;
286 : size_t spdm_response_size;
287 : size_t transport_header_size;
288 :
289 1 : spdm_response_size = sizeof(spdm_set_certificate_response_t);
290 1 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
291 1 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
292 :
293 1 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_13;
294 1 : spdm_response->header.request_response_code = SPDM_SET_CERTIFICATE_RSP;
295 1 : spdm_response->header.param1 = 3;
296 1 : spdm_response->header.param2 = 0;
297 :
298 1 : libspdm_transport_test_encode_message(spdm_context, NULL, false,
299 : false, spdm_response_size,
300 : spdm_response, response_size,
301 : response);
302 : }
303 1 : return LIBSPDM_STATUS_SUCCESS;
304 :
305 0 : default:
306 0 : return LIBSPDM_STATUS_RECEIVE_FAIL;
307 : }
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_set_certificate_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 : void *data;
322 : size_t data_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 |=
332 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_SET_CERT_CAP;
333 :
334 1 : if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
335 : m_libspdm_use_asym_algo,
336 : &data, &data_size, NULL, NULL)) {
337 0 : return;
338 : }
339 :
340 1 : status = libspdm_set_certificate(spdm_context, NULL, 0, data, data_size);
341 :
342 1 : assert_int_equal(status, LIBSPDM_STATUS_SEND_FAIL);
343 1 : free(data);
344 : }
345 :
346 : /**
347 : * Test 2: Successful response to set certificate for slot 0
348 : * Expected Behavior: get a LIBSPDM_STATUS_SUCCESS return code
349 : **/
350 1 : static void req_set_certificate_case2(void **state)
351 : {
352 : libspdm_return_t status;
353 : libspdm_test_context_t *spdm_test_context;
354 : libspdm_context_t *spdm_context;
355 :
356 : void *data;
357 : size_t data_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 |=
367 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_SET_CERT_CAP;
368 :
369 1 : if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
370 : m_libspdm_use_asym_algo,
371 : &data, &data_size, NULL, NULL)) {
372 0 : return;
373 : }
374 :
375 1 : status = libspdm_set_certificate(spdm_context, NULL, 0, data, data_size);
376 :
377 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
378 1 : free(data);
379 : }
380 :
381 : /**
382 : * Test 3: Unsuccessful response to set certificate for slot 0, because cert_chain is NULL.
383 : * Expected Behavior: get a LIBSPDM_STATUS_INVALID_PARAMETER return code
384 : **/
385 1 : static void req_set_certificate_case3(void **state)
386 : {
387 : libspdm_return_t status;
388 : libspdm_test_context_t *spdm_test_context;
389 : libspdm_context_t *spdm_context;
390 :
391 1 : spdm_test_context = *state;
392 1 : spdm_context = spdm_test_context->spdm_context;
393 1 : spdm_test_context->case_id = 0x3;
394 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 <<
395 : SPDM_VERSION_NUMBER_SHIFT_BIT;
396 :
397 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
398 1 : spdm_context->connection_info.capability.flags |=
399 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_SET_CERT_CAP;
400 :
401 1 : status = libspdm_set_certificate(spdm_context, NULL, 0, NULL, 0);
402 :
403 1 : assert_int_equal(status, LIBSPDM_STATUS_INVALID_PARAMETER);
404 1 : }
405 :
406 : /**
407 : * Test 5: Successful response to set certificate for slot 1 in secure session
408 : * Expected Behavior: get a LIBSPDM_STATUS_SUCCESS return code
409 : **/
410 1 : static void req_set_certificate_case5(void **state)
411 : {
412 : libspdm_return_t status;
413 : libspdm_test_context_t *spdm_test_context;
414 : libspdm_context_t *spdm_context;
415 : uint32_t session_id;
416 : libspdm_session_info_t *session_info;
417 :
418 : void *data;
419 : size_t data_size;
420 :
421 1 : spdm_test_context = *state;
422 1 : spdm_context = spdm_test_context->spdm_context;
423 1 : spdm_test_context->case_id = 0x05;
424 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_AUTHENTICATED;
425 :
426 1 : spdm_context->connection_info.capability.flags |=
427 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP_SIG;
428 1 : spdm_context->connection_info.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_PSK_CAP;
429 1 : spdm_context->connection_info.capability.flags |=
430 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_ENCRYPT_CAP;
431 1 : spdm_context->connection_info.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MAC_CAP;
432 1 : spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_PSK_CAP;
433 1 : spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_ENCRYPT_CAP;
434 1 : spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MAC_CAP;
435 1 : spdm_context->connection_info.capability.flags |=
436 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_SET_CERT_CAP;
437 1 : spdm_context->connection_info.algorithm.dhe_named_group = m_libspdm_use_dhe_algo;
438 1 : spdm_context->connection_info.algorithm.aead_cipher_suite = m_libspdm_use_aead_algo;
439 :
440 1 : if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
441 : m_libspdm_use_asym_algo, &data,
442 : &data_size, NULL, NULL)) {
443 0 : return;
444 : }
445 :
446 1 : session_id = 0xFFFFFFFF;
447 1 : session_info = &spdm_context->session_info[0];
448 1 : libspdm_session_info_init(spdm_context, session_info, session_id,
449 : SECURED_SPDM_VERSION_11 << SPDM_VERSION_NUMBER_SHIFT_BIT, true);
450 1 : libspdm_secured_message_set_session_state(session_info->secured_message_context,
451 : LIBSPDM_SESSION_STATE_ESTABLISHED);
452 :
453 : /* slot id is 1*/
454 1 : status = libspdm_set_certificate(spdm_context, &session_id, 1, data, data_size);
455 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
456 :
457 1 : free(data);
458 : }
459 :
460 : /**
461 : * Test 6: Successful response to set certificate for slot 0 with a reset required
462 : * Expected Behavior: get a LIBSPDM_STATUS_SUCCESS return code
463 : **/
464 1 : static void req_set_certificate_case6(void **state)
465 : {
466 : libspdm_return_t status;
467 : libspdm_test_context_t *spdm_test_context;
468 : libspdm_context_t *spdm_context;
469 :
470 : void *data;
471 : size_t data_size;
472 :
473 1 : spdm_test_context = *state;
474 1 : spdm_context = spdm_test_context->spdm_context;
475 1 : spdm_test_context->case_id = 0x6;
476 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 <<
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_SET_CERT_CAP |
482 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_INSTALL_RESET_CAP;
483 :
484 1 : if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
485 : m_libspdm_use_asym_algo,
486 : &data, &data_size, NULL, NULL)) {
487 0 : return;
488 : }
489 :
490 1 : status = libspdm_set_certificate(spdm_context, NULL, 0, data, data_size);
491 :
492 1 : assert_int_equal(status, LIBSPDM_STATUS_RESET_REQUIRED_PEER);
493 1 : free(data);
494 : }
495 :
496 : /**
497 : * Test 7: Successful response to erase certificate for slot 0
498 : * Expected Behavior: get a LIBSPDM_STATUS_SUCCESS return code
499 : **/
500 1 : static void req_set_certificate_case7(void **state)
501 : {
502 : libspdm_return_t status;
503 : libspdm_test_context_t *spdm_test_context;
504 : libspdm_context_t *spdm_context;
505 :
506 1 : spdm_test_context = *state;
507 1 : spdm_context = spdm_test_context->spdm_context;
508 1 : spdm_test_context->case_id = 0x7;
509 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_13 <<
510 : SPDM_VERSION_NUMBER_SHIFT_BIT;
511 :
512 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
513 1 : spdm_context->connection_info.capability.flags |=
514 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_SET_CERT_CAP;
515 :
516 1 : status = libspdm_set_certificate_ex(spdm_context, NULL, 0, NULL, 0,
517 : SPDM_SET_CERTIFICATE_REQUEST_ATTRIBUTES_ERASE, 0);
518 :
519 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
520 1 : }
521 :
522 : /**
523 : * Test 8: Illegal combination of MULTI_KEY_CONN_RSP = true, Erase = false, and SetCertModel = 0.
524 : * Expected Behavior: function returns LIBSPDM_STATUS_INVALID_PARAMETER.
525 : **/
526 1 : static void req_set_certificate_case8(void **state)
527 : {
528 : libspdm_return_t status;
529 : libspdm_test_context_t *spdm_test_context;
530 : libspdm_context_t *spdm_context;
531 :
532 : void *data;
533 : size_t data_size;
534 :
535 1 : spdm_test_context = *state;
536 1 : spdm_context = spdm_test_context->spdm_context;
537 1 : spdm_test_context->case_id = 0x8;
538 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_13 <<
539 : SPDM_VERSION_NUMBER_SHIFT_BIT;
540 :
541 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
542 1 : spdm_context->connection_info.capability.flags |=
543 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_SET_CERT_CAP;
544 1 : spdm_context->connection_info.multi_key_conn_rsp = true;
545 :
546 1 : if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
547 : m_libspdm_use_asym_algo,
548 : &data, &data_size, NULL, NULL)) {
549 0 : return;
550 : }
551 :
552 1 : status = libspdm_set_certificate_ex(spdm_context, NULL, 0, data, data_size,
553 : (SPDM_CERTIFICATE_INFO_CERT_MODEL_NONE <<
554 : SPDM_SET_CERTIFICATE_REQUEST_ATTRIBUTES_CERT_MODEL_OFFSET),
555 : 1);
556 :
557 1 : assert_int_equal(status, LIBSPDM_STATUS_INVALID_PARAMETER);
558 : }
559 :
560 : /**
561 : * Test 9: Set MULTI_KEY_CONN_RSP = true, Erase = false, and SetCertModel = DeviceCert.
562 : * Expected Behavior: function returns LIBSPDM_STATUS_SUCCESS.
563 : **/
564 1 : static void req_set_certificate_case9(void **state)
565 : {
566 : libspdm_return_t status;
567 : libspdm_test_context_t *spdm_test_context;
568 : libspdm_context_t *spdm_context;
569 :
570 : void *data;
571 : size_t data_size;
572 :
573 1 : spdm_test_context = *state;
574 1 : spdm_context = spdm_test_context->spdm_context;
575 1 : spdm_test_context->case_id = 0x9;
576 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_13 <<
577 : SPDM_VERSION_NUMBER_SHIFT_BIT;
578 :
579 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
580 1 : spdm_context->connection_info.capability.flags |=
581 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_SET_CERT_CAP;
582 1 : spdm_context->connection_info.multi_key_conn_rsp = true;
583 :
584 1 : if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
585 : m_libspdm_use_asym_algo,
586 : &data, &data_size, NULL, NULL)) {
587 0 : return;
588 : }
589 :
590 1 : status = libspdm_set_certificate_ex(spdm_context, NULL, 3, data, data_size,
591 : (SPDM_CERTIFICATE_INFO_CERT_MODEL_DEVICE_CERT <<
592 : SPDM_SET_CERTIFICATE_REQUEST_ATTRIBUTES_CERT_MODEL_OFFSET),
593 : 1);
594 :
595 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
596 : }
597 :
598 1 : int libspdm_req_set_certificate_test(void)
599 : {
600 1 : const struct CMUnitTest test_cases[] = {
601 : /* SendRequest failed*/
602 : cmocka_unit_test(req_set_certificate_case1),
603 : /* Successful response to set certificate*/
604 : cmocka_unit_test(req_set_certificate_case2),
605 : /* Set null cert_chain for slot 0*/
606 : cmocka_unit_test(req_set_certificate_case3),
607 : /* Successful response to set certificate for slot 1 in secure session*/
608 : cmocka_unit_test(req_set_certificate_case5),
609 : /* Successful response to set certificate with a reset required */
610 : cmocka_unit_test(req_set_certificate_case6),
611 : /* Successful response to erase certificate*/
612 : cmocka_unit_test(req_set_certificate_case7),
613 : cmocka_unit_test(req_set_certificate_case8),
614 : cmocka_unit_test(req_set_certificate_case9),
615 : };
616 :
617 1 : libspdm_test_context_t test_context = {
618 : LIBSPDM_TEST_CONTEXT_VERSION,
619 : true,
620 : send_message,
621 : receive_message,
622 : };
623 :
624 1 : libspdm_setup_test_context(&test_context);
625 :
626 1 : return cmocka_run_group_tests(test_cases,
627 : libspdm_unit_test_group_setup,
628 : libspdm_unit_test_group_teardown);
629 : }
630 :
631 : #endif /* LIBSPDM_ENABLE_CAPABILITY_SET_CERT_CAP*/
|