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 : #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 = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
103 1 : spdm_context->connection_info.capability.flags |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_HBEAT_CAP;
104 1 : spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_HBEAT_CAP;
105 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
106 1 : spdm_context->connection_info.algorithm.base_asym_algo = m_libspdm_use_asym_algo;
107 1 : spdm_context->connection_info.algorithm.measurement_spec = m_libspdm_use_measurement_spec;
108 1 : spdm_context->connection_info.algorithm.measurement_hash_algo =
109 : m_libspdm_use_measurement_hash_algo;
110 1 : spdm_context->connection_info.algorithm.dhe_named_group = m_libspdm_use_dhe_algo;
111 1 : spdm_context->connection_info.algorithm.aead_cipher_suite = m_libspdm_use_aead_algo;
112 1 : libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
113 : m_libspdm_use_asym_algo, &data1,
114 : &data_size1, NULL, NULL);
115 1 : spdm_context->local_context.local_cert_chain_provision[0] = data1;
116 1 : spdm_context->local_context.local_cert_chain_provision_size[0] = data_size1;
117 :
118 1 : libspdm_reset_message_a(spdm_context);
119 :
120 1 : session_id = 0xFFFFFFFF;
121 1 : spdm_context->latest_session_id = session_id;
122 1 : spdm_context->last_spdm_request_session_id_valid = true;
123 1 : spdm_context->last_spdm_request_session_id = session_id;
124 1 : session_info = &spdm_context->session_info[0];
125 1 : libspdm_session_info_init(spdm_context, session_info, session_id,
126 : SECURED_SPDM_VERSION_11 << SPDM_VERSION_NUMBER_SHIFT_BIT, true);
127 1 : libspdm_secured_message_set_session_state(
128 : session_info->secured_message_context,
129 : LIBSPDM_SESSION_STATE_ESTABLISHED);
130 :
131 1 : response_size = sizeof(response);
132 1 : status = libspdm_get_response_heartbeat(spdm_context,
133 : m_libspdm_heartbeat_request2_size,
134 : &m_libspdm_heartbeat_request2,
135 : &response_size, response);
136 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
137 1 : assert_int_equal(response_size, sizeof(spdm_error_response_t));
138 1 : spdm_response = (void *)response;
139 1 : assert_int_equal(spdm_response->header.request_response_code, SPDM_ERROR);
140 1 : assert_int_equal(spdm_response->header.param1, SPDM_ERROR_CODE_INVALID_REQUEST);
141 1 : assert_int_equal(spdm_response->header.param2, 0);
142 1 : free(data1);
143 1 : }
144 :
145 1 : static void rsp_heartbeat_ack_case3(void **state)
146 : {
147 : libspdm_return_t status;
148 : libspdm_test_context_t *spdm_test_context;
149 : libspdm_context_t *spdm_context;
150 : size_t response_size;
151 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
152 : spdm_heartbeat_response_t *spdm_response;
153 : void *data1;
154 : size_t data_size1;
155 : libspdm_session_info_t *session_info;
156 : uint32_t session_id;
157 :
158 1 : spdm_test_context = *state;
159 1 : spdm_context = spdm_test_context->spdm_context;
160 1 : spdm_test_context->case_id = 0x3;
161 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_11 <<
162 : SPDM_VERSION_NUMBER_SHIFT_BIT;
163 1 : spdm_context->response_state = LIBSPDM_RESPONSE_STATE_BUSY;
164 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
165 1 : spdm_context->connection_info.capability.flags |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_HBEAT_CAP;
166 1 : spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_HBEAT_CAP;
167 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
168 1 : spdm_context->connection_info.algorithm.base_asym_algo = m_libspdm_use_asym_algo;
169 1 : spdm_context->connection_info.algorithm.measurement_spec = m_libspdm_use_measurement_spec;
170 1 : spdm_context->connection_info.algorithm.measurement_hash_algo =
171 : m_libspdm_use_measurement_hash_algo;
172 1 : spdm_context->connection_info.algorithm.dhe_named_group = m_libspdm_use_dhe_algo;
173 1 : spdm_context->connection_info.algorithm.aead_cipher_suite = m_libspdm_use_aead_algo;
174 1 : libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
175 : m_libspdm_use_asym_algo, &data1,
176 : &data_size1, NULL, NULL);
177 1 : spdm_context->local_context.local_cert_chain_provision[0] = data1;
178 1 : spdm_context->local_context.local_cert_chain_provision_size[0] = data_size1;
179 :
180 1 : libspdm_reset_message_a(spdm_context);
181 :
182 1 : session_id = 0xFFFFFFFF;
183 1 : spdm_context->latest_session_id = session_id;
184 1 : spdm_context->last_spdm_request_session_id_valid = true;
185 1 : spdm_context->last_spdm_request_session_id = session_id;
186 1 : session_info = &spdm_context->session_info[0];
187 1 : libspdm_session_info_init(spdm_context, session_info, session_id,
188 : SECURED_SPDM_VERSION_11 << SPDM_VERSION_NUMBER_SHIFT_BIT, true);
189 1 : libspdm_secured_message_set_session_state(
190 : session_info->secured_message_context,
191 : LIBSPDM_SESSION_STATE_ESTABLISHED);
192 :
193 1 : response_size = sizeof(response);
194 1 : status = libspdm_get_response_heartbeat(spdm_context,
195 : m_libspdm_heartbeat_request1_size,
196 : &m_libspdm_heartbeat_request1,
197 : &response_size, response);
198 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
199 1 : assert_int_equal(response_size, sizeof(spdm_error_response_t));
200 1 : spdm_response = (void *)response;
201 1 : assert_int_equal(spdm_response->header.request_response_code, SPDM_ERROR);
202 1 : assert_int_equal(spdm_response->header.param1, SPDM_ERROR_CODE_BUSY);
203 1 : assert_int_equal(spdm_response->header.param2, 0);
204 1 : assert_int_equal(spdm_context->response_state, LIBSPDM_RESPONSE_STATE_BUSY);
205 1 : free(data1);
206 1 : }
207 :
208 1 : static void rsp_heartbeat_ack_case4(void **state)
209 : {
210 : libspdm_return_t status;
211 : libspdm_test_context_t *spdm_test_context;
212 : libspdm_context_t *spdm_context;
213 : size_t response_size;
214 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
215 : spdm_heartbeat_response_t *spdm_response;
216 : void *data1;
217 : size_t data_size1;
218 : libspdm_session_info_t *session_info;
219 : uint32_t session_id;
220 :
221 1 : spdm_test_context = *state;
222 1 : spdm_context = spdm_test_context->spdm_context;
223 1 : spdm_test_context->case_id = 0x4;
224 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_11 <<
225 : SPDM_VERSION_NUMBER_SHIFT_BIT;
226 1 : spdm_context->response_state = LIBSPDM_RESPONSE_STATE_NEED_RESYNC;
227 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
228 1 : spdm_context->connection_info.capability.flags |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_HBEAT_CAP;
229 1 : spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_HBEAT_CAP;
230 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
231 1 : spdm_context->connection_info.algorithm.base_asym_algo = m_libspdm_use_asym_algo;
232 1 : spdm_context->connection_info.algorithm.measurement_spec = m_libspdm_use_measurement_spec;
233 1 : spdm_context->connection_info.algorithm.measurement_hash_algo =
234 : m_libspdm_use_measurement_hash_algo;
235 1 : spdm_context->connection_info.algorithm.dhe_named_group = m_libspdm_use_dhe_algo;
236 1 : spdm_context->connection_info.algorithm.aead_cipher_suite = m_libspdm_use_aead_algo;
237 1 : libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
238 : m_libspdm_use_asym_algo, &data1,
239 : &data_size1, NULL, NULL);
240 1 : spdm_context->local_context.local_cert_chain_provision[0] = data1;
241 1 : spdm_context->local_context.local_cert_chain_provision_size[0] = data_size1;
242 :
243 1 : libspdm_reset_message_a(spdm_context);
244 :
245 1 : session_id = 0xFFFFFFFF;
246 1 : spdm_context->latest_session_id = session_id;
247 1 : spdm_context->last_spdm_request_session_id_valid = true;
248 1 : spdm_context->last_spdm_request_session_id = session_id;
249 1 : session_info = &spdm_context->session_info[0];
250 1 : libspdm_session_info_init(spdm_context, session_info, session_id,
251 : SECURED_SPDM_VERSION_11 << SPDM_VERSION_NUMBER_SHIFT_BIT, true);
252 1 : libspdm_secured_message_set_session_state(
253 : session_info->secured_message_context,
254 : LIBSPDM_SESSION_STATE_ESTABLISHED);
255 :
256 1 : response_size = sizeof(response);
257 1 : status = libspdm_get_response_heartbeat(spdm_context,
258 : m_libspdm_heartbeat_request1_size,
259 : &m_libspdm_heartbeat_request1,
260 : &response_size, response);
261 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
262 1 : assert_int_equal(response_size, sizeof(spdm_error_response_t));
263 1 : spdm_response = (void *)response;
264 1 : assert_int_equal(spdm_response->header.request_response_code, SPDM_ERROR);
265 1 : assert_int_equal(spdm_response->header.param1, SPDM_ERROR_CODE_REQUEST_RESYNCH);
266 1 : assert_int_equal(spdm_response->header.param2, 0);
267 1 : assert_int_equal(spdm_context->response_state, LIBSPDM_RESPONSE_STATE_NEED_RESYNC);
268 1 : free(data1);
269 1 : }
270 :
271 : #if LIBSPDM_RESPOND_IF_READY_SUPPORT
272 1 : static void rsp_heartbeat_ack_case5(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_heartbeat_response_t *spdm_response;
280 : void *data1;
281 : size_t data_size1;
282 : libspdm_session_info_t *session_info;
283 : uint32_t session_id;
284 : spdm_error_data_response_not_ready_t *error_data;
285 :
286 1 : spdm_test_context = *state;
287 1 : spdm_context = spdm_test_context->spdm_context;
288 1 : spdm_test_context->case_id = 0x5;
289 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_11 <<
290 : SPDM_VERSION_NUMBER_SHIFT_BIT;
291 1 : spdm_context->response_state = LIBSPDM_RESPONSE_STATE_NOT_READY;
292 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
293 1 : spdm_context->connection_info.capability.flags |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_HBEAT_CAP;
294 1 : spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_HBEAT_CAP;
295 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
296 1 : spdm_context->connection_info.algorithm.base_asym_algo = m_libspdm_use_asym_algo;
297 1 : spdm_context->connection_info.algorithm.measurement_spec = m_libspdm_use_measurement_spec;
298 1 : spdm_context->connection_info.algorithm.measurement_hash_algo =
299 : m_libspdm_use_measurement_hash_algo;
300 1 : spdm_context->connection_info.algorithm.dhe_named_group = m_libspdm_use_dhe_algo;
301 1 : spdm_context->connection_info.algorithm.aead_cipher_suite = m_libspdm_use_aead_algo;
302 1 : libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
303 : m_libspdm_use_asym_algo, &data1,
304 : &data_size1, NULL, NULL);
305 1 : spdm_context->local_context.local_cert_chain_provision[0] = data1;
306 1 : spdm_context->local_context.local_cert_chain_provision_size[0] = data_size1;
307 :
308 1 : libspdm_reset_message_a(spdm_context);
309 :
310 1 : session_id = 0xFFFFFFFF;
311 1 : spdm_context->latest_session_id = session_id;
312 1 : spdm_context->last_spdm_request_session_id_valid = true;
313 1 : spdm_context->last_spdm_request_session_id = session_id;
314 1 : session_info = &spdm_context->session_info[0];
315 1 : libspdm_session_info_init(spdm_context, session_info, session_id,
316 : SECURED_SPDM_VERSION_11 << SPDM_VERSION_NUMBER_SHIFT_BIT, true);
317 1 : libspdm_secured_message_set_session_state(
318 : session_info->secured_message_context,
319 : LIBSPDM_SESSION_STATE_ESTABLISHED);
320 :
321 1 : response_size = sizeof(response);
322 1 : status = libspdm_get_response_heartbeat(spdm_context,
323 : m_libspdm_heartbeat_request1_size,
324 : &m_libspdm_heartbeat_request1,
325 : &response_size, response);
326 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
327 1 : assert_int_equal(response_size,
328 : sizeof(spdm_error_response_t) +
329 : sizeof(spdm_error_data_response_not_ready_t));
330 1 : spdm_response = (void *)response;
331 1 : error_data = (spdm_error_data_response_not_ready_t *)(spdm_response + 1);
332 1 : assert_int_equal(spdm_response->header.request_response_code, SPDM_ERROR);
333 1 : assert_int_equal(spdm_response->header.param1, SPDM_ERROR_CODE_RESPONSE_NOT_READY);
334 1 : assert_int_equal(spdm_response->header.param2, 0);
335 1 : assert_int_equal(spdm_context->response_state, LIBSPDM_RESPONSE_STATE_NOT_READY);
336 1 : assert_int_equal(error_data->request_code, SPDM_HEARTBEAT);
337 1 : free(data1);
338 1 : }
339 : #endif /* LIBSPDM_RESPOND_IF_READY_SUPPORT */
340 :
341 1 : static void rsp_heartbeat_ack_case6(void **state)
342 : {
343 : libspdm_return_t status;
344 : libspdm_test_context_t *spdm_test_context;
345 : libspdm_context_t *spdm_context;
346 : size_t response_size;
347 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
348 : spdm_heartbeat_response_t *spdm_response;
349 : void *data1;
350 : size_t data_size1;
351 : libspdm_session_info_t *session_info;
352 : uint32_t session_id;
353 :
354 1 : spdm_test_context = *state;
355 1 : spdm_context = spdm_test_context->spdm_context;
356 1 : spdm_test_context->case_id = 0x6;
357 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_11 <<
358 : SPDM_VERSION_NUMBER_SHIFT_BIT;
359 1 : spdm_context->response_state = LIBSPDM_RESPONSE_STATE_NORMAL;
360 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NOT_STARTED;
361 1 : spdm_context->connection_info.capability.flags |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_HBEAT_CAP;
362 1 : spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_HBEAT_CAP;
363 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
364 1 : spdm_context->connection_info.algorithm.base_asym_algo = m_libspdm_use_asym_algo;
365 1 : spdm_context->connection_info.algorithm.measurement_spec = m_libspdm_use_measurement_spec;
366 1 : spdm_context->connection_info.algorithm.measurement_hash_algo =
367 : m_libspdm_use_measurement_hash_algo;
368 1 : spdm_context->connection_info.algorithm.dhe_named_group = m_libspdm_use_dhe_algo;
369 1 : spdm_context->connection_info.algorithm.aead_cipher_suite = m_libspdm_use_aead_algo;
370 1 : libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
371 : m_libspdm_use_asym_algo, &data1,
372 : &data_size1, NULL, NULL);
373 1 : spdm_context->local_context.local_cert_chain_provision[0] = data1;
374 1 : spdm_context->local_context.local_cert_chain_provision_size[0] = data_size1;
375 :
376 1 : libspdm_reset_message_a(spdm_context);
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 : response_size = sizeof(response);
390 1 : status = libspdm_get_response_heartbeat(spdm_context,
391 : m_libspdm_heartbeat_request1_size,
392 : &m_libspdm_heartbeat_request1,
393 : &response_size, response);
394 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
395 1 : assert_int_equal(response_size, sizeof(spdm_error_response_t));
396 1 : spdm_response = (void *)response;
397 1 : assert_int_equal(spdm_response->header.request_response_code, SPDM_ERROR);
398 1 : assert_int_equal(spdm_response->header.param1, SPDM_ERROR_CODE_UNEXPECTED_REQUEST);
399 1 : assert_int_equal(spdm_response->header.param2, 0);
400 1 : free(data1);
401 1 : }
402 :
403 1 : static void rsp_heartbeat_ack_case7(void **state)
404 : {
405 : libspdm_return_t status;
406 : libspdm_test_context_t *spdm_test_context;
407 : libspdm_context_t *spdm_context;
408 : size_t response_size;
409 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
410 : spdm_heartbeat_response_t *spdm_response;
411 : void *data1;
412 : size_t data_size1;
413 : libspdm_session_info_t *session_info;
414 : uint32_t session_id;
415 :
416 1 : spdm_test_context = *state;
417 1 : spdm_context = spdm_test_context->spdm_context;
418 1 : spdm_test_context->case_id = 0x7;
419 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_11 <<
420 : SPDM_VERSION_NUMBER_SHIFT_BIT;
421 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
422 1 : spdm_context->connection_info.capability.flags |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_HBEAT_CAP;
423 1 : spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_HBEAT_CAP;
424 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
425 1 : spdm_context->connection_info.algorithm.base_asym_algo = m_libspdm_use_asym_algo;
426 1 : spdm_context->connection_info.algorithm.measurement_spec = m_libspdm_use_measurement_spec;
427 1 : spdm_context->connection_info.algorithm.measurement_hash_algo =
428 : m_libspdm_use_measurement_hash_algo;
429 1 : spdm_context->connection_info.algorithm.dhe_named_group = m_libspdm_use_dhe_algo;
430 1 : spdm_context->connection_info.algorithm.aead_cipher_suite = m_libspdm_use_aead_algo;
431 1 : libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
432 : m_libspdm_use_asym_algo, &data1,
433 : &data_size1, NULL, NULL);
434 1 : spdm_context->local_context.local_cert_chain_provision[0] = data1;
435 1 : spdm_context->local_context.local_cert_chain_provision_size[0] = data_size1;
436 :
437 1 : libspdm_reset_message_a(spdm_context);
438 :
439 1 : session_id = 0xFFFFFFFF;
440 1 : spdm_context->latest_session_id = session_id;
441 1 : spdm_context->last_spdm_request_session_id_valid = true;
442 1 : spdm_context->last_spdm_request_session_id = session_id;
443 1 : session_info = &spdm_context->session_info[0];
444 1 : libspdm_session_info_init(spdm_context, session_info, session_id,
445 : SECURED_SPDM_VERSION_11 << SPDM_VERSION_NUMBER_SHIFT_BIT, true);
446 1 : libspdm_secured_message_set_session_state(
447 : session_info->secured_message_context,
448 : LIBSPDM_SESSION_STATE_ESTABLISHED);
449 1 : session_info->heartbeat_period = 1;
450 :
451 1 : response_size = sizeof(response);
452 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
453 : session_info->session_transcript.message_m.buffer_size =
454 : session_info->session_transcript.message_m.max_buffer_size;
455 : spdm_context->transcript.message_b.buffer_size =
456 : spdm_context->transcript.message_b.max_buffer_size;
457 : spdm_context->transcript.message_c.buffer_size =
458 : spdm_context->transcript.message_c.max_buffer_size;
459 : spdm_context->transcript.message_mut_b.buffer_size =
460 : spdm_context->transcript.message_mut_b.max_buffer_size;
461 : spdm_context->transcript.message_mut_c.buffer_size =
462 : spdm_context->transcript.message_mut_c.max_buffer_size;
463 : #endif
464 1 : status = libspdm_get_response_heartbeat(spdm_context,
465 : m_libspdm_heartbeat_request1_size,
466 : &m_libspdm_heartbeat_request1,
467 : &response_size, response);
468 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
469 1 : assert_int_equal(response_size, sizeof(spdm_heartbeat_response_t));
470 1 : spdm_response = (void *)response;
471 1 : assert_int_equal(spdm_response->header.request_response_code, SPDM_HEARTBEAT_ACK);
472 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
473 : assert_int_equal(session_info->session_transcript.message_m.buffer_size, 0);
474 : assert_int_equal(spdm_context->transcript.message_b.buffer_size, 0);
475 : assert_int_equal(spdm_context->transcript.message_c.buffer_size, 0);
476 : assert_int_equal(spdm_context->transcript.message_mut_b.buffer_size, 0);
477 : assert_int_equal(spdm_context->transcript.message_mut_c.buffer_size, 0);
478 : #endif
479 :
480 1 : free(data1);
481 1 : }
482 : /**
483 : * Test 2: Responder has set HeartbeatPeriod to a value of 0 but Requester sends
484 : * HEARTBEAT request anyways.
485 : * Expected behavior: Responder returns UnexpectedRequest ERROR message.
486 : **/
487 1 : static void rsp_heartbeat_ack_case8(void **state)
488 : {
489 : libspdm_return_t status;
490 : libspdm_test_context_t *spdm_test_context;
491 : libspdm_context_t *spdm_context;
492 : size_t response_size;
493 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
494 : spdm_heartbeat_response_t *spdm_response;
495 : libspdm_session_info_t *session_info;
496 : uint32_t session_id;
497 :
498 1 : spdm_test_context = *state;
499 1 : spdm_context = spdm_test_context->spdm_context;
500 1 : spdm_test_context->case_id = 0x1;
501 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_11 <<
502 : SPDM_VERSION_NUMBER_SHIFT_BIT;
503 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
504 1 : spdm_context->connection_info.capability.flags |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_HBEAT_CAP;
505 1 : spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_HBEAT_CAP;
506 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
507 1 : spdm_context->connection_info.algorithm.base_asym_algo = m_libspdm_use_asym_algo;
508 1 : spdm_context->connection_info.algorithm.measurement_spec = m_libspdm_use_measurement_spec;
509 1 : spdm_context->connection_info.algorithm.measurement_hash_algo =
510 : m_libspdm_use_measurement_hash_algo;
511 1 : spdm_context->connection_info.algorithm.dhe_named_group = m_libspdm_use_dhe_algo;
512 1 : spdm_context->connection_info.algorithm.aead_cipher_suite = m_libspdm_use_aead_algo;
513 :
514 1 : libspdm_reset_message_a(spdm_context);
515 :
516 1 : session_id = 0xFFFFFFFF;
517 1 : spdm_context->latest_session_id = session_id;
518 1 : spdm_context->last_spdm_request_session_id_valid = true;
519 1 : spdm_context->last_spdm_request_session_id = session_id;
520 1 : session_info = &spdm_context->session_info[0];
521 1 : libspdm_session_info_init(spdm_context, session_info, session_id,
522 : SECURED_SPDM_VERSION_11 << SPDM_VERSION_NUMBER_SHIFT_BIT, true);
523 1 : libspdm_secured_message_set_session_state(
524 : session_info->secured_message_context,
525 : LIBSPDM_SESSION_STATE_ESTABLISHED);
526 1 : session_info->heartbeat_period = 0;
527 :
528 1 : response_size = sizeof(response);
529 1 : status = libspdm_get_response_heartbeat(spdm_context,
530 : m_libspdm_heartbeat_request1_size,
531 : &m_libspdm_heartbeat_request1,
532 : &response_size, response);
533 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
534 1 : assert_int_equal(response_size, sizeof(spdm_error_response_t));
535 1 : spdm_response = (void *)response;
536 1 : assert_int_equal(spdm_response->header.request_response_code, SPDM_ERROR);
537 1 : assert_int_equal(spdm_response->header.param1, SPDM_ERROR_CODE_UNEXPECTED_REQUEST);
538 1 : assert_int_equal(spdm_response->header.param2, 0);
539 1 : }
540 :
541 1 : int libspdm_rsp_heartbeat_ack_test(void)
542 : {
543 1 : const struct CMUnitTest test_cases[] = {
544 : /* Success Case*/
545 : cmocka_unit_test(rsp_heartbeat_ack_case1),
546 : /* Bad request size*/
547 : cmocka_unit_test(rsp_heartbeat_ack_case2),
548 : /* response_state: SPDM_RESPONSE_STATE_BUSY*/
549 : cmocka_unit_test(rsp_heartbeat_ack_case3),
550 : /* response_state: SPDM_RESPONSE_STATE_NEED_RESYNC*/
551 : cmocka_unit_test(rsp_heartbeat_ack_case4),
552 : #if LIBSPDM_RESPOND_IF_READY_SUPPORT
553 : /* response_state: SPDM_RESPONSE_STATE_NOT_READY*/
554 : cmocka_unit_test(rsp_heartbeat_ack_case5),
555 : #endif /* LIBSPDM_RESPOND_IF_READY_SUPPORT */
556 : /* connection_state Check*/
557 : cmocka_unit_test(rsp_heartbeat_ack_case6),
558 : /* Buffer reset*/
559 : cmocka_unit_test(rsp_heartbeat_ack_case7),
560 : cmocka_unit_test(rsp_heartbeat_ack_case8),
561 : };
562 :
563 1 : libspdm_test_context_t test_context = {
564 : LIBSPDM_TEST_CONTEXT_VERSION,
565 : false,
566 : };
567 :
568 1 : libspdm_setup_test_context(&test_context);
569 :
570 1 : return cmocka_run_group_tests(test_cases,
571 : libspdm_unit_test_group_setup,
572 : libspdm_unit_test_group_teardown);
573 : }
574 :
575 : #endif /* (LIBSPDM_ENABLE_CAPABILITY_KEY_EX_CAP) || (LIBSPDM_ENABLE_CAPABILITY_PSK_CAP) */
|