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_responder_lib.h"
9 :
10 : #if defined(_WIN32) || (defined(__clang__) && (defined (LIBSPDM_CPU_AARCH64) || \
11 : defined(LIBSPDM_CPU_ARM)))
12 : #else
13 : #include <fcntl.h>
14 : #include <unistd.h>
15 : #include <sys/stat.h>
16 : #endif
17 :
18 : #if LIBSPDM_ENABLE_CAPABILITY_SET_CERT_CAP
19 :
20 : extern bool g_in_trusted_environment;
21 : extern bool g_set_cert_is_busy;
22 :
23 : /**
24 : * Test 1: receives a valid SET_CERTIFICATE request message from Requester to set cert in slot_id:0 with device_cert model
25 : * Expected Behavior: produces a valid SET_CERTIFICATE_RSP response message
26 : **/
27 1 : static void rsp_set_certificate_rsp_case1(void **state)
28 : {
29 : libspdm_return_t status;
30 : libspdm_test_context_t *spdm_test_context;
31 : libspdm_context_t *spdm_context;
32 : size_t response_size;
33 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
34 : spdm_set_certificate_response_t *spdm_response;
35 : void *cert_chain;
36 : size_t cert_chain_size;
37 : spdm_set_certificate_request_t *m_libspdm_set_certificate_request;
38 :
39 : void *cert_chain_slot_1;
40 : uint8_t *new_cert_chain;
41 : size_t new_cert_chain_size;
42 : size_t root_cert_hash_size;
43 :
44 1 : spdm_test_context = *state;
45 1 : spdm_context = spdm_test_context->spdm_context;
46 1 : spdm_test_context->case_id = 0x1;
47 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 <<
48 : SPDM_VERSION_NUMBER_SHIFT_BIT;
49 :
50 1 : spdm_context->connection_info.connection_state =
51 : LIBSPDM_CONNECTION_STATE_NEGOTIATED;
52 1 : spdm_context->local_context.capability.flags |=
53 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_SET_CERT_CAP;
54 1 : spdm_context->connection_info.algorithm.base_hash_algo =
55 : m_libspdm_use_hash_algo;
56 1 : spdm_context->connection_info.algorithm.base_asym_algo =
57 : m_libspdm_use_asym_algo;
58 :
59 1 : spdm_context->local_context.algorithm.base_hash_algo =
60 : m_libspdm_use_hash_algo;
61 1 : spdm_context->local_context.algorithm.base_asym_algo =
62 : m_libspdm_use_asym_algo;
63 :
64 1 : libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
65 : m_libspdm_use_asym_algo, &cert_chain,
66 : &cert_chain_size, NULL, NULL);
67 :
68 1 : m_libspdm_set_certificate_request = malloc(sizeof(spdm_set_certificate_request_t) +
69 : cert_chain_size);
70 :
71 1 : m_libspdm_set_certificate_request->header.spdm_version = SPDM_MESSAGE_VERSION_12;
72 1 : m_libspdm_set_certificate_request->header.request_response_code = SPDM_SET_CERTIFICATE;
73 1 : m_libspdm_set_certificate_request->header.param1 = 0;
74 1 : m_libspdm_set_certificate_request->header.param2 = 0;
75 :
76 1 : libspdm_copy_mem(m_libspdm_set_certificate_request + 1,
77 : LIBSPDM_MAX_CERT_CHAIN_SIZE,
78 : (uint8_t *)cert_chain, cert_chain_size);
79 :
80 1 : size_t m_libspdm_set_certificate_request_size = sizeof(spdm_set_certificate_request_t) +
81 : cert_chain_size;
82 :
83 1 : response_size = sizeof(response);
84 1 : status = libspdm_get_response_set_certificate(spdm_context,
85 : m_libspdm_set_certificate_request_size,
86 : m_libspdm_set_certificate_request,
87 : &response_size, response);
88 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
89 1 : assert_int_equal(response_size, sizeof(spdm_set_certificate_response_t));
90 1 : spdm_response = (void *)response;
91 1 : assert_int_equal(spdm_response->header.request_response_code,
92 : SPDM_SET_CERTIFICATE_RSP);
93 :
94 1 : free(cert_chain);
95 1 : free(m_libspdm_set_certificate_request);
96 :
97 : /*test overwrite same slot_id cert*/
98 :
99 : /*read a different cert_chain*/
100 1 : libspdm_read_responder_public_certificate_chain_per_slot(1, m_libspdm_use_hash_algo,
101 : m_libspdm_use_asym_algo,
102 : &cert_chain_slot_1,
103 : &cert_chain_size, NULL, NULL);
104 :
105 1 : m_libspdm_set_certificate_request = malloc(sizeof(spdm_set_certificate_request_t) +
106 : cert_chain_size);
107 :
108 1 : m_libspdm_set_certificate_request->header.spdm_version = SPDM_MESSAGE_VERSION_12;
109 1 : m_libspdm_set_certificate_request->header.request_response_code = SPDM_SET_CERTIFICATE;
110 : /*write the same slot_id 0*/
111 1 : m_libspdm_set_certificate_request->header.param1 = 0;
112 1 : m_libspdm_set_certificate_request->header.param2 = 0;
113 :
114 1 : libspdm_copy_mem(m_libspdm_set_certificate_request + 1,
115 : LIBSPDM_MAX_CERT_CHAIN_SIZE,
116 : (uint8_t *)cert_chain_slot_1, cert_chain_size);
117 :
118 1 : m_libspdm_set_certificate_request_size = sizeof(spdm_set_certificate_request_t) +
119 : cert_chain_size;
120 :
121 1 : response_size = sizeof(response);
122 1 : status = libspdm_get_response_set_certificate(spdm_context,
123 : m_libspdm_set_certificate_request_size,
124 : m_libspdm_set_certificate_request,
125 : &response_size, response);
126 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
127 1 : assert_int_equal(response_size, sizeof(spdm_set_certificate_response_t));
128 1 : spdm_response = (void *)response;
129 1 : assert_int_equal(spdm_response->header.request_response_code,
130 : SPDM_SET_CERTIFICATE_RSP);
131 :
132 : /*check that the cert_chain is overwritten*/
133 1 : libspdm_read_input_file("slot_id_0_cert_chain.der",
134 : (void **)&new_cert_chain, &new_cert_chain_size);
135 :
136 : /*get actual cert_chain size*/
137 1 : root_cert_hash_size = libspdm_get_hash_size(
138 : spdm_context->local_context.algorithm.base_hash_algo);
139 1 : cert_chain_size = cert_chain_size - sizeof(spdm_cert_chain_t) - root_cert_hash_size;
140 :
141 : /*point to actual cert_chain*/
142 1 : cert_chain_slot_1 = (void*)((uint8_t *)cert_chain_slot_1
143 1 : + sizeof(spdm_cert_chain_t) + root_cert_hash_size);
144 :
145 1 : assert_memory_equal(cert_chain_slot_1, new_cert_chain, cert_chain_size);
146 :
147 1 : free(new_cert_chain);
148 :
149 : /*point to total cert_chain_slot_1: it is important*/
150 1 : cert_chain_slot_1 = (void*)((uint8_t *)cert_chain_slot_1
151 1 : - sizeof(spdm_cert_chain_t) - root_cert_hash_size);
152 1 : free(cert_chain_slot_1);
153 1 : free(m_libspdm_set_certificate_request);
154 1 : }
155 :
156 : /**
157 : * Test 2: Wrong SET_CERTIFICATE message size (larger than expected)
158 : * Expected Behavior: generate an ERROR_RESPONSE with code SPDM_ERROR_CODE_INVALID_REQUEST
159 : **/
160 1 : static void rsp_set_certificate_rsp_case2(void **state)
161 : {
162 : libspdm_return_t status;
163 : libspdm_test_context_t *spdm_test_context;
164 : libspdm_context_t *spdm_context;
165 : size_t response_size;
166 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
167 : spdm_set_certificate_response_t *spdm_response;
168 : void *cert_chain;
169 : size_t cert_chain_size;
170 :
171 1 : spdm_test_context = *state;
172 1 : spdm_context = spdm_test_context->spdm_context;
173 1 : spdm_test_context->case_id = 0x2;
174 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 <<
175 : SPDM_VERSION_NUMBER_SHIFT_BIT;
176 :
177 1 : spdm_context->connection_info.connection_state =
178 : LIBSPDM_CONNECTION_STATE_NEGOTIATED;
179 1 : spdm_context->local_context.capability.flags |=
180 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_SET_CERT_CAP;
181 1 : spdm_context->connection_info.algorithm.base_hash_algo =
182 : m_libspdm_use_hash_algo;
183 1 : spdm_context->connection_info.algorithm.base_asym_algo =
184 : m_libspdm_use_asym_algo;
185 :
186 1 : spdm_context->local_context.algorithm.base_hash_algo =
187 : m_libspdm_use_hash_algo;
188 1 : spdm_context->local_context.algorithm.base_asym_algo =
189 : m_libspdm_use_asym_algo;
190 :
191 1 : libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
192 : m_libspdm_use_asym_algo, &cert_chain,
193 : &cert_chain_size, NULL, NULL);
194 :
195 : spdm_set_certificate_request_t *m_libspdm_set_certificate_request;
196 1 : m_libspdm_set_certificate_request = malloc(sizeof(spdm_set_certificate_request_t) +
197 : cert_chain_size);
198 :
199 1 : m_libspdm_set_certificate_request->header.spdm_version = SPDM_MESSAGE_VERSION_12;
200 1 : m_libspdm_set_certificate_request->header.request_response_code = SPDM_SET_CERTIFICATE;
201 1 : m_libspdm_set_certificate_request->header.param1 = 0;
202 1 : m_libspdm_set_certificate_request->header.param2 = 0;
203 :
204 1 : libspdm_copy_mem(m_libspdm_set_certificate_request + 1,
205 : LIBSPDM_MAX_CERT_CHAIN_SIZE,
206 : (uint8_t *)cert_chain, cert_chain_size);
207 :
208 : /* Bad request size: only have header size*/
209 1 : size_t m_libspdm_set_certificate_request_size = sizeof(spdm_set_certificate_request_t);
210 :
211 1 : response_size = sizeof(response);
212 1 : status = libspdm_get_response_set_certificate(spdm_context,
213 : m_libspdm_set_certificate_request_size,
214 : m_libspdm_set_certificate_request,
215 : &response_size, response);
216 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
217 1 : assert_int_equal(response_size, sizeof(spdm_error_response_t));
218 1 : spdm_response = (void *)response;
219 1 : assert_int_equal(spdm_response->header.request_response_code,
220 : SPDM_ERROR);
221 1 : assert_int_equal(spdm_response->header.param1,
222 : SPDM_ERROR_CODE_INVALID_REQUEST);
223 1 : assert_int_equal(spdm_response->header.param2, 0);
224 :
225 1 : free(cert_chain);
226 1 : free(m_libspdm_set_certificate_request);
227 1 : }
228 :
229 :
230 : /**
231 : * Test 3: Force response_state = LIBSPDM_RESPONSE_STATE_BUSY when asked SET_CERTIFICATE
232 : * Expected Behavior: generate an ERROR_RESPONSE with code SPDM_ERROR_CODE_BUSY
233 : **/
234 1 : static void rsp_set_certificate_rsp_case3(void **state)
235 : {
236 : libspdm_return_t status;
237 : libspdm_test_context_t *spdm_test_context;
238 : libspdm_context_t *spdm_context;
239 : size_t response_size;
240 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
241 : spdm_set_certificate_response_t *spdm_response;
242 : void *cert_chain;
243 : size_t cert_chain_size;
244 :
245 1 : spdm_test_context = *state;
246 1 : spdm_context = spdm_test_context->spdm_context;
247 1 : spdm_test_context->case_id = 0x3;
248 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 <<
249 : SPDM_VERSION_NUMBER_SHIFT_BIT;
250 1 : spdm_context->response_state = LIBSPDM_RESPONSE_STATE_BUSY;
251 :
252 1 : spdm_context->connection_info.connection_state =
253 : LIBSPDM_CONNECTION_STATE_NEGOTIATED;
254 1 : spdm_context->local_context.capability.flags |=
255 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_SET_CERT_CAP;
256 1 : spdm_context->connection_info.algorithm.base_hash_algo =
257 : m_libspdm_use_hash_algo;
258 1 : spdm_context->connection_info.algorithm.base_asym_algo =
259 : m_libspdm_use_asym_algo;
260 :
261 1 : spdm_context->local_context.algorithm.base_hash_algo =
262 : m_libspdm_use_hash_algo;
263 1 : spdm_context->local_context.algorithm.base_asym_algo =
264 : m_libspdm_use_asym_algo;
265 :
266 1 : libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
267 : m_libspdm_use_asym_algo, &cert_chain,
268 : &cert_chain_size, NULL, NULL);
269 :
270 : spdm_set_certificate_request_t *m_libspdm_set_certificate_request;
271 1 : m_libspdm_set_certificate_request = malloc(sizeof(spdm_set_certificate_request_t) +
272 : cert_chain_size);
273 :
274 1 : m_libspdm_set_certificate_request->header.spdm_version = SPDM_MESSAGE_VERSION_12;
275 1 : m_libspdm_set_certificate_request->header.request_response_code = SPDM_SET_CERTIFICATE;
276 1 : m_libspdm_set_certificate_request->header.param1 = 0;
277 1 : m_libspdm_set_certificate_request->header.param2 = 0;
278 :
279 1 : libspdm_copy_mem(m_libspdm_set_certificate_request + 1,
280 : LIBSPDM_MAX_CERT_CHAIN_SIZE,
281 : (uint8_t *)cert_chain, cert_chain_size);
282 :
283 : /* Bad request size: right request size + 1*/
284 1 : size_t m_libspdm_set_certificate_request_size = sizeof(spdm_set_certificate_request_t) +
285 1 : cert_chain_size + 1;
286 :
287 1 : response_size = sizeof(response);
288 1 : status = libspdm_get_response_set_certificate(spdm_context,
289 : m_libspdm_set_certificate_request_size,
290 : m_libspdm_set_certificate_request,
291 : &response_size, response);
292 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
293 1 : assert_int_equal(response_size, sizeof(spdm_error_response_t));
294 1 : spdm_response = (void *)response;
295 1 : assert_int_equal(spdm_response->header.request_response_code,
296 : SPDM_ERROR);
297 1 : assert_int_equal(spdm_response->header.param1, SPDM_ERROR_CODE_BUSY);
298 1 : assert_int_equal(spdm_response->header.param2, 0);
299 1 : assert_int_equal(spdm_context->response_state,
300 : LIBSPDM_RESPONSE_STATE_BUSY);
301 :
302 1 : free(cert_chain);
303 1 : free(m_libspdm_set_certificate_request);
304 1 : }
305 :
306 :
307 : /**
308 : * Test 4: Force response_state = LIBSPDM_RESPONSE_STATE_NEED_RESYNC when asked SET_CERTIFICATE
309 : * Expected Behavior: generate an ERROR_RESPONSE with code SPDM_ERROR_CODE_REQUEST_RESYNCH
310 : **/
311 1 : static void rsp_set_certificate_rsp_case4(void **state)
312 : {
313 : libspdm_return_t status;
314 : libspdm_test_context_t *spdm_test_context;
315 : libspdm_context_t *spdm_context;
316 : size_t response_size;
317 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
318 : spdm_set_certificate_response_t *spdm_response;
319 : void *cert_chain;
320 : size_t cert_chain_size;
321 : spdm_set_certificate_request_t *m_libspdm_set_certificate_request;
322 :
323 1 : spdm_test_context = *state;
324 1 : spdm_context = spdm_test_context->spdm_context;
325 1 : spdm_test_context->case_id = 0x4;
326 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 <<
327 : SPDM_VERSION_NUMBER_SHIFT_BIT;
328 1 : spdm_context->response_state = LIBSPDM_RESPONSE_STATE_NEED_RESYNC;
329 :
330 1 : spdm_context->connection_info.connection_state =
331 : LIBSPDM_CONNECTION_STATE_NEGOTIATED;
332 1 : spdm_context->local_context.capability.flags |=
333 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_SET_CERT_CAP;
334 1 : spdm_context->connection_info.algorithm.base_hash_algo =
335 : m_libspdm_use_hash_algo;
336 1 : spdm_context->connection_info.algorithm.base_asym_algo =
337 : m_libspdm_use_asym_algo;
338 :
339 1 : spdm_context->local_context.algorithm.base_hash_algo =
340 : m_libspdm_use_hash_algo;
341 1 : spdm_context->local_context.algorithm.base_asym_algo =
342 : m_libspdm_use_asym_algo;
343 :
344 1 : libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
345 : m_libspdm_use_asym_algo, &cert_chain,
346 : &cert_chain_size, NULL, NULL);
347 :
348 1 : m_libspdm_set_certificate_request = malloc(sizeof(spdm_set_certificate_request_t) +
349 : cert_chain_size);
350 :
351 1 : m_libspdm_set_certificate_request->header.spdm_version = SPDM_MESSAGE_VERSION_12;
352 1 : m_libspdm_set_certificate_request->header.request_response_code = SPDM_SET_CERTIFICATE;
353 1 : m_libspdm_set_certificate_request->header.param1 = 0;
354 1 : m_libspdm_set_certificate_request->header.param2 = 0;
355 :
356 1 : libspdm_copy_mem(m_libspdm_set_certificate_request + 1,
357 : LIBSPDM_MAX_CERT_CHAIN_SIZE,
358 : (uint8_t *)cert_chain, cert_chain_size);
359 :
360 1 : size_t m_libspdm_set_certificate_request_size = sizeof(spdm_set_certificate_request_t) +
361 : cert_chain_size;
362 :
363 1 : response_size = sizeof(response);
364 1 : status = libspdm_get_response_set_certificate(spdm_context,
365 : m_libspdm_set_certificate_request_size,
366 : m_libspdm_set_certificate_request,
367 : &response_size, response);
368 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
369 1 : assert_int_equal(response_size, sizeof(spdm_error_response_t));
370 1 : spdm_response = (void *)response;
371 1 : assert_int_equal(spdm_response->header.request_response_code,
372 : SPDM_ERROR);
373 1 : assert_int_equal(spdm_response->header.param1,
374 : SPDM_ERROR_CODE_REQUEST_RESYNCH);
375 1 : assert_int_equal(spdm_response->header.param2, 0);
376 1 : assert_int_equal(spdm_context->response_state,
377 : LIBSPDM_RESPONSE_STATE_NEED_RESYNC);
378 :
379 1 : free(cert_chain);
380 1 : free(m_libspdm_set_certificate_request);
381 1 : }
382 :
383 : /**
384 : * Test 5: receives a valid SET_CERTIFICATE request message from Requester to set cert in slot_id:1 with session
385 : * Expected Behavior: produces a valid SET_CERTIFICATE_RSP response message
386 : **/
387 1 : static void rsp_set_certificate_rsp_case5(void **state)
388 : {
389 : libspdm_return_t status;
390 : libspdm_test_context_t *spdm_test_context;
391 : libspdm_context_t *spdm_context;
392 : size_t response_size;
393 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
394 : spdm_set_certificate_response_t *spdm_response;
395 : void *cert_chain;
396 : size_t cert_chain_size;
397 : spdm_set_certificate_request_t *m_libspdm_set_certificate_request;
398 :
399 : libspdm_session_info_t *session_info;
400 : uint32_t session_id;
401 :
402 1 : spdm_test_context = *state;
403 1 : spdm_context = spdm_test_context->spdm_context;
404 1 : spdm_test_context->case_id = 0x5;
405 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 <<
406 : SPDM_VERSION_NUMBER_SHIFT_BIT;
407 : /*responset_state need to set normal*/
408 1 : spdm_context->response_state = LIBSPDM_RESPONSE_STATE_NORMAL;
409 1 : spdm_context->connection_info.connection_state =
410 : LIBSPDM_CONNECTION_STATE_AUTHENTICATED;
411 1 : spdm_context->local_context.capability.flags |=
412 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_SET_CERT_CAP;
413 1 : spdm_context->local_context.capability.flags |=
414 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP_SIG;
415 1 : spdm_context->connection_info.algorithm.base_hash_algo =
416 : m_libspdm_use_hash_algo;
417 1 : spdm_context->connection_info.algorithm.base_asym_algo =
418 : m_libspdm_use_asym_algo;
419 :
420 1 : spdm_context->local_context.algorithm.base_hash_algo =
421 : m_libspdm_use_hash_algo;
422 1 : spdm_context->local_context.algorithm.base_asym_algo =
423 : m_libspdm_use_asym_algo;
424 :
425 1 : session_id = 0xFFFFFFFF;
426 1 : spdm_context->latest_session_id = session_id;
427 1 : spdm_context->last_spdm_request_session_id_valid = true;
428 1 : spdm_context->last_spdm_request_session_id = session_id;
429 1 : session_info = &spdm_context->session_info[0];
430 1 : libspdm_session_info_init(spdm_context, session_info, session_id,
431 : SECURED_SPDM_VERSION_11 << SPDM_VERSION_NUMBER_SHIFT_BIT, true);
432 1 : libspdm_secured_message_set_session_state(
433 : session_info->secured_message_context,
434 : LIBSPDM_SESSION_STATE_ESTABLISHED);
435 :
436 1 : libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
437 : m_libspdm_use_asym_algo, &cert_chain,
438 : &cert_chain_size, NULL, NULL);
439 :
440 1 : m_libspdm_set_certificate_request = malloc(sizeof(spdm_set_certificate_request_t) +
441 : cert_chain_size);
442 :
443 1 : m_libspdm_set_certificate_request->header.spdm_version = SPDM_MESSAGE_VERSION_12;
444 1 : m_libspdm_set_certificate_request->header.request_response_code = SPDM_SET_CERTIFICATE;
445 1 : m_libspdm_set_certificate_request->header.param1 = 1;
446 1 : m_libspdm_set_certificate_request->header.param2 = 0;
447 :
448 1 : libspdm_copy_mem(m_libspdm_set_certificate_request + 1,
449 : LIBSPDM_MAX_CERT_CHAIN_SIZE,
450 : (uint8_t *)cert_chain, cert_chain_size);
451 :
452 1 : size_t m_libspdm_set_certificate_request_size = sizeof(spdm_set_certificate_request_t) +
453 : cert_chain_size;
454 :
455 1 : response_size = sizeof(response);
456 1 : status = libspdm_get_response_set_certificate(spdm_context,
457 : m_libspdm_set_certificate_request_size,
458 : m_libspdm_set_certificate_request,
459 : &response_size, response);
460 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
461 1 : assert_int_equal(response_size, sizeof(spdm_set_certificate_response_t));
462 1 : spdm_response = (void *)response;
463 1 : assert_int_equal(spdm_response->header.request_response_code,
464 : SPDM_SET_CERTIFICATE_RSP);
465 :
466 1 : free(cert_chain);
467 1 : free(m_libspdm_set_certificate_request);
468 1 : }
469 :
470 : /**
471 : * Test 6: receives a valid SET_CERTIFICATE request message from Requester with need_reset
472 : * Expected Behavior: The Responder return need reset
473 : **/
474 1 : static void rsp_set_certificate_rsp_case6(void **state)
475 : {
476 : libspdm_return_t status;
477 : libspdm_test_context_t *spdm_test_context;
478 : libspdm_context_t *spdm_context;
479 : size_t response_size;
480 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
481 : spdm_set_certificate_response_t *spdm_response;
482 : void *cert_chain;
483 : size_t cert_chain_size;
484 : spdm_set_certificate_request_t *m_libspdm_set_certificate_request;
485 :
486 1 : spdm_test_context = *state;
487 1 : spdm_context = spdm_test_context->spdm_context;
488 1 : spdm_test_context->case_id = 0x6;
489 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 <<
490 : SPDM_VERSION_NUMBER_SHIFT_BIT;
491 :
492 1 : spdm_context->connection_info.connection_state =
493 : LIBSPDM_CONNECTION_STATE_NEGOTIATED;
494 1 : spdm_context->local_context.capability.flags |=
495 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_SET_CERT_CAP;
496 1 : spdm_context->local_context.capability.flags |=
497 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_INSTALL_RESET_CAP;
498 1 : spdm_context->connection_info.algorithm.base_hash_algo =
499 : m_libspdm_use_hash_algo;
500 1 : spdm_context->connection_info.algorithm.base_asym_algo =
501 : m_libspdm_use_asym_algo;
502 :
503 1 : spdm_context->local_context.algorithm.base_hash_algo =
504 : m_libspdm_use_hash_algo;
505 1 : spdm_context->local_context.algorithm.base_asym_algo =
506 : m_libspdm_use_asym_algo;
507 :
508 1 : libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
509 : m_libspdm_use_asym_algo, &cert_chain,
510 : &cert_chain_size, NULL, NULL);
511 :
512 1 : m_libspdm_set_certificate_request = malloc(sizeof(spdm_set_certificate_request_t) +
513 : cert_chain_size);
514 :
515 1 : m_libspdm_set_certificate_request->header.spdm_version = SPDM_MESSAGE_VERSION_12;
516 1 : m_libspdm_set_certificate_request->header.request_response_code = SPDM_SET_CERTIFICATE;
517 1 : m_libspdm_set_certificate_request->header.param1 = 0;
518 1 : m_libspdm_set_certificate_request->header.param2 = 0;
519 :
520 1 : libspdm_copy_mem(m_libspdm_set_certificate_request + 1,
521 : LIBSPDM_MAX_CERT_CHAIN_SIZE,
522 : (uint8_t *)cert_chain, cert_chain_size);
523 :
524 1 : size_t m_libspdm_set_certificate_request_size = sizeof(spdm_set_certificate_request_t) +
525 : cert_chain_size;
526 :
527 1 : response_size = sizeof(response);
528 1 : status = libspdm_get_response_set_certificate(spdm_context,
529 : m_libspdm_set_certificate_request_size,
530 : m_libspdm_set_certificate_request,
531 : &response_size, response);
532 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
533 1 : assert_int_equal(response_size, sizeof(spdm_error_response_t));
534 1 : spdm_response = (void *)response;
535 1 : assert_int_equal(spdm_response->header.request_response_code,
536 : SPDM_ERROR);
537 1 : assert_int_equal(spdm_response->header.param1,
538 : SPDM_ERROR_CODE_RESET_REQUIRED);
539 1 : assert_int_equal(spdm_response->header.param2, 0);
540 :
541 1 : free(cert_chain);
542 1 : free(m_libspdm_set_certificate_request);
543 1 : }
544 :
545 : /**
546 : * Test 7: receives a valid SET_CERTIFICATE request message from Requester to set cert in slot_id:0 with alias_cert model
547 : * Expected Behavior: produces a valid SET_CERTIFICATE_RSP response message
548 : **/
549 1 : static void rsp_set_certificate_rsp_case7(void **state)
550 : {
551 : libspdm_return_t status;
552 : libspdm_test_context_t *spdm_test_context;
553 : libspdm_context_t *spdm_context;
554 : size_t response_size;
555 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
556 : spdm_set_certificate_response_t *spdm_response;
557 : void *cert_chain;
558 : size_t cert_chain_size;
559 : spdm_set_certificate_request_t *m_libspdm_set_certificate_request;
560 :
561 1 : spdm_test_context = *state;
562 1 : spdm_context = spdm_test_context->spdm_context;
563 1 : spdm_test_context->case_id = 0x7;
564 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 <<
565 : SPDM_VERSION_NUMBER_SHIFT_BIT;
566 :
567 1 : spdm_context->connection_info.connection_state =
568 : LIBSPDM_CONNECTION_STATE_NEGOTIATED;
569 1 : spdm_context->local_context.capability.flags |=
570 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_SET_CERT_CAP;
571 1 : spdm_context->connection_info.algorithm.base_hash_algo =
572 : m_libspdm_use_hash_algo;
573 1 : spdm_context->connection_info.algorithm.base_asym_algo =
574 : m_libspdm_use_asym_algo;
575 1 : spdm_context->local_context.capability.flags &=
576 : ~SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_INSTALL_RESET_CAP;
577 :
578 1 : spdm_context->local_context.algorithm.base_hash_algo =
579 : m_libspdm_use_hash_algo;
580 1 : spdm_context->local_context.algorithm.base_asym_algo =
581 : m_libspdm_use_asym_algo;
582 :
583 : /*set alias cert mode*/
584 1 : spdm_context->local_context.capability.flags |=
585 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_ALIAS_CERT_CAP;
586 : /*read alias cert(alias cert chain is partial)*/
587 1 : libspdm_read_responder_public_certificate_chain_alias_cert_till_dev_cert_ca(
588 : m_libspdm_use_hash_algo, m_libspdm_use_asym_algo,
589 : &cert_chain, &cert_chain_size, NULL, NULL);
590 :
591 1 : m_libspdm_set_certificate_request = malloc(sizeof(spdm_set_certificate_request_t) +
592 : cert_chain_size);
593 :
594 1 : m_libspdm_set_certificate_request->header.spdm_version = SPDM_MESSAGE_VERSION_12;
595 1 : m_libspdm_set_certificate_request->header.request_response_code = SPDM_SET_CERTIFICATE;
596 1 : m_libspdm_set_certificate_request->header.param1 = 0;
597 1 : m_libspdm_set_certificate_request->header.param2 = 0;
598 :
599 1 : libspdm_copy_mem(m_libspdm_set_certificate_request + 1,
600 : LIBSPDM_MAX_CERT_CHAIN_SIZE,
601 : (uint8_t *)cert_chain, cert_chain_size);
602 :
603 1 : size_t m_libspdm_set_certificate_request_size = sizeof(spdm_set_certificate_request_t) +
604 : cert_chain_size;
605 :
606 1 : response_size = sizeof(response);
607 1 : status = libspdm_get_response_set_certificate(spdm_context,
608 : m_libspdm_set_certificate_request_size,
609 : m_libspdm_set_certificate_request,
610 : &response_size, response);
611 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
612 1 : assert_int_equal(response_size, sizeof(spdm_set_certificate_response_t));
613 1 : spdm_response = (void *)response;
614 1 : assert_int_equal(spdm_response->header.request_response_code,
615 : SPDM_SET_CERTIFICATE_RSP);
616 :
617 1 : free(cert_chain);
618 1 : free(m_libspdm_set_certificate_request);
619 1 : }
620 :
621 : /**
622 : * Test 8: receives a SET_CERTIFICATE request message to set cert in slot_id:1 without session and with trusted environment
623 : * Expected Behavior: produces a valid SET_CERTIFICATE_RSP response message
624 : **/
625 1 : static void rsp_set_certificate_rsp_case8(void **state)
626 : {
627 : libspdm_return_t status;
628 : libspdm_test_context_t *spdm_test_context;
629 : libspdm_context_t *spdm_context;
630 : size_t response_size;
631 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
632 : spdm_set_certificate_response_t *spdm_response;
633 : void *cert_chain;
634 : size_t cert_chain_size;
635 : spdm_set_certificate_request_t *m_libspdm_set_certificate_request;
636 :
637 1 : spdm_test_context = *state;
638 1 : spdm_context = spdm_test_context->spdm_context;
639 1 : spdm_test_context->case_id = 0x8;
640 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 <<
641 : SPDM_VERSION_NUMBER_SHIFT_BIT;
642 : /*responset_state need to set normal*/
643 1 : spdm_context->response_state = LIBSPDM_RESPONSE_STATE_NORMAL;
644 1 : spdm_context->connection_info.connection_state =
645 : LIBSPDM_CONNECTION_STATE_AUTHENTICATED;
646 1 : spdm_context->local_context.capability.flags |=
647 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_SET_CERT_CAP;
648 1 : spdm_context->local_context.capability.flags &=
649 : ~SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_INSTALL_RESET_CAP;
650 1 : spdm_context->local_context.capability.flags &=
651 : ~SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_ALIAS_CERT_CAP;
652 1 : spdm_context->local_context.capability.flags |=
653 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP_SIG;
654 1 : spdm_context->connection_info.algorithm.base_hash_algo =
655 : m_libspdm_use_hash_algo;
656 1 : spdm_context->connection_info.algorithm.base_asym_algo =
657 : m_libspdm_use_asym_algo;
658 :
659 1 : spdm_context->last_spdm_request_session_id_valid = false;
660 1 : g_in_trusted_environment = true;
661 :
662 1 : libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
663 : m_libspdm_use_asym_algo, &cert_chain,
664 : &cert_chain_size, NULL, NULL);
665 :
666 1 : m_libspdm_set_certificate_request = malloc(sizeof(spdm_set_certificate_request_t) +
667 : cert_chain_size);
668 :
669 1 : m_libspdm_set_certificate_request->header.spdm_version = SPDM_MESSAGE_VERSION_12;
670 1 : m_libspdm_set_certificate_request->header.request_response_code = SPDM_SET_CERTIFICATE;
671 1 : m_libspdm_set_certificate_request->header.param1 = 1;
672 1 : m_libspdm_set_certificate_request->header.param2 = 0;
673 :
674 1 : libspdm_copy_mem(m_libspdm_set_certificate_request + 1,
675 : LIBSPDM_MAX_CERT_CHAIN_SIZE,
676 : (uint8_t *)cert_chain, cert_chain_size);
677 :
678 1 : size_t m_libspdm_set_certificate_request_size = sizeof(spdm_set_certificate_request_t) +
679 : cert_chain_size;
680 :
681 1 : response_size = sizeof(response);
682 1 : status = libspdm_get_response_set_certificate(spdm_context,
683 : m_libspdm_set_certificate_request_size,
684 : m_libspdm_set_certificate_request,
685 : &response_size, response);
686 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
687 1 : assert_int_equal(response_size, sizeof(spdm_set_certificate_response_t));
688 1 : spdm_response = (void *)response;
689 1 : assert_int_equal(spdm_response->header.request_response_code,
690 : SPDM_SET_CERTIFICATE_RSP);
691 :
692 1 : free(cert_chain);
693 1 : free(m_libspdm_set_certificate_request);
694 1 : }
695 :
696 : /**
697 : * Test 9: receives a SET_CERTIFICATE request message to set cert in slot_id:1 without session and without trusted environment
698 : * Expected Behavior: produces a valid ERROR response message
699 : **/
700 1 : static void rsp_set_certificate_rsp_case9(void **state)
701 : {
702 : libspdm_return_t status;
703 : libspdm_test_context_t *spdm_test_context;
704 : libspdm_context_t *spdm_context;
705 : size_t response_size;
706 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
707 : spdm_set_certificate_response_t *spdm_response;
708 : void *cert_chain;
709 : size_t cert_chain_size;
710 : spdm_set_certificate_request_t *m_libspdm_set_certificate_request;
711 :
712 1 : spdm_test_context = *state;
713 1 : spdm_context = spdm_test_context->spdm_context;
714 1 : spdm_test_context->case_id = 0x9;
715 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 <<
716 : SPDM_VERSION_NUMBER_SHIFT_BIT;
717 : /*responset_state need to set normal*/
718 1 : spdm_context->response_state = LIBSPDM_RESPONSE_STATE_NORMAL;
719 1 : spdm_context->connection_info.connection_state =
720 : LIBSPDM_CONNECTION_STATE_AUTHENTICATED;
721 1 : spdm_context->local_context.capability.flags |=
722 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_SET_CERT_CAP;
723 1 : spdm_context->local_context.capability.flags &=
724 : ~SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_INSTALL_RESET_CAP;
725 1 : spdm_context->local_context.capability.flags &=
726 : ~SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_ALIAS_CERT_CAP;
727 1 : spdm_context->local_context.capability.flags |=
728 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP_SIG;
729 1 : spdm_context->connection_info.algorithm.base_hash_algo =
730 : m_libspdm_use_hash_algo;
731 1 : spdm_context->connection_info.algorithm.base_asym_algo =
732 : m_libspdm_use_asym_algo;
733 :
734 1 : spdm_context->last_spdm_request_session_id_valid = false;
735 1 : g_in_trusted_environment = false;
736 :
737 1 : libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
738 : m_libspdm_use_asym_algo, &cert_chain,
739 : &cert_chain_size, NULL, NULL);
740 :
741 1 : m_libspdm_set_certificate_request = malloc(sizeof(spdm_set_certificate_request_t) +
742 : cert_chain_size);
743 :
744 1 : m_libspdm_set_certificate_request->header.spdm_version = SPDM_MESSAGE_VERSION_12;
745 1 : m_libspdm_set_certificate_request->header.request_response_code = SPDM_SET_CERTIFICATE;
746 1 : m_libspdm_set_certificate_request->header.param1 = 1;
747 1 : m_libspdm_set_certificate_request->header.param2 = 0;
748 :
749 1 : libspdm_copy_mem(m_libspdm_set_certificate_request + 1,
750 : LIBSPDM_MAX_CERT_CHAIN_SIZE,
751 : (uint8_t *)cert_chain, cert_chain_size);
752 :
753 1 : size_t m_libspdm_set_certificate_request_size = sizeof(spdm_set_certificate_request_t) +
754 : cert_chain_size;
755 :
756 1 : response_size = sizeof(response);
757 1 : status = libspdm_get_response_set_certificate(spdm_context,
758 : m_libspdm_set_certificate_request_size,
759 : m_libspdm_set_certificate_request,
760 : &response_size, response);
761 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
762 1 : assert_int_equal(response_size, sizeof(spdm_error_response_t));
763 1 : spdm_response = (void *)response;
764 1 : assert_int_equal(spdm_response->header.request_response_code,
765 : SPDM_ERROR);
766 1 : assert_int_equal(spdm_response->header.param1,
767 : SPDM_ERROR_CODE_UNEXPECTED_REQUEST);
768 1 : assert_int_equal(spdm_response->header.param2, 0);
769 :
770 1 : free(cert_chain);
771 1 : free(m_libspdm_set_certificate_request);
772 1 : }
773 :
774 : /**
775 : * Test 10: receives a valid SET_CERTIFICATE request message from Requester to erase cert in slot_id:1 with session
776 : * Expected Behavior: produces a valid SET_CERTIFICATE_RSP response message
777 : **/
778 1 : static void rsp_set_certificate_rsp_case10(void **state)
779 : {
780 : libspdm_return_t status;
781 : libspdm_test_context_t *spdm_test_context;
782 : libspdm_context_t *spdm_context;
783 : size_t response_size;
784 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
785 : spdm_set_certificate_response_t *spdm_response;
786 : spdm_set_certificate_request_t *m_libspdm_set_certificate_request;
787 :
788 : libspdm_session_info_t *session_info;
789 : uint32_t session_id;
790 : uint8_t slot_id;
791 : #if defined(_WIN32) || (defined(__clang__) && (defined (LIBSPDM_CPU_AARCH64) || \
792 : defined(LIBSPDM_CPU_ARM)))
793 : FILE *fp_out;
794 : #else
795 : int64_t fp_out;
796 : struct stat file_stat;
797 : #endif
798 : size_t cert_file_size;
799 :
800 1 : char file_name[] = "slot_id_0_cert_chain.der";
801 1 : slot_id = 1;
802 :
803 1 : spdm_test_context = *state;
804 1 : spdm_context = spdm_test_context->spdm_context;
805 1 : spdm_test_context->case_id = 0xA;
806 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_13 <<
807 : SPDM_VERSION_NUMBER_SHIFT_BIT;
808 : /*responset_state need to set normal*/
809 1 : spdm_context->response_state = LIBSPDM_RESPONSE_STATE_NORMAL;
810 1 : spdm_context->connection_info.connection_state =
811 : LIBSPDM_CONNECTION_STATE_AUTHENTICATED;
812 1 : spdm_context->local_context.capability.flags |=
813 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_SET_CERT_CAP;
814 1 : spdm_context->local_context.capability.flags |=
815 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP_SIG;
816 1 : spdm_context->connection_info.algorithm.base_hash_algo =
817 : m_libspdm_use_hash_algo;
818 1 : spdm_context->connection_info.algorithm.base_asym_algo =
819 : m_libspdm_use_asym_algo;
820 :
821 1 : spdm_context->local_context.algorithm.base_hash_algo =
822 : m_libspdm_use_hash_algo;
823 1 : spdm_context->local_context.algorithm.base_asym_algo =
824 : m_libspdm_use_asym_algo;
825 :
826 1 : session_id = 0xFFFFFFFF;
827 1 : spdm_context->latest_session_id = session_id;
828 1 : spdm_context->last_spdm_request_session_id_valid = true;
829 1 : spdm_context->last_spdm_request_session_id = session_id;
830 1 : session_info = &spdm_context->session_info[0];
831 1 : libspdm_session_info_init(spdm_context, session_info, session_id,
832 : SECURED_SPDM_VERSION_11 << SPDM_VERSION_NUMBER_SHIFT_BIT, true);
833 1 : libspdm_secured_message_set_session_state(
834 : session_info->secured_message_context,
835 : LIBSPDM_SESSION_STATE_ESTABLISHED);
836 :
837 1 : m_libspdm_set_certificate_request = malloc(sizeof(spdm_set_certificate_request_t));
838 :
839 1 : m_libspdm_set_certificate_request->header.spdm_version = SPDM_MESSAGE_VERSION_13;
840 1 : m_libspdm_set_certificate_request->header.request_response_code = SPDM_SET_CERTIFICATE;
841 1 : m_libspdm_set_certificate_request->header.param1 = slot_id |
842 : SPDM_SET_CERTIFICATE_REQUEST_ATTRIBUTES_ERASE;
843 1 : m_libspdm_set_certificate_request->header.param2 = 0;
844 :
845 1 : size_t m_libspdm_set_certificate_request_size = sizeof(spdm_set_certificate_request_t);
846 :
847 1 : response_size = sizeof(response);
848 1 : status = libspdm_get_response_set_certificate(spdm_context,
849 : m_libspdm_set_certificate_request_size,
850 : m_libspdm_set_certificate_request,
851 : &response_size, response);
852 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
853 1 : assert_int_equal(response_size, sizeof(spdm_set_certificate_response_t));
854 1 : spdm_response = (void *)response;
855 1 : assert_int_equal(spdm_response->header.request_response_code,
856 : SPDM_SET_CERTIFICATE_RSP);
857 1 : assert_int_equal(spdm_response->header.param1, slot_id);
858 :
859 : /*change the file name, for example: slot_id_1_cert_chain.der*/
860 1 : file_name[8] = (char)(slot_id + '0');
861 :
862 : #if defined(_WIN32) || (defined(__clang__) && (defined (LIBSPDM_CPU_AARCH64) || \
863 : defined(LIBSPDM_CPU_ARM)))
864 : if ((fp_out = fopen(file_name, "r")) == NULL) {
865 : printf("Unable to open file %s\n", file_name);
866 : assert_false(true);
867 : }
868 :
869 : /*check the cert is erased*/
870 : fseek(fp_out, 0, SEEK_END);
871 : cert_file_size = ftell(fp_out);
872 : assert_int_equal(cert_file_size, 0);
873 :
874 : fclose(fp_out);
875 : #else
876 1 : if ((fp_out = open(file_name, O_RDONLY)) == -1) {
877 0 : printf("Unable to open file %s\n", file_name);
878 0 : assert_false(true);
879 : }
880 :
881 1 : if (fstat(fp_out, &file_stat) != 0) {
882 0 : assert_false(true);
883 : }
884 :
885 1 : cert_file_size = file_stat.st_size;
886 1 : assert_int_equal(cert_file_size, 0);
887 :
888 1 : close(fp_out);
889 : #endif
890 :
891 1 : free(m_libspdm_set_certificate_request);
892 1 : }
893 :
894 : /**
895 : * Test 11: receives a valid SET_CERTIFICATE request message from Requester to set cert in slot_id:1 with key_pair_id
896 : * Expected Behavior: produces a valid SET_CERTIFICATE_RSP response message
897 : **/
898 1 : static void rsp_set_certificate_rsp_case11(void **state)
899 : {
900 : libspdm_return_t status;
901 : libspdm_test_context_t *spdm_test_context;
902 : libspdm_context_t *spdm_context;
903 : size_t response_size;
904 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
905 : spdm_set_certificate_response_t *spdm_response;
906 : void *cert_chain;
907 : size_t cert_chain_size;
908 : spdm_set_certificate_request_t *m_libspdm_set_certificate_request;
909 : uint8_t slot_id;
910 : uint8_t key_pair_id;
911 :
912 1 : spdm_test_context = *state;
913 1 : spdm_context = spdm_test_context->spdm_context;
914 1 : spdm_test_context->case_id = 0xB;
915 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_13 <<
916 : SPDM_VERSION_NUMBER_SHIFT_BIT;
917 1 : slot_id = 1;
918 1 : key_pair_id = 1;
919 :
920 1 : spdm_context->connection_info.connection_state =
921 : LIBSPDM_CONNECTION_STATE_NEGOTIATED;
922 1 : spdm_context->local_context.capability.flags |=
923 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_SET_CERT_CAP;
924 1 : spdm_context->connection_info.algorithm.base_hash_algo =
925 : m_libspdm_use_hash_algo;
926 1 : spdm_context->connection_info.algorithm.base_asym_algo =
927 : m_libspdm_use_asym_algo;
928 1 : spdm_context->connection_info.multi_key_conn_rsp = true;
929 :
930 1 : spdm_context->local_context.algorithm.base_hash_algo =
931 : m_libspdm_use_hash_algo;
932 1 : spdm_context->local_context.algorithm.base_asym_algo =
933 : m_libspdm_use_asym_algo;
934 :
935 1 : libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
936 : m_libspdm_use_asym_algo, &cert_chain,
937 : &cert_chain_size, NULL, NULL);
938 :
939 1 : m_libspdm_set_certificate_request = malloc(sizeof(spdm_set_certificate_request_t) +
940 : cert_chain_size);
941 :
942 1 : m_libspdm_set_certificate_request->header.spdm_version = SPDM_MESSAGE_VERSION_13;
943 1 : m_libspdm_set_certificate_request->header.request_response_code = SPDM_SET_CERTIFICATE;
944 1 : m_libspdm_set_certificate_request->header.param1 =
945 : slot_id | (SPDM_CERTIFICATE_INFO_CERT_MODEL_DEVICE_CERT <<
946 : SPDM_SET_CERTIFICATE_REQUEST_ATTRIBUTES_CERT_MODEL_OFFSET);
947 1 : m_libspdm_set_certificate_request->header.param2 = key_pair_id;
948 :
949 1 : libspdm_copy_mem(m_libspdm_set_certificate_request + 1,
950 : LIBSPDM_MAX_CERT_CHAIN_SIZE,
951 : (uint8_t *)cert_chain, cert_chain_size);
952 :
953 1 : size_t m_libspdm_set_certificate_request_size = sizeof(spdm_set_certificate_request_t) +
954 : cert_chain_size;
955 :
956 1 : response_size = sizeof(response);
957 1 : status = libspdm_get_response_set_certificate(spdm_context,
958 : m_libspdm_set_certificate_request_size,
959 : m_libspdm_set_certificate_request,
960 : &response_size, response);
961 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
962 1 : assert_int_equal(response_size, sizeof(spdm_set_certificate_response_t));
963 1 : spdm_response = (void *)response;
964 1 : assert_int_equal(spdm_response->header.request_response_code,
965 : SPDM_SET_CERTIFICATE_RSP);
966 :
967 1 : free(cert_chain);
968 1 : free(m_libspdm_set_certificate_request);
969 1 : }
970 :
971 : /**
972 : * Test 12: Illegal combination of MULTI_KEY_CONN_RSP = true, Erase = false, and SetCertModel = 0.
973 : * Expected Behavior: produces SPDM_ERROR_CODE_INVALID_REQUEST message.
974 : **/
975 1 : static void rsp_set_certificate_rsp_case12(void **state)
976 : {
977 : libspdm_return_t status;
978 : libspdm_test_context_t *spdm_test_context;
979 : libspdm_context_t *spdm_context;
980 : size_t response_size;
981 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
982 : spdm_set_certificate_response_t *spdm_response;
983 : void *cert_chain;
984 : size_t cert_chain_size;
985 : spdm_set_certificate_request_t *m_libspdm_set_certificate_request;
986 : uint8_t slot_id;
987 : uint8_t key_pair_id;
988 :
989 1 : spdm_test_context = *state;
990 1 : spdm_context = spdm_test_context->spdm_context;
991 1 : spdm_test_context->case_id = 0xc;
992 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_13 <<
993 : SPDM_VERSION_NUMBER_SHIFT_BIT;
994 1 : slot_id = 1;
995 1 : key_pair_id = 1;
996 :
997 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
998 1 : spdm_context->local_context.capability.flags |=
999 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_SET_CERT_CAP;
1000 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
1001 1 : spdm_context->connection_info.algorithm.base_asym_algo = m_libspdm_use_asym_algo;
1002 1 : spdm_context->connection_info.multi_key_conn_rsp = true;
1003 :
1004 1 : spdm_context->local_context.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
1005 1 : spdm_context->local_context.algorithm.base_asym_algo = m_libspdm_use_asym_algo;
1006 :
1007 1 : libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
1008 : m_libspdm_use_asym_algo, &cert_chain,
1009 : &cert_chain_size, NULL, NULL);
1010 :
1011 1 : m_libspdm_set_certificate_request = malloc(sizeof(spdm_set_certificate_request_t) +
1012 : cert_chain_size);
1013 :
1014 1 : m_libspdm_set_certificate_request->header.spdm_version = SPDM_MESSAGE_VERSION_13;
1015 1 : m_libspdm_set_certificate_request->header.request_response_code = SPDM_SET_CERTIFICATE;
1016 1 : m_libspdm_set_certificate_request->header.param1 =
1017 : slot_id | (SPDM_CERTIFICATE_INFO_CERT_MODEL_NONE <<
1018 : SPDM_SET_CERTIFICATE_REQUEST_ATTRIBUTES_CERT_MODEL_OFFSET);
1019 1 : m_libspdm_set_certificate_request->header.param2 = key_pair_id;
1020 :
1021 1 : libspdm_copy_mem(m_libspdm_set_certificate_request + 1,
1022 : LIBSPDM_MAX_CERT_CHAIN_SIZE,
1023 : (uint8_t *)cert_chain, cert_chain_size);
1024 :
1025 1 : size_t m_libspdm_set_certificate_request_size = sizeof(spdm_set_certificate_request_t) +
1026 : cert_chain_size;
1027 :
1028 1 : response_size = sizeof(response);
1029 1 : status = libspdm_get_response_set_certificate(spdm_context,
1030 : m_libspdm_set_certificate_request_size,
1031 : m_libspdm_set_certificate_request,
1032 : &response_size, response);
1033 :
1034 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
1035 1 : assert_int_equal(response_size, sizeof(spdm_error_response_t));
1036 1 : spdm_response = (void *)response;
1037 1 : assert_int_equal(spdm_response->header.request_response_code, SPDM_ERROR);
1038 1 : assert_int_equal(spdm_response->header.param1, SPDM_ERROR_CODE_INVALID_REQUEST);
1039 1 : assert_int_equal(spdm_response->header.param2, 0);
1040 :
1041 1 : free(cert_chain);
1042 1 : free(m_libspdm_set_certificate_request);
1043 1 : }
1044 :
1045 : /**
1046 : * Test 13: The Responder cannot complete request due to busy response when writing to NVM.
1047 : * Expected Behavior: The Responder returns a Busy error response.
1048 : **/
1049 1 : static void rsp_set_certificate_rsp_case13(void **state)
1050 : {
1051 : libspdm_return_t status;
1052 : libspdm_test_context_t *spdm_test_context;
1053 : libspdm_context_t *spdm_context;
1054 : size_t response_size;
1055 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
1056 : spdm_set_certificate_response_t *spdm_response;
1057 : void *cert_chain;
1058 : size_t cert_chain_size;
1059 : spdm_set_certificate_request_t *m_libspdm_set_certificate_request;
1060 :
1061 1 : spdm_test_context = *state;
1062 1 : spdm_context = spdm_test_context->spdm_context;
1063 1 : spdm_test_context->case_id = 0xd;
1064 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_12 <<
1065 : SPDM_VERSION_NUMBER_SHIFT_BIT;
1066 :
1067 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
1068 1 : spdm_context->local_context.capability.flags |=
1069 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_SET_CERT_CAP;
1070 1 : spdm_context->local_context.capability.flags |=
1071 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_INSTALL_RESET_CAP;
1072 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
1073 1 : spdm_context->connection_info.algorithm.base_asym_algo = m_libspdm_use_asym_algo;
1074 :
1075 1 : spdm_context->local_context.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
1076 1 : spdm_context->local_context.algorithm.base_asym_algo = m_libspdm_use_asym_algo;
1077 :
1078 1 : libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
1079 : m_libspdm_use_asym_algo, &cert_chain,
1080 : &cert_chain_size, NULL, NULL);
1081 :
1082 1 : m_libspdm_set_certificate_request = malloc(sizeof(spdm_set_certificate_request_t) +
1083 : cert_chain_size);
1084 :
1085 1 : m_libspdm_set_certificate_request->header.spdm_version = SPDM_MESSAGE_VERSION_12;
1086 1 : m_libspdm_set_certificate_request->header.request_response_code = SPDM_SET_CERTIFICATE;
1087 1 : m_libspdm_set_certificate_request->header.param1 = 0;
1088 1 : m_libspdm_set_certificate_request->header.param2 = 0;
1089 :
1090 1 : libspdm_copy_mem(m_libspdm_set_certificate_request + 1,
1091 : LIBSPDM_MAX_CERT_CHAIN_SIZE,
1092 : (uint8_t *)cert_chain, cert_chain_size);
1093 :
1094 1 : size_t m_libspdm_set_certificate_request_size = sizeof(spdm_set_certificate_request_t) +
1095 : cert_chain_size;
1096 :
1097 : /* Unable to write to NVM due to busy condition. */
1098 1 : g_set_cert_is_busy = true;
1099 :
1100 1 : response_size = sizeof(response);
1101 1 : status = libspdm_get_response_set_certificate(spdm_context,
1102 : m_libspdm_set_certificate_request_size,
1103 : m_libspdm_set_certificate_request,
1104 : &response_size, response);
1105 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
1106 1 : assert_int_equal(response_size, sizeof(spdm_error_response_t));
1107 1 : spdm_response = (void *)response;
1108 1 : assert_int_equal(spdm_response->header.request_response_code, SPDM_ERROR);
1109 1 : assert_int_equal(spdm_response->header.param1, SPDM_ERROR_CODE_BUSY);
1110 1 : assert_int_equal(spdm_response->header.param2, 0);
1111 :
1112 1 : g_set_cert_is_busy = false;
1113 :
1114 1 : free(cert_chain);
1115 1 : free(m_libspdm_set_certificate_request);
1116 1 : }
1117 :
1118 1 : int libspdm_rsp_set_certificate_rsp_test(void)
1119 : {
1120 1 : const struct CMUnitTest test_cases[] = {
1121 : /* Success Case for set_certificate to slot_id:0 with device_cert mode*/
1122 : cmocka_unit_test(rsp_set_certificate_rsp_case1),
1123 : /* Bad request size*/
1124 : cmocka_unit_test(rsp_set_certificate_rsp_case2),
1125 : /* response_state: LIBSPDM_RESPONSE_STATE_BUSY*/
1126 : cmocka_unit_test(rsp_set_certificate_rsp_case3),
1127 : /* response_state: LIBSPDM_RESPONSE_STATE_NEED_RESYNC*/
1128 : cmocka_unit_test(rsp_set_certificate_rsp_case4),
1129 : /* Success Case for set_certificate to slot_id:1 with session*/
1130 : cmocka_unit_test(rsp_set_certificate_rsp_case5),
1131 : /* Responder requires a reset to complete the SET_CERTIFICATE request */
1132 : cmocka_unit_test(rsp_set_certificate_rsp_case6),
1133 : /* Success Case for set_certificate to slot_id:0 with alias_cert mode*/
1134 : cmocka_unit_test(rsp_set_certificate_rsp_case7),
1135 : /* Success Case for set_certificate to slot_id:1 without session and with trusted environment */
1136 : cmocka_unit_test(rsp_set_certificate_rsp_case8),
1137 : /* Error Case for set_certificate to slot_id:1 without session and without trusted environment */
1138 : cmocka_unit_test(rsp_set_certificate_rsp_case9),
1139 : /* Success Case for erase certificate to slot_id:1 with session*/
1140 : cmocka_unit_test(rsp_set_certificate_rsp_case10),
1141 : /* Success Case for set_certificate to slot_id:1 with key_pair_id*/
1142 : cmocka_unit_test(rsp_set_certificate_rsp_case11),
1143 : cmocka_unit_test(rsp_set_certificate_rsp_case12),
1144 : cmocka_unit_test(rsp_set_certificate_rsp_case13),
1145 : };
1146 :
1147 1 : libspdm_test_context_t test_context = {
1148 : LIBSPDM_TEST_CONTEXT_VERSION,
1149 : false,
1150 : };
1151 :
1152 1 : libspdm_setup_test_context(&test_context);
1153 :
1154 1 : return cmocka_run_group_tests(test_cases,
1155 : libspdm_unit_test_group_setup,
1156 : libspdm_unit_test_group_teardown);
1157 : }
1158 :
1159 : #endif /* LIBSPDM_ENABLE_CAPABILITY_SET_CERT_CAP*/
|