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