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