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_requester_lib.h"
10 : #include "internal/libspdm_secured_message_lib.h"
11 :
12 : #if LIBSPDM_RESPOND_IF_READY_SUPPORT
13 :
14 : #if (LIBSPDM_ENABLE_CAPABILITY_CERT_CAP || LIBSPDM_ENABLE_CAPABILITY_CHAL_CAP || \
15 : LIBSPDM_ENABLE_CAPABILITY_MEAS_CAP || LIBSPDM_ENABLE_CAPABILITY_KEY_EX_CAP || \
16 : LIBSPDM_ENABLE_CAPABILITY_PSK_CAP)
17 :
18 : #define LIBSPDM_MY_TEST_TOKEN 0x30
19 : #define LIBSPDM_MY_WRONG_TEST_TOKEN 0x2F
20 :
21 : static libspdm_th_managed_buffer_t th_curr;
22 :
23 : extern size_t libspdm_secret_lib_challenge_opaque_data_size;
24 :
25 : spdm_response_if_ready_request_t m_libspdm_respond_if_ready_request1 = {
26 : {
27 : SPDM_MESSAGE_VERSION_11,
28 : SPDM_RESPOND_IF_READY,
29 : SPDM_GET_DIGESTS,
30 : LIBSPDM_MY_TEST_TOKEN
31 : },
32 : };
33 : size_t m_libspdm_respond_if_ready_request1_size = sizeof(spdm_message_header_t);
34 :
35 : spdm_response_if_ready_request_t m_libspdm_respond_if_ready_request2 = {
36 : {
37 : SPDM_MESSAGE_VERSION_11,
38 : SPDM_RESPOND_IF_READY,
39 : SPDM_GET_CERTIFICATE,
40 : LIBSPDM_MY_TEST_TOKEN
41 : },
42 : };
43 : size_t m_libspdm_respond_if_ready_request2_size = sizeof(spdm_message_header_t);
44 :
45 : spdm_response_if_ready_request_t m_libspdm_respond_if_ready_request3 = {
46 : {
47 : SPDM_MESSAGE_VERSION_11,
48 : SPDM_RESPOND_IF_READY,
49 : SPDM_CHALLENGE,
50 : LIBSPDM_MY_TEST_TOKEN
51 : },
52 : };
53 : size_t m_libspdm_respond_if_ready_request3_size = sizeof(spdm_message_header_t);
54 :
55 : spdm_response_if_ready_request_t m_libspdm_respond_if_ready_request4 = {
56 : {
57 : SPDM_MESSAGE_VERSION_11,
58 : SPDM_RESPOND_IF_READY,
59 : SPDM_GET_MEASUREMENTS,
60 : LIBSPDM_MY_TEST_TOKEN
61 : },
62 : };
63 : size_t m_libspdm_respond_if_ready_request4_size = sizeof(spdm_message_header_t);
64 :
65 : spdm_response_if_ready_request_t m_libspdm_respond_if_ready_request5 = {
66 : {
67 : SPDM_MESSAGE_VERSION_11,
68 : SPDM_RESPOND_IF_READY,
69 : SPDM_KEY_EXCHANGE,
70 : LIBSPDM_MY_TEST_TOKEN
71 : },
72 : };
73 : size_t m_libspdm_respond_if_ready_request5_size = sizeof(spdm_message_header_t);
74 :
75 : spdm_response_if_ready_request_t m_libspdm_respond_if_ready_request6 = {
76 : {
77 : SPDM_MESSAGE_VERSION_11,
78 : SPDM_RESPOND_IF_READY,
79 : SPDM_FINISH,
80 : LIBSPDM_MY_TEST_TOKEN
81 : },
82 : };
83 : size_t m_libspdm_respond_if_ready_request6_size = sizeof(spdm_message_header_t);
84 :
85 : spdm_response_if_ready_request_t m_libspdm_respond_if_ready_request7 = {
86 : {
87 : SPDM_MESSAGE_VERSION_11,
88 : SPDM_RESPOND_IF_READY,
89 : SPDM_PSK_EXCHANGE,
90 : LIBSPDM_MY_TEST_TOKEN
91 : },
92 : };
93 : size_t m_libspdm_respond_if_ready_request7_size = sizeof(spdm_message_header_t);
94 :
95 : spdm_response_if_ready_request_t m_libspdm_respond_if_ready_request8 = {
96 : {
97 : SPDM_MESSAGE_VERSION_11,
98 : SPDM_RESPOND_IF_READY,
99 : SPDM_PSK_FINISH,
100 : LIBSPDM_MY_TEST_TOKEN
101 : },
102 : };
103 : size_t m_libspdm_respond_if_ready_request8_size = sizeof(spdm_message_header_t);
104 :
105 : spdm_response_if_ready_request_t m_libspdm_respond_if_ready_request10 = {
106 : {
107 : SPDM_MESSAGE_VERSION_11,
108 : SPDM_RESPOND_IF_READY,
109 : SPDM_GET_DIGESTS,
110 : LIBSPDM_MY_WRONG_TEST_TOKEN /*wrong token*/
111 : },
112 : };
113 : size_t m_libspdm_respond_if_ready_request10_size = sizeof(spdm_message_header_t);
114 :
115 : spdm_response_if_ready_request_t m_libspdm_respond_if_ready_request11 = {
116 : {
117 : SPDM_MESSAGE_VERSION_11,
118 : SPDM_RESPOND_IF_READY,
119 : SPDM_GET_CERTIFICATE, /*wrong original request code*/
120 : LIBSPDM_MY_TEST_TOKEN
121 : },
122 : };
123 : size_t m_libspdm_respond_if_ready_request11_size = sizeof(spdm_message_header_t);
124 :
125 : #if LIBSPDM_ENABLE_CAPABILITY_CERT_CAP
126 : spdm_get_digest_request_t m_libspdm_get_digest_request = {
127 : {
128 : SPDM_MESSAGE_VERSION_11,
129 : SPDM_GET_DIGESTS,
130 : 0,
131 : 0
132 : },
133 : };
134 : size_t m_libspdm_get_digest_request_size = sizeof(spdm_message_header_t);
135 :
136 : spdm_get_certificate_request_t m_libspdm_get_certificate_request = {
137 : {
138 : SPDM_MESSAGE_VERSION_11,
139 : SPDM_GET_CERTIFICATE,
140 : 0,
141 : 0
142 : },
143 : 0,
144 : LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN
145 : };
146 : size_t m_libspdm_get_certificate_request_size = sizeof(m_libspdm_get_certificate_request);
147 :
148 : #endif /* LIBSPDM_ENABLE_CAPABILITY_CERT_CAP*/
149 :
150 : #if LIBSPDM_ENABLE_CAPABILITY_CHAL_CAP
151 :
152 : spdm_challenge_request_t m_libspdm_challenge_request = {
153 : {
154 : SPDM_MESSAGE_VERSION_11,
155 : SPDM_CHALLENGE,
156 : 0,
157 : SPDM_CHALLENGE_REQUEST_NO_MEASUREMENT_SUMMARY_HASH
158 : },
159 : };
160 : size_t m_libspdm_challenge_request_size = sizeof(m_libspdm_challenge_request);
161 :
162 : #endif /* LIBSPDM_ENABLE_CAPABILITY_CHAL_CAP*/
163 :
164 : #if LIBSPDM_ENABLE_CAPABILITY_MEAS_CAP
165 : spdm_get_measurements_request_t m_libspdm_get_measurements_request = {
166 : {
167 : SPDM_MESSAGE_VERSION_11,
168 : SPDM_GET_MEASUREMENTS,
169 : 0,
170 : SPDM_GET_MEASUREMENTS_REQUEST_MEASUREMENT_OPERATION_TOTAL_NUMBER_OF_MEASUREMENTS
171 : },
172 : };
173 : size_t m_libspdm_get_measurements_request_size = sizeof(spdm_message_header_t);
174 : #endif /* LIBSPDM_ENABLE_CAPABILITY_MEAS_CAP*/
175 :
176 : #pragma pack(1)
177 :
178 : typedef struct {
179 : spdm_message_header_t header;
180 : uint16_t req_session_id;
181 : uint8_t session_policy;
182 : uint8_t reserved;
183 : uint8_t random_data[SPDM_RANDOM_DATA_SIZE];
184 : uint8_t exchange_data[LIBSPDM_MAX_DHE_KEY_SIZE];
185 : uint16_t opaque_length;
186 : uint8_t opaque_data[SPDM_MAX_OPAQUE_DATA_SIZE];
187 : } libspdm_key_exchange_request_mine_t;
188 :
189 : typedef struct {
190 : spdm_message_header_t header;
191 : uint8_t signature[LIBSPDM_MAX_ASYM_SIG_SIZE];
192 : uint8_t verify_data[LIBSPDM_MAX_HASH_SIZE];
193 : } libspdm_finish_request_mine_t;
194 :
195 : #if LIBSPDM_ENABLE_CAPABILITY_PSK_CAP
196 : typedef struct {
197 : spdm_message_header_t header;
198 : uint16_t req_session_id;
199 : uint16_t psk_hint_length;
200 : uint16_t requester_context_length;
201 : uint16_t opaque_length;
202 : uint8_t psk_hint[LIBSPDM_PSK_MAX_HINT_LENGTH];
203 : uint8_t requester_context[LIBSPDM_PSK_CONTEXT_LENGTH];
204 : uint8_t opaque_data[SPDM_MAX_OPAQUE_DATA_SIZE];
205 : } libspdm_psk_exchange_request_mine_t;
206 :
207 : typedef struct {
208 : spdm_message_header_t header;
209 : uint8_t verify_data[LIBSPDM_MAX_HASH_SIZE];
210 : } libspdm_psk_finish_request_mine_t;
211 : #endif /* LIBSPDM_ENABLE_CAPABILITY_PSK_CAP */
212 :
213 : #pragma pack()
214 :
215 : libspdm_key_exchange_request_mine_t m_libspdm_key_exchange_request = {
216 : {
217 : SPDM_MESSAGE_VERSION_11,
218 : SPDM_KEY_EXCHANGE,
219 : SPDM_KEY_EXCHANGE_REQUEST_NO_MEASUREMENT_SUMMARY_HASH,
220 : 0
221 : },
222 : };
223 : size_t m_libspdm_key_exchange_request_size = sizeof(m_libspdm_key_exchange_request);
224 :
225 : libspdm_finish_request_mine_t m_libspdm_finish_request = {
226 : {
227 : SPDM_MESSAGE_VERSION_11,
228 : SPDM_FINISH,
229 : 0,
230 : 0
231 : },
232 : };
233 : size_t m_libspdm_finish_request_size = sizeof(m_libspdm_finish_request);
234 :
235 : #if LIBSPDM_ENABLE_CAPABILITY_PSK_CAP
236 : libspdm_psk_exchange_request_mine_t m_libspdm_psk_exchange_request = {
237 : {
238 : SPDM_MESSAGE_VERSION_11,
239 : SPDM_PSK_EXCHANGE,
240 : SPDM_PSK_EXCHANGE_REQUEST_NO_MEASUREMENT_SUMMARY_HASH,
241 : 0
242 : },
243 : };
244 : size_t m_libspdm_psk_exchange_request_size = sizeof(m_libspdm_psk_exchange_request);
245 :
246 : libspdm_psk_finish_request_mine_t m_libspdm_psk_finish_request = {
247 : {
248 : SPDM_MESSAGE_VERSION_11,
249 : SPDM_PSK_FINISH,
250 : 0,
251 : 0
252 : },
253 : };
254 : size_t m_libspdm_psk_finish_request_size = sizeof(m_libspdm_psk_finish_request);
255 : #endif /* LIBSPDM_ENABLE_CAPABILITY_PSK_CAP */
256 :
257 : spdm_end_session_request_t m_libspdm_end_session_request = {
258 : {
259 : SPDM_MESSAGE_VERSION_11,
260 : SPDM_END_SESSION,
261 : 0,
262 : 0
263 : }
264 : };
265 : size_t m_libspdm_end_session_request_size = sizeof(m_libspdm_end_session_request);
266 : #if LIBSPDM_ENABLE_CAPABILITY_CERT_CAP
267 : static uint8_t m_libspdm_local_certificate_chain[LIBSPDM_MAX_CERT_CHAIN_SIZE];
268 : #endif
269 2 : static void libspdm_secured_message_set_request_finished_key(
270 : void *spdm_secured_message_context, const void *key, size_t key_size)
271 : {
272 : libspdm_secured_message_context_t *secured_message_context;
273 :
274 2 : secured_message_context = spdm_secured_message_context;
275 2 : LIBSPDM_ASSERT(key_size == secured_message_context->hash_size);
276 2 : libspdm_copy_mem(secured_message_context->handshake_secret.request_finished_key,
277 : sizeof(secured_message_context->handshake_secret.request_finished_key),
278 : key, secured_message_context->hash_size);
279 2 : }
280 :
281 : #if LIBSPDM_ENABLE_CAPABILITY_CERT_CAP
282 : /**
283 : * Test 1: receiving a correct RESPOND_IF_READY from the requester, after a
284 : * GET_DIGESTS could not be processed.
285 : * Expected behavior: the responder accepts the request and produces a valid DIGESTS
286 : * response message.
287 : **/
288 1 : static void rsp_respond_if_ready_case1(void **state) {
289 : libspdm_return_t status;
290 : libspdm_test_context_t *spdm_test_context;
291 : libspdm_context_t *spdm_context;
292 : size_t response_size;
293 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
294 : spdm_digest_response_t *spdm_response; /*response to the original request (DIGESTS)*/
295 :
296 1 : spdm_test_context = *state;
297 1 : spdm_context = spdm_test_context->spdm_context;
298 1 : spdm_test_context->case_id = 0x1;
299 1 : spdm_context->response_state = LIBSPDM_RESPONSE_STATE_NORMAL;
300 :
301 : /*state for the the original request (GET_DIGESTS)*/
302 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
303 1 : spdm_context->local_context.capability.flags = 0;
304 1 : spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
305 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
306 :
307 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_11 <<
308 : SPDM_VERSION_NUMBER_SHIFT_BIT;
309 1 : spdm_context->local_context.local_cert_chain_provision[0] = m_libspdm_local_certificate_chain;
310 1 : spdm_context->local_context.local_cert_chain_provision_size[0] =
311 : sizeof(m_libspdm_local_certificate_chain);
312 1 : libspdm_set_mem (m_libspdm_local_certificate_chain, sizeof(m_libspdm_local_certificate_chain),
313 : (uint8_t)(0xFF));
314 :
315 1 : spdm_context->last_spdm_request_size = m_libspdm_get_digest_request_size;
316 1 : libspdm_copy_mem(spdm_context->last_spdm_request,
317 1 : libspdm_get_scratch_buffer_last_spdm_request_capacity(spdm_context),
318 : &m_libspdm_get_digest_request, m_libspdm_get_digest_request_size);
319 :
320 : /*RESPOND_IF_READY specific data*/
321 1 : spdm_context->cache_spdm_request_size = spdm_context->last_spdm_request_size;
322 1 : libspdm_copy_mem(spdm_context->cache_spdm_request,
323 1 : libspdm_get_scratch_buffer_cache_spdm_request_capacity(spdm_context),
324 1 : spdm_context->last_spdm_request, spdm_context->last_spdm_request_size);
325 1 : spdm_context->error_data.rd_exponent = 1;
326 1 : spdm_context->error_data.rd_tm = 1;
327 1 : spdm_context->error_data.request_code = SPDM_GET_DIGESTS;
328 1 : spdm_context->error_data.token = LIBSPDM_MY_TEST_TOKEN;
329 :
330 : /*check DIGESTS response*/
331 1 : response_size = sizeof(response);
332 1 : status = libspdm_get_response_respond_if_ready(spdm_context,
333 : m_libspdm_respond_if_ready_request1_size,
334 : &m_libspdm_respond_if_ready_request1,
335 : &response_size,
336 : response);
337 1 : assert_int_equal (status, LIBSPDM_STATUS_SUCCESS);
338 1 : assert_int_equal (response_size,
339 : sizeof(spdm_digest_response_t) +
340 : libspdm_get_hash_size(spdm_context->connection_info.algorithm.base_hash_algo));
341 1 : spdm_response = (void *)response;
342 1 : assert_int_equal (spdm_response->header.request_response_code, SPDM_DIGESTS);
343 1 : }
344 :
345 : #endif /* LIBSPDM_ENABLE_CAPABILITY_CERT_CAP*/
346 :
347 : /**
348 : * Test 2: receiving a correct RESPOND_IF_READY from the requester, after a
349 : * GET_CERTIFICATE could not be processed.
350 : * Expected behavior: the responder accepts the request and produces a valid CERTIFICATE
351 : * response message.
352 : **/
353 :
354 : #if LIBSPDM_ENABLE_CAPABILITY_CERT_CAP
355 :
356 1 : static void rsp_respond_if_ready_case2(void **state) {
357 : libspdm_return_t status;
358 : libspdm_test_context_t *spdm_test_context;
359 : libspdm_context_t *spdm_context;
360 : size_t response_size;
361 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
362 : spdm_certificate_response_t *spdm_response; /*response to the original request (CERTIFICATE)*/
363 : void *data;
364 : size_t data_size;
365 :
366 1 : spdm_test_context = *state;
367 1 : spdm_context = spdm_test_context->spdm_context;
368 1 : spdm_test_context->case_id = 0x2;
369 1 : spdm_context->response_state = LIBSPDM_RESPONSE_STATE_NORMAL;
370 :
371 : /*state for the the original request (GET_CERTIFICATE)*/
372 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_AFTER_DIGESTS;
373 1 : spdm_context->local_context.capability.flags = 0;
374 1 : spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
375 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
376 1 : spdm_context->connection_info.algorithm.base_asym_algo = m_libspdm_use_asym_algo;
377 :
378 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_11 <<
379 : SPDM_VERSION_NUMBER_SHIFT_BIT;
380 1 : libspdm_read_responder_public_certificate_chain (m_libspdm_use_hash_algo,
381 : m_libspdm_use_asym_algo,
382 : &data, &data_size,
383 : NULL, NULL);
384 1 : spdm_context->local_context.local_cert_chain_provision[0] = data;
385 1 : spdm_context->local_context.local_cert_chain_provision_size[0] = data_size;
386 :
387 1 : spdm_context->last_spdm_request_size = m_libspdm_get_certificate_request_size;
388 1 : libspdm_copy_mem(spdm_context->last_spdm_request,
389 1 : libspdm_get_scratch_buffer_last_spdm_request_capacity(spdm_context),
390 : &m_libspdm_get_certificate_request, m_libspdm_get_certificate_request_size);
391 :
392 : /*RESPOND_IF_READY specific data*/
393 1 : spdm_context->cache_spdm_request_size = spdm_context->last_spdm_request_size;
394 1 : libspdm_copy_mem(spdm_context->cache_spdm_request,
395 1 : libspdm_get_scratch_buffer_cache_spdm_request_capacity(spdm_context),
396 1 : spdm_context->last_spdm_request, spdm_context->last_spdm_request_size);
397 1 : spdm_context->error_data.rd_exponent = 1;
398 1 : spdm_context->error_data.rd_tm = 1;
399 1 : spdm_context->error_data.request_code = SPDM_GET_CERTIFICATE;
400 1 : spdm_context->error_data.token = LIBSPDM_MY_TEST_TOKEN;
401 :
402 : /*check CERTIFICATE response*/
403 1 : response_size = sizeof(response);
404 1 : status = libspdm_get_response_respond_if_ready(spdm_context,
405 : m_libspdm_respond_if_ready_request2_size,
406 : &m_libspdm_respond_if_ready_request2,
407 : &response_size,
408 : response);
409 1 : assert_int_equal (status, LIBSPDM_STATUS_SUCCESS);
410 1 : assert_int_equal (response_size,
411 : sizeof(spdm_certificate_response_t) + LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN);
412 1 : spdm_response = (void *)response;
413 1 : assert_int_equal (spdm_response->header.request_response_code, SPDM_CERTIFICATE);
414 1 : assert_int_equal (spdm_response->header.param1, 0);
415 1 : assert_int_equal (spdm_response->portion_length, LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN);
416 1 : assert_int_equal (spdm_response->remainder_length,
417 : data_size - LIBSPDM_MAX_CERT_CHAIN_BLOCK_LEN);
418 1 : free(data);
419 1 : }
420 :
421 : #endif /* LIBSPDM_ENABLE_CAPABILITY_CERT_CAP*/
422 :
423 : /**
424 : * Test 3: receiving a correct RESPOND_IF_READY from the requester, after a
425 : * CHALLENGE could not be processed.
426 : * Expected behavior: the responder accepts the request and produces a valid CHALLENGE_AUTH
427 : * response message.
428 : **/
429 : #if LIBSPDM_ENABLE_CAPABILITY_CHAL_CAP
430 1 : static void rsp_respond_if_ready_case3(void **state) {
431 : libspdm_return_t status;
432 : libspdm_test_context_t *spdm_test_context;
433 : libspdm_context_t *spdm_context;
434 : size_t response_size;
435 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
436 : spdm_challenge_auth_response_t *spdm_response; /*response to the original request (CHALLENGE_AUTH)*/
437 : void *data;
438 : size_t data_size;
439 :
440 1 : spdm_test_context = *state;
441 1 : spdm_context = spdm_test_context->spdm_context;
442 1 : spdm_test_context->case_id = 0x3;
443 1 : spdm_context->response_state = LIBSPDM_RESPONSE_STATE_NORMAL;
444 :
445 : /*state for the the original request (CHALLENGE)*/
446 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
447 1 : spdm_context->local_context.capability.flags = 0;
448 1 : spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
449 1 : spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CHAL_CAP;
450 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
451 1 : spdm_context->connection_info.algorithm.base_asym_algo = m_libspdm_use_asym_algo;
452 1 : spdm_context->connection_info.algorithm.measurement_spec = m_libspdm_use_measurement_spec;
453 1 : spdm_context->connection_info.algorithm.measurement_hash_algo =
454 : m_libspdm_use_measurement_hash_algo;
455 :
456 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_11 <<
457 : SPDM_VERSION_NUMBER_SHIFT_BIT;
458 1 : libspdm_read_responder_public_certificate_chain (m_libspdm_use_hash_algo,
459 : m_libspdm_use_asym_algo,
460 : &data, &data_size,
461 : NULL, NULL);
462 1 : spdm_context->local_context.local_cert_chain_provision[0] = data;
463 1 : spdm_context->local_context.local_cert_chain_provision_size[0] = data_size;
464 :
465 1 : libspdm_secret_lib_challenge_opaque_data_size = 0;
466 :
467 1 : spdm_context->last_spdm_request_size = m_libspdm_challenge_request_size;
468 1 : libspdm_copy_mem(spdm_context->last_spdm_request,
469 1 : libspdm_get_scratch_buffer_last_spdm_request_capacity(spdm_context),
470 : &m_libspdm_challenge_request, m_libspdm_challenge_request_size);
471 :
472 : /*RESPOND_IF_READY specific data*/
473 1 : spdm_context->cache_spdm_request_size = spdm_context->last_spdm_request_size;
474 1 : libspdm_copy_mem(spdm_context->cache_spdm_request,
475 1 : libspdm_get_scratch_buffer_cache_spdm_request_capacity(spdm_context),
476 1 : spdm_context->last_spdm_request, spdm_context->last_spdm_request_size);
477 1 : spdm_context->error_data.rd_exponent = 1;
478 1 : spdm_context->error_data.rd_tm = 1;
479 1 : spdm_context->error_data.request_code = SPDM_CHALLENGE;
480 1 : spdm_context->error_data.token = LIBSPDM_MY_TEST_TOKEN;
481 :
482 : /*check CHALLENGE response*/
483 1 : response_size = sizeof(response);
484 1 : libspdm_get_random_number (SPDM_NONCE_SIZE, m_libspdm_challenge_request.nonce);
485 1 : status = libspdm_get_response_respond_if_ready(spdm_context,
486 : m_libspdm_respond_if_ready_request3_size,
487 : &m_libspdm_respond_if_ready_request3,
488 : &response_size,
489 : response);
490 1 : assert_int_equal (status, LIBSPDM_STATUS_SUCCESS);
491 1 : assert_int_equal (response_size, sizeof(spdm_challenge_auth_response_t) + libspdm_get_hash_size (
492 : m_libspdm_use_hash_algo) + SPDM_NONCE_SIZE + 0 + sizeof(uint16_t) + 0 +
493 : libspdm_get_asym_signature_size ( m_libspdm_use_asym_algo));
494 1 : spdm_response = (void *)response;
495 1 : assert_int_equal (spdm_response->header.request_response_code, SPDM_CHALLENGE_AUTH);
496 1 : assert_int_equal (spdm_response->header.param1, 0);
497 1 : assert_int_equal (spdm_response->header.param2, 1 << 0);
498 1 : free(data);
499 1 : }
500 : #endif /* LIBSPDM_ENABLE_CAPABILITY_CHAL_CAP*/
501 :
502 : /**
503 : * Test 4: receiving a correct RESPOND_IF_READY from the requester, after a
504 : * GET_MEASUREMENTS could not be processed.
505 : * Expected behavior: the responder accepts the request and produces a valid MEASUREMENTS
506 : * response message.
507 : **/
508 :
509 : #if LIBSPDM_ENABLE_CAPABILITY_MEAS_CAP
510 :
511 : extern size_t libspdm_secret_lib_meas_opaque_data_size;
512 :
513 1 : static void rsp_respond_if_ready_case4(void **state) {
514 : libspdm_return_t status;
515 : libspdm_test_context_t *spdm_test_context;
516 : libspdm_context_t *spdm_context;
517 : size_t response_size;
518 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
519 : spdm_measurements_response_t *spdm_response; /*response to the original request (MEASUREMENTS)*/
520 :
521 1 : spdm_test_context = *state;
522 1 : spdm_context = spdm_test_context->spdm_context;
523 1 : spdm_test_context->case_id = 0x4;
524 1 : spdm_context->response_state = LIBSPDM_RESPONSE_STATE_NORMAL;
525 :
526 : /*state for the the original request (GET_MEASUREMENTS)*/
527 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_AUTHENTICATED;
528 1 : spdm_context->local_context.capability.flags = 0;
529 1 : spdm_context->local_context.capability.flags |=
530 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MEAS_CAP_SIG;
531 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
532 1 : spdm_context->connection_info.algorithm.base_asym_algo = m_libspdm_use_asym_algo;
533 1 : spdm_context->connection_info.algorithm.measurement_spec = m_libspdm_use_measurement_spec;
534 1 : spdm_context->connection_info.algorithm.measurement_hash_algo =
535 : m_libspdm_use_measurement_hash_algo;
536 :
537 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_11 <<
538 : SPDM_VERSION_NUMBER_SHIFT_BIT;
539 1 : libspdm_secret_lib_meas_opaque_data_size = 0;
540 :
541 1 : spdm_context->last_spdm_request_size = m_libspdm_get_measurements_request_size;
542 1 : libspdm_copy_mem(spdm_context->last_spdm_request,
543 1 : libspdm_get_scratch_buffer_last_spdm_request_capacity(spdm_context),
544 : &m_libspdm_get_measurements_request, m_libspdm_get_measurements_request_size);
545 :
546 : /*RESPOND_IF_READY specific data*/
547 1 : spdm_context->cache_spdm_request_size = spdm_context->last_spdm_request_size;
548 1 : libspdm_copy_mem(spdm_context->cache_spdm_request,
549 1 : libspdm_get_scratch_buffer_cache_spdm_request_capacity(spdm_context),
550 1 : spdm_context->last_spdm_request, spdm_context->last_spdm_request_size);
551 1 : spdm_context->error_data.rd_exponent = 1;
552 1 : spdm_context->error_data.rd_tm = 1;
553 1 : spdm_context->error_data.request_code = SPDM_GET_MEASUREMENTS;
554 1 : spdm_context->error_data.token = LIBSPDM_MY_TEST_TOKEN;
555 :
556 : /*check MEASUREMENT response*/
557 1 : response_size = sizeof(response);
558 1 : libspdm_get_random_number (SPDM_NONCE_SIZE, m_libspdm_get_measurements_request.nonce);
559 1 : status = libspdm_get_response_respond_if_ready(spdm_context,
560 : m_libspdm_respond_if_ready_request4_size,
561 : &m_libspdm_respond_if_ready_request4,
562 : &response_size,
563 : response);
564 1 : assert_int_equal (status, LIBSPDM_STATUS_SUCCESS);
565 1 : assert_int_equal (response_size,
566 : sizeof(spdm_measurements_response_t) + sizeof(uint16_t) + SPDM_NONCE_SIZE);
567 1 : spdm_response = (void *)response;
568 1 : assert_int_equal (spdm_response->header.request_response_code, SPDM_MEASUREMENTS);
569 1 : assert_int_equal (spdm_response->header.param1, LIBSPDM_MEASUREMENT_BLOCK_NUMBER);
570 1 : }
571 :
572 : #endif /* LIBSPDM_ENABLE_CAPABILITY_MEAS_CAP*/
573 :
574 : /**
575 : * Test 5: receiving a correct RESPOND_IF_READY from the requester, after a
576 : * KEY_EXCHANGE could not be processed.
577 : * Expected behavior: the responder accepts the request and produces a valid KEY_EXCHANGE_RSP
578 : * response message.
579 : **/
580 : #if LIBSPDM_ENABLE_CAPABILITY_KEY_EX_CAP
581 :
582 1 : static void rsp_respond_if_ready_case5(void **state) {
583 : libspdm_return_t status;
584 : libspdm_test_context_t *spdm_test_context;
585 : libspdm_context_t *spdm_context;
586 : size_t response_size;
587 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
588 : spdm_key_exchange_response_t *spdm_response; /*response to the original request (KEY_EXCHANGE_RSP)*/
589 : void *data;
590 : size_t data_size;
591 : uint8_t *ptr;
592 : size_t dhe_key_size;
593 : void *dhe_context;
594 : size_t opaque_key_exchange_req_size;
595 :
596 1 : spdm_test_context = *state;
597 1 : spdm_context = spdm_test_context->spdm_context;
598 1 : spdm_test_context->case_id = 0x5;
599 1 : spdm_context->response_state = LIBSPDM_RESPONSE_STATE_NORMAL;
600 :
601 : /*state for the the original request (KEY_EXCHANGE)*/
602 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_AUTHENTICATED;
603 1 : spdm_context->connection_info.capability.flags |=
604 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_KEY_EX_CAP |
605 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MAC_CAP;
606 1 : spdm_context->local_context.capability.flags =
607 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_KEY_EX_CAP |
608 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MAC_CAP |
609 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
610 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
611 1 : spdm_context->connection_info.algorithm.base_asym_algo = m_libspdm_use_asym_algo;
612 1 : spdm_context->connection_info.algorithm.measurement_spec = m_libspdm_use_measurement_spec;
613 1 : spdm_context->connection_info.algorithm.measurement_hash_algo =
614 : m_libspdm_use_measurement_hash_algo;
615 1 : spdm_context->connection_info.algorithm.dhe_named_group = m_libspdm_use_dhe_algo;
616 1 : spdm_context->connection_info.algorithm.aead_cipher_suite = m_libspdm_use_aead_algo;
617 :
618 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_11 <<
619 : SPDM_VERSION_NUMBER_SHIFT_BIT;
620 1 : libspdm_read_responder_public_certificate_chain (m_libspdm_use_hash_algo,
621 : m_libspdm_use_asym_algo,
622 : &data, &data_size,
623 : NULL, NULL);
624 1 : spdm_context->local_context.local_cert_chain_provision[0] = data;
625 1 : spdm_context->local_context.local_cert_chain_provision_size[0] = data_size;
626 :
627 1 : m_libspdm_key_exchange_request.req_session_id = 0xFFFF;
628 1 : m_libspdm_key_exchange_request.reserved = 0;
629 1 : ptr = m_libspdm_key_exchange_request.random_data;
630 1 : libspdm_get_random_number (SPDM_RANDOM_DATA_SIZE, ptr);
631 1 : ptr += SPDM_RANDOM_DATA_SIZE;
632 1 : dhe_key_size = libspdm_get_dhe_pub_key_size (m_libspdm_use_dhe_algo);
633 1 : dhe_context = libspdm_dhe_new (spdm_context->connection_info.version, m_libspdm_use_dhe_algo,
634 : false);
635 1 : libspdm_dhe_generate_key (m_libspdm_use_dhe_algo, dhe_context, ptr, &dhe_key_size);
636 1 : ptr += dhe_key_size;
637 1 : libspdm_dhe_free (m_libspdm_use_dhe_algo, dhe_context);
638 1 : opaque_key_exchange_req_size =
639 1 : libspdm_get_opaque_data_supported_version_data_size (spdm_context);
640 1 : libspdm_write_uint16(ptr, (uint16_t)opaque_key_exchange_req_size);
641 1 : ptr += sizeof(uint16_t);
642 1 : libspdm_build_opaque_data_supported_version_data (spdm_context, &opaque_key_exchange_req_size,
643 : ptr);
644 1 : ptr += opaque_key_exchange_req_size;
645 :
646 1 : spdm_context->last_spdm_request_size = m_libspdm_key_exchange_request_size;
647 1 : libspdm_copy_mem(spdm_context->last_spdm_request,
648 1 : libspdm_get_scratch_buffer_last_spdm_request_capacity(spdm_context),
649 : &m_libspdm_key_exchange_request, m_libspdm_key_exchange_request_size);
650 :
651 : /*RESPOND_IF_READY specific data*/
652 1 : spdm_context->cache_spdm_request_size = spdm_context->last_spdm_request_size;
653 1 : libspdm_copy_mem(spdm_context->cache_spdm_request,
654 1 : libspdm_get_scratch_buffer_cache_spdm_request_capacity(spdm_context),
655 1 : spdm_context->last_spdm_request, spdm_context->last_spdm_request_size);
656 1 : spdm_context->error_data.rd_exponent = 1;
657 1 : spdm_context->error_data.rd_tm = 1;
658 1 : spdm_context->error_data.request_code = SPDM_KEY_EXCHANGE;
659 1 : spdm_context->error_data.token = LIBSPDM_MY_TEST_TOKEN;
660 :
661 : /*check KEY_EXCHANGE_RSP response*/
662 1 : response_size = sizeof(response);
663 1 : status = libspdm_get_response_respond_if_ready(spdm_context,
664 : m_libspdm_respond_if_ready_request5_size,
665 : &m_libspdm_respond_if_ready_request5,
666 : &response_size,
667 : response);
668 1 : assert_int_equal (status, LIBSPDM_STATUS_SUCCESS);
669 1 : assert_int_equal (response_size,
670 : sizeof(spdm_key_exchange_response_t) + dhe_key_size + 2 +
671 : libspdm_get_opaque_data_version_selection_data_size(
672 : spdm_context) +
673 : libspdm_get_opaque_data_aead_limit_element_size(
674 : spdm_context,
675 : SECURED_SPDM_VERSION_13 << SPDM_VERSION_NUMBER_SHIFT_BIT) +
676 : libspdm_get_asym_signature_size (
677 : m_libspdm_use_asym_algo) +
678 : libspdm_get_hash_size (m_libspdm_use_hash_algo));
679 1 : assert_int_equal (libspdm_secured_message_get_session_state (spdm_context->session_info[0].
680 : secured_message_context),
681 : LIBSPDM_SESSION_STATE_HANDSHAKING);
682 1 : spdm_response = (void *)response;
683 1 : assert_int_equal (spdm_response->header.request_response_code, SPDM_KEY_EXCHANGE_RSP);
684 1 : assert_int_equal (spdm_response->rsp_session_id, 0xFFFF);
685 1 : free(data);
686 1 : libspdm_free_session_id (spdm_context, (0xFFFFFFFF));
687 1 : }
688 :
689 : #endif /* LIBSPDM_ENABLE_CAPABILITY_KEY_EX_CAP*/
690 :
691 : /**
692 : * Test 6: receiving a correct RESPOND_IF_READY from the requester, after a
693 : * FINISH could not be processed.
694 : * Expected behavior: the responder accepts the request and produces a valid FINISH_RSP
695 : * response message.
696 : **/
697 : #if LIBSPDM_ENABLE_CAPABILITY_KEY_EX_CAP
698 :
699 1 : static void rsp_respond_if_ready_case6(void **state) {
700 : libspdm_return_t status;
701 : libspdm_test_context_t *spdm_test_context;
702 : libspdm_context_t *spdm_context;
703 : size_t response_size;
704 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
705 : spdm_finish_response_t *spdm_response; /*response to the original request (FINISH_RSP)*/
706 : void *data;
707 : size_t data_size;
708 : uint8_t *ptr;
709 : uint8_t dummy_buffer[LIBSPDM_MAX_HASH_SIZE];
710 : uint8_t *cert_buffer;
711 : size_t cert_buffer_size;
712 : uint8_t cert_buffer_hash[LIBSPDM_MAX_HASH_SIZE];
713 : uint8_t hash_data[LIBSPDM_MAX_HASH_SIZE];
714 : uint8_t request_finished_key[LIBSPDM_MAX_HASH_SIZE];
715 : libspdm_session_info_t *session_info;
716 : uint32_t session_id;
717 : uint32_t hash_size;
718 : uint32_t hmac_size;
719 :
720 1 : spdm_test_context = *state;
721 1 : spdm_context = spdm_test_context->spdm_context;
722 1 : spdm_test_context->case_id = 0x6;
723 1 : spdm_context->response_state = LIBSPDM_RESPONSE_STATE_NORMAL;
724 :
725 : /*state for the the original request (FINISH)*/
726 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_AUTHENTICATED;
727 1 : spdm_context->local_context.capability.flags = 0;
728 1 : spdm_context->connection_info.capability.flags |=
729 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_KEY_EX_CAP;
730 1 : spdm_context->connection_info.capability.flags |=
731 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_HANDSHAKE_IN_THE_CLEAR_CAP;
732 1 : spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_KEY_EX_CAP;
733 1 : spdm_context->local_context.capability.flags |=
734 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_HANDSHAKE_IN_THE_CLEAR_CAP;
735 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
736 1 : spdm_context->connection_info.algorithm.base_asym_algo = m_libspdm_use_asym_algo;
737 1 : spdm_context->connection_info.algorithm.measurement_spec = m_libspdm_use_measurement_spec;
738 1 : spdm_context->connection_info.algorithm.measurement_hash_algo =
739 : m_libspdm_use_measurement_hash_algo;
740 1 : spdm_context->connection_info.algorithm.dhe_named_group = m_libspdm_use_dhe_algo;
741 1 : spdm_context->connection_info.algorithm.aead_cipher_suite = m_libspdm_use_aead_algo;
742 :
743 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_11 <<
744 : SPDM_VERSION_NUMBER_SHIFT_BIT;
745 1 : libspdm_read_responder_public_certificate_chain (m_libspdm_use_hash_algo,
746 : m_libspdm_use_asym_algo,
747 : &data, &data_size,
748 : NULL, NULL);
749 1 : spdm_context->local_context.local_cert_chain_provision[0] = data;
750 1 : spdm_context->local_context.local_cert_chain_provision_size[0] = data_size;
751 :
752 1 : session_id = 0xFFFFFFFF;
753 1 : spdm_context->latest_session_id = session_id;
754 1 : session_info = &spdm_context->session_info[0];
755 1 : libspdm_session_info_init (spdm_context, session_info, session_id,
756 : SECURED_SPDM_VERSION_11 << SPDM_VERSION_NUMBER_SHIFT_BIT, false);
757 1 : session_info->local_used_cert_chain_slot_id = 0;
758 1 : hash_size = libspdm_get_hash_size (m_libspdm_use_hash_algo);
759 1 : libspdm_set_mem (dummy_buffer, hash_size, (uint8_t)(0xFF));
760 1 : libspdm_secured_message_set_request_finished_key (session_info->secured_message_context,
761 : dummy_buffer, hash_size);
762 1 : libspdm_secured_message_set_session_state (session_info->secured_message_context,
763 : LIBSPDM_SESSION_STATE_HANDSHAKING);
764 :
765 1 : hash_size = libspdm_get_hash_size (m_libspdm_use_hash_algo);
766 1 : hmac_size = libspdm_get_hash_size (m_libspdm_use_hash_algo);
767 1 : ptr = m_libspdm_finish_request.signature;
768 1 : libspdm_init_managed_buffer(&th_curr, sizeof(th_curr.buffer));
769 1 : cert_buffer = (uint8_t *)data;
770 1 : cert_buffer_size = data_size;
771 1 : libspdm_hash_all (m_libspdm_use_hash_algo, cert_buffer, cert_buffer_size, cert_buffer_hash);
772 : /* Transcript.MessageA size is 0*/
773 1 : libspdm_append_managed_buffer (&th_curr, cert_buffer_hash, hash_size);
774 : /* SessionTranscript.MessageK is 0*/
775 1 : libspdm_append_managed_buffer (&th_curr, (uint8_t *)&m_libspdm_finish_request,
776 : sizeof(spdm_finish_request_t));
777 1 : libspdm_set_mem (request_finished_key, LIBSPDM_MAX_HASH_SIZE, (uint8_t)(0xFF));
778 1 : libspdm_hash_all(m_libspdm_use_hash_algo, libspdm_get_managed_buffer(&th_curr),
779 : libspdm_get_managed_buffer_size(&th_curr), hash_data);
780 1 : libspdm_hmac_all(m_libspdm_use_hash_algo, hash_data, hash_size,
781 : request_finished_key, hash_size, ptr);
782 :
783 1 : spdm_context->last_spdm_request_size = sizeof(spdm_finish_request_t) + hmac_size;
784 1 : libspdm_copy_mem(spdm_context->last_spdm_request,
785 1 : libspdm_get_scratch_buffer_last_spdm_request_capacity(spdm_context),
786 : &m_libspdm_finish_request, m_libspdm_finish_request_size);
787 :
788 : /*RESPOND_IF_READY specific data*/
789 1 : spdm_context->cache_spdm_request_size = spdm_context->last_spdm_request_size;
790 1 : libspdm_copy_mem(spdm_context->cache_spdm_request,
791 1 : libspdm_get_scratch_buffer_cache_spdm_request_capacity(spdm_context),
792 1 : spdm_context->last_spdm_request, spdm_context->last_spdm_request_size);
793 1 : spdm_context->error_data.rd_exponent = 1;
794 1 : spdm_context->error_data.rd_tm = 1;
795 1 : spdm_context->error_data.request_code = SPDM_FINISH;
796 1 : spdm_context->error_data.token = LIBSPDM_MY_TEST_TOKEN;
797 :
798 : /*check FINISH_RSP response*/
799 1 : response_size = sizeof(response);
800 1 : status = libspdm_get_response_respond_if_ready(spdm_context,
801 : m_libspdm_respond_if_ready_request6_size,
802 : &m_libspdm_respond_if_ready_request6,
803 : &response_size,
804 : response);
805 1 : assert_int_equal (status, LIBSPDM_STATUS_SUCCESS);
806 1 : assert_int_equal (response_size, sizeof(spdm_finish_response_t) + hmac_size);
807 1 : spdm_response = (void *)response;
808 1 : assert_int_equal (spdm_response->header.request_response_code, SPDM_FINISH_RSP);
809 1 : free(data);
810 1 : libspdm_free_session_id (spdm_context, (0xFFFFFFFF));
811 1 : }
812 : #endif /* LIBSPDM_ENABLE_CAPABILITY_KEY_EX_CAP*/
813 :
814 : /**
815 : * Test 7: receiving a correct RESPOND_IF_READY from the requester, after a
816 : * PSK_EXCHANGE could not be processed.
817 : * Expected behavior: the responder accepts the request and produces a valid PSK_EXCHANGE_RSP
818 : * response message.
819 : **/
820 : #if LIBSPDM_ENABLE_CAPABILITY_PSK_CAP
821 :
822 1 : static void rsp_respond_if_ready_case7(void **state) {
823 : libspdm_return_t status;
824 : libspdm_test_context_t *spdm_test_context;
825 : libspdm_context_t *spdm_context;
826 : size_t response_size;
827 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
828 : spdm_psk_exchange_response_t *spdm_response; /*response to the original request (PSK_EXCHANGE_RSP)*/
829 : void *data;
830 : size_t data_size;
831 : uint8_t *ptr;
832 : size_t opaque_psk_exchange_req_size;
833 :
834 1 : spdm_test_context = *state;
835 1 : spdm_context = spdm_test_context->spdm_context;
836 1 : spdm_test_context->case_id = 0x7;
837 1 : spdm_context->response_state = LIBSPDM_RESPONSE_STATE_NORMAL;
838 :
839 : /*state for the the original request (PSK_EXCHANGE)*/
840 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_AUTHENTICATED;
841 1 : spdm_context->local_context.capability.flags = 0;
842 1 : spdm_context->connection_info.capability.flags |=
843 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_PSK_CAP |
844 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MAC_CAP;
845 1 : spdm_context->local_context.capability.flags |=
846 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_PSK_CAP |
847 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MAC_CAP;
848 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
849 1 : spdm_context->connection_info.algorithm.base_asym_algo = m_libspdm_use_asym_algo;
850 1 : spdm_context->connection_info.algorithm.measurement_spec = m_libspdm_use_measurement_spec;
851 1 : spdm_context->connection_info.algorithm.measurement_hash_algo =
852 : m_libspdm_use_measurement_hash_algo;
853 1 : spdm_context->connection_info.algorithm.dhe_named_group = m_libspdm_use_dhe_algo;
854 1 : spdm_context->connection_info.algorithm.aead_cipher_suite = m_libspdm_use_aead_algo;
855 1 : spdm_context->connection_info.algorithm.key_schedule = m_libspdm_use_key_schedule_algo;
856 :
857 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_11 <<
858 : SPDM_VERSION_NUMBER_SHIFT_BIT;
859 1 : libspdm_read_responder_public_certificate_chain (m_libspdm_use_hash_algo,
860 : m_libspdm_use_asym_algo,
861 : &data, &data_size,
862 : NULL, NULL);
863 1 : spdm_context->local_context.local_cert_chain_provision[0] = data;
864 1 : spdm_context->local_context.local_cert_chain_provision_size[0] = data_size;
865 :
866 1 : m_libspdm_psk_exchange_request.psk_hint_length = (uint16_t)sizeof(LIBSPDM_TEST_PSK_HINT_STRING);
867 1 : m_libspdm_psk_exchange_request.requester_context_length = LIBSPDM_PSK_CONTEXT_LENGTH;
868 1 : opaque_psk_exchange_req_size =
869 1 : libspdm_get_opaque_data_supported_version_data_size (spdm_context);
870 1 : m_libspdm_psk_exchange_request.opaque_length = (uint16_t)opaque_psk_exchange_req_size;
871 1 : m_libspdm_psk_exchange_request.req_session_id = 0xFFFF;
872 1 : ptr = m_libspdm_psk_exchange_request.psk_hint;
873 1 : libspdm_copy_mem(ptr, sizeof(m_libspdm_psk_exchange_request.psk_hint),
874 : LIBSPDM_TEST_PSK_HINT_STRING,
875 : sizeof(LIBSPDM_TEST_PSK_HINT_STRING));
876 1 : ptr += m_libspdm_psk_exchange_request.psk_hint_length;
877 1 : libspdm_get_random_number (LIBSPDM_PSK_CONTEXT_LENGTH, ptr);
878 1 : ptr += m_libspdm_psk_exchange_request.requester_context_length;
879 1 : libspdm_build_opaque_data_supported_version_data (spdm_context, &opaque_psk_exchange_req_size,
880 : ptr);
881 1 : ptr += opaque_psk_exchange_req_size;
882 :
883 1 : spdm_context->last_spdm_request_size = m_libspdm_psk_exchange_request_size;
884 1 : libspdm_copy_mem(spdm_context->last_spdm_request,
885 1 : libspdm_get_scratch_buffer_last_spdm_request_capacity(spdm_context),
886 : &m_libspdm_psk_exchange_request, m_libspdm_psk_exchange_request_size);
887 :
888 : /*RESPOND_IF_READY specific data*/
889 1 : spdm_context->cache_spdm_request_size = spdm_context->last_spdm_request_size;
890 1 : libspdm_copy_mem(spdm_context->cache_spdm_request,
891 1 : libspdm_get_scratch_buffer_cache_spdm_request_capacity(spdm_context),
892 1 : spdm_context->last_spdm_request, spdm_context->last_spdm_request_size);
893 1 : spdm_context->error_data.rd_exponent = 1;
894 1 : spdm_context->error_data.rd_tm = 1;
895 1 : spdm_context->error_data.request_code = SPDM_PSK_EXCHANGE;
896 1 : spdm_context->error_data.token = LIBSPDM_MY_TEST_TOKEN;
897 :
898 : /*check PSK_EXCHANGE_RSP response*/
899 1 : response_size = sizeof(response);
900 1 : status = libspdm_get_response_respond_if_ready(spdm_context,
901 : m_libspdm_respond_if_ready_request7_size,
902 : &m_libspdm_respond_if_ready_request7,
903 : &response_size,
904 : response);
905 1 : assert_int_equal (status, LIBSPDM_STATUS_SUCCESS);
906 1 : assert_int_equal (response_size,
907 : sizeof(spdm_psk_exchange_response_t) + LIBSPDM_PSK_CONTEXT_LENGTH +
908 : libspdm_get_opaque_data_version_selection_data_size(
909 : spdm_context) +
910 : libspdm_get_opaque_data_aead_limit_element_size(
911 : spdm_context,
912 : SECURED_SPDM_VERSION_13 << SPDM_VERSION_NUMBER_SHIFT_BIT) +
913 : libspdm_get_hash_size (m_libspdm_use_hash_algo));
914 1 : assert_int_equal (libspdm_secured_message_get_session_state (spdm_context->session_info[0].
915 : secured_message_context),
916 : LIBSPDM_SESSION_STATE_HANDSHAKING);
917 1 : spdm_response = (void *)response;
918 1 : assert_int_equal (spdm_response->header.request_response_code, SPDM_PSK_EXCHANGE_RSP);
919 1 : assert_int_equal (spdm_response->rsp_session_id, 0xFFFF);
920 1 : free(data);
921 1 : libspdm_free_session_id (spdm_context, (0xFFFFFFFF));
922 1 : }
923 : #endif /* LIBSPDM_ENABLE_CAPABILITY_PSK_CAP*/
924 :
925 : /**
926 : * Test 8: receiving a correct RESPOND_IF_READY from the requester, after a
927 : * PSK_FINISH could not be processed.
928 : * Expected behavior: the responder accepts the request and produces a valid PSK_FINISH_RSP
929 : * response message.
930 : **/
931 : #if LIBSPDM_ENABLE_CAPABILITY_PSK_CAP
932 1 : static void rsp_respond_if_ready_case8(void **state) {
933 : libspdm_return_t status;
934 : libspdm_test_context_t *spdm_test_context;
935 : libspdm_context_t *spdm_context;
936 : size_t response_size;
937 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
938 : spdm_psk_finish_response_t *spdm_response; /*response to the original request (FINISH_PSK_RSP)*/
939 : void *data;
940 : size_t data_size;
941 : uint8_t *ptr;
942 : uint8_t dummy_buffer[LIBSPDM_MAX_HASH_SIZE];
943 : uint8_t hash_data[LIBSPDM_MAX_HASH_SIZE];
944 : uint8_t request_finished_key[LIBSPDM_MAX_HASH_SIZE];
945 : libspdm_session_info_t *session_info;
946 : uint32_t session_id;
947 : uint32_t hash_size;
948 : uint32_t hmac_size;
949 :
950 1 : spdm_test_context = *state;
951 1 : spdm_context = spdm_test_context->spdm_context;
952 1 : spdm_test_context->case_id = 0x8;
953 1 : spdm_context->response_state = LIBSPDM_RESPONSE_STATE_NORMAL;
954 :
955 : /*state for the the original request (PSK_FINISH)*/
956 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_AUTHENTICATED;
957 1 : spdm_context->local_context.capability.flags = 0;
958 1 : spdm_context->connection_info.capability.flags |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_PSK_CAP;
959 1 : spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_PSK_CAP;
960 1 : spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_KEY_EX_CAP;
961 1 : spdm_context->local_context.capability.flags |=
962 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_HANDSHAKE_IN_THE_CLEAR_CAP;
963 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
964 1 : spdm_context->connection_info.algorithm.base_asym_algo = m_libspdm_use_asym_algo;
965 1 : spdm_context->connection_info.algorithm.measurement_spec = m_libspdm_use_measurement_spec;
966 1 : spdm_context->connection_info.algorithm.measurement_hash_algo =
967 : m_libspdm_use_measurement_hash_algo;
968 1 : spdm_context->connection_info.algorithm.dhe_named_group = m_libspdm_use_dhe_algo;
969 1 : spdm_context->connection_info.algorithm.aead_cipher_suite = m_libspdm_use_aead_algo;
970 :
971 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_11 <<
972 : SPDM_VERSION_NUMBER_SHIFT_BIT;
973 1 : libspdm_read_responder_public_certificate_chain (m_libspdm_use_hash_algo,
974 : m_libspdm_use_asym_algo,
975 : &data, &data_size,
976 : NULL, NULL);
977 1 : spdm_context->local_context.local_cert_chain_provision[0] = data;
978 1 : spdm_context->local_context.local_cert_chain_provision_size[0] = data_size;
979 :
980 1 : session_id = 0xFFFFFFFF;
981 1 : spdm_context->latest_session_id = session_id;
982 1 : spdm_context->last_spdm_request_session_id_valid = true;
983 1 : spdm_context->last_spdm_request_session_id = session_id;
984 1 : session_info = &spdm_context->session_info[0];
985 1 : libspdm_session_info_init (spdm_context, session_info, session_id,
986 : SECURED_SPDM_VERSION_11 << SPDM_VERSION_NUMBER_SHIFT_BIT, true);
987 1 : libspdm_session_info_set_psk_hint(session_info,
988 : LIBSPDM_TEST_PSK_HINT_STRING,
989 : sizeof(LIBSPDM_TEST_PSK_HINT_STRING));
990 1 : hash_size = libspdm_get_hash_size (m_libspdm_use_hash_algo);
991 1 : libspdm_set_mem (dummy_buffer, hash_size, (uint8_t)(0xFF));
992 1 : libspdm_secured_message_set_request_finished_key (session_info->secured_message_context,
993 : dummy_buffer, hash_size);
994 1 : libspdm_secured_message_set_session_state (session_info->secured_message_context,
995 : LIBSPDM_SESSION_STATE_HANDSHAKING);
996 :
997 1 : hash_size = libspdm_get_hash_size (m_libspdm_use_hash_algo);
998 1 : hmac_size = libspdm_get_hash_size (m_libspdm_use_hash_algo);
999 1 : ptr = m_libspdm_psk_finish_request.verify_data;
1000 1 : libspdm_init_managed_buffer(&th_curr, sizeof(th_curr.buffer));
1001 : /* Transcript.MessageA size is 0
1002 : * SessionTranscript.MessageK is 0*/
1003 1 : libspdm_append_managed_buffer (&th_curr, (uint8_t *)&m_libspdm_psk_finish_request,
1004 : sizeof(spdm_psk_finish_request_t));
1005 1 : libspdm_set_mem (request_finished_key, LIBSPDM_MAX_HASH_SIZE, (uint8_t)(0xFF));
1006 1 : libspdm_hash_all(m_libspdm_use_hash_algo, libspdm_get_managed_buffer(&th_curr),
1007 : libspdm_get_managed_buffer_size(&th_curr), hash_data);
1008 1 : libspdm_hmac_all(m_libspdm_use_hash_algo, hash_data, hash_size,
1009 : request_finished_key, hash_size, ptr);
1010 :
1011 1 : spdm_context->last_spdm_request_size = sizeof(spdm_psk_finish_request_t) + hmac_size;
1012 1 : libspdm_copy_mem(spdm_context->last_spdm_request,
1013 1 : libspdm_get_scratch_buffer_last_spdm_request_capacity(spdm_context),
1014 : &m_libspdm_psk_finish_request, m_libspdm_psk_finish_request_size);
1015 :
1016 : /*RESPOND_IF_READY specific data*/
1017 1 : spdm_context->cache_spdm_request_size = spdm_context->last_spdm_request_size;
1018 1 : libspdm_copy_mem(spdm_context->cache_spdm_request,
1019 1 : libspdm_get_scratch_buffer_cache_spdm_request_capacity(spdm_context),
1020 1 : spdm_context->last_spdm_request, spdm_context->last_spdm_request_size);
1021 : /* The original PSK_FINISH was in a session; the RESPOND_IF_READY arrives in that same session. */
1022 1 : spdm_context->cache_spdm_request_session_id_valid = true;
1023 1 : spdm_context->cache_spdm_request_session_id = session_id;
1024 1 : spdm_context->error_data.rd_exponent = 1;
1025 1 : spdm_context->error_data.rd_tm = 1;
1026 1 : spdm_context->error_data.request_code = SPDM_PSK_FINISH;
1027 1 : spdm_context->error_data.token = LIBSPDM_MY_TEST_TOKEN;
1028 :
1029 : /*check FINISH_PSK_RSP response*/
1030 1 : response_size = sizeof(response);
1031 1 : status = libspdm_get_response_respond_if_ready(spdm_context,
1032 : m_libspdm_respond_if_ready_request8_size,
1033 : &m_libspdm_respond_if_ready_request8,
1034 : &response_size,
1035 : response);
1036 1 : assert_int_equal (status, LIBSPDM_STATUS_SUCCESS);
1037 1 : assert_int_equal (response_size, sizeof(spdm_psk_finish_response_t));
1038 1 : spdm_response = (void *)response;
1039 1 : assert_int_equal (spdm_response->header.request_response_code, SPDM_PSK_FINISH_RSP);
1040 1 : free(data);
1041 1 : libspdm_free_session_id (spdm_context, (0xFFFFFFFF));
1042 1 : }
1043 : #endif /* LIBSPDM_ENABLE_CAPABILITY_PSK_CAP*/
1044 :
1045 : #if LIBSPDM_ENABLE_CAPABILITY_CERT_CAP
1046 :
1047 : /**
1048 : * Test 9:
1049 : * Expected behavior:
1050 : **/
1051 1 : static void rsp_respond_if_ready_case9(void **state) {
1052 1 : }
1053 :
1054 : #endif /* LIBSPDM_ENABLE_CAPABILITY_CERT_CAP*/
1055 :
1056 : #if LIBSPDM_ENABLE_CAPABILITY_CERT_CAP
1057 : /**
1058 : * Test 10: receiving a correct RESPOND_IF_READY from the requester, but the responder is in
1059 : * a Busy state.
1060 : * Expected behavior: the responder accepts the request, but produces an ERROR message
1061 : * indicating the Busy state.
1062 : **/
1063 1 : static void rsp_respond_if_ready_case10(void **state) {
1064 : libspdm_return_t status;
1065 : libspdm_test_context_t *spdm_test_context;
1066 : libspdm_context_t *spdm_context;
1067 : size_t response_size;
1068 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
1069 : spdm_digest_response_t *spdm_response; /*response to the original request (DIGESTS)*/
1070 :
1071 1 : spdm_test_context = *state;
1072 1 : spdm_context = spdm_test_context->spdm_context;
1073 1 : spdm_test_context->case_id = 0xA;
1074 : /* Connection (non-session) original request and RESPOND_IF_READY: both contexts are
1075 : * out-of-session. Set explicitly so the test does not depend on prior cases' state. */
1076 1 : spdm_context->cache_spdm_request_session_id_valid = false;
1077 1 : spdm_context->last_spdm_request_session_id_valid = false;
1078 1 : spdm_context->response_state = LIBSPDM_RESPONSE_STATE_BUSY;
1079 :
1080 : /*state for the the original request (GET_DIGESTS)*/
1081 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
1082 1 : spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
1083 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
1084 1 : spdm_context->local_context.local_cert_chain_provision[0] = m_libspdm_local_certificate_chain;
1085 1 : spdm_context->local_context.local_cert_chain_provision_size[0] =
1086 : sizeof(m_libspdm_local_certificate_chain);
1087 1 : libspdm_set_mem (m_libspdm_local_certificate_chain, sizeof(m_libspdm_local_certificate_chain),
1088 : (uint8_t)(0xFF));
1089 :
1090 1 : spdm_context->last_spdm_request_size = m_libspdm_get_digest_request_size;
1091 1 : libspdm_copy_mem(spdm_context->last_spdm_request,
1092 1 : libspdm_get_scratch_buffer_last_spdm_request_capacity(spdm_context),
1093 : &m_libspdm_get_digest_request, m_libspdm_get_digest_request_size);
1094 :
1095 : /*RESPOND_IF_READY specific data*/
1096 1 : spdm_context->cache_spdm_request_size = spdm_context->last_spdm_request_size;
1097 1 : libspdm_copy_mem(spdm_context->cache_spdm_request,
1098 1 : libspdm_get_scratch_buffer_cache_spdm_request_capacity(spdm_context),
1099 1 : spdm_context->last_spdm_request, spdm_context->last_spdm_request_size);
1100 1 : spdm_context->error_data.rd_exponent = 1;
1101 1 : spdm_context->error_data.rd_tm = 1;
1102 1 : spdm_context->error_data.request_code = SPDM_GET_DIGESTS;
1103 1 : spdm_context->error_data.token = LIBSPDM_MY_TEST_TOKEN;
1104 :
1105 : /*check ERROR response*/
1106 1 : response_size = sizeof(response);
1107 1 : status = libspdm_get_response_respond_if_ready(spdm_context,
1108 : m_libspdm_respond_if_ready_request1_size,
1109 : &m_libspdm_respond_if_ready_request1,
1110 : &response_size,
1111 : response);
1112 1 : assert_int_equal (status, LIBSPDM_STATUS_SUCCESS);
1113 1 : assert_int_equal (response_size, sizeof(spdm_error_response_t));
1114 1 : spdm_response = (void *)response;
1115 1 : assert_int_equal (spdm_response->header.request_response_code, SPDM_ERROR);
1116 1 : assert_int_equal (spdm_response->header.param1, SPDM_ERROR_CODE_BUSY);
1117 1 : assert_int_equal (spdm_response->header.param2, 0);
1118 1 : assert_int_equal (spdm_context->response_state, LIBSPDM_RESPONSE_STATE_BUSY);
1119 1 : }
1120 :
1121 : #endif /* LIBSPDM_ENABLE_CAPABILITY_CERT_CAP*/
1122 :
1123 : #if LIBSPDM_ENABLE_CAPABILITY_CERT_CAP
1124 : /**
1125 : * Test 11: receiving a correct RESPOND_IF_READY from the requester, but the responder requires
1126 : * resynchronization with the requester.
1127 : * Expected behavior: the responder accepts the request, but produces an ERROR message
1128 : * indicating the NeedResynch state.
1129 : **/
1130 1 : static void rsp_respond_if_ready_case11(void **state) {
1131 : libspdm_return_t status;
1132 : libspdm_test_context_t *spdm_test_context;
1133 : libspdm_context_t *spdm_context;
1134 : size_t response_size;
1135 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
1136 : spdm_digest_response_t *spdm_response; /*response to the original request (DIGESTS)*/
1137 :
1138 1 : spdm_test_context = *state;
1139 1 : spdm_context = spdm_test_context->spdm_context;
1140 1 : spdm_test_context->case_id = 0xB;
1141 : /* Connection (non-session) original request and RESPOND_IF_READY: both contexts are
1142 : * out-of-session. Set explicitly so the test does not depend on prior cases' state. */
1143 1 : spdm_context->cache_spdm_request_session_id_valid = false;
1144 1 : spdm_context->last_spdm_request_session_id_valid = false;
1145 1 : spdm_context->response_state = LIBSPDM_RESPONSE_STATE_NEED_RESYNC;
1146 :
1147 : /*state for the the original request (GET_DIGESTS)*/
1148 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
1149 1 : spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
1150 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
1151 1 : spdm_context->local_context.local_cert_chain_provision[0] = m_libspdm_local_certificate_chain;
1152 1 : spdm_context->local_context.local_cert_chain_provision_size[0] =
1153 : sizeof(m_libspdm_local_certificate_chain);
1154 1 : libspdm_set_mem (m_libspdm_local_certificate_chain, sizeof(m_libspdm_local_certificate_chain),
1155 : (uint8_t)(0xFF));
1156 :
1157 1 : spdm_context->last_spdm_request_size = m_libspdm_get_digest_request_size;
1158 1 : libspdm_copy_mem(spdm_context->last_spdm_request,
1159 1 : libspdm_get_scratch_buffer_last_spdm_request_capacity(spdm_context),
1160 : &m_libspdm_get_digest_request, m_libspdm_get_digest_request_size);
1161 :
1162 : /*RESPOND_IF_READY specific data*/
1163 1 : spdm_context->cache_spdm_request_size = spdm_context->last_spdm_request_size;
1164 1 : libspdm_copy_mem(spdm_context->cache_spdm_request,
1165 1 : libspdm_get_scratch_buffer_cache_spdm_request_capacity(spdm_context),
1166 1 : spdm_context->last_spdm_request, spdm_context->last_spdm_request_size);
1167 1 : spdm_context->error_data.rd_exponent = 1;
1168 1 : spdm_context->error_data.rd_tm = 1;
1169 1 : spdm_context->error_data.request_code = SPDM_GET_DIGESTS;
1170 1 : spdm_context->error_data.token = LIBSPDM_MY_TEST_TOKEN;
1171 :
1172 : /*check ERROR response*/
1173 1 : response_size = sizeof(response);
1174 1 : status = libspdm_get_response_respond_if_ready(spdm_context,
1175 : m_libspdm_respond_if_ready_request1_size,
1176 : &m_libspdm_respond_if_ready_request1,
1177 : &response_size,
1178 : response);
1179 1 : assert_int_equal (status, LIBSPDM_STATUS_SUCCESS);
1180 1 : assert_int_equal (response_size, sizeof(spdm_error_response_t));
1181 1 : spdm_response = (void *)response;
1182 1 : assert_int_equal (spdm_response->header.request_response_code, SPDM_ERROR);
1183 1 : assert_int_equal (spdm_response->header.param1, SPDM_ERROR_CODE_REQUEST_RESYNCH);
1184 1 : assert_int_equal (spdm_response->header.param2, 0);
1185 1 : assert_int_equal (spdm_context->response_state, LIBSPDM_RESPONSE_STATE_NEED_RESYNC);
1186 1 : }
1187 :
1188 : #endif /* LIBSPDM_ENABLE_CAPABILITY_CERT_CAP*/
1189 :
1190 : #if LIBSPDM_ENABLE_CAPABILITY_CERT_CAP
1191 :
1192 : /**
1193 : * Test 12: receiving a correct RESPOND_IF_READY from the requester, but the responder could not
1194 : * produce the response in time.
1195 : * Expected behavior: the responder accepts the request, but produces an ERROR message
1196 : * indicating the ResponseNotReady state, with the same token as the request.
1197 : **/
1198 1 : static void rsp_respond_if_ready_case12(void **state) {
1199 : libspdm_return_t status;
1200 : libspdm_test_context_t *spdm_test_context;
1201 : libspdm_context_t *spdm_context;
1202 : size_t response_size;
1203 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
1204 : spdm_digest_response_t *spdm_response; /*response to the original request (DIGESTS)*/
1205 : spdm_error_data_response_not_ready_t *error_data;
1206 :
1207 1 : spdm_test_context = *state;
1208 1 : spdm_context = spdm_test_context->spdm_context;
1209 1 : spdm_test_context->case_id = 0xC;
1210 : /* Connection (non-session) original request and RESPOND_IF_READY: both contexts are
1211 : * out-of-session. Set explicitly so the test does not depend on prior cases' state. */
1212 1 : spdm_context->cache_spdm_request_session_id_valid = false;
1213 1 : spdm_context->last_spdm_request_session_id_valid = false;
1214 1 : spdm_context->response_state = LIBSPDM_RESPONSE_STATE_NOT_READY;
1215 :
1216 : /*state for the the original request (GET_DIGESTS)*/
1217 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
1218 1 : spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
1219 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
1220 1 : spdm_context->local_context.local_cert_chain_provision[0] = m_libspdm_local_certificate_chain;
1221 1 : spdm_context->local_context.local_cert_chain_provision_size[0] =
1222 : sizeof(m_libspdm_local_certificate_chain);
1223 1 : libspdm_set_mem (m_libspdm_local_certificate_chain, sizeof(m_libspdm_local_certificate_chain),
1224 : (uint8_t)(0xFF));
1225 :
1226 1 : spdm_context->last_spdm_request_size = m_libspdm_get_digest_request_size;
1227 1 : libspdm_copy_mem(spdm_context->last_spdm_request,
1228 1 : libspdm_get_scratch_buffer_last_spdm_request_capacity(spdm_context),
1229 : &m_libspdm_get_digest_request, m_libspdm_get_digest_request_size);
1230 :
1231 : /*RESPOND_IF_READY specific data*/
1232 1 : spdm_context->cache_spdm_request_size = spdm_context->last_spdm_request_size;
1233 1 : libspdm_copy_mem(spdm_context->cache_spdm_request,
1234 1 : libspdm_get_scratch_buffer_cache_spdm_request_capacity(spdm_context),
1235 1 : spdm_context->last_spdm_request, spdm_context->last_spdm_request_size);
1236 1 : spdm_context->error_data.rd_exponent = 1;
1237 1 : spdm_context->error_data.rd_tm = 1;
1238 1 : spdm_context->error_data.request_code = SPDM_GET_DIGESTS;
1239 1 : spdm_context->error_data.token = LIBSPDM_MY_TEST_TOKEN;
1240 :
1241 : /*check ERROR response*/
1242 1 : response_size = sizeof(response);
1243 1 : status = libspdm_get_response_respond_if_ready(spdm_context,
1244 : m_libspdm_respond_if_ready_request1_size,
1245 : &m_libspdm_respond_if_ready_request1,
1246 : &response_size,
1247 : response);
1248 1 : assert_int_equal (status, LIBSPDM_STATUS_SUCCESS);
1249 1 : assert_int_equal (response_size,
1250 : sizeof(spdm_error_response_t) + sizeof(spdm_error_data_response_not_ready_t));
1251 1 : spdm_response = (void *)response;
1252 1 : error_data = (spdm_error_data_response_not_ready_t*)(spdm_response + 1);
1253 1 : assert_int_equal (spdm_response->header.request_response_code, SPDM_ERROR);
1254 1 : assert_int_equal (spdm_response->header.param1, SPDM_ERROR_CODE_RESPONSE_NOT_READY);
1255 1 : assert_int_equal (spdm_response->header.param2, 0);
1256 1 : assert_int_equal (spdm_context->response_state, LIBSPDM_RESPONSE_STATE_NOT_READY);
1257 1 : assert_int_equal (error_data->request_code, SPDM_GET_DIGESTS);
1258 1 : assert_int_equal (error_data->token, LIBSPDM_MY_TEST_TOKEN);
1259 1 : }
1260 :
1261 : #endif /* LIBSPDM_ENABLE_CAPABILITY_CERT_CAP*/
1262 :
1263 : #if LIBSPDM_ENABLE_CAPABILITY_CERT_CAP
1264 :
1265 : /**
1266 : * Test 13: receiving a correct RESPOND_IF_READY from the requester, with the correct original
1267 : * request code, but with a token different from the expected.
1268 : * Expected behavior: the responder refuses the RESPOND_IF_READY message and produces an
1269 : * ERROR message indicating the InvalidRequest.
1270 : **/
1271 1 : static void rsp_respond_if_ready_case13(void **state) {
1272 : libspdm_return_t status;
1273 : libspdm_test_context_t *spdm_test_context;
1274 : libspdm_context_t *spdm_context;
1275 : size_t response_size;
1276 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
1277 : spdm_digest_response_t *spdm_response; /*response to the original request (DIGESTS)*/
1278 :
1279 1 : spdm_test_context = *state;
1280 1 : spdm_context = spdm_test_context->spdm_context;
1281 1 : spdm_test_context->case_id = 0xD;
1282 : /* Connection (non-session) original request and RESPOND_IF_READY: both contexts are
1283 : * out-of-session. Set explicitly so the test does not depend on prior cases' state. */
1284 1 : spdm_context->cache_spdm_request_session_id_valid = false;
1285 1 : spdm_context->last_spdm_request_session_id_valid = false;
1286 1 : spdm_context->response_state = LIBSPDM_RESPONSE_STATE_NORMAL;
1287 :
1288 : /*state for the the original request (GET_DIGESTS)*/
1289 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
1290 1 : spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
1291 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
1292 1 : spdm_context->local_context.local_cert_chain_provision[0] = m_libspdm_local_certificate_chain;
1293 1 : spdm_context->local_context.local_cert_chain_provision_size[0] =
1294 : sizeof(m_libspdm_local_certificate_chain);
1295 1 : libspdm_set_mem (m_libspdm_local_certificate_chain, sizeof(m_libspdm_local_certificate_chain),
1296 : (uint8_t)(0xFF));
1297 :
1298 1 : spdm_context->last_spdm_request_size = m_libspdm_get_digest_request_size;
1299 1 : libspdm_copy_mem(spdm_context->last_spdm_request,
1300 1 : libspdm_get_scratch_buffer_last_spdm_request_capacity(spdm_context),
1301 : &m_libspdm_get_digest_request, m_libspdm_get_digest_request_size);
1302 :
1303 : /*RESPOND_IF_READY specific data*/
1304 1 : spdm_context->cache_spdm_request_size = spdm_context->last_spdm_request_size;
1305 1 : libspdm_copy_mem(spdm_context->cache_spdm_request,
1306 1 : libspdm_get_scratch_buffer_cache_spdm_request_capacity(spdm_context),
1307 1 : spdm_context->last_spdm_request, spdm_context->last_spdm_request_size);
1308 1 : spdm_context->error_data.rd_exponent = 1;
1309 1 : spdm_context->error_data.rd_tm = 1;
1310 1 : spdm_context->error_data.request_code = SPDM_GET_DIGESTS;
1311 1 : spdm_context->error_data.token = LIBSPDM_MY_TEST_TOKEN;
1312 :
1313 : /*check ERROR response*/
1314 1 : response_size = sizeof(response);
1315 1 : status = libspdm_get_response_respond_if_ready(spdm_context,
1316 : m_libspdm_respond_if_ready_request10_size,
1317 : &m_libspdm_respond_if_ready_request10,
1318 : &response_size,
1319 : response);
1320 1 : assert_int_equal (status, LIBSPDM_STATUS_SUCCESS);
1321 1 : assert_int_equal (response_size, sizeof(spdm_error_response_t));
1322 1 : spdm_response = (void *)response;
1323 1 : assert_int_equal (spdm_response->header.request_response_code, SPDM_ERROR);
1324 1 : assert_int_equal (spdm_response->header.param1, SPDM_ERROR_CODE_INVALID_REQUEST);
1325 1 : assert_int_equal (spdm_response->header.param2, 0);
1326 1 : }
1327 : #endif /* LIBSPDM_ENABLE_CAPABILITY_CERT_CAP*/
1328 :
1329 : #if LIBSPDM_ENABLE_CAPABILITY_CERT_CAP
1330 : /**
1331 : * Test 14: receiving a correct RESPOND_IF_READY from the requester, with the correct token,
1332 : * but with a request code different from the expected.
1333 : * Expected behavior: the responder refuses the RESPOND_IF_READY message and produces an
1334 : * ERROR message indicating the InvalidRequest.
1335 : **/
1336 1 : static void rsp_respond_if_ready_case14(void **state) {
1337 : libspdm_return_t status;
1338 : libspdm_test_context_t *spdm_test_context;
1339 : libspdm_context_t *spdm_context;
1340 : size_t response_size;
1341 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
1342 : spdm_digest_response_t *spdm_response; /*response to the original request (DIGESTS)*/
1343 :
1344 1 : spdm_test_context = *state;
1345 1 : spdm_context = spdm_test_context->spdm_context;
1346 1 : spdm_test_context->case_id = 0xE;
1347 : /* Connection (non-session) original request and RESPOND_IF_READY: both contexts are
1348 : * out-of-session. Set explicitly so the test does not depend on prior cases' state. */
1349 1 : spdm_context->cache_spdm_request_session_id_valid = false;
1350 1 : spdm_context->last_spdm_request_session_id_valid = false;
1351 1 : spdm_context->response_state = LIBSPDM_RESPONSE_STATE_NORMAL;
1352 :
1353 : /*state for the the original request (GET_DIGESTS)*/
1354 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
1355 1 : spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
1356 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
1357 1 : spdm_context->local_context.local_cert_chain_provision[0] = m_libspdm_local_certificate_chain;
1358 1 : spdm_context->local_context.local_cert_chain_provision_size[0] =
1359 : sizeof(m_libspdm_local_certificate_chain);
1360 1 : libspdm_set_mem (m_libspdm_local_certificate_chain, sizeof(m_libspdm_local_certificate_chain),
1361 : (uint8_t)(0xFF));
1362 :
1363 1 : spdm_context->last_spdm_request_size = m_libspdm_get_digest_request_size;
1364 1 : libspdm_copy_mem(spdm_context->last_spdm_request,
1365 1 : libspdm_get_scratch_buffer_last_spdm_request_capacity(spdm_context),
1366 : &m_libspdm_get_digest_request, m_libspdm_get_digest_request_size);
1367 :
1368 : /*RESPOND_IF_READY specific data*/
1369 1 : spdm_context->cache_spdm_request_size = spdm_context->last_spdm_request_size;
1370 1 : libspdm_copy_mem(spdm_context->cache_spdm_request,
1371 1 : libspdm_get_scratch_buffer_cache_spdm_request_capacity(spdm_context),
1372 1 : spdm_context->last_spdm_request, spdm_context->last_spdm_request_size);
1373 1 : spdm_context->error_data.rd_exponent = 1;
1374 1 : spdm_context->error_data.rd_tm = 1;
1375 1 : spdm_context->error_data.request_code = SPDM_GET_DIGESTS;
1376 1 : spdm_context->error_data.token = LIBSPDM_MY_TEST_TOKEN;
1377 :
1378 : /*check ERROR response*/
1379 1 : response_size = sizeof(response);
1380 1 : status = libspdm_get_response_respond_if_ready(spdm_context,
1381 : m_libspdm_respond_if_ready_request11_size,
1382 : &m_libspdm_respond_if_ready_request11,
1383 : &response_size,
1384 : response);
1385 1 : assert_int_equal (status, LIBSPDM_STATUS_SUCCESS);
1386 1 : assert_int_equal (response_size, sizeof(spdm_error_response_t));
1387 1 : spdm_response = (void *)response;
1388 1 : assert_int_equal (spdm_response->header.request_response_code, SPDM_ERROR);
1389 1 : assert_int_equal (spdm_response->header.param1, SPDM_ERROR_CODE_INVALID_REQUEST);
1390 1 : assert_int_equal (spdm_response->header.param2, 0);
1391 1 : }
1392 :
1393 : /**
1394 : * Test 15: receiving a RESPOND_IF_READY with the correct original request code and token, but in a
1395 : * DIFFERENT session context than the original request. Here the original request (GET_DIGESTS) was
1396 : * received outside of a session, but the RESPOND_IF_READY arrives inside a session.
1397 : * Expected behavior: per DSP0274 the validity of RESPOND_IF_READY is defined by the original
1398 : * request, so a context mismatch is refused with ERROR(UnexpectedRequest); the cached response is
1399 : * NOT returned.
1400 : **/
1401 1 : static void rsp_respond_if_ready_case15(void **state) {
1402 : libspdm_return_t status;
1403 : libspdm_test_context_t *spdm_test_context;
1404 : libspdm_context_t *spdm_context;
1405 : size_t response_size;
1406 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
1407 : spdm_error_response_t *spdm_response;
1408 :
1409 1 : spdm_test_context = *state;
1410 1 : spdm_context = spdm_test_context->spdm_context;
1411 1 : spdm_test_context->case_id = 0xF;
1412 1 : spdm_context->response_state = LIBSPDM_RESPONSE_STATE_NORMAL;
1413 :
1414 : /*state for the the original request (GET_DIGESTS)*/
1415 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
1416 1 : spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
1417 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
1418 1 : spdm_context->local_context.local_cert_chain_provision[0] = m_libspdm_local_certificate_chain;
1419 1 : spdm_context->local_context.local_cert_chain_provision_size[0] =
1420 : sizeof(m_libspdm_local_certificate_chain);
1421 1 : libspdm_set_mem (m_libspdm_local_certificate_chain, sizeof(m_libspdm_local_certificate_chain),
1422 : (uint8_t)(0xFF));
1423 :
1424 1 : spdm_context->last_spdm_request_size = m_libspdm_get_digest_request_size;
1425 1 : libspdm_copy_mem(spdm_context->last_spdm_request,
1426 1 : libspdm_get_scratch_buffer_last_spdm_request_capacity(spdm_context),
1427 : &m_libspdm_get_digest_request, m_libspdm_get_digest_request_size);
1428 :
1429 : /*RESPOND_IF_READY specific data: the original GET_DIGESTS was received OUTSIDE a session.*/
1430 1 : spdm_context->cache_spdm_request_size = spdm_context->last_spdm_request_size;
1431 1 : libspdm_copy_mem(spdm_context->cache_spdm_request,
1432 1 : libspdm_get_scratch_buffer_cache_spdm_request_capacity(spdm_context),
1433 1 : spdm_context->last_spdm_request, spdm_context->last_spdm_request_size);
1434 1 : spdm_context->cache_spdm_request_session_id_valid = false;
1435 1 : spdm_context->error_data.rd_exponent = 1;
1436 1 : spdm_context->error_data.rd_tm = 1;
1437 1 : spdm_context->error_data.request_code = SPDM_GET_DIGESTS;
1438 1 : spdm_context->error_data.token = LIBSPDM_MY_TEST_TOKEN;
1439 :
1440 : /* But the RESPOND_IF_READY arrives INSIDE a session -- a context mismatch. */
1441 1 : spdm_context->last_spdm_request_session_id_valid = true;
1442 1 : spdm_context->last_spdm_request_session_id = 0xFFFFFFFF;
1443 :
1444 : /*check ERROR response*/
1445 1 : response_size = sizeof(response);
1446 1 : status = libspdm_get_response_respond_if_ready(spdm_context,
1447 : m_libspdm_respond_if_ready_request1_size,
1448 : &m_libspdm_respond_if_ready_request1,
1449 : &response_size,
1450 : response);
1451 1 : assert_int_equal (status, LIBSPDM_STATUS_SUCCESS);
1452 1 : assert_int_equal (response_size, sizeof(spdm_error_response_t));
1453 1 : spdm_response = (void *)response;
1454 1 : assert_int_equal (spdm_response->header.request_response_code, SPDM_ERROR);
1455 1 : assert_int_equal (spdm_response->header.param1, SPDM_ERROR_CODE_UNEXPECTED_REQUEST);
1456 1 : assert_int_equal (spdm_response->header.param2, 0);
1457 :
1458 : /* restore for subsequent cases */
1459 1 : spdm_context->last_spdm_request_session_id_valid = false;
1460 1 : }
1461 : #endif /* LIBSPDM_ENABLE_CAPABILITY_CERT_CAP*/
1462 :
1463 1 : int libspdm_rsp_respond_if_ready_test(void) {
1464 1 : const struct CMUnitTest test_cases[] = {
1465 : /* Success Case*/
1466 : #if LIBSPDM_ENABLE_CAPABILITY_CERT_CAP
1467 : cmocka_unit_test(rsp_respond_if_ready_case1),
1468 : cmocka_unit_test(rsp_respond_if_ready_case2),
1469 : #endif /* LIBSPDM_ENABLE_CAPABILITY_CERT_CAP*/
1470 :
1471 : #if LIBSPDM_ENABLE_CAPABILITY_CHAL_CAP
1472 : cmocka_unit_test(rsp_respond_if_ready_case3),
1473 : #endif /* LIBSPDM_ENABLE_CAPABILITY_CHAL_CAP*/
1474 :
1475 : #if LIBSPDM_ENABLE_CAPABILITY_MEAS_CAP
1476 : cmocka_unit_test(rsp_respond_if_ready_case4),
1477 : #endif /* LIBSPDM_ENABLE_CAPABILITY_MEAS_CAP*/
1478 :
1479 : #if LIBSPDM_ENABLE_CAPABILITY_KEY_EX_CAP
1480 : cmocka_unit_test(rsp_respond_if_ready_case5),
1481 : cmocka_unit_test(rsp_respond_if_ready_case6),
1482 : #endif /* LIBSPDM_ENABLE_CAPABILITY_KEY_EX_CAP*/
1483 :
1484 : #if LIBSPDM_ENABLE_CAPABILITY_PSK_CAP
1485 : cmocka_unit_test(rsp_respond_if_ready_case7),
1486 : cmocka_unit_test(rsp_respond_if_ready_case8),
1487 : #endif /* LIBSPDM_ENABLE_CAPABILITY_PSK_CAP*/
1488 :
1489 : #if LIBSPDM_ENABLE_CAPABILITY_CERT_CAP
1490 : cmocka_unit_test(rsp_respond_if_ready_case9),
1491 : cmocka_unit_test(rsp_respond_if_ready_case10),
1492 : cmocka_unit_test(rsp_respond_if_ready_case11),
1493 : cmocka_unit_test(rsp_respond_if_ready_case12),
1494 : cmocka_unit_test(rsp_respond_if_ready_case13),
1495 : cmocka_unit_test(rsp_respond_if_ready_case14),
1496 : cmocka_unit_test(rsp_respond_if_ready_case15),
1497 : #endif /* LIBSPDM_ENABLE_CAPABILITY_CERT_CAP*/
1498 :
1499 : };
1500 :
1501 1 : libspdm_test_context_t test_context = {
1502 : LIBSPDM_TEST_CONTEXT_VERSION,
1503 : false,
1504 : };
1505 :
1506 1 : libspdm_setup_test_context (&test_context);
1507 :
1508 1 : return cmocka_run_group_tests(test_cases,
1509 : libspdm_unit_test_group_setup,
1510 : libspdm_unit_test_group_teardown);
1511 : }
1512 : #endif /* LIBSPDM_ENABLE_CAPABILITY_*_CAP */
1513 : #endif /* LIBSPDM_RESPOND_IF_READY_SUPPORT */
|