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_requester_lib.h"
9 :
10 : #if (LIBSPDM_ENABLE_CAPABILITY_MUT_AUTH_CAP) && (LIBSPDM_ENABLE_CAPABILITY_ENCAP_CAP) && \
11 : (LIBSPDM_ENABLE_CAPABILITY_CHAL_CAP)
12 :
13 : spdm_challenge_request_t m_spdm_challenge_request1 = {
14 : {SPDM_MESSAGE_VERSION_11, SPDM_CHALLENGE, 0,
15 : SPDM_CHALLENGE_REQUEST_NO_MEASUREMENT_SUMMARY_HASH},
16 : };
17 : size_t m_spdm_challenge_request1_size = sizeof(m_spdm_challenge_request1);
18 :
19 : spdm_challenge_request_t m_spdm_challenge_request3 = {
20 : {SPDM_MESSAGE_VERSION_11, SPDM_CHALLENGE, SPDM_MAX_SLOT_COUNT,
21 : SPDM_CHALLENGE_REQUEST_NO_MEASUREMENT_SUMMARY_HASH},
22 : };
23 : size_t m_spdm_challenge_request3_size = sizeof(m_spdm_challenge_request3);
24 :
25 : spdm_challenge_request_t m_spdm_challenge_request4 = {
26 : {SPDM_MESSAGE_VERSION_11, SPDM_CHALLENGE, 0xFF,
27 : SPDM_CHALLENGE_REQUEST_NO_MEASUREMENT_SUMMARY_HASH},
28 : };
29 : size_t m_spdm_challenge_request4_size = sizeof(m_spdm_challenge_request4);
30 :
31 : spdm_challenge_request_t m_spdm_challenge_request5 = {
32 : {SPDM_MESSAGE_VERSION_13, SPDM_CHALLENGE, 0,
33 : SPDM_CHALLENGE_REQUEST_NO_MEASUREMENT_SUMMARY_HASH},
34 : };
35 : size_t m_spdm_challenge_request5_size = sizeof(m_spdm_challenge_request5);
36 :
37 : extern size_t libspdm_secret_lib_challenge_opaque_data_size;
38 :
39 : /**
40 : * Test 1: receiving a correct CHALLENGE message from the requester with
41 : * no opaque data, no measurements, and slot number 0.
42 : * Expected behavior: the requester accepts the request and produces a valid
43 : * CHALLENGE_AUTH response message and Completion of CHALLENGE sets M1/M2 to null.
44 : **/
45 1 : static void req_encap_challenge_auth_case1(void **state)
46 : {
47 : libspdm_return_t status;
48 : libspdm_test_context_t *spdm_test_context;
49 : libspdm_context_t *spdm_context;
50 : size_t response_size;
51 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
52 : spdm_challenge_auth_response_t *spdm_response;
53 : void *data;
54 : size_t data_size;
55 :
56 1 : spdm_test_context = *state;
57 1 : spdm_context = spdm_test_context->spdm_context;
58 1 : spdm_test_context->case_id = 0x1;
59 :
60 1 : spdm_context->local_context.capability.flags = 0;
61 1 : spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHAL_CAP;
62 1 : spdm_context->connection_info.capability.flags = 0;
63 :
64 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
65 1 : spdm_context->connection_info.algorithm.base_asym_algo = m_libspdm_use_asym_algo;
66 1 : spdm_context->connection_info.algorithm.measurement_spec = m_libspdm_use_measurement_spec;
67 1 : spdm_context->connection_info.algorithm.measurement_hash_algo =
68 : m_libspdm_use_measurement_hash_algo;
69 :
70 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
71 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
72 1 : spdm_context->connection_info.algorithm.base_asym_algo = m_libspdm_use_asym_algo;
73 1 : spdm_context->connection_info.algorithm.measurement_spec = m_libspdm_use_measurement_spec;
74 1 : spdm_context->connection_info.algorithm.measurement_hash_algo =
75 : m_libspdm_use_measurement_hash_algo;
76 :
77 1 : spdm_context->connection_info.algorithm.req_base_asym_alg =
78 : SPDM_ALGORITHMS_BASE_ASYM_ALGO_TPM_ALG_RSASSA_2048;
79 :
80 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_11
81 : << SPDM_VERSION_NUMBER_SHIFT_BIT;
82 1 : libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
83 : m_libspdm_use_asym_algo, &data,
84 : &data_size, NULL, NULL);
85 1 : spdm_context->local_context.local_cert_chain_provision[0] = data;
86 1 : spdm_context->local_context.local_cert_chain_provision_size[0] = data_size;
87 :
88 1 : libspdm_secret_lib_challenge_opaque_data_size = 0;
89 1 : libspdm_reset_message_mut_c(spdm_context);
90 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
91 : spdm_context->transcript.message_m.buffer_size =
92 : spdm_context->transcript.message_m.max_buffer_size;
93 : #endif
94 :
95 1 : response_size = sizeof(response);
96 1 : libspdm_get_random_number(SPDM_NONCE_SIZE, m_spdm_challenge_request1.nonce);
97 1 : status = libspdm_get_encap_response_challenge_auth(
98 : spdm_context, m_spdm_challenge_request1_size,
99 : &m_spdm_challenge_request1, &response_size, response);
100 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
101 1 : assert_int_equal(response_size, sizeof(spdm_challenge_auth_response_t) +
102 : libspdm_get_hash_size(spdm_context->connection_info.algorithm.base_hash_algo) +
103 : SPDM_NONCE_SIZE + 0 +
104 : sizeof(uint16_t) +
105 : libspdm_secret_lib_challenge_opaque_data_size +
106 : libspdm_get_req_asym_signature_size(
107 : spdm_context->connection_info.algorithm.req_base_asym_alg));
108 1 : spdm_response = (void *)response;
109 1 : assert_int_equal(spdm_response->header.request_response_code, SPDM_CHALLENGE_AUTH);
110 1 : assert_int_equal(spdm_response->header.param1, 0);
111 1 : assert_int_equal(spdm_response->header.param2, 1 << 0);
112 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
113 : assert_int_equal(spdm_context->transcript.message_m.buffer_size, 0);
114 : assert_int_equal(spdm_context->transcript.message_mut_c.buffer_size, 0);
115 : #else
116 1 : assert_null(spdm_context->transcript.digest_context_mut_m1m2);
117 : #endif
118 1 : free(data);
119 1 : }
120 :
121 : /**
122 : * Test 2:
123 : * Expected behavior:
124 : **/
125 1 : static void req_encap_challenge_auth_case2(void **state)
126 : {
127 1 : }
128 :
129 : /**
130 : * Test 3: receiving a correct CHALLENGE from the requester, but the requester does not
131 : * have the challenge capability set.
132 : * Expected behavior: the requester accepts the request and produces a valid
133 : * CHALLENGE_AUTH response message.
134 : **/
135 1 : static void req_encap_challenge_auth_case3(void **state)
136 : {
137 : libspdm_return_t status;
138 : libspdm_test_context_t *spdm_test_context;
139 : libspdm_context_t *spdm_context;
140 : size_t response_size;
141 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
142 : spdm_challenge_auth_response_t *spdm_response;
143 : void *data;
144 : size_t data_size;
145 :
146 1 : spdm_test_context = *state;
147 1 : spdm_context = spdm_test_context->spdm_context;
148 1 : spdm_test_context->case_id = 0x3;
149 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
150 1 : spdm_context->local_context.capability.flags = 0;
151 : /* spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHAL_CAP;*/
152 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
153 1 : spdm_context->connection_info.algorithm.base_asym_algo = m_libspdm_use_asym_algo;
154 1 : spdm_context->connection_info.algorithm.measurement_spec = m_libspdm_use_measurement_spec;
155 1 : spdm_context->connection_info.algorithm.measurement_hash_algo =
156 : m_libspdm_use_measurement_hash_algo;
157 :
158 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_11
159 : << SPDM_VERSION_NUMBER_SHIFT_BIT;
160 1 : libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
161 : m_libspdm_use_asym_algo, &data, &data_size,
162 : NULL, NULL);
163 1 : spdm_context->local_context.local_cert_chain_provision[0] = data;
164 1 : spdm_context->local_context.local_cert_chain_provision_size[0] = data_size;
165 :
166 1 : libspdm_secret_lib_challenge_opaque_data_size = 0;
167 1 : libspdm_reset_message_c(spdm_context);
168 :
169 1 : response_size = sizeof(response);
170 1 : libspdm_get_random_number(SPDM_NONCE_SIZE, m_spdm_challenge_request1.nonce);
171 1 : status = libspdm_get_encap_response_challenge_auth(spdm_context, m_spdm_challenge_request1_size,
172 : &m_spdm_challenge_request1, &response_size,
173 : response);
174 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
175 1 : assert_int_equal(response_size, sizeof(spdm_error_response_t));
176 1 : spdm_response = (void *)response;
177 1 : assert_int_equal(spdm_response->header.request_response_code, SPDM_ERROR);
178 1 : assert_int_equal(spdm_response->header.param1, SPDM_ERROR_CODE_UNSUPPORTED_REQUEST);
179 1 : assert_int_equal(spdm_response->header.param2, SPDM_CHALLENGE);
180 1 : free(data);
181 1 : }
182 :
183 : /**
184 : * Test 4: receiving an incorrect CHALLENGE from the requester, with the slot number
185 : * larger than the specification limit.
186 : * Expected behavior: the requester rejects the request, and produces an ERROR message
187 : * indicating the UnexpectedRequest.
188 : **/
189 1 : static void req_encap_challenge_auth_case4(void **state)
190 : {
191 : libspdm_return_t status;
192 : libspdm_test_context_t *spdm_test_context;
193 : libspdm_context_t *spdm_context;
194 : size_t response_size;
195 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
196 : spdm_challenge_auth_response_t *spdm_response;
197 : void *data;
198 : size_t data_size;
199 :
200 1 : spdm_test_context = *state;
201 1 : spdm_context = spdm_test_context->spdm_context;
202 1 : spdm_test_context->case_id = 0x4;
203 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
204 1 : spdm_context->local_context.capability.flags = 0;
205 1 : spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHAL_CAP;
206 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
207 1 : spdm_context->connection_info.algorithm.base_asym_algo = m_libspdm_use_asym_algo;
208 1 : spdm_context->connection_info.algorithm.measurement_spec = m_libspdm_use_measurement_spec;
209 1 : spdm_context->connection_info.algorithm.measurement_hash_algo =
210 : m_libspdm_use_measurement_hash_algo;
211 :
212 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_11
213 : << SPDM_VERSION_NUMBER_SHIFT_BIT;
214 1 : libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
215 : m_libspdm_use_asym_algo, &data, &data_size,
216 : NULL, NULL);
217 1 : spdm_context->local_context.local_cert_chain_provision[0] = data;
218 1 : spdm_context->local_context.local_cert_chain_provision_size[0] = data_size;
219 :
220 1 : libspdm_secret_lib_challenge_opaque_data_size = 0;
221 1 : libspdm_reset_message_c(spdm_context);
222 :
223 1 : response_size = sizeof(response);
224 1 : libspdm_get_random_number(SPDM_NONCE_SIZE, m_spdm_challenge_request1.nonce);
225 1 : status = libspdm_get_encap_response_challenge_auth(spdm_context, m_spdm_challenge_request3_size,
226 : &m_spdm_challenge_request3, &response_size,
227 : response);
228 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
229 1 : assert_int_equal(response_size, sizeof(spdm_error_response_t));
230 1 : spdm_response = (void *)response;
231 1 : assert_int_equal(spdm_response->header.request_response_code, SPDM_ERROR);
232 1 : assert_int_equal(spdm_response->header.param1, SPDM_ERROR_CODE_INVALID_REQUEST);
233 1 : assert_int_equal(spdm_response->header.param2, 0);
234 1 : free(data);
235 1 : }
236 :
237 : /**
238 : * Test 5: receiving a correct CHALLENGE from the requester, but with certificate
239 : * unavailable at the requested slot number (1).
240 : * Expected behavior: the requester rejects the request, and produces an ERROR message
241 : * indicating the UnexpectedRequest.
242 : **/
243 1 : static void req_encap_challenge_auth_case5(void **state)
244 : {
245 : libspdm_return_t status;
246 : libspdm_test_context_t *spdm_test_context;
247 : libspdm_context_t *spdm_context;
248 : size_t response_size;
249 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
250 : spdm_challenge_auth_response_t *spdm_response;
251 : void *data;
252 : size_t data_size;
253 :
254 1 : spdm_test_context = *state;
255 1 : spdm_context = spdm_test_context->spdm_context;
256 1 : spdm_test_context->case_id = 0x05;
257 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
258 1 : spdm_context->local_context.capability.flags = 0;
259 1 : spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHAL_CAP;
260 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
261 1 : spdm_context->connection_info.algorithm.base_asym_algo = m_libspdm_use_asym_algo;
262 1 : spdm_context->connection_info.algorithm.measurement_spec = m_libspdm_use_measurement_spec;
263 1 : spdm_context->connection_info.algorithm.measurement_hash_algo =
264 : m_libspdm_use_measurement_hash_algo;
265 :
266 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_11
267 : << SPDM_VERSION_NUMBER_SHIFT_BIT;
268 1 : libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
269 : m_libspdm_use_asym_algo, &data, &data_size,
270 : NULL, NULL);
271 1 : spdm_context->local_context.local_cert_chain_provision[0] = data;
272 1 : spdm_context->local_context.local_cert_chain_provision_size[0] = data_size;
273 :
274 1 : libspdm_secret_lib_challenge_opaque_data_size = 0;
275 1 : libspdm_reset_message_c(spdm_context);
276 :
277 1 : response_size = sizeof(response);
278 1 : libspdm_get_random_number(SPDM_NONCE_SIZE, m_spdm_challenge_request1.nonce);
279 1 : status = libspdm_get_encap_response_challenge_auth(spdm_context, m_spdm_challenge_request3_size,
280 : &m_spdm_challenge_request3, &response_size,
281 : response);
282 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
283 1 : assert_int_equal(response_size, sizeof(spdm_error_response_t));
284 1 : spdm_response = (void *)response;
285 1 : assert_int_equal(spdm_response->header.request_response_code, SPDM_ERROR);
286 1 : assert_int_equal(spdm_response->header.param1, SPDM_ERROR_CODE_INVALID_REQUEST);
287 1 : assert_int_equal(spdm_response->header.param2, 0);
288 1 : free(data);
289 1 : }
290 :
291 : /**
292 : * Test 6: receiving a correct CHALLENGE message from the requester with
293 : * no opaque data, no measurements, and slot number 0xFF.
294 : * Expected behavior: the requester accepts the request and produces a valid
295 : * CHALLENGE_AUTH response message using provisioned public key (slot number 0xFF).
296 : **/
297 1 : static void req_encap_challenge_auth_case6(void **state)
298 : {
299 : libspdm_return_t status;
300 : libspdm_test_context_t *spdm_test_context;
301 : libspdm_context_t *spdm_context;
302 : size_t response_size;
303 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
304 : spdm_challenge_auth_response_t *spdm_response;
305 : void *data;
306 : size_t data_size;
307 :
308 1 : spdm_test_context = *state;
309 1 : spdm_context = spdm_test_context->spdm_context;
310 1 : spdm_test_context->case_id = 0x6;
311 :
312 1 : spdm_context->local_context.capability.flags = 0;
313 1 : spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHAL_CAP;
314 :
315 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
316 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
317 1 : spdm_context->connection_info.algorithm.req_base_asym_alg = m_libspdm_use_req_asym_algo;
318 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_11
319 : << SPDM_VERSION_NUMBER_SHIFT_BIT;
320 :
321 1 : libspdm_read_requester_public_key(m_libspdm_use_req_asym_algo, &data, &data_size);
322 1 : spdm_context->local_context.local_public_key_provision = data;
323 1 : spdm_context->local_context.local_public_key_provision_size = data_size;
324 :
325 1 : libspdm_secret_lib_challenge_opaque_data_size = 0;
326 1 : libspdm_reset_message_c(spdm_context);
327 :
328 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
329 : spdm_context->transcript.message_m.buffer_size =
330 : spdm_context->transcript.message_m.max_buffer_size;
331 : #endif
332 :
333 1 : response_size = sizeof(response);
334 1 : libspdm_get_random_number(SPDM_NONCE_SIZE, m_spdm_challenge_request4.nonce);
335 1 : status = libspdm_get_encap_response_challenge_auth(
336 : spdm_context,
337 : m_spdm_challenge_request4_size, &m_spdm_challenge_request4,
338 : &response_size, response);
339 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
340 1 : assert_int_equal(
341 : response_size,
342 : sizeof(spdm_challenge_auth_response_t) +
343 : libspdm_get_hash_size(spdm_context->connection_info.algorithm.base_hash_algo) +
344 : SPDM_NONCE_SIZE + 0 +
345 : sizeof(uint16_t) + 0 +
346 : libspdm_get_req_asym_signature_size(
347 : spdm_context->connection_info.algorithm.req_base_asym_alg));
348 1 : spdm_response = (void *)response;
349 1 : assert_int_equal(spdm_response->header.request_response_code, SPDM_CHALLENGE_AUTH);
350 1 : assert_int_equal(spdm_response->header.param1, 0xF);
351 1 : assert_int_equal(spdm_response->header.param2, 0);
352 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
353 : assert_int_equal(spdm_context->transcript.message_m.buffer_size, 0);
354 : #endif
355 1 : free(data);
356 1 : }
357 :
358 : /**
359 : * Test 7: receiving a correct CHALLENGE message from the requester with context field
360 : * no opaque data, no measurements, and slot number 0.
361 : * Expected behavior: get a LIBSPDM_STATUS_SUCCESS return code, correct context field
362 : **/
363 1 : static void req_encap_challenge_auth_case7(void **state)
364 : {
365 : libspdm_return_t status;
366 : libspdm_test_context_t *spdm_test_context;
367 : libspdm_context_t *spdm_context;
368 : size_t response_size;
369 : uint8_t request[LIBSPDM_MAX_SPDM_MSG_SIZE];
370 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
371 : spdm_challenge_auth_response_t *spdm_response;
372 : void *data;
373 : size_t data_size;
374 : uint8_t *requester_context;
375 : uint8_t *responder_context;
376 :
377 1 : spdm_test_context = *state;
378 1 : spdm_context = spdm_test_context->spdm_context;
379 1 : spdm_test_context->case_id = 0x7;
380 :
381 1 : spdm_context->local_context.capability.flags = 0;
382 1 : spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHAL_CAP;
383 1 : spdm_context->connection_info.capability.flags = 0;
384 :
385 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
386 1 : spdm_context->connection_info.algorithm.base_asym_algo = m_libspdm_use_asym_algo;
387 1 : spdm_context->connection_info.algorithm.measurement_spec = m_libspdm_use_measurement_spec;
388 1 : spdm_context->connection_info.algorithm.measurement_hash_algo =
389 : m_libspdm_use_measurement_hash_algo;
390 :
391 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
392 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
393 1 : spdm_context->connection_info.algorithm.base_asym_algo = m_libspdm_use_asym_algo;
394 1 : spdm_context->connection_info.algorithm.measurement_spec = m_libspdm_use_measurement_spec;
395 1 : spdm_context->connection_info.algorithm.measurement_hash_algo =
396 : m_libspdm_use_measurement_hash_algo;
397 1 : spdm_context->connection_info.algorithm.req_base_asym_alg = m_libspdm_use_req_asym_algo;
398 :
399 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_13
400 : << SPDM_VERSION_NUMBER_SHIFT_BIT;
401 1 : libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
402 : m_libspdm_use_asym_algo, &data,
403 : &data_size, NULL, NULL);
404 1 : spdm_context->local_context.local_cert_chain_provision[0] = data;
405 1 : spdm_context->local_context.local_cert_chain_provision_size[0] = data_size;
406 :
407 1 : libspdm_reset_message_mut_c(spdm_context);
408 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
409 : spdm_context->transcript.message_m.buffer_size =
410 : spdm_context->transcript.message_m.max_buffer_size;
411 : #endif
412 :
413 1 : response_size = sizeof(response);
414 1 : libspdm_get_random_number(SPDM_NONCE_SIZE, m_spdm_challenge_request5.nonce);
415 :
416 1 : libspdm_zero_mem(request, sizeof(request));
417 1 : libspdm_copy_mem(request, sizeof(spdm_challenge_request_t),
418 : &m_spdm_challenge_request5, m_spdm_challenge_request5_size);
419 1 : requester_context = request + m_spdm_challenge_request5_size;
420 1 : libspdm_set_mem(requester_context, SPDM_REQ_CONTEXT_SIZE, 0xAA);
421 1 : m_spdm_challenge_request5_size += SPDM_REQ_CONTEXT_SIZE;
422 :
423 1 : status = libspdm_get_encap_response_challenge_auth(
424 : spdm_context, m_spdm_challenge_request5_size,
425 : request, &response_size, response);
426 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
427 1 : assert_int_equal(response_size, sizeof(spdm_challenge_auth_response_t) +
428 : libspdm_get_hash_size(m_libspdm_use_hash_algo) +
429 : SPDM_NONCE_SIZE + 0 + sizeof(uint16_t) +
430 : libspdm_get_asym_signature_size(m_libspdm_use_req_asym_algo) +
431 : SPDM_REQ_CONTEXT_SIZE);
432 1 : spdm_response = (void *)response;
433 1 : assert_int_equal(spdm_response->header.request_response_code, SPDM_CHALLENGE_AUTH);
434 1 : assert_int_equal(spdm_response->header.param1, 0);
435 1 : assert_int_equal(spdm_response->header.param2, 1 << 0);
436 :
437 1 : responder_context = (void *)response;
438 1 : responder_context += sizeof(spdm_challenge_auth_response_t) +
439 1 : libspdm_get_hash_size(m_libspdm_use_hash_algo) +
440 1 : SPDM_NONCE_SIZE + 0 + sizeof(uint16_t);
441 1 : assert_memory_equal(requester_context, responder_context, SPDM_REQ_CONTEXT_SIZE);
442 :
443 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
444 : assert_int_equal(spdm_context->transcript.message_m.buffer_size, 0);
445 : assert_int_equal(spdm_context->transcript.message_mut_c.buffer_size, 0);
446 : #else
447 1 : assert_null(spdm_context->transcript.digest_context_mut_m1m2);
448 : #endif
449 1 : free(data);
450 1 : }
451 :
452 : /**
453 : * Test 8: The key usage bit mask is not set, the SlotID fields in CHALLENGE and CHALLENGE_AUTH shall not specify this certificate slot
454 : * Expected behavior: the responder accepts the request, but produces an ERROR message
455 : * indicating the invalid state.
456 : **/
457 1 : static void req_encap_challenge_auth_case8(void **state)
458 : {
459 : libspdm_return_t status;
460 : libspdm_test_context_t *spdm_test_context;
461 : libspdm_context_t *spdm_context;
462 : size_t response_size;
463 : uint8_t request[LIBSPDM_MAX_SPDM_MSG_SIZE];
464 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
465 : spdm_challenge_auth_response_t *spdm_response;
466 : void *data;
467 : size_t data_size;
468 : uint8_t *requester_context;
469 : uint8_t slot_id;
470 :
471 1 : spdm_test_context = *state;
472 1 : spdm_context = spdm_test_context->spdm_context;
473 1 : spdm_test_context->case_id = 0x8;
474 :
475 1 : spdm_context->local_context.capability.flags = 0;
476 1 : spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_CHAL_CAP;
477 1 : spdm_context->connection_info.capability.flags = 0;
478 :
479 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
480 1 : spdm_context->connection_info.algorithm.base_asym_algo = m_libspdm_use_asym_algo;
481 1 : spdm_context->connection_info.algorithm.measurement_spec = m_libspdm_use_measurement_spec;
482 1 : spdm_context->connection_info.algorithm.measurement_hash_algo =
483 : m_libspdm_use_measurement_hash_algo;
484 :
485 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
486 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
487 1 : spdm_context->connection_info.algorithm.base_asym_algo = m_libspdm_use_asym_algo;
488 1 : spdm_context->connection_info.algorithm.measurement_spec = m_libspdm_use_measurement_spec;
489 1 : spdm_context->connection_info.algorithm.measurement_hash_algo =
490 : m_libspdm_use_measurement_hash_algo;
491 1 : spdm_context->connection_info.algorithm.req_base_asym_alg = m_libspdm_use_req_asym_algo;
492 1 : spdm_context->connection_info.multi_key_conn_req = true;
493 :
494 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_13
495 : << SPDM_VERSION_NUMBER_SHIFT_BIT;
496 1 : libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
497 : m_libspdm_use_asym_algo, &data,
498 : &data_size, NULL, NULL);
499 1 : spdm_context->local_context.local_cert_chain_provision[0] = data;
500 1 : spdm_context->local_context.local_cert_chain_provision_size[0] = data_size;
501 :
502 1 : libspdm_reset_message_mut_c(spdm_context);
503 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
504 : spdm_context->transcript.message_m.buffer_size =
505 : spdm_context->transcript.message_m.max_buffer_size;
506 : #endif
507 :
508 : /* If set, the SlotID fields in CHALLENGE and CHALLENGE_AUTH can specify this certificate slot. If not set, the
509 : * SlotID fields in CHALLENGE and CHALLENGE_AUTH shall not specify this certificate slot. */
510 1 : slot_id = 0;
511 1 : m_spdm_challenge_request5.header.param1 = slot_id;
512 1 : spdm_context->local_context.local_key_usage_bit_mask[slot_id] =
513 : SPDM_KEY_USAGE_BIT_MASK_KEY_EX_USE |
514 : SPDM_KEY_USAGE_BIT_MASK_MEASUREMENT_USE;
515 :
516 1 : response_size = sizeof(response);
517 1 : libspdm_get_random_number(SPDM_NONCE_SIZE, m_spdm_challenge_request5.nonce);
518 :
519 1 : libspdm_zero_mem(request, sizeof(request));
520 1 : libspdm_copy_mem(request, sizeof(spdm_challenge_request_t),
521 : &m_spdm_challenge_request5, sizeof(m_spdm_challenge_request5));
522 1 : requester_context = request + sizeof(m_spdm_challenge_request5);
523 1 : libspdm_set_mem(requester_context, SPDM_REQ_CONTEXT_SIZE, 0xAA);
524 1 : m_spdm_challenge_request5_size = sizeof(m_spdm_challenge_request5) + SPDM_REQ_CONTEXT_SIZE;
525 :
526 1 : status = libspdm_get_encap_response_challenge_auth(
527 : spdm_context, m_spdm_challenge_request5_size,
528 : request, &response_size, response);
529 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
530 1 : assert_int_equal (response_size, sizeof(spdm_error_response_t));
531 1 : spdm_response = (void *)response;
532 1 : assert_int_equal (spdm_response->header.request_response_code, SPDM_ERROR);
533 1 : assert_int_equal (spdm_response->header.param1, SPDM_ERROR_CODE_INVALID_REQUEST);
534 1 : assert_int_equal (spdm_response->header.param2, 0);
535 :
536 1 : free(data);
537 1 : }
538 :
539 1 : int libspdm_req_encap_challenge_auth_test(void)
540 : {
541 1 : const struct CMUnitTest test_cases[] = {
542 : /* Success Case*/
543 : cmocka_unit_test(req_encap_challenge_auth_case1),
544 : /* Can be populated with new test.*/
545 : cmocka_unit_test(req_encap_challenge_auth_case2),
546 : /* connection_state Check*/
547 : cmocka_unit_test(req_encap_challenge_auth_case3),
548 : cmocka_unit_test(req_encap_challenge_auth_case4),
549 : cmocka_unit_test(req_encap_challenge_auth_case5),
550 : /* Success Case, use provisioned public key (slot 0xFF) */
551 : cmocka_unit_test(req_encap_challenge_auth_case6),
552 : /* Success Case: V1.3 get a correct context field */
553 : cmocka_unit_test(req_encap_challenge_auth_case7),
554 : /* The key usage bit mask is not set, failed Case*/
555 : cmocka_unit_test(req_encap_challenge_auth_case8),
556 : };
557 :
558 1 : libspdm_test_context_t test_context = {
559 : LIBSPDM_TEST_CONTEXT_VERSION,
560 : false,
561 : };
562 :
563 1 : libspdm_setup_test_context(&test_context);
564 :
565 1 : return cmocka_run_group_tests(test_cases,
566 : libspdm_unit_test_group_setup,
567 : libspdm_unit_test_group_teardown);
568 : }
569 :
570 : #endif /* (LIBSPDM_ENABLE_CAPABILITY_MUT_AUTH_CAP) && (..) */
|