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 LIBSPDM_ENABLE_CAPABILITY_CERT_CAP
11 :
12 : spdm_get_digest_request_t m_libspdm_get_digests_request1 = {
13 : {
14 : SPDM_MESSAGE_VERSION_10,
15 : SPDM_GET_DIGESTS,
16 : },
17 : };
18 : size_t m_libspdm_get_digests_request1_size = sizeof(m_libspdm_get_digests_request1);
19 :
20 : spdm_get_digest_request_t m_libspdm_get_digests_request2 = {
21 : {
22 : SPDM_MESSAGE_VERSION_13,
23 : SPDM_GET_DIGESTS,
24 : },
25 : };
26 : size_t m_libspdm_get_digests_request2_size = sizeof(m_libspdm_get_digests_request2);
27 :
28 : static uint8_t m_libspdm_local_certificate_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
29 :
30 : /**
31 : * Test 1: receives a valid GET_DIGESTS request message from Requester
32 : * Expected Behavior: produces a valid DIGESTS response message
33 : **/
34 1 : static void rsp_digests_case1(void **state)
35 : {
36 : libspdm_return_t status;
37 : libspdm_test_context_t *spdm_test_context;
38 : libspdm_context_t *spdm_context;
39 : size_t response_size;
40 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
41 : spdm_digest_response_t *spdm_response;
42 :
43 1 : spdm_test_context = *state;
44 1 : spdm_context = spdm_test_context->spdm_context;
45 1 : spdm_test_context->case_id = 0x1;
46 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
47 : SPDM_VERSION_NUMBER_SHIFT_BIT;
48 1 : spdm_context->connection_info.connection_state =
49 : LIBSPDM_CONNECTION_STATE_NEGOTIATED;
50 1 : spdm_context->local_context.capability.flags |=
51 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
52 1 : spdm_context->connection_info.algorithm.base_hash_algo =
53 : m_libspdm_use_hash_algo;
54 1 : spdm_context->local_context.local_cert_chain_provision[0] =
55 : m_libspdm_local_certificate_chain;
56 1 : spdm_context->local_context.local_cert_chain_provision_size[0] =
57 : sizeof(m_libspdm_local_certificate_chain);
58 1 : libspdm_set_mem(m_libspdm_local_certificate_chain,
59 : sizeof(m_libspdm_local_certificate_chain),
60 : (uint8_t)(0xFF));
61 :
62 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
63 : spdm_context->transcript.message_m.buffer_size =
64 : spdm_context->transcript.message_m.max_buffer_size;
65 : #endif
66 :
67 1 : response_size = sizeof(response);
68 1 : status = libspdm_get_response_digests(spdm_context,
69 : m_libspdm_get_digests_request1_size,
70 : &m_libspdm_get_digests_request1,
71 : &response_size, response);
72 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
73 1 : assert_int_equal(
74 : response_size,
75 : sizeof(spdm_digest_response_t) +
76 : libspdm_get_hash_size(spdm_context->connection_info
77 : .algorithm.base_hash_algo));
78 1 : spdm_response = (void *)response;
79 1 : assert_int_equal(spdm_response->header.request_response_code,
80 : SPDM_DIGESTS);
81 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
82 : assert_int_equal(spdm_context->transcript.message_m.buffer_size,
83 : 0);
84 : #endif
85 1 : }
86 :
87 : /**
88 : * Test 2:
89 : * Expected Behavior:
90 : **/
91 1 : static void rsp_digests_case2(void **state)
92 : {
93 1 : }
94 :
95 : /**
96 : * Test 3: receives a valid GET_DIGESTS request message from Requester, but Responder is not ready to accept the new
97 : * request message (is busy) and may be able to process the request message if it is sent again in the future
98 : * Expected Behavior: produces an ERROR response message with error code = Busy
99 : **/
100 1 : static void rsp_digests_case3(void **state)
101 : {
102 : libspdm_return_t status;
103 : libspdm_test_context_t *spdm_test_context;
104 : libspdm_context_t *spdm_context;
105 : size_t response_size;
106 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
107 : spdm_digest_response_t *spdm_response;
108 :
109 1 : spdm_test_context = *state;
110 1 : spdm_context = spdm_test_context->spdm_context;
111 1 : spdm_test_context->case_id = 0x3;
112 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
113 : SPDM_VERSION_NUMBER_SHIFT_BIT;
114 1 : spdm_context->response_state = LIBSPDM_RESPONSE_STATE_BUSY;
115 1 : spdm_context->connection_info.connection_state =
116 : LIBSPDM_CONNECTION_STATE_NEGOTIATED;
117 1 : spdm_context->local_context.capability.flags |=
118 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
119 1 : spdm_context->connection_info.algorithm.base_hash_algo =
120 : m_libspdm_use_hash_algo;
121 1 : spdm_context->local_context.local_cert_chain_provision[0] =
122 : m_libspdm_local_certificate_chain;
123 1 : spdm_context->local_context.local_cert_chain_provision_size[0] =
124 : sizeof(m_libspdm_local_certificate_chain);
125 1 : libspdm_set_mem(m_libspdm_local_certificate_chain,
126 : sizeof(m_libspdm_local_certificate_chain),
127 : (uint8_t)(0xFF));
128 :
129 1 : response_size = sizeof(response);
130 1 : status = libspdm_get_response_digests(spdm_context,
131 : m_libspdm_get_digests_request1_size,
132 : &m_libspdm_get_digests_request1,
133 : &response_size, response);
134 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
135 1 : assert_int_equal(response_size, sizeof(spdm_error_response_t));
136 1 : spdm_response = (void *)response;
137 1 : assert_int_equal(spdm_response->header.request_response_code,
138 : SPDM_ERROR);
139 1 : assert_int_equal(spdm_response->header.param1, SPDM_ERROR_CODE_BUSY);
140 1 : assert_int_equal(spdm_response->header.param2, 0);
141 1 : assert_int_equal(spdm_context->response_state,
142 : LIBSPDM_RESPONSE_STATE_BUSY);
143 1 : }
144 :
145 : /**
146 : * Test 4: receives a valid GET_DIGESTS request message from Requester, but Responder needs the Requester to reissue GET_VERSION to resynchronize
147 : * Expected Behavior: produces an ERROR response message with error code = RequestResynch
148 : **/
149 1 : static void rsp_digests_case4(void **state)
150 : {
151 : libspdm_return_t status;
152 : libspdm_test_context_t *spdm_test_context;
153 : libspdm_context_t *spdm_context;
154 : size_t response_size;
155 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
156 : spdm_digest_response_t *spdm_response;
157 :
158 1 : spdm_test_context = *state;
159 1 : spdm_context = spdm_test_context->spdm_context;
160 1 : spdm_test_context->case_id = 0x4;
161 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
162 : SPDM_VERSION_NUMBER_SHIFT_BIT;
163 1 : spdm_context->response_state = LIBSPDM_RESPONSE_STATE_NEED_RESYNC;
164 1 : spdm_context->connection_info.connection_state =
165 : LIBSPDM_CONNECTION_STATE_NEGOTIATED;
166 1 : spdm_context->local_context.capability.flags |=
167 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
168 1 : spdm_context->connection_info.algorithm.base_hash_algo =
169 : m_libspdm_use_hash_algo;
170 1 : spdm_context->local_context.local_cert_chain_provision[0] =
171 : m_libspdm_local_certificate_chain;
172 1 : spdm_context->local_context.local_cert_chain_provision_size[0] =
173 : sizeof(m_libspdm_local_certificate_chain);
174 1 : libspdm_set_mem(m_libspdm_local_certificate_chain,
175 : sizeof(m_libspdm_local_certificate_chain),
176 : (uint8_t)(0xFF));
177 :
178 1 : response_size = sizeof(response);
179 1 : status = libspdm_get_response_digests(spdm_context,
180 : m_libspdm_get_digests_request1_size,
181 : &m_libspdm_get_digests_request1,
182 : &response_size, response);
183 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
184 1 : assert_int_equal(response_size, sizeof(spdm_error_response_t));
185 1 : spdm_response = (void *)response;
186 1 : assert_int_equal(spdm_response->header.request_response_code,
187 : SPDM_ERROR);
188 1 : assert_int_equal(spdm_response->header.param1,
189 : SPDM_ERROR_CODE_REQUEST_RESYNCH);
190 1 : assert_int_equal(spdm_response->header.param2, 0);
191 1 : assert_int_equal(spdm_context->response_state,
192 : LIBSPDM_RESPONSE_STATE_NEED_RESYNC);
193 1 : }
194 :
195 : #if LIBSPDM_RESPOND_IF_READY_SUPPORT
196 : /**
197 : * Test 5: receives a valid GET_DIGESTS request message from Requester, but Responder cannot produce the response message in time
198 : * Expected Behavior: produces an ERROR response message with error code = ResponseNotReady
199 : **/
200 1 : static void rsp_digests_case5(void **state)
201 : {
202 : libspdm_return_t status;
203 : libspdm_test_context_t *spdm_test_context;
204 : libspdm_context_t *spdm_context;
205 : size_t response_size;
206 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
207 : spdm_digest_response_t *spdm_response;
208 : spdm_error_data_response_not_ready_t *error_data;
209 :
210 1 : spdm_test_context = *state;
211 1 : spdm_context = spdm_test_context->spdm_context;
212 1 : spdm_test_context->case_id = 0x5;
213 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
214 : SPDM_VERSION_NUMBER_SHIFT_BIT;
215 1 : spdm_context->response_state = LIBSPDM_RESPONSE_STATE_NOT_READY;
216 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
217 1 : spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
218 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
219 1 : spdm_context->local_context.local_cert_chain_provision[0] =
220 : m_libspdm_local_certificate_chain;
221 1 : spdm_context->local_context.local_cert_chain_provision_size[0] =
222 : sizeof(m_libspdm_local_certificate_chain);
223 1 : libspdm_set_mem(m_libspdm_local_certificate_chain,
224 : sizeof(m_libspdm_local_certificate_chain),
225 : (uint8_t)(0xFF));
226 :
227 1 : response_size = sizeof(response);
228 1 : status = libspdm_get_response_digests(spdm_context,
229 : m_libspdm_get_digests_request1_size,
230 : &m_libspdm_get_digests_request1,
231 : &response_size, response);
232 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
233 1 : assert_int_equal(response_size,
234 : sizeof(spdm_error_response_t) +
235 : sizeof(spdm_error_data_response_not_ready_t));
236 1 : spdm_response = (void *)response;
237 1 : error_data = (spdm_error_data_response_not_ready_t *)(spdm_response + 1);
238 1 : assert_int_equal(spdm_response->header.request_response_code,
239 : SPDM_ERROR);
240 1 : assert_int_equal(spdm_response->header.param1,
241 : SPDM_ERROR_CODE_RESPONSE_NOT_READY);
242 1 : assert_int_equal(spdm_response->header.param2, 0);
243 1 : assert_int_equal(spdm_context->response_state,
244 : LIBSPDM_RESPONSE_STATE_NOT_READY);
245 1 : assert_int_equal(error_data->request_code, SPDM_GET_DIGESTS);
246 1 : }
247 : #endif /* LIBSPDM_RESPOND_IF_READY_SUPPORT */
248 :
249 : /**
250 : * Test 6: receives a valid GET_DIGESTS request message from Requester, but connection_state equals to zero and makes the check fail,
251 : * meaning that steps GET_CAPABILITIES-CAPABILITIES and NEGOTIATE_ALGORITHMS-ALGORITHMS of the protocol were not previously completed
252 : * Expected Behavior: produces an ERROR response message with error code = UnexpectedRequest
253 : **/
254 1 : static void rsp_digests_case6(void **state)
255 : {
256 : libspdm_return_t status;
257 : libspdm_test_context_t *spdm_test_context;
258 : libspdm_context_t *spdm_context;
259 : size_t response_size;
260 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
261 : spdm_digest_response_t *spdm_response;
262 :
263 1 : spdm_test_context = *state;
264 1 : spdm_context = spdm_test_context->spdm_context;
265 1 : spdm_test_context->case_id = 0x6;
266 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
267 : SPDM_VERSION_NUMBER_SHIFT_BIT;
268 1 : spdm_context->response_state = LIBSPDM_RESPONSE_STATE_NORMAL;
269 1 : spdm_context->connection_info.connection_state =
270 : LIBSPDM_CONNECTION_STATE_NOT_STARTED;
271 1 : spdm_context->local_context.capability.flags |=
272 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
273 1 : spdm_context->connection_info.algorithm.base_hash_algo =
274 : m_libspdm_use_hash_algo;
275 1 : spdm_context->local_context.local_cert_chain_provision[0] =
276 : m_libspdm_local_certificate_chain;
277 1 : spdm_context->local_context.local_cert_chain_provision_size[0] =
278 : sizeof(m_libspdm_local_certificate_chain);
279 1 : libspdm_set_mem(m_libspdm_local_certificate_chain,
280 : sizeof(m_libspdm_local_certificate_chain),
281 : (uint8_t)(0xFF));
282 :
283 1 : response_size = sizeof(response);
284 1 : status = libspdm_get_response_digests(spdm_context,
285 : m_libspdm_get_digests_request1_size,
286 : &m_libspdm_get_digests_request1,
287 : &response_size, response);
288 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
289 1 : assert_int_equal(response_size, sizeof(spdm_error_response_t));
290 1 : spdm_response = (void *)response;
291 1 : assert_int_equal(spdm_response->header.request_response_code,
292 : SPDM_ERROR);
293 1 : assert_int_equal(spdm_response->header.param1,
294 : SPDM_ERROR_CODE_UNEXPECTED_REQUEST);
295 1 : assert_int_equal(spdm_response->header.param2, 0);
296 1 : }
297 :
298 : /**
299 : * Test 7: receives a valid GET_DIGESTS request message from Requester, but there is no local certificate chain, i.e. there is no digest to send
300 : * Expected Behavior: produces an ERROR response message with error code = Unspecified
301 : **/
302 1 : static void rsp_digests_case7(void **state)
303 : {
304 : libspdm_return_t status;
305 : libspdm_test_context_t *spdm_test_context;
306 : libspdm_context_t *spdm_context;
307 : size_t response_size;
308 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
309 : spdm_digest_response_t *spdm_response;
310 : size_t index;
311 :
312 1 : spdm_test_context = *state;
313 1 : spdm_context = spdm_test_context->spdm_context;
314 1 : spdm_test_context->case_id = 0x7;
315 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
316 : SPDM_VERSION_NUMBER_SHIFT_BIT;
317 1 : spdm_context->connection_info.connection_state =
318 : LIBSPDM_CONNECTION_STATE_NEGOTIATED;
319 1 : spdm_context->local_context.capability.flags |=
320 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
321 1 : spdm_context->connection_info.algorithm.base_hash_algo =
322 : m_libspdm_use_hash_algo;
323 :
324 9 : for (index = 0; index < SPDM_MAX_SLOT_COUNT; index++) {
325 8 : spdm_context->local_context.local_cert_chain_provision[index] =
326 : NULL;
327 : spdm_context->local_context
328 8 : .local_cert_chain_provision_size[index] = 0;
329 : }
330 :
331 1 : response_size = sizeof(response);
332 1 : libspdm_reset_message_b(spdm_context);
333 1 : status = libspdm_get_response_digests(spdm_context,
334 : m_libspdm_get_digests_request1_size,
335 : &m_libspdm_get_digests_request1,
336 : &response_size, response);
337 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
338 1 : assert_int_equal(response_size, sizeof(spdm_error_response_t));
339 1 : spdm_response = (void *)response;
340 1 : assert_int_equal(spdm_response->header.request_response_code,
341 : SPDM_ERROR);
342 1 : assert_int_equal(spdm_response->header.param1,
343 : SPDM_ERROR_CODE_UNSPECIFIED);
344 1 : assert_int_equal(spdm_response->header.param2, 0);
345 1 : }
346 :
347 : /**
348 : * Test 08: receives a valid GET_DIGESTS request message from Requester in a session
349 : * Expected Behavior: produces a valid DIGESTS response message
350 : **/
351 1 : static void rsp_digests_case8(void **state)
352 : {
353 : libspdm_return_t status;
354 : libspdm_test_context_t *spdm_test_context;
355 : libspdm_context_t *spdm_context;
356 : size_t response_size;
357 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
358 : spdm_digest_response_t *spdm_response;
359 : libspdm_session_info_t *session_info;
360 : uint32_t session_id;
361 :
362 1 : spdm_test_context = *state;
363 1 : spdm_context = spdm_test_context->spdm_context;
364 1 : spdm_test_context->case_id = 0x8;
365 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_10 <<
366 : SPDM_VERSION_NUMBER_SHIFT_BIT;
367 1 : spdm_context->connection_info.connection_state =
368 : LIBSPDM_CONNECTION_STATE_NEGOTIATED;
369 1 : spdm_context->local_context.capability.flags |=
370 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
371 1 : spdm_context->connection_info.algorithm.base_hash_algo =
372 : m_libspdm_use_hash_algo;
373 1 : spdm_context->local_context.local_cert_chain_provision[0] =
374 : m_libspdm_local_certificate_chain;
375 1 : spdm_context->local_context.local_cert_chain_provision_size[0] =
376 : sizeof(m_libspdm_local_certificate_chain);
377 :
378 1 : session_id = 0xFFFFFFFF;
379 1 : spdm_context->latest_session_id = session_id;
380 1 : spdm_context->last_spdm_request_session_id_valid = true;
381 1 : spdm_context->last_spdm_request_session_id = session_id;
382 1 : session_info = &spdm_context->session_info[0];
383 1 : libspdm_session_info_init(spdm_context, session_info, session_id,
384 : SECURED_SPDM_VERSION_11 << SPDM_VERSION_NUMBER_SHIFT_BIT, true);
385 1 : libspdm_secured_message_set_session_state(
386 : session_info->secured_message_context,
387 : LIBSPDM_SESSION_STATE_ESTABLISHED);
388 :
389 1 : libspdm_set_mem(m_libspdm_local_certificate_chain,
390 : sizeof(m_libspdm_local_certificate_chain),
391 : (uint8_t)(0xFF));
392 :
393 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
394 : session_info->session_transcript.message_m.buffer_size =
395 : session_info->session_transcript.message_m.max_buffer_size;
396 : #endif
397 :
398 1 : response_size = sizeof(response);
399 1 : status = libspdm_get_response_digests(spdm_context,
400 : m_libspdm_get_digests_request1_size,
401 : &m_libspdm_get_digests_request1,
402 : &response_size, response);
403 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
404 1 : assert_int_equal(
405 : response_size,
406 : sizeof(spdm_digest_response_t) +
407 : libspdm_get_hash_size(spdm_context->connection_info
408 : .algorithm.base_hash_algo));
409 1 : spdm_response = (void *)response;
410 1 : assert_int_equal(spdm_response->header.request_response_code,
411 : SPDM_DIGESTS);
412 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
413 : assert_int_equal(session_info->session_transcript.message_m.buffer_size,
414 : 0);
415 : #endif
416 1 : }
417 :
418 : /**
419 : * Test 9: receives a valid GET_DIGESTS request message from Requester , set multi_key_conn_rsp to check if it responds correctly
420 : * Expected Behavior: produces a valid DIGESTS response message
421 : **/
422 1 : static void rsp_digests_case9(void **state)
423 : {
424 : libspdm_return_t status;
425 : libspdm_test_context_t *spdm_test_context;
426 : libspdm_context_t *spdm_context;
427 : size_t response_size;
428 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
429 : spdm_digest_response_t *spdm_response;
430 :
431 1 : spdm_test_context = *state;
432 1 : spdm_context = spdm_test_context->spdm_context;
433 1 : spdm_test_context->case_id = 0x9;
434 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_13 <<
435 : SPDM_VERSION_NUMBER_SHIFT_BIT;
436 1 : spdm_context->connection_info.connection_state =
437 : LIBSPDM_CONNECTION_STATE_NEGOTIATED;
438 1 : spdm_context->local_context.capability.flags = 0;
439 1 : spdm_context->last_spdm_request_session_id_valid = false;
440 1 : spdm_context->local_context.capability.flags |=
441 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
442 1 : spdm_context->connection_info.algorithm.base_hash_algo =
443 : m_libspdm_use_hash_algo;
444 1 : spdm_context->local_context.local_cert_chain_provision[0] =
445 : m_libspdm_local_certificate_chain;
446 1 : spdm_context->local_context.local_cert_chain_provision_size[0] =
447 : sizeof(m_libspdm_local_certificate_chain);
448 1 : libspdm_set_mem(m_libspdm_local_certificate_chain,
449 : sizeof(m_libspdm_local_certificate_chain),
450 : (uint8_t)(0xFF));
451 :
452 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
453 : spdm_context->transcript.message_m.buffer_size =
454 : spdm_context->transcript.message_m.max_buffer_size;
455 : #endif
456 : /* Sub Case 1: Set multi_key_conn_rsp to true*/
457 1 : spdm_context->connection_info.multi_key_conn_rsp = true;
458 1 : libspdm_reset_message_d(spdm_context);
459 :
460 1 : response_size = sizeof(response);
461 1 : status = libspdm_get_response_digests(spdm_context,
462 : m_libspdm_get_digests_request2_size,
463 : &m_libspdm_get_digests_request2,
464 : &response_size, response);
465 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
466 1 : assert_int_equal(
467 : response_size,
468 : sizeof(spdm_digest_response_t) + sizeof(spdm_key_pair_id_t) +
469 : sizeof(spdm_certificate_info_t) +
470 : sizeof(spdm_key_usage_bit_mask_t) +
471 : libspdm_get_hash_size(spdm_context->connection_info
472 : .algorithm.base_hash_algo));
473 1 : spdm_response = (void *)response;
474 1 : assert_int_equal(spdm_response->header.request_response_code,
475 : SPDM_DIGESTS);
476 1 : assert_int_equal(spdm_context->transcript.message_d.buffer_size,
477 : sizeof(spdm_digest_response_t) +
478 : sizeof(spdm_key_pair_id_t) +
479 : sizeof(spdm_certificate_info_t) +
480 : sizeof(spdm_key_usage_bit_mask_t) +
481 : libspdm_get_hash_size(spdm_context->connection_info.algorithm.base_hash_algo));
482 :
483 : /* Sub Case 2: Set multi_key_conn_rsp to false*/
484 1 : spdm_context->connection_info.multi_key_conn_rsp = false;
485 1 : libspdm_reset_message_d(spdm_context);
486 :
487 1 : response_size = sizeof(response);
488 1 : status = libspdm_get_response_digests(spdm_context,
489 : m_libspdm_get_digests_request2_size,
490 : &m_libspdm_get_digests_request2,
491 : &response_size, response);
492 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
493 1 : assert_int_equal(
494 : response_size,
495 : sizeof(spdm_digest_response_t) +
496 : libspdm_get_hash_size(spdm_context->connection_info
497 : .algorithm.base_hash_algo));
498 1 : spdm_response = (void *)response;
499 1 : assert_int_equal(spdm_response->header.request_response_code,
500 : SPDM_DIGESTS);
501 1 : assert_int_equal(spdm_context->transcript.message_d.buffer_size, 0);
502 1 : }
503 :
504 : /**
505 : * Test10: a response message is successfully sent ,
506 : * Check KeyPairID CertificateInfo and KeyUsageMask
507 : * Expected Behavior: requester returns the status LIBSPDM_STATUS_SUCCESS
508 : **/
509 1 : static void rsp_digests_case10(void **state)
510 : {
511 : libspdm_return_t status;
512 : libspdm_test_context_t *spdm_test_context;
513 : libspdm_context_t *spdm_context;
514 : size_t response_size;
515 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
516 : spdm_digest_response_t *spdm_response;
517 : uint8_t *digest;
518 : spdm_key_pair_id_t *key_pair_id;
519 : spdm_certificate_info_t *cert_info;
520 : spdm_key_usage_bit_mask_t *key_usage_bit_mask;
521 : uint32_t hash_size;
522 : uint8_t slot_count;
523 : size_t additional_size;
524 :
525 1 : slot_count = SPDM_MAX_SLOT_COUNT;
526 1 : additional_size = sizeof(spdm_key_pair_id_t) + sizeof(spdm_certificate_info_t) +
527 : sizeof(spdm_key_usage_bit_mask_t);
528 1 : hash_size = libspdm_get_hash_size(m_libspdm_use_hash_algo);
529 :
530 1 : spdm_test_context = *state;
531 1 : spdm_context = spdm_test_context->spdm_context;
532 1 : spdm_test_context->case_id = 0x0A;
533 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_13 <<
534 : SPDM_VERSION_NUMBER_SHIFT_BIT;
535 1 : spdm_context->connection_info.connection_state =
536 : LIBSPDM_CONNECTION_STATE_NEGOTIATED;
537 1 : spdm_context->local_context.capability.flags = 0;
538 1 : spdm_context->last_spdm_request_session_id_valid = false;
539 1 : spdm_context->local_context.capability.flags |=
540 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
541 1 : spdm_context->connection_info.algorithm.base_hash_algo =
542 : m_libspdm_use_hash_algo;
543 :
544 9 : for (uint8_t index = 0; index < SPDM_MAX_SLOT_COUNT; index++) {
545 8 : spdm_context->local_context.local_cert_chain_provision[index] =
546 8 : &m_libspdm_local_certificate_chain[hash_size *index];
547 8 : spdm_context->local_context.local_cert_chain_provision_size[index] = hash_size;
548 : }
549 :
550 1 : libspdm_set_mem(m_libspdm_local_certificate_chain,
551 : sizeof(m_libspdm_local_certificate_chain),
552 : (uint8_t)(0xFF));
553 :
554 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
555 : spdm_context->transcript.message_m.buffer_size =
556 : spdm_context->transcript.message_m.max_buffer_size;
557 : #endif
558 1 : spdm_context->connection_info.multi_key_conn_rsp = true;
559 1 : libspdm_reset_message_d(spdm_context);
560 :
561 1 : response_size = sizeof(response);
562 1 : status = libspdm_get_response_digests(spdm_context,
563 : m_libspdm_get_digests_request2_size,
564 : &m_libspdm_get_digests_request2,
565 : &response_size, response);
566 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
567 1 : assert_int_equal(response_size,
568 : sizeof(spdm_digest_response_t) +
569 : (hash_size + additional_size) *
570 : slot_count);
571 :
572 1 : spdm_response = (void *)response;
573 1 : assert_int_equal(spdm_response->header.request_response_code,
574 : SPDM_DIGESTS);
575 1 : assert_int_equal(spdm_context->transcript.message_d.buffer_size,
576 : sizeof(spdm_digest_response_t) + (hash_size + additional_size) * slot_count);
577 :
578 1 : digest = (void *)(spdm_response + 1);
579 1 : libspdm_zero_mem (digest, hash_size * slot_count);
580 1 : key_pair_id = (spdm_key_pair_id_t *)((uint8_t *)digest + (hash_size * slot_count));
581 1 : cert_info = (spdm_certificate_info_t *)((uint8_t *)key_pair_id +
582 1 : sizeof(spdm_key_pair_id_t) * slot_count);
583 1 : key_usage_bit_mask = (spdm_key_usage_bit_mask_t *)((uint8_t *)cert_info +
584 1 : sizeof(spdm_certificate_info_t) *
585 : slot_count);
586 9 : for (uint8_t index = 0; index < SPDM_MAX_SLOT_COUNT; index++) {
587 8 : assert_memory_equal((void *)&key_pair_id[index],
588 : (void *)&spdm_context->local_context.local_key_pair_id[index],
589 : sizeof(spdm_key_pair_id_t));
590 8 : assert_memory_equal((void *)&cert_info[index],
591 : (void *)&spdm_context->local_context.local_cert_info[index],
592 : sizeof(spdm_certificate_info_t));
593 8 : assert_memory_equal((void *)&key_usage_bit_mask[index],
594 : (void *)&spdm_context->local_context.local_key_usage_bit_mask[index],
595 : sizeof(spdm_key_usage_bit_mask_t));
596 : }
597 1 : }
598 :
599 : /**
600 : * Test 11: GET_DIGESTS is sent when at least one certificate slot is in the reset state.
601 : * Expected Behavior: Responder responds with ResetRequired.
602 : **/
603 1 : static void rsp_digests_case11(void **state)
604 : {
605 : libspdm_return_t status;
606 : libspdm_test_context_t *spdm_test_context;
607 : libspdm_context_t *spdm_context;
608 : size_t response_size;
609 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
610 : spdm_error_response_t *spdm_response;
611 :
612 1 : spdm_test_context = *state;
613 1 : spdm_context = spdm_test_context->spdm_context;
614 1 : spdm_test_context->case_id = 0x0B;
615 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_13 <<
616 : SPDM_VERSION_NUMBER_SHIFT_BIT;
617 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
618 1 : spdm_context->local_context.capability.flags = 0;
619 1 : spdm_context->last_spdm_request_session_id_valid = false;
620 1 : spdm_context->local_context.capability.flags |=
621 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
622 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
623 :
624 : /* Responder needs to be reset before DIGESTS can be successful. */
625 1 : spdm_context->local_context.cert_slot_reset_mask = 0x1a;
626 :
627 1 : spdm_context->connection_info.multi_key_conn_rsp = true;
628 1 : libspdm_reset_message_d(spdm_context);
629 :
630 1 : response_size = sizeof(response);
631 1 : status = libspdm_get_response_digests(spdm_context,
632 : m_libspdm_get_digests_request2_size,
633 : &m_libspdm_get_digests_request2,
634 : &response_size, response);
635 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
636 1 : assert_int_equal(response_size, sizeof(spdm_error_response_t));
637 1 : spdm_response = (void *)response;
638 1 : assert_int_equal(spdm_response->header.request_response_code, SPDM_ERROR);
639 1 : assert_int_equal(spdm_response->header.param1, SPDM_ERROR_CODE_RESET_REQUIRED);
640 1 : assert_int_equal(spdm_response->header.param2, 0);
641 1 : }
642 :
643 1 : int libspdm_rsp_digests_test(void)
644 : {
645 1 : const struct CMUnitTest test_cases[] = {
646 : /* Success Case*/
647 : cmocka_unit_test(rsp_digests_case1),
648 : /* Can be populated with new test.*/
649 : cmocka_unit_test(rsp_digests_case2),
650 : /* response_state: SPDM_RESPONSE_STATE_BUSY*/
651 : cmocka_unit_test(rsp_digests_case3),
652 : /* response_state: LIBSPDM_RESPONSE_STATE_NEED_RESYNC*/
653 : cmocka_unit_test(rsp_digests_case4),
654 : #if LIBSPDM_RESPOND_IF_READY_SUPPORT
655 : /* response_state: LIBSPDM_RESPONSE_STATE_NOT_READY*/
656 : cmocka_unit_test(rsp_digests_case5),
657 : #endif /* LIBSPDM_RESPOND_IF_READY_SUPPORT */
658 : /* connection_state Check*/
659 : cmocka_unit_test(rsp_digests_case6),
660 : /* No digest to send*/
661 : cmocka_unit_test(rsp_digests_case7),
662 : /* Success Case in a session*/
663 : cmocka_unit_test(rsp_digests_case8),
664 : /* Set multi_key_conn_rsp to check if it responds correctly */
665 : cmocka_unit_test(rsp_digests_case9),
666 : /* Check KeyPairID CertificateInfo and KeyUsageMask*/
667 : cmocka_unit_test(rsp_digests_case10),
668 : cmocka_unit_test(rsp_digests_case11),
669 : };
670 :
671 1 : libspdm_test_context_t test_context = {
672 : LIBSPDM_TEST_CONTEXT_VERSION,
673 : false,
674 : };
675 :
676 1 : libspdm_setup_test_context(&test_context);
677 :
678 1 : return cmocka_run_group_tests(test_cases,
679 : libspdm_unit_test_group_setup,
680 : libspdm_unit_test_group_teardown);
681 : }
682 :
683 : #endif /* LIBSPDM_ENABLE_CAPABILITY_CERT_CAP*/
|