Line data Source code
1 : /**
2 : * Copyright Notice:
3 : * Copyright 2021-2022 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 : void libspdm_test_responder_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 : void libspdm_test_responder_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 : void libspdm_test_responder_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 : void libspdm_test_responder_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 : void libspdm_test_responder_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 : void libspdm_test_responder_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 : void libspdm_test_responder_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 : void libspdm_test_responder_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, true);
384 1 : libspdm_secured_message_set_session_state(
385 : session_info->secured_message_context,
386 : LIBSPDM_SESSION_STATE_ESTABLISHED);
387 :
388 1 : libspdm_set_mem(m_libspdm_local_certificate_chain,
389 : sizeof(m_libspdm_local_certificate_chain),
390 : (uint8_t)(0xFF));
391 :
392 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
393 : session_info->session_transcript.message_m.buffer_size =
394 : session_info->session_transcript.message_m.max_buffer_size;
395 : #endif
396 :
397 1 : response_size = sizeof(response);
398 1 : status = libspdm_get_response_digests(spdm_context,
399 : m_libspdm_get_digests_request1_size,
400 : &m_libspdm_get_digests_request1,
401 : &response_size, response);
402 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
403 1 : assert_int_equal(
404 : response_size,
405 : sizeof(spdm_digest_response_t) +
406 : libspdm_get_hash_size(spdm_context->connection_info
407 : .algorithm.base_hash_algo));
408 1 : spdm_response = (void *)response;
409 1 : assert_int_equal(spdm_response->header.request_response_code,
410 : SPDM_DIGESTS);
411 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
412 : assert_int_equal(session_info->session_transcript.message_m.buffer_size,
413 : 0);
414 : #endif
415 1 : }
416 :
417 : /**
418 : * Test 9: receives a valid GET_DIGESTS request message from Requester , set multi_key_conn_rsp to check if it responds correctly
419 : * Expected Behavior: produces a valid DIGESTS response message
420 : **/
421 1 : void libspdm_test_responder_digests_case9(void **state)
422 : {
423 : libspdm_return_t status;
424 : libspdm_test_context_t *spdm_test_context;
425 : libspdm_context_t *spdm_context;
426 : size_t response_size;
427 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
428 : spdm_digest_response_t *spdm_response;
429 :
430 1 : spdm_test_context = *state;
431 1 : spdm_context = spdm_test_context->spdm_context;
432 1 : spdm_test_context->case_id = 0x9;
433 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_13 <<
434 : SPDM_VERSION_NUMBER_SHIFT_BIT;
435 1 : spdm_context->connection_info.connection_state =
436 : LIBSPDM_CONNECTION_STATE_NEGOTIATED;
437 1 : spdm_context->local_context.capability.flags = 0;
438 1 : spdm_context->last_spdm_request_session_id_valid = false;
439 1 : spdm_context->local_context.capability.flags |=
440 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
441 1 : spdm_context->connection_info.algorithm.base_hash_algo =
442 : m_libspdm_use_hash_algo;
443 1 : spdm_context->local_context.local_cert_chain_provision[0] =
444 : m_libspdm_local_certificate_chain;
445 1 : spdm_context->local_context.local_cert_chain_provision_size[0] =
446 : sizeof(m_libspdm_local_certificate_chain);
447 1 : libspdm_set_mem(m_libspdm_local_certificate_chain,
448 : sizeof(m_libspdm_local_certificate_chain),
449 : (uint8_t)(0xFF));
450 :
451 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
452 : spdm_context->transcript.message_m.buffer_size =
453 : spdm_context->transcript.message_m.max_buffer_size;
454 : #endif
455 : /* Sub Case 1: Set multi_key_conn_rsp to true*/
456 1 : spdm_context->connection_info.multi_key_conn_rsp = true;
457 1 : libspdm_reset_message_d(spdm_context);
458 :
459 1 : response_size = sizeof(response);
460 1 : status = libspdm_get_response_digests(spdm_context,
461 : m_libspdm_get_digests_request2_size,
462 : &m_libspdm_get_digests_request2,
463 : &response_size, response);
464 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
465 1 : assert_int_equal(
466 : response_size,
467 : sizeof(spdm_digest_response_t) + sizeof(spdm_key_pair_id_t) +
468 : sizeof(spdm_certificate_info_t) +
469 : sizeof(spdm_key_usage_bit_mask_t) +
470 : libspdm_get_hash_size(spdm_context->connection_info
471 : .algorithm.base_hash_algo));
472 1 : spdm_response = (void *)response;
473 1 : assert_int_equal(spdm_response->header.request_response_code,
474 : SPDM_DIGESTS);
475 1 : assert_int_equal(spdm_context->transcript.message_d.buffer_size,
476 : sizeof(spdm_digest_response_t) +
477 : sizeof(spdm_key_pair_id_t) +
478 : sizeof(spdm_certificate_info_t) +
479 : sizeof(spdm_key_usage_bit_mask_t) +
480 : libspdm_get_hash_size(spdm_context->connection_info.algorithm.base_hash_algo));
481 :
482 : /* Sub Case 2: Set multi_key_conn_rsp to false*/
483 1 : spdm_context->connection_info.multi_key_conn_rsp = false;
484 1 : libspdm_reset_message_d(spdm_context);
485 :
486 1 : response_size = sizeof(response);
487 1 : status = libspdm_get_response_digests(spdm_context,
488 : m_libspdm_get_digests_request2_size,
489 : &m_libspdm_get_digests_request2,
490 : &response_size, response);
491 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
492 1 : assert_int_equal(
493 : response_size,
494 : sizeof(spdm_digest_response_t) +
495 : libspdm_get_hash_size(spdm_context->connection_info
496 : .algorithm.base_hash_algo));
497 1 : spdm_response = (void *)response;
498 1 : assert_int_equal(spdm_response->header.request_response_code,
499 : SPDM_DIGESTS);
500 1 : assert_int_equal(spdm_context->transcript.message_d.buffer_size, 0);
501 1 : }
502 :
503 : /**
504 : * Test10: a response message is successfully sent ,
505 : * Check KeyPairID CertificateInfo and KeyUsageMask
506 : * Expected Behavior: requester returns the status LIBSPDM_STATUS_SUCCESS
507 : **/
508 1 : void libspdm_test_responder_digests_case10(void **state)
509 : {
510 : libspdm_return_t status;
511 : libspdm_test_context_t *spdm_test_context;
512 : libspdm_context_t *spdm_context;
513 : size_t response_size;
514 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
515 : spdm_digest_response_t *spdm_response;
516 : uint8_t *digest;
517 : spdm_key_pair_id_t *key_pair_id;
518 : spdm_certificate_info_t *cert_info;
519 : spdm_key_usage_bit_mask_t *key_usage_bit_mask;
520 : uint32_t hash_size;
521 : uint8_t slot_count;
522 : size_t additional_size;
523 :
524 1 : slot_count = SPDM_MAX_SLOT_COUNT;
525 1 : additional_size = sizeof(spdm_key_pair_id_t) + sizeof(spdm_certificate_info_t) +
526 : sizeof(spdm_key_usage_bit_mask_t);
527 1 : hash_size = libspdm_get_hash_size(m_libspdm_use_hash_algo);
528 :
529 1 : spdm_test_context = *state;
530 1 : spdm_context = spdm_test_context->spdm_context;
531 1 : spdm_test_context->case_id = 0x0A;
532 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_13 <<
533 : SPDM_VERSION_NUMBER_SHIFT_BIT;
534 1 : spdm_context->connection_info.connection_state =
535 : LIBSPDM_CONNECTION_STATE_NEGOTIATED;
536 1 : spdm_context->local_context.capability.flags = 0;
537 1 : spdm_context->last_spdm_request_session_id_valid = false;
538 1 : spdm_context->local_context.capability.flags |=
539 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
540 1 : spdm_context->connection_info.algorithm.base_hash_algo =
541 : m_libspdm_use_hash_algo;
542 :
543 9 : for (uint8_t index = 0; index < SPDM_MAX_SLOT_COUNT; index++) {
544 8 : spdm_context->local_context.local_cert_chain_provision[index] =
545 8 : &m_libspdm_local_certificate_chain[hash_size *index];
546 8 : spdm_context->local_context.local_cert_chain_provision_size[index] = hash_size;
547 : }
548 :
549 1 : libspdm_set_mem(m_libspdm_local_certificate_chain,
550 : sizeof(m_libspdm_local_certificate_chain),
551 : (uint8_t)(0xFF));
552 :
553 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
554 : spdm_context->transcript.message_m.buffer_size =
555 : spdm_context->transcript.message_m.max_buffer_size;
556 : #endif
557 1 : spdm_context->connection_info.multi_key_conn_rsp = true;
558 1 : libspdm_reset_message_d(spdm_context);
559 :
560 1 : response_size = sizeof(response);
561 1 : status = libspdm_get_response_digests(spdm_context,
562 : m_libspdm_get_digests_request2_size,
563 : &m_libspdm_get_digests_request2,
564 : &response_size, response);
565 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
566 1 : assert_int_equal(response_size,
567 : sizeof(spdm_digest_response_t) +
568 : (hash_size + additional_size) *
569 : slot_count);
570 :
571 1 : spdm_response = (void *)response;
572 1 : assert_int_equal(spdm_response->header.request_response_code,
573 : SPDM_DIGESTS);
574 1 : assert_int_equal(spdm_context->transcript.message_d.buffer_size,
575 : sizeof(spdm_digest_response_t) + (hash_size + additional_size) * slot_count);
576 :
577 1 : digest = (void *)(spdm_response + 1);
578 1 : libspdm_zero_mem (digest, hash_size * slot_count);
579 1 : key_pair_id = (spdm_key_pair_id_t *)((uint8_t *)digest + (hash_size * slot_count));
580 1 : cert_info = (spdm_certificate_info_t *)((uint8_t *)key_pair_id +
581 1 : sizeof(spdm_key_pair_id_t) * slot_count);
582 1 : key_usage_bit_mask = (spdm_key_usage_bit_mask_t *)((uint8_t *)cert_info +
583 1 : sizeof(spdm_certificate_info_t) *
584 : slot_count);
585 9 : for (uint8_t index = 0; index < SPDM_MAX_SLOT_COUNT; index++) {
586 8 : assert_memory_equal((void *)&key_pair_id[index],
587 : (void *)&spdm_context->local_context.local_key_pair_id[index],
588 : sizeof(spdm_key_pair_id_t));
589 8 : assert_memory_equal((void *)&cert_info[index],
590 : (void *)&spdm_context->local_context.local_cert_info[index],
591 : sizeof(spdm_certificate_info_t));
592 8 : assert_memory_equal((void *)&key_usage_bit_mask[index],
593 : (void *)&spdm_context->local_context.local_key_usage_bit_mask[index],
594 : sizeof(spdm_key_usage_bit_mask_t));
595 : }
596 1 : }
597 :
598 : /**
599 : * Test 11: GET_DIGESTS is sent when at least one certificate slot is in the reset state.
600 : * Expected Behavior: Responder responds with ResetRequired.
601 : **/
602 1 : void libspdm_test_responder_digests_case11(void **state)
603 : {
604 : libspdm_return_t status;
605 : libspdm_test_context_t *spdm_test_context;
606 : libspdm_context_t *spdm_context;
607 : size_t response_size;
608 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
609 : spdm_error_response_t *spdm_response;
610 :
611 1 : spdm_test_context = *state;
612 1 : spdm_context = spdm_test_context->spdm_context;
613 1 : spdm_test_context->case_id = 0x0B;
614 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_13 <<
615 : SPDM_VERSION_NUMBER_SHIFT_BIT;
616 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
617 1 : spdm_context->local_context.capability.flags = 0;
618 1 : spdm_context->last_spdm_request_session_id_valid = false;
619 1 : spdm_context->local_context.capability.flags |=
620 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
621 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
622 :
623 : /* Responder needs to be reset before DIGESTS can be successful. */
624 1 : spdm_context->local_context.cert_slot_reset_mask = 0x1a;
625 :
626 1 : spdm_context->connection_info.multi_key_conn_rsp = true;
627 1 : libspdm_reset_message_d(spdm_context);
628 :
629 1 : response_size = sizeof(response);
630 1 : status = libspdm_get_response_digests(spdm_context,
631 : m_libspdm_get_digests_request2_size,
632 : &m_libspdm_get_digests_request2,
633 : &response_size, response);
634 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
635 1 : assert_int_equal(response_size, sizeof(spdm_error_response_t));
636 1 : spdm_response = (void *)response;
637 1 : assert_int_equal(spdm_response->header.request_response_code, SPDM_ERROR);
638 1 : assert_int_equal(spdm_response->header.param1, SPDM_ERROR_CODE_RESET_REQUIRED);
639 1 : assert_int_equal(spdm_response->header.param2, 0);
640 1 : }
641 :
642 1 : int libspdm_responder_digests_test_main(void)
643 : {
644 1 : const struct CMUnitTest spdm_responder_digests_tests[] = {
645 : /* Success Case*/
646 : cmocka_unit_test(libspdm_test_responder_digests_case1),
647 : /* Can be populated with new test.*/
648 : cmocka_unit_test(libspdm_test_responder_digests_case2),
649 : /* response_state: SPDM_RESPONSE_STATE_BUSY*/
650 : cmocka_unit_test(libspdm_test_responder_digests_case3),
651 : /* response_state: LIBSPDM_RESPONSE_STATE_NEED_RESYNC*/
652 : cmocka_unit_test(libspdm_test_responder_digests_case4),
653 : #if LIBSPDM_RESPOND_IF_READY_SUPPORT
654 : /* response_state: LIBSPDM_RESPONSE_STATE_NOT_READY*/
655 : cmocka_unit_test(libspdm_test_responder_digests_case5),
656 : #endif /* LIBSPDM_RESPOND_IF_READY_SUPPORT */
657 : /* connection_state Check*/
658 : cmocka_unit_test(libspdm_test_responder_digests_case6),
659 : /* No digest to send*/
660 : cmocka_unit_test(libspdm_test_responder_digests_case7),
661 : /* Success Case in a session*/
662 : cmocka_unit_test(libspdm_test_responder_digests_case8),
663 : /* Set multi_key_conn_rsp to check if it responds correctly */
664 : cmocka_unit_test(libspdm_test_responder_digests_case9),
665 : /* Check KeyPairID CertificateInfo and KeyUsageMask*/
666 : cmocka_unit_test(libspdm_test_responder_digests_case10),
667 : cmocka_unit_test(libspdm_test_responder_digests_case11),
668 : };
669 :
670 1 : libspdm_test_context_t test_context = {
671 : LIBSPDM_TEST_CONTEXT_VERSION,
672 : false,
673 : };
674 :
675 1 : libspdm_setup_test_context(&test_context);
676 :
677 1 : return cmocka_run_group_tests(spdm_responder_digests_tests,
678 : libspdm_unit_test_group_setup,
679 : libspdm_unit_test_group_teardown);
680 : }
681 :
682 : #endif /* LIBSPDM_ENABLE_CAPABILITY_CERT_CAP*/
|