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