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