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 : #include "internal/libspdm_secured_message_lib.h"
10 :
11 : #if (LIBSPDM_ENABLE_CAPABILITY_KEY_EX_CAP) || (LIBSPDM_ENABLE_CAPABILITY_PSK_CAP)
12 :
13 : spdm_heartbeat_request_t m_libspdm_heartbeat_request1 = {
14 : { SPDM_MESSAGE_VERSION_11, SPDM_HEARTBEAT, 0, 0 }
15 : };
16 : size_t m_libspdm_heartbeat_request1_size = sizeof(m_libspdm_heartbeat_request1);
17 :
18 : spdm_heartbeat_request_t m_libspdm_heartbeat_request2 = {
19 : { SPDM_MESSAGE_VERSION_11, SPDM_HEARTBEAT, 0, 0 }
20 : };
21 : size_t m_libspdm_heartbeat_request2_size = LIBSPDM_MAX_SPDM_MSG_SIZE;
22 :
23 :
24 1 : static void rsp_heartbeat_ack_case1(void **state)
25 : {
26 : libspdm_return_t status;
27 : libspdm_test_context_t *spdm_test_context;
28 : libspdm_context_t *spdm_context;
29 : size_t response_size;
30 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
31 : spdm_heartbeat_response_t *spdm_response;
32 : void *data1;
33 : size_t data_size1;
34 : libspdm_session_info_t *session_info;
35 : uint32_t session_id;
36 :
37 1 : spdm_test_context = *state;
38 1 : spdm_context = spdm_test_context->spdm_context;
39 1 : spdm_test_context->case_id = 0x1;
40 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_11 <<
41 : SPDM_VERSION_NUMBER_SHIFT_BIT;
42 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
43 1 : spdm_context->connection_info.capability.flags |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_HBEAT_CAP;
44 1 : spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_HBEAT_CAP;
45 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
46 1 : spdm_context->connection_info.algorithm.base_asym_algo = m_libspdm_use_asym_algo;
47 1 : spdm_context->connection_info.algorithm.measurement_spec = m_libspdm_use_measurement_spec;
48 1 : spdm_context->connection_info.algorithm.measurement_hash_algo =
49 : m_libspdm_use_measurement_hash_algo;
50 1 : spdm_context->connection_info.algorithm.dhe_named_group = m_libspdm_use_dhe_algo;
51 1 : spdm_context->connection_info.algorithm.aead_cipher_suite = m_libspdm_use_aead_algo;
52 1 : libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
53 : m_libspdm_use_asym_algo, &data1,
54 : &data_size1, NULL, NULL);
55 1 : spdm_context->local_context.local_cert_chain_provision[0] = data1;
56 1 : spdm_context->local_context.local_cert_chain_provision_size[0] = data_size1;
57 :
58 1 : libspdm_reset_message_a(spdm_context);
59 :
60 1 : session_id = 0xFFFFFFFF;
61 1 : spdm_context->latest_session_id = session_id;
62 1 : spdm_context->last_spdm_request_session_id_valid = true;
63 1 : spdm_context->last_spdm_request_session_id = session_id;
64 1 : session_info = &spdm_context->session_info[0];
65 1 : libspdm_session_info_init(spdm_context, session_info, session_id,
66 : SECURED_SPDM_VERSION_11 << SPDM_VERSION_NUMBER_SHIFT_BIT, true);
67 1 : libspdm_secured_message_set_session_state(
68 : session_info->secured_message_context,
69 : LIBSPDM_SESSION_STATE_ESTABLISHED);
70 1 : session_info->heartbeat_period = 1;
71 :
72 1 : response_size = sizeof(response);
73 1 : status = libspdm_get_response_heartbeat(spdm_context,
74 : m_libspdm_heartbeat_request1_size,
75 : &m_libspdm_heartbeat_request1,
76 : &response_size, response);
77 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
78 1 : assert_int_equal(response_size, sizeof(spdm_heartbeat_response_t));
79 1 : spdm_response = (void *)response;
80 1 : assert_int_equal(spdm_response->header.request_response_code, SPDM_HEARTBEAT_ACK);
81 1 : free(data1);
82 1 : }
83 :
84 1 : static void rsp_heartbeat_ack_case2(void **state)
85 : {
86 : libspdm_return_t status;
87 : libspdm_test_context_t *spdm_test_context;
88 : libspdm_context_t *spdm_context;
89 : size_t response_size;
90 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
91 : spdm_heartbeat_response_t *spdm_response;
92 : void *data1;
93 : size_t data_size1;
94 : libspdm_session_info_t *session_info;
95 : uint32_t session_id;
96 :
97 1 : spdm_test_context = *state;
98 1 : spdm_context = spdm_test_context->spdm_context;
99 1 : spdm_test_context->case_id = 0x2;
100 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_11 <<
101 : SPDM_VERSION_NUMBER_SHIFT_BIT;
102 1 : spdm_context->connection_info.connection_state =
103 : LIBSPDM_CONNECTION_STATE_NEGOTIATED;
104 1 : spdm_context->connection_info.capability.flags |=
105 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_HBEAT_CAP;
106 1 : spdm_context->local_context.capability.flags |=
107 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_HBEAT_CAP;
108 1 : spdm_context->connection_info.algorithm.base_hash_algo =
109 : m_libspdm_use_hash_algo;
110 1 : spdm_context->connection_info.algorithm.base_asym_algo =
111 : m_libspdm_use_asym_algo;
112 1 : spdm_context->connection_info.algorithm.measurement_spec =
113 : m_libspdm_use_measurement_spec;
114 1 : spdm_context->connection_info.algorithm.measurement_hash_algo =
115 : m_libspdm_use_measurement_hash_algo;
116 1 : spdm_context->connection_info.algorithm.dhe_named_group =
117 : m_libspdm_use_dhe_algo;
118 1 : spdm_context->connection_info.algorithm.aead_cipher_suite =
119 : m_libspdm_use_aead_algo;
120 1 : libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
121 : m_libspdm_use_asym_algo, &data1,
122 : &data_size1, NULL, NULL);
123 1 : spdm_context->local_context.local_cert_chain_provision[0] = data1;
124 1 : spdm_context->local_context.local_cert_chain_provision_size[0] =
125 : data_size1;
126 :
127 1 : libspdm_reset_message_a(spdm_context);
128 :
129 1 : session_id = 0xFFFFFFFF;
130 1 : spdm_context->latest_session_id = session_id;
131 1 : spdm_context->last_spdm_request_session_id_valid = true;
132 1 : spdm_context->last_spdm_request_session_id = session_id;
133 1 : session_info = &spdm_context->session_info[0];
134 1 : libspdm_session_info_init(spdm_context, session_info, session_id,
135 : SECURED_SPDM_VERSION_11 << SPDM_VERSION_NUMBER_SHIFT_BIT, true);
136 1 : libspdm_secured_message_set_session_state(
137 : session_info->secured_message_context,
138 : LIBSPDM_SESSION_STATE_ESTABLISHED);
139 :
140 1 : response_size = sizeof(response);
141 1 : status = libspdm_get_response_heartbeat(spdm_context,
142 : m_libspdm_heartbeat_request2_size,
143 : &m_libspdm_heartbeat_request2,
144 : &response_size, response);
145 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
146 1 : assert_int_equal(response_size, sizeof(spdm_error_response_t));
147 1 : spdm_response = (void *)response;
148 1 : assert_int_equal(spdm_response->header.request_response_code,
149 : SPDM_ERROR);
150 1 : assert_int_equal(spdm_response->header.param1,
151 : SPDM_ERROR_CODE_INVALID_REQUEST);
152 1 : assert_int_equal(spdm_response->header.param2, 0);
153 1 : free(data1);
154 1 : }
155 :
156 1 : static void rsp_heartbeat_ack_case3(void **state)
157 : {
158 : libspdm_return_t status;
159 : libspdm_test_context_t *spdm_test_context;
160 : libspdm_context_t *spdm_context;
161 : size_t response_size;
162 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
163 : spdm_heartbeat_response_t *spdm_response;
164 : void *data1;
165 : size_t data_size1;
166 : libspdm_session_info_t *session_info;
167 : uint32_t session_id;
168 :
169 1 : spdm_test_context = *state;
170 1 : spdm_context = spdm_test_context->spdm_context;
171 1 : spdm_test_context->case_id = 0x3;
172 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_11 <<
173 : SPDM_VERSION_NUMBER_SHIFT_BIT;
174 1 : spdm_context->response_state = LIBSPDM_RESPONSE_STATE_BUSY;
175 1 : spdm_context->connection_info.connection_state =
176 : LIBSPDM_CONNECTION_STATE_NEGOTIATED;
177 1 : spdm_context->connection_info.capability.flags |=
178 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_HBEAT_CAP;
179 1 : spdm_context->local_context.capability.flags |=
180 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_HBEAT_CAP;
181 1 : spdm_context->connection_info.algorithm.base_hash_algo =
182 : m_libspdm_use_hash_algo;
183 1 : spdm_context->connection_info.algorithm.base_asym_algo =
184 : m_libspdm_use_asym_algo;
185 1 : spdm_context->connection_info.algorithm.measurement_spec =
186 : m_libspdm_use_measurement_spec;
187 1 : spdm_context->connection_info.algorithm.measurement_hash_algo =
188 : m_libspdm_use_measurement_hash_algo;
189 1 : spdm_context->connection_info.algorithm.dhe_named_group =
190 : m_libspdm_use_dhe_algo;
191 1 : spdm_context->connection_info.algorithm.aead_cipher_suite =
192 : m_libspdm_use_aead_algo;
193 1 : libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
194 : m_libspdm_use_asym_algo, &data1,
195 : &data_size1, NULL, NULL);
196 1 : spdm_context->local_context.local_cert_chain_provision[0] = data1;
197 1 : spdm_context->local_context.local_cert_chain_provision_size[0] =
198 : data_size1;
199 :
200 1 : libspdm_reset_message_a(spdm_context);
201 :
202 1 : session_id = 0xFFFFFFFF;
203 1 : spdm_context->latest_session_id = session_id;
204 1 : spdm_context->last_spdm_request_session_id_valid = true;
205 1 : spdm_context->last_spdm_request_session_id = session_id;
206 1 : session_info = &spdm_context->session_info[0];
207 1 : libspdm_session_info_init(spdm_context, session_info, session_id,
208 : SECURED_SPDM_VERSION_11 << SPDM_VERSION_NUMBER_SHIFT_BIT, true);
209 1 : libspdm_secured_message_set_session_state(
210 : session_info->secured_message_context,
211 : LIBSPDM_SESSION_STATE_ESTABLISHED);
212 :
213 1 : response_size = sizeof(response);
214 1 : status = libspdm_get_response_heartbeat(spdm_context,
215 : m_libspdm_heartbeat_request1_size,
216 : &m_libspdm_heartbeat_request1,
217 : &response_size, response);
218 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
219 1 : assert_int_equal(response_size, sizeof(spdm_error_response_t));
220 1 : spdm_response = (void *)response;
221 1 : assert_int_equal(spdm_response->header.request_response_code,
222 : SPDM_ERROR);
223 1 : assert_int_equal(spdm_response->header.param1, SPDM_ERROR_CODE_BUSY);
224 1 : assert_int_equal(spdm_response->header.param2, 0);
225 1 : assert_int_equal(spdm_context->response_state,
226 : LIBSPDM_RESPONSE_STATE_BUSY);
227 1 : free(data1);
228 1 : }
229 :
230 1 : static void rsp_heartbeat_ack_case4(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_heartbeat_response_t *spdm_response;
238 : void *data1;
239 : size_t data_size1;
240 : libspdm_session_info_t *session_info;
241 : uint32_t session_id;
242 :
243 1 : spdm_test_context = *state;
244 1 : spdm_context = spdm_test_context->spdm_context;
245 1 : spdm_test_context->case_id = 0x4;
246 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_11 <<
247 : SPDM_VERSION_NUMBER_SHIFT_BIT;
248 1 : spdm_context->response_state = LIBSPDM_RESPONSE_STATE_NEED_RESYNC;
249 1 : spdm_context->connection_info.connection_state =
250 : LIBSPDM_CONNECTION_STATE_NEGOTIATED;
251 1 : spdm_context->connection_info.capability.flags |=
252 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_HBEAT_CAP;
253 1 : spdm_context->local_context.capability.flags |=
254 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_HBEAT_CAP;
255 1 : spdm_context->connection_info.algorithm.base_hash_algo =
256 : m_libspdm_use_hash_algo;
257 1 : spdm_context->connection_info.algorithm.base_asym_algo =
258 : m_libspdm_use_asym_algo;
259 1 : spdm_context->connection_info.algorithm.measurement_spec =
260 : m_libspdm_use_measurement_spec;
261 1 : spdm_context->connection_info.algorithm.measurement_hash_algo =
262 : m_libspdm_use_measurement_hash_algo;
263 1 : spdm_context->connection_info.algorithm.dhe_named_group =
264 : m_libspdm_use_dhe_algo;
265 1 : spdm_context->connection_info.algorithm.aead_cipher_suite =
266 : m_libspdm_use_aead_algo;
267 1 : libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
268 : m_libspdm_use_asym_algo, &data1,
269 : &data_size1, NULL, NULL);
270 1 : spdm_context->local_context.local_cert_chain_provision[0] = data1;
271 1 : spdm_context->local_context.local_cert_chain_provision_size[0] =
272 : data_size1;
273 :
274 1 : libspdm_reset_message_a(spdm_context);
275 :
276 1 : session_id = 0xFFFFFFFF;
277 1 : spdm_context->latest_session_id = session_id;
278 1 : spdm_context->last_spdm_request_session_id_valid = true;
279 1 : spdm_context->last_spdm_request_session_id = session_id;
280 1 : session_info = &spdm_context->session_info[0];
281 1 : libspdm_session_info_init(spdm_context, session_info, session_id,
282 : SECURED_SPDM_VERSION_11 << SPDM_VERSION_NUMBER_SHIFT_BIT, true);
283 1 : libspdm_secured_message_set_session_state(
284 : session_info->secured_message_context,
285 : LIBSPDM_SESSION_STATE_ESTABLISHED);
286 :
287 1 : response_size = sizeof(response);
288 1 : status = libspdm_get_response_heartbeat(spdm_context,
289 : m_libspdm_heartbeat_request1_size,
290 : &m_libspdm_heartbeat_request1,
291 : &response_size, response);
292 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
293 1 : assert_int_equal(response_size, sizeof(spdm_error_response_t));
294 1 : spdm_response = (void *)response;
295 1 : assert_int_equal(spdm_response->header.request_response_code,
296 : SPDM_ERROR);
297 1 : assert_int_equal(spdm_response->header.param1,
298 : SPDM_ERROR_CODE_REQUEST_RESYNCH);
299 1 : assert_int_equal(spdm_response->header.param2, 0);
300 1 : assert_int_equal(spdm_context->response_state,
301 : LIBSPDM_RESPONSE_STATE_NEED_RESYNC);
302 1 : free(data1);
303 1 : }
304 :
305 : #if LIBSPDM_RESPOND_IF_READY_SUPPORT
306 1 : static void rsp_heartbeat_ack_case5(void **state)
307 : {
308 : libspdm_return_t status;
309 : libspdm_test_context_t *spdm_test_context;
310 : libspdm_context_t *spdm_context;
311 : size_t response_size;
312 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
313 : spdm_heartbeat_response_t *spdm_response;
314 : void *data1;
315 : size_t data_size1;
316 : libspdm_session_info_t *session_info;
317 : uint32_t session_id;
318 : spdm_error_data_response_not_ready_t *error_data;
319 :
320 1 : spdm_test_context = *state;
321 1 : spdm_context = spdm_test_context->spdm_context;
322 1 : spdm_test_context->case_id = 0x5;
323 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_11 <<
324 : SPDM_VERSION_NUMBER_SHIFT_BIT;
325 1 : spdm_context->response_state = LIBSPDM_RESPONSE_STATE_NOT_READY;
326 1 : spdm_context->connection_info.connection_state =
327 : LIBSPDM_CONNECTION_STATE_NEGOTIATED;
328 1 : spdm_context->connection_info.capability.flags |=
329 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_HBEAT_CAP;
330 1 : spdm_context->local_context.capability.flags |=
331 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_HBEAT_CAP;
332 1 : spdm_context->connection_info.algorithm.base_hash_algo =
333 : m_libspdm_use_hash_algo;
334 1 : spdm_context->connection_info.algorithm.base_asym_algo =
335 : m_libspdm_use_asym_algo;
336 1 : spdm_context->connection_info.algorithm.measurement_spec =
337 : m_libspdm_use_measurement_spec;
338 1 : spdm_context->connection_info.algorithm.measurement_hash_algo =
339 : m_libspdm_use_measurement_hash_algo;
340 1 : spdm_context->connection_info.algorithm.dhe_named_group =
341 : m_libspdm_use_dhe_algo;
342 1 : spdm_context->connection_info.algorithm.aead_cipher_suite =
343 : m_libspdm_use_aead_algo;
344 1 : libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
345 : m_libspdm_use_asym_algo, &data1,
346 : &data_size1, NULL, NULL);
347 1 : spdm_context->local_context.local_cert_chain_provision[0] = data1;
348 1 : spdm_context->local_context.local_cert_chain_provision_size[0] =
349 : data_size1;
350 :
351 1 : libspdm_reset_message_a(spdm_context);
352 :
353 1 : session_id = 0xFFFFFFFF;
354 1 : spdm_context->latest_session_id = session_id;
355 1 : spdm_context->last_spdm_request_session_id_valid = true;
356 1 : spdm_context->last_spdm_request_session_id = session_id;
357 1 : session_info = &spdm_context->session_info[0];
358 1 : libspdm_session_info_init(spdm_context, session_info, session_id,
359 : SECURED_SPDM_VERSION_11 << SPDM_VERSION_NUMBER_SHIFT_BIT, true);
360 1 : libspdm_secured_message_set_session_state(
361 : session_info->secured_message_context,
362 : LIBSPDM_SESSION_STATE_ESTABLISHED);
363 :
364 1 : response_size = sizeof(response);
365 1 : status = libspdm_get_response_heartbeat(spdm_context,
366 : m_libspdm_heartbeat_request1_size,
367 : &m_libspdm_heartbeat_request1,
368 : &response_size, response);
369 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
370 1 : assert_int_equal(response_size,
371 : sizeof(spdm_error_response_t) +
372 : sizeof(spdm_error_data_response_not_ready_t));
373 1 : spdm_response = (void *)response;
374 1 : error_data =
375 : (spdm_error_data_response_not_ready_t *)(spdm_response + 1);
376 1 : assert_int_equal(spdm_response->header.request_response_code,
377 : SPDM_ERROR);
378 1 : assert_int_equal(spdm_response->header.param1,
379 : SPDM_ERROR_CODE_RESPONSE_NOT_READY);
380 1 : assert_int_equal(spdm_response->header.param2, 0);
381 1 : assert_int_equal(spdm_context->response_state,
382 : LIBSPDM_RESPONSE_STATE_NOT_READY);
383 1 : assert_int_equal(error_data->request_code, SPDM_HEARTBEAT);
384 1 : free(data1);
385 1 : }
386 : #endif /* LIBSPDM_RESPOND_IF_READY_SUPPORT */
387 :
388 1 : static void rsp_heartbeat_ack_case6(void **state)
389 : {
390 : libspdm_return_t status;
391 : libspdm_test_context_t *spdm_test_context;
392 : libspdm_context_t *spdm_context;
393 : size_t response_size;
394 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
395 : spdm_heartbeat_response_t *spdm_response;
396 : void *data1;
397 : size_t data_size1;
398 : libspdm_session_info_t *session_info;
399 : uint32_t session_id;
400 :
401 1 : spdm_test_context = *state;
402 1 : spdm_context = spdm_test_context->spdm_context;
403 1 : spdm_test_context->case_id = 0x6;
404 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_11 <<
405 : SPDM_VERSION_NUMBER_SHIFT_BIT;
406 1 : spdm_context->response_state = LIBSPDM_RESPONSE_STATE_NORMAL;
407 1 : spdm_context->connection_info.connection_state =
408 : LIBSPDM_CONNECTION_STATE_NOT_STARTED;
409 1 : spdm_context->connection_info.capability.flags |=
410 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_HBEAT_CAP;
411 1 : spdm_context->local_context.capability.flags |=
412 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_HBEAT_CAP;
413 1 : spdm_context->connection_info.algorithm.base_hash_algo =
414 : m_libspdm_use_hash_algo;
415 1 : spdm_context->connection_info.algorithm.base_asym_algo =
416 : m_libspdm_use_asym_algo;
417 1 : spdm_context->connection_info.algorithm.measurement_spec =
418 : m_libspdm_use_measurement_spec;
419 1 : spdm_context->connection_info.algorithm.measurement_hash_algo =
420 : m_libspdm_use_measurement_hash_algo;
421 1 : spdm_context->connection_info.algorithm.dhe_named_group =
422 : m_libspdm_use_dhe_algo;
423 1 : spdm_context->connection_info.algorithm.aead_cipher_suite =
424 : m_libspdm_use_aead_algo;
425 1 : libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
426 : m_libspdm_use_asym_algo, &data1,
427 : &data_size1, NULL, NULL);
428 1 : spdm_context->local_context.local_cert_chain_provision[0] = data1;
429 1 : spdm_context->local_context.local_cert_chain_provision_size[0] =
430 : data_size1;
431 :
432 1 : libspdm_reset_message_a(spdm_context);
433 :
434 1 : session_id = 0xFFFFFFFF;
435 1 : spdm_context->latest_session_id = session_id;
436 1 : spdm_context->last_spdm_request_session_id_valid = true;
437 1 : spdm_context->last_spdm_request_session_id = session_id;
438 1 : session_info = &spdm_context->session_info[0];
439 1 : libspdm_session_info_init(spdm_context, session_info, session_id,
440 : SECURED_SPDM_VERSION_11 << SPDM_VERSION_NUMBER_SHIFT_BIT, true);
441 1 : libspdm_secured_message_set_session_state(
442 : session_info->secured_message_context,
443 : LIBSPDM_SESSION_STATE_ESTABLISHED);
444 :
445 1 : response_size = sizeof(response);
446 1 : status = libspdm_get_response_heartbeat(spdm_context,
447 : m_libspdm_heartbeat_request1_size,
448 : &m_libspdm_heartbeat_request1,
449 : &response_size, response);
450 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
451 1 : assert_int_equal(response_size, sizeof(spdm_error_response_t));
452 1 : spdm_response = (void *)response;
453 1 : assert_int_equal(spdm_response->header.request_response_code,
454 : SPDM_ERROR);
455 1 : assert_int_equal(spdm_response->header.param1,
456 : SPDM_ERROR_CODE_UNEXPECTED_REQUEST);
457 1 : assert_int_equal(spdm_response->header.param2, 0);
458 1 : free(data1);
459 1 : }
460 :
461 1 : static void rsp_heartbeat_ack_case7(void **state)
462 : {
463 : libspdm_return_t status;
464 : libspdm_test_context_t *spdm_test_context;
465 : libspdm_context_t *spdm_context;
466 : size_t response_size;
467 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
468 : spdm_heartbeat_response_t *spdm_response;
469 : void *data1;
470 : size_t data_size1;
471 : libspdm_session_info_t *session_info;
472 : uint32_t session_id;
473 :
474 1 : spdm_test_context = *state;
475 1 : spdm_context = spdm_test_context->spdm_context;
476 1 : spdm_test_context->case_id = 0x7;
477 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_11 <<
478 : SPDM_VERSION_NUMBER_SHIFT_BIT;
479 1 : spdm_context->connection_info.connection_state =
480 : LIBSPDM_CONNECTION_STATE_NEGOTIATED;
481 1 : spdm_context->connection_info.capability.flags |=
482 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_HBEAT_CAP;
483 1 : spdm_context->local_context.capability.flags |=
484 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_HBEAT_CAP;
485 1 : spdm_context->connection_info.algorithm.base_hash_algo =
486 : m_libspdm_use_hash_algo;
487 1 : spdm_context->connection_info.algorithm.base_asym_algo =
488 : m_libspdm_use_asym_algo;
489 1 : spdm_context->connection_info.algorithm.measurement_spec =
490 : m_libspdm_use_measurement_spec;
491 1 : spdm_context->connection_info.algorithm.measurement_hash_algo =
492 : m_libspdm_use_measurement_hash_algo;
493 1 : spdm_context->connection_info.algorithm.dhe_named_group =
494 : m_libspdm_use_dhe_algo;
495 1 : spdm_context->connection_info.algorithm.aead_cipher_suite =
496 : m_libspdm_use_aead_algo;
497 1 : libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
498 : m_libspdm_use_asym_algo, &data1,
499 : &data_size1, NULL, NULL);
500 1 : spdm_context->local_context.local_cert_chain_provision[0] = data1;
501 1 : spdm_context->local_context.local_cert_chain_provision_size[0] =
502 : data_size1;
503 :
504 1 : libspdm_reset_message_a(spdm_context);
505 :
506 1 : session_id = 0xFFFFFFFF;
507 1 : spdm_context->latest_session_id = session_id;
508 1 : spdm_context->last_spdm_request_session_id_valid = true;
509 1 : spdm_context->last_spdm_request_session_id = session_id;
510 1 : session_info = &spdm_context->session_info[0];
511 1 : libspdm_session_info_init(spdm_context, session_info, session_id,
512 : SECURED_SPDM_VERSION_11 << SPDM_VERSION_NUMBER_SHIFT_BIT, true);
513 1 : libspdm_secured_message_set_session_state(
514 : session_info->secured_message_context,
515 : LIBSPDM_SESSION_STATE_ESTABLISHED);
516 1 : session_info->heartbeat_period = 1;
517 :
518 1 : response_size = sizeof(response);
519 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
520 : session_info->session_transcript.message_m.buffer_size =
521 : session_info->session_transcript.message_m.max_buffer_size;
522 : spdm_context->transcript.message_b.buffer_size =
523 : spdm_context->transcript.message_b.max_buffer_size;
524 : spdm_context->transcript.message_c.buffer_size =
525 : spdm_context->transcript.message_c.max_buffer_size;
526 : spdm_context->transcript.message_mut_b.buffer_size =
527 : spdm_context->transcript.message_mut_b.max_buffer_size;
528 : spdm_context->transcript.message_mut_c.buffer_size =
529 : spdm_context->transcript.message_mut_c.max_buffer_size;
530 : #endif
531 1 : status = libspdm_get_response_heartbeat(spdm_context,
532 : m_libspdm_heartbeat_request1_size,
533 : &m_libspdm_heartbeat_request1,
534 : &response_size, response);
535 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
536 1 : assert_int_equal(response_size, sizeof(spdm_heartbeat_response_t));
537 1 : spdm_response = (void *)response;
538 1 : assert_int_equal(spdm_response->header.request_response_code, SPDM_HEARTBEAT_ACK);
539 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
540 : assert_int_equal(session_info->session_transcript.message_m.buffer_size, 0);
541 : assert_int_equal(spdm_context->transcript.message_b.buffer_size, 0);
542 : assert_int_equal(spdm_context->transcript.message_c.buffer_size, 0);
543 : assert_int_equal(spdm_context->transcript.message_mut_b.buffer_size, 0);
544 : assert_int_equal(spdm_context->transcript.message_mut_c.buffer_size, 0);
545 : #endif
546 :
547 1 : free(data1);
548 1 : }
549 : /**
550 : * Test 2: Responder has set HeartbeatPeriod to a value of 0 but Requester sends
551 : * HEARTBEAT request anyways.
552 : * Expected behavior: Responder returns UnexpectedRequest ERROR message.
553 : **/
554 1 : static void rsp_heartbeat_ack_case8(void **state)
555 : {
556 : libspdm_return_t status;
557 : libspdm_test_context_t *spdm_test_context;
558 : libspdm_context_t *spdm_context;
559 : size_t response_size;
560 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
561 : spdm_heartbeat_response_t *spdm_response;
562 : libspdm_session_info_t *session_info;
563 : uint32_t session_id;
564 :
565 1 : spdm_test_context = *state;
566 1 : spdm_context = spdm_test_context->spdm_context;
567 1 : spdm_test_context->case_id = 0x1;
568 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_11 <<
569 : SPDM_VERSION_NUMBER_SHIFT_BIT;
570 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
571 1 : spdm_context->connection_info.capability.flags |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_HBEAT_CAP;
572 1 : spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_HBEAT_CAP;
573 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
574 1 : spdm_context->connection_info.algorithm.base_asym_algo = m_libspdm_use_asym_algo;
575 1 : spdm_context->connection_info.algorithm.measurement_spec = m_libspdm_use_measurement_spec;
576 1 : spdm_context->connection_info.algorithm.measurement_hash_algo =
577 : m_libspdm_use_measurement_hash_algo;
578 1 : spdm_context->connection_info.algorithm.dhe_named_group = m_libspdm_use_dhe_algo;
579 1 : spdm_context->connection_info.algorithm.aead_cipher_suite = m_libspdm_use_aead_algo;
580 :
581 1 : libspdm_reset_message_a(spdm_context);
582 :
583 1 : session_id = 0xFFFFFFFF;
584 1 : spdm_context->latest_session_id = session_id;
585 1 : spdm_context->last_spdm_request_session_id_valid = true;
586 1 : spdm_context->last_spdm_request_session_id = session_id;
587 1 : session_info = &spdm_context->session_info[0];
588 1 : libspdm_session_info_init(spdm_context, session_info, session_id,
589 : SECURED_SPDM_VERSION_11 << SPDM_VERSION_NUMBER_SHIFT_BIT, true);
590 1 : libspdm_secured_message_set_session_state(
591 : session_info->secured_message_context,
592 : LIBSPDM_SESSION_STATE_ESTABLISHED);
593 1 : session_info->heartbeat_period = 0;
594 :
595 1 : response_size = sizeof(response);
596 1 : status = libspdm_get_response_heartbeat(spdm_context,
597 : m_libspdm_heartbeat_request1_size,
598 : &m_libspdm_heartbeat_request1,
599 : &response_size, response);
600 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
601 1 : assert_int_equal(response_size, sizeof(spdm_error_response_t));
602 1 : spdm_response = (void *)response;
603 1 : assert_int_equal(spdm_response->header.request_response_code, SPDM_ERROR);
604 1 : assert_int_equal(spdm_response->header.param1, SPDM_ERROR_CODE_UNEXPECTED_REQUEST);
605 1 : assert_int_equal(spdm_response->header.param2, 0);
606 1 : }
607 :
608 1 : int libspdm_rsp_heartbeat_ack_test(void)
609 : {
610 1 : const struct CMUnitTest test_cases[] = {
611 : /* Success Case*/
612 : cmocka_unit_test(rsp_heartbeat_ack_case1),
613 : /* Bad request size*/
614 : cmocka_unit_test(rsp_heartbeat_ack_case2),
615 : /* response_state: SPDM_RESPONSE_STATE_BUSY*/
616 : cmocka_unit_test(rsp_heartbeat_ack_case3),
617 : /* response_state: SPDM_RESPONSE_STATE_NEED_RESYNC*/
618 : cmocka_unit_test(rsp_heartbeat_ack_case4),
619 : #if LIBSPDM_RESPOND_IF_READY_SUPPORT
620 : /* response_state: SPDM_RESPONSE_STATE_NOT_READY*/
621 : cmocka_unit_test(rsp_heartbeat_ack_case5),
622 : #endif /* LIBSPDM_RESPOND_IF_READY_SUPPORT */
623 : /* connection_state Check*/
624 : cmocka_unit_test(rsp_heartbeat_ack_case6),
625 : /* Buffer reset*/
626 : cmocka_unit_test(rsp_heartbeat_ack_case7),
627 : cmocka_unit_test(rsp_heartbeat_ack_case8),
628 : };
629 :
630 1 : libspdm_test_context_t test_context = {
631 : LIBSPDM_TEST_CONTEXT_VERSION,
632 : false,
633 : };
634 :
635 1 : libspdm_setup_test_context(&test_context);
636 :
637 1 : return cmocka_run_group_tests(test_cases,
638 : libspdm_unit_test_group_setup,
639 : libspdm_unit_test_group_teardown);
640 : }
641 :
642 : #endif /* (LIBSPDM_ENABLE_CAPABILITY_KEY_EX_CAP) || (LIBSPDM_ENABLE_CAPABILITY_PSK_CAP) */
|