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) + libspdm_get_asym_signature_size (
673 : m_libspdm_use_asym_algo) +
674 : libspdm_get_hash_size (m_libspdm_use_hash_algo));
675 1 : assert_int_equal (libspdm_secured_message_get_session_state (spdm_context->session_info[0].
676 : secured_message_context),
677 : LIBSPDM_SESSION_STATE_HANDSHAKING);
678 1 : spdm_response = (void *)response;
679 1 : assert_int_equal (spdm_response->header.request_response_code, SPDM_KEY_EXCHANGE_RSP);
680 1 : assert_int_equal (spdm_response->rsp_session_id, 0xFFFF);
681 1 : free(data);
682 1 : libspdm_free_session_id (spdm_context, (0xFFFFFFFF));
683 1 : }
684 :
685 : #endif /* LIBSPDM_ENABLE_CAPABILITY_KEY_EX_CAP*/
686 :
687 : /**
688 : * Test 6: receiving a correct RESPOND_IF_READY from the requester, after a
689 : * FINISH could not be processed.
690 : * Expected behavior: the responder accepts the request and produces a valid FINISH_RSP
691 : * response message.
692 : **/
693 : #if LIBSPDM_ENABLE_CAPABILITY_KEY_EX_CAP
694 :
695 1 : static void rsp_respond_if_ready_case6(void **state) {
696 : libspdm_return_t status;
697 : libspdm_test_context_t *spdm_test_context;
698 : libspdm_context_t *spdm_context;
699 : size_t response_size;
700 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
701 : spdm_finish_response_t *spdm_response; /*response to the original request (FINISH_RSP)*/
702 : void *data;
703 : size_t data_size;
704 : uint8_t *ptr;
705 : uint8_t dummy_buffer[LIBSPDM_MAX_HASH_SIZE];
706 : uint8_t *cert_buffer;
707 : size_t cert_buffer_size;
708 : uint8_t cert_buffer_hash[LIBSPDM_MAX_HASH_SIZE];
709 : uint8_t hash_data[LIBSPDM_MAX_HASH_SIZE];
710 : uint8_t request_finished_key[LIBSPDM_MAX_HASH_SIZE];
711 : libspdm_session_info_t *session_info;
712 : uint32_t session_id;
713 : uint32_t hash_size;
714 : uint32_t hmac_size;
715 :
716 1 : spdm_test_context = *state;
717 1 : spdm_context = spdm_test_context->spdm_context;
718 1 : spdm_test_context->case_id = 0x6;
719 1 : spdm_context->response_state = LIBSPDM_RESPONSE_STATE_NORMAL;
720 :
721 : /*state for the the original request (FINISH)*/
722 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_AUTHENTICATED;
723 1 : spdm_context->local_context.capability.flags = 0;
724 1 : spdm_context->connection_info.capability.flags |=
725 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_KEY_EX_CAP;
726 1 : spdm_context->connection_info.capability.flags |=
727 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_HANDSHAKE_IN_THE_CLEAR_CAP;
728 1 : spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_KEY_EX_CAP;
729 1 : spdm_context->local_context.capability.flags |=
730 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_HANDSHAKE_IN_THE_CLEAR_CAP;
731 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
732 1 : spdm_context->connection_info.algorithm.base_asym_algo = m_libspdm_use_asym_algo;
733 1 : spdm_context->connection_info.algorithm.measurement_spec = m_libspdm_use_measurement_spec;
734 1 : spdm_context->connection_info.algorithm.measurement_hash_algo =
735 : m_libspdm_use_measurement_hash_algo;
736 1 : spdm_context->connection_info.algorithm.dhe_named_group = m_libspdm_use_dhe_algo;
737 1 : spdm_context->connection_info.algorithm.aead_cipher_suite = m_libspdm_use_aead_algo;
738 :
739 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_11 <<
740 : SPDM_VERSION_NUMBER_SHIFT_BIT;
741 1 : libspdm_read_responder_public_certificate_chain (m_libspdm_use_hash_algo,
742 : m_libspdm_use_asym_algo,
743 : &data, &data_size,
744 : NULL, NULL);
745 1 : spdm_context->local_context.local_cert_chain_provision[0] = data;
746 1 : spdm_context->local_context.local_cert_chain_provision_size[0] = data_size;
747 :
748 1 : session_id = 0xFFFFFFFF;
749 1 : spdm_context->latest_session_id = session_id;
750 1 : session_info = &spdm_context->session_info[0];
751 1 : libspdm_session_info_init (spdm_context, session_info, session_id,
752 : SECURED_SPDM_VERSION_11 << SPDM_VERSION_NUMBER_SHIFT_BIT, false);
753 1 : session_info->local_used_cert_chain_slot_id = 0;
754 1 : hash_size = libspdm_get_hash_size (m_libspdm_use_hash_algo);
755 1 : libspdm_set_mem (dummy_buffer, hash_size, (uint8_t)(0xFF));
756 1 : libspdm_secured_message_set_request_finished_key (session_info->secured_message_context,
757 : dummy_buffer, hash_size);
758 1 : libspdm_secured_message_set_session_state (session_info->secured_message_context,
759 : LIBSPDM_SESSION_STATE_HANDSHAKING);
760 :
761 1 : hash_size = libspdm_get_hash_size (m_libspdm_use_hash_algo);
762 1 : hmac_size = libspdm_get_hash_size (m_libspdm_use_hash_algo);
763 1 : ptr = m_libspdm_finish_request.signature;
764 1 : libspdm_init_managed_buffer(&th_curr, sizeof(th_curr.buffer));
765 1 : cert_buffer = (uint8_t *)data;
766 1 : cert_buffer_size = data_size;
767 1 : libspdm_hash_all (m_libspdm_use_hash_algo, cert_buffer, cert_buffer_size, cert_buffer_hash);
768 : /* Transcript.MessageA size is 0*/
769 1 : libspdm_append_managed_buffer (&th_curr, cert_buffer_hash, hash_size);
770 : /* SessionTranscript.MessageK is 0*/
771 1 : libspdm_append_managed_buffer (&th_curr, (uint8_t *)&m_libspdm_finish_request,
772 : sizeof(spdm_finish_request_t));
773 1 : libspdm_set_mem (request_finished_key, LIBSPDM_MAX_HASH_SIZE, (uint8_t)(0xFF));
774 1 : libspdm_hash_all(m_libspdm_use_hash_algo, libspdm_get_managed_buffer(&th_curr),
775 : libspdm_get_managed_buffer_size(&th_curr), hash_data);
776 1 : libspdm_hmac_all(m_libspdm_use_hash_algo, hash_data, hash_size,
777 : request_finished_key, hash_size, ptr);
778 :
779 1 : spdm_context->last_spdm_request_size = sizeof(spdm_finish_request_t) + hmac_size;
780 1 : libspdm_copy_mem(spdm_context->last_spdm_request,
781 1 : libspdm_get_scratch_buffer_last_spdm_request_capacity(spdm_context),
782 : &m_libspdm_finish_request, m_libspdm_finish_request_size);
783 :
784 : /*RESPOND_IF_READY specific data*/
785 1 : spdm_context->cache_spdm_request_size = spdm_context->last_spdm_request_size;
786 1 : libspdm_copy_mem(spdm_context->cache_spdm_request,
787 1 : libspdm_get_scratch_buffer_cache_spdm_request_capacity(spdm_context),
788 1 : spdm_context->last_spdm_request, spdm_context->last_spdm_request_size);
789 1 : spdm_context->error_data.rd_exponent = 1;
790 1 : spdm_context->error_data.rd_tm = 1;
791 1 : spdm_context->error_data.request_code = SPDM_FINISH;
792 1 : spdm_context->error_data.token = LIBSPDM_MY_TEST_TOKEN;
793 :
794 : /*check FINISH_RSP response*/
795 1 : response_size = sizeof(response);
796 1 : status = libspdm_get_response_respond_if_ready(spdm_context,
797 : m_libspdm_respond_if_ready_request6_size,
798 : &m_libspdm_respond_if_ready_request6,
799 : &response_size,
800 : response);
801 1 : assert_int_equal (status, LIBSPDM_STATUS_SUCCESS);
802 1 : assert_int_equal (response_size, sizeof(spdm_finish_response_t) + hmac_size);
803 1 : spdm_response = (void *)response;
804 1 : assert_int_equal (spdm_response->header.request_response_code, SPDM_FINISH_RSP);
805 1 : free(data);
806 1 : libspdm_free_session_id (spdm_context, (0xFFFFFFFF));
807 1 : }
808 : #endif /* LIBSPDM_ENABLE_CAPABILITY_KEY_EX_CAP*/
809 :
810 : /**
811 : * Test 7: receiving a correct RESPOND_IF_READY from the requester, after a
812 : * PSK_EXCHANGE could not be processed.
813 : * Expected behavior: the responder accepts the request and produces a valid PSK_EXCHANGE_RSP
814 : * response message.
815 : **/
816 : #if LIBSPDM_ENABLE_CAPABILITY_PSK_CAP
817 :
818 1 : static void rsp_respond_if_ready_case7(void **state) {
819 : libspdm_return_t status;
820 : libspdm_test_context_t *spdm_test_context;
821 : libspdm_context_t *spdm_context;
822 : size_t response_size;
823 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
824 : spdm_psk_exchange_response_t *spdm_response; /*response to the original request (PSK_EXCHANGE_RSP)*/
825 : void *data;
826 : size_t data_size;
827 : uint8_t *ptr;
828 : size_t opaque_psk_exchange_req_size;
829 :
830 1 : spdm_test_context = *state;
831 1 : spdm_context = spdm_test_context->spdm_context;
832 1 : spdm_test_context->case_id = 0x7;
833 1 : spdm_context->response_state = LIBSPDM_RESPONSE_STATE_NORMAL;
834 :
835 : /*state for the the original request (PSK_EXCHANGE)*/
836 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_AUTHENTICATED;
837 1 : spdm_context->local_context.capability.flags = 0;
838 1 : spdm_context->connection_info.capability.flags |=
839 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_PSK_CAP |
840 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MAC_CAP;
841 1 : spdm_context->local_context.capability.flags |=
842 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_PSK_CAP |
843 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MAC_CAP;
844 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
845 1 : spdm_context->connection_info.algorithm.base_asym_algo = m_libspdm_use_asym_algo;
846 1 : spdm_context->connection_info.algorithm.measurement_spec = m_libspdm_use_measurement_spec;
847 1 : spdm_context->connection_info.algorithm.measurement_hash_algo =
848 : m_libspdm_use_measurement_hash_algo;
849 1 : spdm_context->connection_info.algorithm.dhe_named_group = m_libspdm_use_dhe_algo;
850 1 : spdm_context->connection_info.algorithm.aead_cipher_suite = m_libspdm_use_aead_algo;
851 1 : spdm_context->connection_info.algorithm.key_schedule = m_libspdm_use_key_schedule_algo;
852 :
853 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_11 <<
854 : SPDM_VERSION_NUMBER_SHIFT_BIT;
855 1 : libspdm_read_responder_public_certificate_chain (m_libspdm_use_hash_algo,
856 : m_libspdm_use_asym_algo,
857 : &data, &data_size,
858 : NULL, NULL);
859 1 : spdm_context->local_context.local_cert_chain_provision[0] = data;
860 1 : spdm_context->local_context.local_cert_chain_provision_size[0] = data_size;
861 :
862 1 : m_libspdm_psk_exchange_request.psk_hint_length = (uint16_t)sizeof(LIBSPDM_TEST_PSK_HINT_STRING);
863 1 : m_libspdm_psk_exchange_request.requester_context_length = LIBSPDM_PSK_CONTEXT_LENGTH;
864 1 : opaque_psk_exchange_req_size =
865 1 : libspdm_get_opaque_data_supported_version_data_size (spdm_context);
866 1 : m_libspdm_psk_exchange_request.opaque_length = (uint16_t)opaque_psk_exchange_req_size;
867 1 : m_libspdm_psk_exchange_request.req_session_id = 0xFFFF;
868 1 : ptr = m_libspdm_psk_exchange_request.psk_hint;
869 1 : libspdm_copy_mem(ptr, sizeof(m_libspdm_psk_exchange_request.psk_hint),
870 : LIBSPDM_TEST_PSK_HINT_STRING,
871 : sizeof(LIBSPDM_TEST_PSK_HINT_STRING));
872 1 : ptr += m_libspdm_psk_exchange_request.psk_hint_length;
873 1 : libspdm_get_random_number (LIBSPDM_PSK_CONTEXT_LENGTH, ptr);
874 1 : ptr += m_libspdm_psk_exchange_request.requester_context_length;
875 1 : libspdm_build_opaque_data_supported_version_data (spdm_context, &opaque_psk_exchange_req_size,
876 : ptr);
877 1 : ptr += opaque_psk_exchange_req_size;
878 :
879 1 : spdm_context->last_spdm_request_size = m_libspdm_psk_exchange_request_size;
880 1 : libspdm_copy_mem(spdm_context->last_spdm_request,
881 1 : libspdm_get_scratch_buffer_last_spdm_request_capacity(spdm_context),
882 : &m_libspdm_psk_exchange_request, m_libspdm_psk_exchange_request_size);
883 :
884 : /*RESPOND_IF_READY specific data*/
885 1 : spdm_context->cache_spdm_request_size = spdm_context->last_spdm_request_size;
886 1 : libspdm_copy_mem(spdm_context->cache_spdm_request,
887 1 : libspdm_get_scratch_buffer_cache_spdm_request_capacity(spdm_context),
888 1 : spdm_context->last_spdm_request, spdm_context->last_spdm_request_size);
889 1 : spdm_context->error_data.rd_exponent = 1;
890 1 : spdm_context->error_data.rd_tm = 1;
891 1 : spdm_context->error_data.request_code = SPDM_PSK_EXCHANGE;
892 1 : spdm_context->error_data.token = LIBSPDM_MY_TEST_TOKEN;
893 :
894 : /*check PSK_EXCHANGE_RSP response*/
895 1 : response_size = sizeof(response);
896 1 : status = libspdm_get_response_respond_if_ready(spdm_context,
897 : m_libspdm_respond_if_ready_request7_size,
898 : &m_libspdm_respond_if_ready_request7,
899 : &response_size,
900 : response);
901 1 : assert_int_equal (status, LIBSPDM_STATUS_SUCCESS);
902 1 : assert_int_equal (response_size,
903 : sizeof(spdm_psk_exchange_response_t) + LIBSPDM_PSK_CONTEXT_LENGTH +
904 : libspdm_get_opaque_data_version_selection_data_size(
905 : spdm_context) + libspdm_get_hash_size (m_libspdm_use_hash_algo));
906 1 : assert_int_equal (libspdm_secured_message_get_session_state (spdm_context->session_info[0].
907 : secured_message_context),
908 : LIBSPDM_SESSION_STATE_HANDSHAKING);
909 1 : spdm_response = (void *)response;
910 1 : assert_int_equal (spdm_response->header.request_response_code, SPDM_PSK_EXCHANGE_RSP);
911 1 : assert_int_equal (spdm_response->rsp_session_id, 0xFFFF);
912 1 : free(data);
913 1 : libspdm_free_session_id (spdm_context, (0xFFFFFFFF));
914 1 : }
915 : #endif /* LIBSPDM_ENABLE_CAPABILITY_PSK_CAP*/
916 :
917 : /**
918 : * Test 8: receiving a correct RESPOND_IF_READY from the requester, after a
919 : * PSK_FINISH could not be processed.
920 : * Expected behavior: the responder accepts the request and produces a valid PSK_FINISH_RSP
921 : * response message.
922 : **/
923 : #if LIBSPDM_ENABLE_CAPABILITY_PSK_CAP
924 1 : static void rsp_respond_if_ready_case8(void **state) {
925 : libspdm_return_t status;
926 : libspdm_test_context_t *spdm_test_context;
927 : libspdm_context_t *spdm_context;
928 : size_t response_size;
929 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
930 : spdm_psk_finish_response_t *spdm_response; /*response to the original request (FINISH_PSK_RSP)*/
931 : void *data;
932 : size_t data_size;
933 : uint8_t *ptr;
934 : uint8_t dummy_buffer[LIBSPDM_MAX_HASH_SIZE];
935 : uint8_t hash_data[LIBSPDM_MAX_HASH_SIZE];
936 : uint8_t request_finished_key[LIBSPDM_MAX_HASH_SIZE];
937 : libspdm_session_info_t *session_info;
938 : uint32_t session_id;
939 : uint32_t hash_size;
940 : uint32_t hmac_size;
941 :
942 1 : spdm_test_context = *state;
943 1 : spdm_context = spdm_test_context->spdm_context;
944 1 : spdm_test_context->case_id = 0x8;
945 1 : spdm_context->response_state = LIBSPDM_RESPONSE_STATE_NORMAL;
946 :
947 : /*state for the the original request (PSK_FINISH)*/
948 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_AUTHENTICATED;
949 1 : spdm_context->local_context.capability.flags = 0;
950 1 : spdm_context->connection_info.capability.flags |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_PSK_CAP;
951 1 : spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_PSK_CAP;
952 1 : spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_KEY_EX_CAP;
953 1 : spdm_context->local_context.capability.flags |=
954 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_HANDSHAKE_IN_THE_CLEAR_CAP;
955 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
956 1 : spdm_context->connection_info.algorithm.base_asym_algo = m_libspdm_use_asym_algo;
957 1 : spdm_context->connection_info.algorithm.measurement_spec = m_libspdm_use_measurement_spec;
958 1 : spdm_context->connection_info.algorithm.measurement_hash_algo =
959 : m_libspdm_use_measurement_hash_algo;
960 1 : spdm_context->connection_info.algorithm.dhe_named_group = m_libspdm_use_dhe_algo;
961 1 : spdm_context->connection_info.algorithm.aead_cipher_suite = m_libspdm_use_aead_algo;
962 :
963 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_11 <<
964 : SPDM_VERSION_NUMBER_SHIFT_BIT;
965 1 : libspdm_read_responder_public_certificate_chain (m_libspdm_use_hash_algo,
966 : m_libspdm_use_asym_algo,
967 : &data, &data_size,
968 : NULL, NULL);
969 1 : spdm_context->local_context.local_cert_chain_provision[0] = data;
970 1 : spdm_context->local_context.local_cert_chain_provision_size[0] = data_size;
971 :
972 1 : session_id = 0xFFFFFFFF;
973 1 : spdm_context->latest_session_id = session_id;
974 1 : spdm_context->last_spdm_request_session_id_valid = true;
975 1 : spdm_context->last_spdm_request_session_id = session_id;
976 1 : session_info = &spdm_context->session_info[0];
977 1 : libspdm_session_info_init (spdm_context, session_info, session_id,
978 : SECURED_SPDM_VERSION_11 << SPDM_VERSION_NUMBER_SHIFT_BIT, true);
979 1 : libspdm_session_info_set_psk_hint(session_info,
980 : LIBSPDM_TEST_PSK_HINT_STRING,
981 : sizeof(LIBSPDM_TEST_PSK_HINT_STRING));
982 1 : hash_size = libspdm_get_hash_size (m_libspdm_use_hash_algo);
983 1 : libspdm_set_mem (dummy_buffer, hash_size, (uint8_t)(0xFF));
984 1 : libspdm_secured_message_set_request_finished_key (session_info->secured_message_context,
985 : dummy_buffer, hash_size);
986 1 : libspdm_secured_message_set_session_state (session_info->secured_message_context,
987 : LIBSPDM_SESSION_STATE_HANDSHAKING);
988 :
989 1 : hash_size = libspdm_get_hash_size (m_libspdm_use_hash_algo);
990 1 : hmac_size = libspdm_get_hash_size (m_libspdm_use_hash_algo);
991 1 : ptr = m_libspdm_psk_finish_request.verify_data;
992 1 : libspdm_init_managed_buffer(&th_curr, sizeof(th_curr.buffer));
993 : /* Transcript.MessageA size is 0
994 : * SessionTranscript.MessageK is 0*/
995 1 : libspdm_append_managed_buffer (&th_curr, (uint8_t *)&m_libspdm_psk_finish_request,
996 : sizeof(spdm_psk_finish_request_t));
997 1 : libspdm_set_mem (request_finished_key, LIBSPDM_MAX_HASH_SIZE, (uint8_t)(0xFF));
998 1 : libspdm_hash_all(m_libspdm_use_hash_algo, libspdm_get_managed_buffer(&th_curr),
999 : libspdm_get_managed_buffer_size(&th_curr), hash_data);
1000 1 : libspdm_hmac_all(m_libspdm_use_hash_algo, hash_data, hash_size,
1001 : request_finished_key, hash_size, ptr);
1002 :
1003 1 : spdm_context->last_spdm_request_size = sizeof(spdm_psk_finish_request_t) + hmac_size;
1004 1 : libspdm_copy_mem(spdm_context->last_spdm_request,
1005 1 : libspdm_get_scratch_buffer_last_spdm_request_capacity(spdm_context),
1006 : &m_libspdm_psk_finish_request, m_libspdm_psk_finish_request_size);
1007 :
1008 : /*RESPOND_IF_READY specific data*/
1009 1 : spdm_context->cache_spdm_request_size = spdm_context->last_spdm_request_size;
1010 1 : libspdm_copy_mem(spdm_context->cache_spdm_request,
1011 1 : libspdm_get_scratch_buffer_cache_spdm_request_capacity(spdm_context),
1012 1 : spdm_context->last_spdm_request, spdm_context->last_spdm_request_size);
1013 : /* The original PSK_FINISH was in a session; the RESPOND_IF_READY arrives in that same session. */
1014 1 : spdm_context->cache_spdm_request_session_id_valid = true;
1015 1 : spdm_context->cache_spdm_request_session_id = session_id;
1016 1 : spdm_context->error_data.rd_exponent = 1;
1017 1 : spdm_context->error_data.rd_tm = 1;
1018 1 : spdm_context->error_data.request_code = SPDM_PSK_FINISH;
1019 1 : spdm_context->error_data.token = LIBSPDM_MY_TEST_TOKEN;
1020 :
1021 : /*check FINISH_PSK_RSP response*/
1022 1 : response_size = sizeof(response);
1023 1 : status = libspdm_get_response_respond_if_ready(spdm_context,
1024 : m_libspdm_respond_if_ready_request8_size,
1025 : &m_libspdm_respond_if_ready_request8,
1026 : &response_size,
1027 : response);
1028 1 : assert_int_equal (status, LIBSPDM_STATUS_SUCCESS);
1029 1 : assert_int_equal (response_size, sizeof(spdm_psk_finish_response_t));
1030 1 : spdm_response = (void *)response;
1031 1 : assert_int_equal (spdm_response->header.request_response_code, SPDM_PSK_FINISH_RSP);
1032 1 : free(data);
1033 1 : libspdm_free_session_id (spdm_context, (0xFFFFFFFF));
1034 1 : }
1035 : #endif /* LIBSPDM_ENABLE_CAPABILITY_PSK_CAP*/
1036 :
1037 : #if LIBSPDM_ENABLE_CAPABILITY_CERT_CAP
1038 :
1039 : /**
1040 : * Test 9:
1041 : * Expected behavior:
1042 : **/
1043 1 : static void rsp_respond_if_ready_case9(void **state) {
1044 1 : }
1045 :
1046 : #endif /* LIBSPDM_ENABLE_CAPABILITY_CERT_CAP*/
1047 :
1048 : #if LIBSPDM_ENABLE_CAPABILITY_CERT_CAP
1049 : /**
1050 : * Test 10: receiving a correct RESPOND_IF_READY from the requester, but the responder is in
1051 : * a Busy state.
1052 : * Expected behavior: the responder accepts the request, but produces an ERROR message
1053 : * indicating the Busy state.
1054 : **/
1055 1 : static void rsp_respond_if_ready_case10(void **state) {
1056 : libspdm_return_t status;
1057 : libspdm_test_context_t *spdm_test_context;
1058 : libspdm_context_t *spdm_context;
1059 : size_t response_size;
1060 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
1061 : spdm_digest_response_t *spdm_response; /*response to the original request (DIGESTS)*/
1062 :
1063 1 : spdm_test_context = *state;
1064 1 : spdm_context = spdm_test_context->spdm_context;
1065 1 : spdm_test_context->case_id = 0xA;
1066 : /* Connection (non-session) original request and RESPOND_IF_READY: both contexts are
1067 : * out-of-session. Set explicitly so the test does not depend on prior cases' state. */
1068 1 : spdm_context->cache_spdm_request_session_id_valid = false;
1069 1 : spdm_context->last_spdm_request_session_id_valid = false;
1070 1 : spdm_context->response_state = LIBSPDM_RESPONSE_STATE_BUSY;
1071 :
1072 : /*state for the the original request (GET_DIGESTS)*/
1073 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
1074 1 : spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
1075 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
1076 1 : spdm_context->local_context.local_cert_chain_provision[0] = m_libspdm_local_certificate_chain;
1077 1 : spdm_context->local_context.local_cert_chain_provision_size[0] =
1078 : sizeof(m_libspdm_local_certificate_chain);
1079 1 : libspdm_set_mem (m_libspdm_local_certificate_chain, sizeof(m_libspdm_local_certificate_chain),
1080 : (uint8_t)(0xFF));
1081 :
1082 1 : spdm_context->last_spdm_request_size = m_libspdm_get_digest_request_size;
1083 1 : libspdm_copy_mem(spdm_context->last_spdm_request,
1084 1 : libspdm_get_scratch_buffer_last_spdm_request_capacity(spdm_context),
1085 : &m_libspdm_get_digest_request, m_libspdm_get_digest_request_size);
1086 :
1087 : /*RESPOND_IF_READY specific data*/
1088 1 : spdm_context->cache_spdm_request_size = spdm_context->last_spdm_request_size;
1089 1 : libspdm_copy_mem(spdm_context->cache_spdm_request,
1090 1 : libspdm_get_scratch_buffer_cache_spdm_request_capacity(spdm_context),
1091 1 : spdm_context->last_spdm_request, spdm_context->last_spdm_request_size);
1092 1 : spdm_context->error_data.rd_exponent = 1;
1093 1 : spdm_context->error_data.rd_tm = 1;
1094 1 : spdm_context->error_data.request_code = SPDM_GET_DIGESTS;
1095 1 : spdm_context->error_data.token = LIBSPDM_MY_TEST_TOKEN;
1096 :
1097 : /*check ERROR response*/
1098 1 : response_size = sizeof(response);
1099 1 : status = libspdm_get_response_respond_if_ready(spdm_context,
1100 : m_libspdm_respond_if_ready_request1_size,
1101 : &m_libspdm_respond_if_ready_request1,
1102 : &response_size,
1103 : response);
1104 1 : assert_int_equal (status, LIBSPDM_STATUS_SUCCESS);
1105 1 : assert_int_equal (response_size, sizeof(spdm_error_response_t));
1106 1 : spdm_response = (void *)response;
1107 1 : assert_int_equal (spdm_response->header.request_response_code, SPDM_ERROR);
1108 1 : assert_int_equal (spdm_response->header.param1, SPDM_ERROR_CODE_BUSY);
1109 1 : assert_int_equal (spdm_response->header.param2, 0);
1110 1 : assert_int_equal (spdm_context->response_state, LIBSPDM_RESPONSE_STATE_BUSY);
1111 1 : }
1112 :
1113 : #endif /* LIBSPDM_ENABLE_CAPABILITY_CERT_CAP*/
1114 :
1115 : #if LIBSPDM_ENABLE_CAPABILITY_CERT_CAP
1116 : /**
1117 : * Test 11: receiving a correct RESPOND_IF_READY from the requester, but the responder requires
1118 : * resynchronization with the requester.
1119 : * Expected behavior: the responder accepts the request, but produces an ERROR message
1120 : * indicating the NeedResynch state.
1121 : **/
1122 1 : static void rsp_respond_if_ready_case11(void **state) {
1123 : libspdm_return_t status;
1124 : libspdm_test_context_t *spdm_test_context;
1125 : libspdm_context_t *spdm_context;
1126 : size_t response_size;
1127 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
1128 : spdm_digest_response_t *spdm_response; /*response to the original request (DIGESTS)*/
1129 :
1130 1 : spdm_test_context = *state;
1131 1 : spdm_context = spdm_test_context->spdm_context;
1132 1 : spdm_test_context->case_id = 0xB;
1133 : /* Connection (non-session) original request and RESPOND_IF_READY: both contexts are
1134 : * out-of-session. Set explicitly so the test does not depend on prior cases' state. */
1135 1 : spdm_context->cache_spdm_request_session_id_valid = false;
1136 1 : spdm_context->last_spdm_request_session_id_valid = false;
1137 1 : spdm_context->response_state = LIBSPDM_RESPONSE_STATE_NEED_RESYNC;
1138 :
1139 : /*state for the the original request (GET_DIGESTS)*/
1140 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
1141 1 : spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
1142 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
1143 1 : spdm_context->local_context.local_cert_chain_provision[0] = m_libspdm_local_certificate_chain;
1144 1 : spdm_context->local_context.local_cert_chain_provision_size[0] =
1145 : sizeof(m_libspdm_local_certificate_chain);
1146 1 : libspdm_set_mem (m_libspdm_local_certificate_chain, sizeof(m_libspdm_local_certificate_chain),
1147 : (uint8_t)(0xFF));
1148 :
1149 1 : spdm_context->last_spdm_request_size = m_libspdm_get_digest_request_size;
1150 1 : libspdm_copy_mem(spdm_context->last_spdm_request,
1151 1 : libspdm_get_scratch_buffer_last_spdm_request_capacity(spdm_context),
1152 : &m_libspdm_get_digest_request, m_libspdm_get_digest_request_size);
1153 :
1154 : /*RESPOND_IF_READY specific data*/
1155 1 : spdm_context->cache_spdm_request_size = spdm_context->last_spdm_request_size;
1156 1 : libspdm_copy_mem(spdm_context->cache_spdm_request,
1157 1 : libspdm_get_scratch_buffer_cache_spdm_request_capacity(spdm_context),
1158 1 : spdm_context->last_spdm_request, spdm_context->last_spdm_request_size);
1159 1 : spdm_context->error_data.rd_exponent = 1;
1160 1 : spdm_context->error_data.rd_tm = 1;
1161 1 : spdm_context->error_data.request_code = SPDM_GET_DIGESTS;
1162 1 : spdm_context->error_data.token = LIBSPDM_MY_TEST_TOKEN;
1163 :
1164 : /*check ERROR response*/
1165 1 : response_size = sizeof(response);
1166 1 : status = libspdm_get_response_respond_if_ready(spdm_context,
1167 : m_libspdm_respond_if_ready_request1_size,
1168 : &m_libspdm_respond_if_ready_request1,
1169 : &response_size,
1170 : response);
1171 1 : assert_int_equal (status, LIBSPDM_STATUS_SUCCESS);
1172 1 : assert_int_equal (response_size, sizeof(spdm_error_response_t));
1173 1 : spdm_response = (void *)response;
1174 1 : assert_int_equal (spdm_response->header.request_response_code, SPDM_ERROR);
1175 1 : assert_int_equal (spdm_response->header.param1, SPDM_ERROR_CODE_REQUEST_RESYNCH);
1176 1 : assert_int_equal (spdm_response->header.param2, 0);
1177 1 : assert_int_equal (spdm_context->response_state, LIBSPDM_RESPONSE_STATE_NEED_RESYNC);
1178 1 : }
1179 :
1180 : #endif /* LIBSPDM_ENABLE_CAPABILITY_CERT_CAP*/
1181 :
1182 : #if LIBSPDM_ENABLE_CAPABILITY_CERT_CAP
1183 :
1184 : /**
1185 : * Test 12: receiving a correct RESPOND_IF_READY from the requester, but the responder could not
1186 : * produce the response in time.
1187 : * Expected behavior: the responder accepts the request, but produces an ERROR message
1188 : * indicating the ResponseNotReady state, with the same token as the request.
1189 : **/
1190 1 : static void rsp_respond_if_ready_case12(void **state) {
1191 : libspdm_return_t status;
1192 : libspdm_test_context_t *spdm_test_context;
1193 : libspdm_context_t *spdm_context;
1194 : size_t response_size;
1195 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
1196 : spdm_digest_response_t *spdm_response; /*response to the original request (DIGESTS)*/
1197 : spdm_error_data_response_not_ready_t *error_data;
1198 :
1199 1 : spdm_test_context = *state;
1200 1 : spdm_context = spdm_test_context->spdm_context;
1201 1 : spdm_test_context->case_id = 0xC;
1202 : /* Connection (non-session) original request and RESPOND_IF_READY: both contexts are
1203 : * out-of-session. Set explicitly so the test does not depend on prior cases' state. */
1204 1 : spdm_context->cache_spdm_request_session_id_valid = false;
1205 1 : spdm_context->last_spdm_request_session_id_valid = false;
1206 1 : spdm_context->response_state = LIBSPDM_RESPONSE_STATE_NOT_READY;
1207 :
1208 : /*state for the the original request (GET_DIGESTS)*/
1209 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
1210 1 : spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
1211 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
1212 1 : spdm_context->local_context.local_cert_chain_provision[0] = m_libspdm_local_certificate_chain;
1213 1 : spdm_context->local_context.local_cert_chain_provision_size[0] =
1214 : sizeof(m_libspdm_local_certificate_chain);
1215 1 : libspdm_set_mem (m_libspdm_local_certificate_chain, sizeof(m_libspdm_local_certificate_chain),
1216 : (uint8_t)(0xFF));
1217 :
1218 1 : spdm_context->last_spdm_request_size = m_libspdm_get_digest_request_size;
1219 1 : libspdm_copy_mem(spdm_context->last_spdm_request,
1220 1 : libspdm_get_scratch_buffer_last_spdm_request_capacity(spdm_context),
1221 : &m_libspdm_get_digest_request, m_libspdm_get_digest_request_size);
1222 :
1223 : /*RESPOND_IF_READY specific data*/
1224 1 : spdm_context->cache_spdm_request_size = spdm_context->last_spdm_request_size;
1225 1 : libspdm_copy_mem(spdm_context->cache_spdm_request,
1226 1 : libspdm_get_scratch_buffer_cache_spdm_request_capacity(spdm_context),
1227 1 : spdm_context->last_spdm_request, spdm_context->last_spdm_request_size);
1228 1 : spdm_context->error_data.rd_exponent = 1;
1229 1 : spdm_context->error_data.rd_tm = 1;
1230 1 : spdm_context->error_data.request_code = SPDM_GET_DIGESTS;
1231 1 : spdm_context->error_data.token = LIBSPDM_MY_TEST_TOKEN;
1232 :
1233 : /*check ERROR response*/
1234 1 : response_size = sizeof(response);
1235 1 : status = libspdm_get_response_respond_if_ready(spdm_context,
1236 : m_libspdm_respond_if_ready_request1_size,
1237 : &m_libspdm_respond_if_ready_request1,
1238 : &response_size,
1239 : response);
1240 1 : assert_int_equal (status, LIBSPDM_STATUS_SUCCESS);
1241 1 : assert_int_equal (response_size,
1242 : sizeof(spdm_error_response_t) + sizeof(spdm_error_data_response_not_ready_t));
1243 1 : spdm_response = (void *)response;
1244 1 : error_data = (spdm_error_data_response_not_ready_t*)(spdm_response + 1);
1245 1 : assert_int_equal (spdm_response->header.request_response_code, SPDM_ERROR);
1246 1 : assert_int_equal (spdm_response->header.param1, SPDM_ERROR_CODE_RESPONSE_NOT_READY);
1247 1 : assert_int_equal (spdm_response->header.param2, 0);
1248 1 : assert_int_equal (spdm_context->response_state, LIBSPDM_RESPONSE_STATE_NOT_READY);
1249 1 : assert_int_equal (error_data->request_code, SPDM_GET_DIGESTS);
1250 1 : assert_int_equal (error_data->token, LIBSPDM_MY_TEST_TOKEN);
1251 1 : }
1252 :
1253 : #endif /* LIBSPDM_ENABLE_CAPABILITY_CERT_CAP*/
1254 :
1255 : #if LIBSPDM_ENABLE_CAPABILITY_CERT_CAP
1256 :
1257 : /**
1258 : * Test 13: receiving a correct RESPOND_IF_READY from the requester, with the correct original
1259 : * request code, but with a token different from the expected.
1260 : * Expected behavior: the responder refuses the RESPOND_IF_READY message and produces an
1261 : * ERROR message indicating the InvalidRequest.
1262 : **/
1263 1 : static void rsp_respond_if_ready_case13(void **state) {
1264 : libspdm_return_t status;
1265 : libspdm_test_context_t *spdm_test_context;
1266 : libspdm_context_t *spdm_context;
1267 : size_t response_size;
1268 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
1269 : spdm_digest_response_t *spdm_response; /*response to the original request (DIGESTS)*/
1270 :
1271 1 : spdm_test_context = *state;
1272 1 : spdm_context = spdm_test_context->spdm_context;
1273 1 : spdm_test_context->case_id = 0xD;
1274 : /* Connection (non-session) original request and RESPOND_IF_READY: both contexts are
1275 : * out-of-session. Set explicitly so the test does not depend on prior cases' state. */
1276 1 : spdm_context->cache_spdm_request_session_id_valid = false;
1277 1 : spdm_context->last_spdm_request_session_id_valid = false;
1278 1 : spdm_context->response_state = LIBSPDM_RESPONSE_STATE_NORMAL;
1279 :
1280 : /*state for the the original request (GET_DIGESTS)*/
1281 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
1282 1 : spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
1283 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
1284 1 : spdm_context->local_context.local_cert_chain_provision[0] = m_libspdm_local_certificate_chain;
1285 1 : spdm_context->local_context.local_cert_chain_provision_size[0] =
1286 : sizeof(m_libspdm_local_certificate_chain);
1287 1 : libspdm_set_mem (m_libspdm_local_certificate_chain, sizeof(m_libspdm_local_certificate_chain),
1288 : (uint8_t)(0xFF));
1289 :
1290 1 : spdm_context->last_spdm_request_size = m_libspdm_get_digest_request_size;
1291 1 : libspdm_copy_mem(spdm_context->last_spdm_request,
1292 1 : libspdm_get_scratch_buffer_last_spdm_request_capacity(spdm_context),
1293 : &m_libspdm_get_digest_request, m_libspdm_get_digest_request_size);
1294 :
1295 : /*RESPOND_IF_READY specific data*/
1296 1 : spdm_context->cache_spdm_request_size = spdm_context->last_spdm_request_size;
1297 1 : libspdm_copy_mem(spdm_context->cache_spdm_request,
1298 1 : libspdm_get_scratch_buffer_cache_spdm_request_capacity(spdm_context),
1299 1 : spdm_context->last_spdm_request, spdm_context->last_spdm_request_size);
1300 1 : spdm_context->error_data.rd_exponent = 1;
1301 1 : spdm_context->error_data.rd_tm = 1;
1302 1 : spdm_context->error_data.request_code = SPDM_GET_DIGESTS;
1303 1 : spdm_context->error_data.token = LIBSPDM_MY_TEST_TOKEN;
1304 :
1305 : /*check ERROR response*/
1306 1 : response_size = sizeof(response);
1307 1 : status = libspdm_get_response_respond_if_ready(spdm_context,
1308 : m_libspdm_respond_if_ready_request10_size,
1309 : &m_libspdm_respond_if_ready_request10,
1310 : &response_size,
1311 : response);
1312 1 : assert_int_equal (status, LIBSPDM_STATUS_SUCCESS);
1313 1 : assert_int_equal (response_size, sizeof(spdm_error_response_t));
1314 1 : spdm_response = (void *)response;
1315 1 : assert_int_equal (spdm_response->header.request_response_code, SPDM_ERROR);
1316 1 : assert_int_equal (spdm_response->header.param1, SPDM_ERROR_CODE_INVALID_REQUEST);
1317 1 : assert_int_equal (spdm_response->header.param2, 0);
1318 1 : }
1319 : #endif /* LIBSPDM_ENABLE_CAPABILITY_CERT_CAP*/
1320 :
1321 : #if LIBSPDM_ENABLE_CAPABILITY_CERT_CAP
1322 : /**
1323 : * Test 14: receiving a correct RESPOND_IF_READY from the requester, with the correct token,
1324 : * but with a request code different from the expected.
1325 : * Expected behavior: the responder refuses the RESPOND_IF_READY message and produces an
1326 : * ERROR message indicating the InvalidRequest.
1327 : **/
1328 1 : static void rsp_respond_if_ready_case14(void **state) {
1329 : libspdm_return_t status;
1330 : libspdm_test_context_t *spdm_test_context;
1331 : libspdm_context_t *spdm_context;
1332 : size_t response_size;
1333 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
1334 : spdm_digest_response_t *spdm_response; /*response to the original request (DIGESTS)*/
1335 :
1336 1 : spdm_test_context = *state;
1337 1 : spdm_context = spdm_test_context->spdm_context;
1338 1 : spdm_test_context->case_id = 0xE;
1339 : /* Connection (non-session) original request and RESPOND_IF_READY: both contexts are
1340 : * out-of-session. Set explicitly so the test does not depend on prior cases' state. */
1341 1 : spdm_context->cache_spdm_request_session_id_valid = false;
1342 1 : spdm_context->last_spdm_request_session_id_valid = false;
1343 1 : spdm_context->response_state = LIBSPDM_RESPONSE_STATE_NORMAL;
1344 :
1345 : /*state for the the original request (GET_DIGESTS)*/
1346 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
1347 1 : spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
1348 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
1349 1 : spdm_context->local_context.local_cert_chain_provision[0] = m_libspdm_local_certificate_chain;
1350 1 : spdm_context->local_context.local_cert_chain_provision_size[0] =
1351 : sizeof(m_libspdm_local_certificate_chain);
1352 1 : libspdm_set_mem (m_libspdm_local_certificate_chain, sizeof(m_libspdm_local_certificate_chain),
1353 : (uint8_t)(0xFF));
1354 :
1355 1 : spdm_context->last_spdm_request_size = m_libspdm_get_digest_request_size;
1356 1 : libspdm_copy_mem(spdm_context->last_spdm_request,
1357 1 : libspdm_get_scratch_buffer_last_spdm_request_capacity(spdm_context),
1358 : &m_libspdm_get_digest_request, m_libspdm_get_digest_request_size);
1359 :
1360 : /*RESPOND_IF_READY specific data*/
1361 1 : spdm_context->cache_spdm_request_size = spdm_context->last_spdm_request_size;
1362 1 : libspdm_copy_mem(spdm_context->cache_spdm_request,
1363 1 : libspdm_get_scratch_buffer_cache_spdm_request_capacity(spdm_context),
1364 1 : spdm_context->last_spdm_request, spdm_context->last_spdm_request_size);
1365 1 : spdm_context->error_data.rd_exponent = 1;
1366 1 : spdm_context->error_data.rd_tm = 1;
1367 1 : spdm_context->error_data.request_code = SPDM_GET_DIGESTS;
1368 1 : spdm_context->error_data.token = LIBSPDM_MY_TEST_TOKEN;
1369 :
1370 : /*check ERROR response*/
1371 1 : response_size = sizeof(response);
1372 1 : status = libspdm_get_response_respond_if_ready(spdm_context,
1373 : m_libspdm_respond_if_ready_request11_size,
1374 : &m_libspdm_respond_if_ready_request11,
1375 : &response_size,
1376 : response);
1377 1 : assert_int_equal (status, LIBSPDM_STATUS_SUCCESS);
1378 1 : assert_int_equal (response_size, sizeof(spdm_error_response_t));
1379 1 : spdm_response = (void *)response;
1380 1 : assert_int_equal (spdm_response->header.request_response_code, SPDM_ERROR);
1381 1 : assert_int_equal (spdm_response->header.param1, SPDM_ERROR_CODE_INVALID_REQUEST);
1382 1 : assert_int_equal (spdm_response->header.param2, 0);
1383 1 : }
1384 :
1385 : /**
1386 : * Test 15: receiving a RESPOND_IF_READY with the correct original request code and token, but in a
1387 : * DIFFERENT session context than the original request. Here the original request (GET_DIGESTS) was
1388 : * received outside of a session, but the RESPOND_IF_READY arrives inside a session.
1389 : * Expected behavior: per DSP0274 the validity of RESPOND_IF_READY is defined by the original
1390 : * request, so a context mismatch is refused with ERROR(UnexpectedRequest); the cached response is
1391 : * NOT returned.
1392 : **/
1393 1 : static void rsp_respond_if_ready_case15(void **state) {
1394 : libspdm_return_t status;
1395 : libspdm_test_context_t *spdm_test_context;
1396 : libspdm_context_t *spdm_context;
1397 : size_t response_size;
1398 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
1399 : spdm_error_response_t *spdm_response;
1400 :
1401 1 : spdm_test_context = *state;
1402 1 : spdm_context = spdm_test_context->spdm_context;
1403 1 : spdm_test_context->case_id = 0xF;
1404 1 : spdm_context->response_state = LIBSPDM_RESPONSE_STATE_NORMAL;
1405 :
1406 : /*state for the the original request (GET_DIGESTS)*/
1407 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
1408 1 : spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_CERT_CAP;
1409 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
1410 1 : spdm_context->local_context.local_cert_chain_provision[0] = m_libspdm_local_certificate_chain;
1411 1 : spdm_context->local_context.local_cert_chain_provision_size[0] =
1412 : sizeof(m_libspdm_local_certificate_chain);
1413 1 : libspdm_set_mem (m_libspdm_local_certificate_chain, sizeof(m_libspdm_local_certificate_chain),
1414 : (uint8_t)(0xFF));
1415 :
1416 1 : spdm_context->last_spdm_request_size = m_libspdm_get_digest_request_size;
1417 1 : libspdm_copy_mem(spdm_context->last_spdm_request,
1418 1 : libspdm_get_scratch_buffer_last_spdm_request_capacity(spdm_context),
1419 : &m_libspdm_get_digest_request, m_libspdm_get_digest_request_size);
1420 :
1421 : /*RESPOND_IF_READY specific data: the original GET_DIGESTS was received OUTSIDE a session.*/
1422 1 : spdm_context->cache_spdm_request_size = spdm_context->last_spdm_request_size;
1423 1 : libspdm_copy_mem(spdm_context->cache_spdm_request,
1424 1 : libspdm_get_scratch_buffer_cache_spdm_request_capacity(spdm_context),
1425 1 : spdm_context->last_spdm_request, spdm_context->last_spdm_request_size);
1426 1 : spdm_context->cache_spdm_request_session_id_valid = false;
1427 1 : spdm_context->error_data.rd_exponent = 1;
1428 1 : spdm_context->error_data.rd_tm = 1;
1429 1 : spdm_context->error_data.request_code = SPDM_GET_DIGESTS;
1430 1 : spdm_context->error_data.token = LIBSPDM_MY_TEST_TOKEN;
1431 :
1432 : /* But the RESPOND_IF_READY arrives INSIDE a session -- a context mismatch. */
1433 1 : spdm_context->last_spdm_request_session_id_valid = true;
1434 1 : spdm_context->last_spdm_request_session_id = 0xFFFFFFFF;
1435 :
1436 : /*check ERROR response*/
1437 1 : response_size = sizeof(response);
1438 1 : status = libspdm_get_response_respond_if_ready(spdm_context,
1439 : m_libspdm_respond_if_ready_request1_size,
1440 : &m_libspdm_respond_if_ready_request1,
1441 : &response_size,
1442 : response);
1443 1 : assert_int_equal (status, LIBSPDM_STATUS_SUCCESS);
1444 1 : assert_int_equal (response_size, sizeof(spdm_error_response_t));
1445 1 : spdm_response = (void *)response;
1446 1 : assert_int_equal (spdm_response->header.request_response_code, SPDM_ERROR);
1447 1 : assert_int_equal (spdm_response->header.param1, SPDM_ERROR_CODE_UNEXPECTED_REQUEST);
1448 1 : assert_int_equal (spdm_response->header.param2, 0);
1449 :
1450 : /* restore for subsequent cases */
1451 1 : spdm_context->last_spdm_request_session_id_valid = false;
1452 1 : }
1453 : #endif /* LIBSPDM_ENABLE_CAPABILITY_CERT_CAP*/
1454 :
1455 1 : int libspdm_rsp_respond_if_ready_test(void) {
1456 1 : const struct CMUnitTest test_cases[] = {
1457 : /* Success Case*/
1458 : #if LIBSPDM_ENABLE_CAPABILITY_CERT_CAP
1459 : cmocka_unit_test(rsp_respond_if_ready_case1),
1460 : cmocka_unit_test(rsp_respond_if_ready_case2),
1461 : #endif /* LIBSPDM_ENABLE_CAPABILITY_CERT_CAP*/
1462 :
1463 : #if LIBSPDM_ENABLE_CAPABILITY_CHAL_CAP
1464 : cmocka_unit_test(rsp_respond_if_ready_case3),
1465 : #endif /* LIBSPDM_ENABLE_CAPABILITY_CHAL_CAP*/
1466 :
1467 : #if LIBSPDM_ENABLE_CAPABILITY_MEAS_CAP
1468 : cmocka_unit_test(rsp_respond_if_ready_case4),
1469 : #endif /* LIBSPDM_ENABLE_CAPABILITY_MEAS_CAP*/
1470 :
1471 : #if LIBSPDM_ENABLE_CAPABILITY_KEY_EX_CAP
1472 : cmocka_unit_test(rsp_respond_if_ready_case5),
1473 : cmocka_unit_test(rsp_respond_if_ready_case6),
1474 : #endif /* LIBSPDM_ENABLE_CAPABILITY_KEY_EX_CAP*/
1475 :
1476 : #if LIBSPDM_ENABLE_CAPABILITY_PSK_CAP
1477 : cmocka_unit_test(rsp_respond_if_ready_case7),
1478 : cmocka_unit_test(rsp_respond_if_ready_case8),
1479 : #endif /* LIBSPDM_ENABLE_CAPABILITY_PSK_CAP*/
1480 :
1481 : #if LIBSPDM_ENABLE_CAPABILITY_CERT_CAP
1482 : cmocka_unit_test(rsp_respond_if_ready_case9),
1483 : cmocka_unit_test(rsp_respond_if_ready_case10),
1484 : cmocka_unit_test(rsp_respond_if_ready_case11),
1485 : cmocka_unit_test(rsp_respond_if_ready_case12),
1486 : cmocka_unit_test(rsp_respond_if_ready_case13),
1487 : cmocka_unit_test(rsp_respond_if_ready_case14),
1488 : cmocka_unit_test(rsp_respond_if_ready_case15),
1489 : #endif /* LIBSPDM_ENABLE_CAPABILITY_CERT_CAP*/
1490 :
1491 : };
1492 :
1493 1 : libspdm_test_context_t test_context = {
1494 : LIBSPDM_TEST_CONTEXT_VERSION,
1495 : false,
1496 : };
1497 :
1498 1 : libspdm_setup_test_context (&test_context);
1499 :
1500 1 : return cmocka_run_group_tests(test_cases,
1501 : libspdm_unit_test_group_setup,
1502 : libspdm_unit_test_group_teardown);
1503 : }
1504 : #endif /* LIBSPDM_ENABLE_CAPABILITY_*_CAP */
1505 : #endif /* LIBSPDM_RESPOND_IF_READY_SUPPORT */
|