Line data Source code
1 : /**
2 : * Copyright Notice:
3 : * Copyright 2025-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_ENCAP_CAP) && (LIBSPDM_ENABLE_CAPABILITY_ENDPOINT_INFO_CAP)
11 :
12 : #pragma pack(1)
13 : typedef struct {
14 : spdm_message_header_t header;
15 : /* param1 - subcode of the request
16 : * param2 - Bit[7:4]: reserved
17 : * Bit[3:0]: slot_id */
18 : uint8_t request_attributes;
19 : uint8_t reserved[3];
20 : uint8_t nonce[32];
21 : } spdm_get_endpoint_info_request_max_t;
22 : #pragma pack()
23 :
24 : /* request signature, correct */
25 : spdm_get_endpoint_info_request_max_t m_libspdm_get_endpoint_info_request1 = {
26 : { SPDM_MESSAGE_VERSION_13, SPDM_GET_ENDPOINT_INFO,
27 : SPDM_GET_ENDPOINT_INFO_REQUEST_SUBCODE_DEVICE_CLASS_IDENTIFIER, 0},
28 : SPDM_GET_ENDPOINT_INFO_REQUEST_ATTRIBUTE_SIGNATURE_REQUESTED,
29 : {0, 0, 0},
30 : /* nonce */
31 : };
32 : size_t m_libspdm_get_endpoint_info_request1_size =
33 : sizeof(spdm_get_endpoint_info_request_t) + SPDM_NONCE_SIZE;
34 :
35 : /* request signature, correct, with slot_id == 0x1 */
36 : spdm_get_endpoint_info_request_max_t m_libspdm_get_endpoint_info_request2 = {
37 : { SPDM_MESSAGE_VERSION_13, SPDM_GET_ENDPOINT_INFO,
38 : SPDM_GET_ENDPOINT_INFO_REQUEST_SUBCODE_DEVICE_CLASS_IDENTIFIER, 0x1},
39 : SPDM_GET_ENDPOINT_INFO_REQUEST_ATTRIBUTE_SIGNATURE_REQUESTED,
40 : {0, 0, 0},
41 : /* nonce */
42 : };
43 : size_t m_libspdm_get_endpoint_info_request2_size =
44 : sizeof(spdm_get_endpoint_info_request_t) + SPDM_NONCE_SIZE;
45 :
46 : /* request signature, correct, with slot_id == 0xF */
47 : spdm_get_endpoint_info_request_max_t m_libspdm_get_endpoint_info_request3 = {
48 : { SPDM_MESSAGE_VERSION_13, SPDM_GET_ENDPOINT_INFO,
49 : SPDM_GET_ENDPOINT_INFO_REQUEST_SUBCODE_DEVICE_CLASS_IDENTIFIER, 0xF},
50 : SPDM_GET_ENDPOINT_INFO_REQUEST_ATTRIBUTE_SIGNATURE_REQUESTED,
51 : {0, 0, 0},
52 : /* nonce */
53 : };
54 : size_t m_libspdm_get_endpoint_info_request3_size =
55 : sizeof(spdm_get_endpoint_info_request_t) + SPDM_NONCE_SIZE;
56 :
57 : /* not request signature, correct */
58 : spdm_get_endpoint_info_request_max_t m_libspdm_get_endpoint_info_request4 = {
59 : { SPDM_MESSAGE_VERSION_13, SPDM_GET_ENDPOINT_INFO,
60 : SPDM_GET_ENDPOINT_INFO_REQUEST_SUBCODE_DEVICE_CLASS_IDENTIFIER, 0},
61 : 0,
62 : {0, 0, 0},
63 : };
64 : size_t m_libspdm_get_endpoint_info_request4_size = sizeof(spdm_get_endpoint_info_request_t);
65 :
66 : /**
67 : * Test 1: Successful response to get endpoint_info with signature
68 : * Expected Behavior: get a LIBSPDM_STATUS_SUCCESS return code,
69 : * correct transcript.message_encap_e size,
70 : * correct response message size and fields
71 : * correct signature verification
72 : **/
73 1 : static void req_encap_endpoint_info_case1(void **state)
74 : {
75 : libspdm_return_t status;
76 : libspdm_test_context_t *spdm_test_context;
77 : libspdm_context_t *spdm_context;
78 : libspdm_session_info_t* session_info;
79 : size_t response_size;
80 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
81 : spdm_endpoint_info_response_t *spdm_response;
82 : uint32_t endpoint_info_size;
83 : uint8_t endpoint_info_buffer[LIBSPDM_MAX_ENDPOINT_INFO_LENGTH];
84 : void* signature;
85 : size_t signature_size;
86 : bool result;
87 : void *data;
88 : size_t data_size;
89 :
90 1 : spdm_test_context = *state;
91 1 : spdm_context = spdm_test_context->spdm_context;
92 1 : spdm_test_context->case_id = 0x1;
93 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_13 <<
94 : SPDM_VERSION_NUMBER_SHIFT_BIT;
95 1 : spdm_context->local_context.capability.flags = 0;
96 1 : spdm_context->local_context.capability.flags |=
97 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_EP_INFO_CAP_SIG;
98 1 : spdm_context->connection_info.capability.flags = 0;
99 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
100 1 : spdm_context->connection_info.algorithm.base_asym_algo = m_libspdm_use_asym_algo;
101 1 : spdm_context->connection_info.algorithm.req_base_asym_alg = m_libspdm_use_req_asym_algo;
102 :
103 1 : libspdm_read_requester_public_certificate_chain(m_libspdm_use_hash_algo,
104 : m_libspdm_use_req_asym_algo, &data,
105 : &data_size, NULL, NULL);
106 :
107 1 : spdm_context->local_context.local_cert_chain_provision_size[0] = data_size;
108 1 : spdm_context->local_context.local_cert_chain_provision[0] = data;
109 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
110 : spdm_context->connection_info.peer_used_cert_chain[0].buffer_size = data_size;
111 : libspdm_copy_mem(spdm_context->connection_info.peer_used_cert_chain[0].buffer,
112 : sizeof(spdm_context->connection_info.peer_used_cert_chain[0].buffer),
113 : data, data_size);
114 : #else
115 1 : libspdm_hash_all(
116 : spdm_context->connection_info.algorithm.base_hash_algo,
117 : data, data_size,
118 1 : spdm_context->connection_info.peer_used_cert_chain[0].buffer_hash);
119 1 : spdm_context->connection_info.peer_used_cert_chain[0].buffer_hash_size =
120 1 : libspdm_get_hash_size(spdm_context->connection_info.algorithm.base_hash_algo);
121 1 : libspdm_get_leaf_cert_public_key_from_cert_chain(
122 : spdm_context->connection_info.algorithm.base_hash_algo,
123 1 : spdm_context->connection_info.algorithm.req_base_asym_alg,
124 : data, data_size,
125 : &spdm_context->connection_info.peer_used_cert_chain[0].leaf_cert_public_key);
126 : #endif
127 :
128 1 : session_info = NULL;
129 :
130 1 : libspdm_reset_message_encap_e(spdm_context, session_info);
131 1 : response_size = sizeof(response);
132 1 : libspdm_get_random_number(SPDM_NONCE_SIZE, m_libspdm_get_endpoint_info_request1.nonce);
133 1 : status = libspdm_get_encap_response_endpoint_info(
134 : spdm_context, m_libspdm_get_endpoint_info_request1_size,
135 : &m_libspdm_get_endpoint_info_request1, &response_size, response);
136 :
137 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
138 :
139 : /* response size check */
140 1 : endpoint_info_size = 0;
141 1 : libspdm_generate_device_endpoint_info(
142 : spdm_context, SPDM_GET_ENDPOINT_INFO_REQUEST_SUBCODE_DEVICE_CLASS_IDENTIFIER,
143 : SPDM_GET_ENDPOINT_INFO_REQUEST_ATTRIBUTE_SIGNATURE_REQUESTED,
144 : &endpoint_info_size, endpoint_info_buffer);
145 2 : signature_size = libspdm_get_asym_signature_size(
146 1 : spdm_context->connection_info.algorithm.req_base_asym_alg);
147 1 : assert_int_equal(response_size,
148 : sizeof(spdm_endpoint_info_response_t) + SPDM_NONCE_SIZE +
149 : sizeof(uint32_t) + endpoint_info_size + signature_size);
150 1 : spdm_response = (void *)response;
151 :
152 : /* response message check */
153 1 : assert_int_equal(spdm_response->header.request_response_code, SPDM_ENDPOINT_INFO);
154 :
155 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
156 : /* transcript.message_encap_e size check */
157 : assert_int_equal(spdm_context->transcript.message_encap_e.buffer_size, 0);
158 : #endif
159 :
160 : /* signature verification */
161 1 : status = libspdm_append_message_encap_e(spdm_context, session_info,
162 : &m_libspdm_get_endpoint_info_request1,
163 : m_libspdm_get_endpoint_info_request1_size);
164 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
165 :
166 1 : status = libspdm_append_message_encap_e(spdm_context, session_info, spdm_response,
167 : response_size - signature_size);
168 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
169 :
170 1 : signature = (void *)((uint8_t *)spdm_response + response_size - signature_size);
171 1 : result = libspdm_verify_endpoint_info_signature(
172 1 : spdm_context, session_info, false, m_libspdm_get_endpoint_info_request1.header.param2,
173 : signature, signature_size);
174 1 : assert_true(result);
175 1 : }
176 :
177 : /**
178 : * Test 2: Successful response to get endpoint_info with signature, slot_id == 0x1
179 : * Expected Behavior: get a LIBSPDM_STATUS_SUCCESS return code,
180 : * correct transcript.message_encap_e size,
181 : * correct response message size and fields
182 : * correct signature verification
183 : **/
184 1 : static void req_encap_endpoint_info_case2(void **state)
185 : {
186 : libspdm_return_t status;
187 : libspdm_test_context_t *spdm_test_context;
188 : libspdm_context_t *spdm_context;
189 : libspdm_session_info_t* session_info;
190 : size_t response_size;
191 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
192 : spdm_endpoint_info_response_t *spdm_response;
193 : uint32_t endpoint_info_size;
194 : uint8_t endpoint_info_buffer[LIBSPDM_MAX_ENDPOINT_INFO_LENGTH];
195 : void* signature;
196 : size_t signature_size;
197 : bool result;
198 : void *data;
199 : size_t data_size;
200 :
201 1 : spdm_test_context = *state;
202 1 : spdm_context = spdm_test_context->spdm_context;
203 1 : spdm_test_context->case_id = 0x2;
204 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_13 <<
205 : SPDM_VERSION_NUMBER_SHIFT_BIT;
206 1 : spdm_context->local_context.capability.flags = 0;
207 1 : spdm_context->local_context.capability.flags |=
208 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_EP_INFO_CAP_SIG;
209 1 : spdm_context->connection_info.capability.flags = 0;
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.req_base_asym_alg = m_libspdm_use_req_asym_algo;
213 :
214 1 : libspdm_read_requester_public_certificate_chain(m_libspdm_use_hash_algo,
215 : m_libspdm_use_req_asym_algo, &data,
216 : &data_size, NULL, NULL);
217 1 : spdm_context->local_context.local_cert_chain_provision_size[1] = data_size;
218 1 : spdm_context->local_context.local_cert_chain_provision[1] = data;
219 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
220 : spdm_context->connection_info.peer_used_cert_chain[1].buffer_size = data_size;
221 : libspdm_copy_mem(spdm_context->connection_info.peer_used_cert_chain[1].buffer,
222 : sizeof(spdm_context->connection_info.peer_used_cert_chain[1].buffer),
223 : data, data_size);
224 : #else
225 1 : libspdm_hash_all(
226 : spdm_context->connection_info.algorithm.base_hash_algo,
227 : data, data_size,
228 1 : spdm_context->connection_info.peer_used_cert_chain[1].buffer_hash);
229 1 : spdm_context->connection_info.peer_used_cert_chain[1].buffer_hash_size =
230 1 : libspdm_get_hash_size(spdm_context->connection_info.algorithm.base_hash_algo);
231 1 : libspdm_get_leaf_cert_public_key_from_cert_chain(
232 : spdm_context->connection_info.algorithm.base_hash_algo,
233 1 : spdm_context->connection_info.algorithm.req_base_asym_alg,
234 : data, data_size,
235 : &spdm_context->connection_info.peer_used_cert_chain[1].leaf_cert_public_key);
236 : #endif
237 :
238 1 : session_info = NULL;
239 :
240 1 : libspdm_reset_message_encap_e(spdm_context, session_info);
241 1 : response_size = sizeof(response);
242 1 : libspdm_get_random_number(SPDM_NONCE_SIZE, m_libspdm_get_endpoint_info_request1.nonce);
243 1 : status = libspdm_get_encap_response_endpoint_info(
244 : spdm_context, m_libspdm_get_endpoint_info_request2_size,
245 : &m_libspdm_get_endpoint_info_request2, &response_size, response);
246 :
247 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
248 :
249 : /* response size check */
250 1 : endpoint_info_size = 0;
251 1 : libspdm_generate_device_endpoint_info(
252 : spdm_context, SPDM_GET_ENDPOINT_INFO_REQUEST_SUBCODE_DEVICE_CLASS_IDENTIFIER,
253 : SPDM_GET_ENDPOINT_INFO_REQUEST_ATTRIBUTE_SIGNATURE_REQUESTED,
254 : &endpoint_info_size, endpoint_info_buffer);
255 2 : signature_size = libspdm_get_asym_signature_size(
256 1 : spdm_context->connection_info.algorithm.req_base_asym_alg);
257 1 : assert_int_equal(response_size,
258 : sizeof(spdm_endpoint_info_response_t) + SPDM_NONCE_SIZE +
259 : sizeof(uint32_t) + endpoint_info_size + signature_size);
260 1 : spdm_response = (void *)response;
261 :
262 : /* response message check */
263 1 : assert_int_equal(spdm_response->header.request_response_code, SPDM_ENDPOINT_INFO);
264 :
265 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
266 : /* transcript.message_encap_e size check */
267 : assert_int_equal(spdm_context->transcript.message_encap_e.buffer_size, 0);
268 : #endif
269 :
270 : /* signature verification */
271 1 : status = libspdm_append_message_encap_e(spdm_context, session_info,
272 : &m_libspdm_get_endpoint_info_request2,
273 : m_libspdm_get_endpoint_info_request2_size);
274 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
275 :
276 1 : status = libspdm_append_message_encap_e(spdm_context, session_info, spdm_response,
277 : response_size - signature_size);
278 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
279 :
280 1 : signature = (void *)((uint8_t *)spdm_response + response_size - signature_size);
281 1 : result = libspdm_verify_endpoint_info_signature(
282 1 : spdm_context, session_info, false, m_libspdm_get_endpoint_info_request2.header.param2,
283 : signature, signature_size);
284 1 : assert_true(result);
285 1 : }
286 :
287 : /**
288 : * Test 3: Successful response to get endpoint_info with signature, slot_id == 0xF
289 : * Expected Behavior: get a LIBSPDM_STATUS_SUCCESS return code,
290 : * correct transcript.message_encap_e size,
291 : * correct response message size and fields
292 : * correct signature verification
293 : **/
294 1 : static void req_encap_endpoint_info_case3(void **state)
295 : {
296 : libspdm_return_t status;
297 : libspdm_test_context_t *spdm_test_context;
298 : libspdm_context_t *spdm_context;
299 : libspdm_session_info_t* session_info;
300 : size_t response_size;
301 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
302 : spdm_endpoint_info_response_t *spdm_response;
303 : uint32_t endpoint_info_size;
304 : uint8_t endpoint_info_buffer[LIBSPDM_MAX_ENDPOINT_INFO_LENGTH];
305 : void* signature;
306 : size_t signature_size;
307 : bool result;
308 : void *data;
309 : size_t data_size;
310 :
311 1 : spdm_test_context = *state;
312 1 : spdm_context = spdm_test_context->spdm_context;
313 1 : spdm_test_context->case_id = 0x3;
314 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_13 <<
315 : SPDM_VERSION_NUMBER_SHIFT_BIT;
316 1 : spdm_context->local_context.capability.flags = 0;
317 1 : spdm_context->local_context.capability.flags |=
318 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_EP_INFO_CAP_SIG;
319 1 : spdm_context->connection_info.capability.flags = 0;
320 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
321 1 : spdm_context->connection_info.algorithm.base_asym_algo = m_libspdm_use_asym_algo;
322 1 : spdm_context->connection_info.algorithm.req_base_asym_alg = m_libspdm_use_req_asym_algo;
323 :
324 1 : libspdm_read_requester_public_key(m_libspdm_use_req_asym_algo, &data, &data_size);
325 1 : spdm_context->local_context.local_public_key_provision = data;
326 1 : spdm_context->local_context.local_public_key_provision_size = data_size;
327 1 : spdm_context->encap_context.req_slot_id = 0xF;
328 1 : spdm_context->local_context.peer_public_key_provision = data;
329 1 : spdm_context->local_context.peer_public_key_provision_size = data_size;
330 :
331 1 : session_info = NULL;
332 :
333 1 : libspdm_reset_message_encap_e(spdm_context, session_info);
334 1 : response_size = sizeof(response);
335 1 : libspdm_get_random_number(SPDM_NONCE_SIZE, m_libspdm_get_endpoint_info_request1.nonce);
336 1 : status = libspdm_get_encap_response_endpoint_info(
337 : spdm_context, m_libspdm_get_endpoint_info_request3_size,
338 : &m_libspdm_get_endpoint_info_request3, &response_size, response);
339 :
340 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
341 :
342 : /* response size check */
343 1 : endpoint_info_size = 0;
344 1 : libspdm_generate_device_endpoint_info(
345 : spdm_context, SPDM_GET_ENDPOINT_INFO_REQUEST_SUBCODE_DEVICE_CLASS_IDENTIFIER,
346 : SPDM_GET_ENDPOINT_INFO_REQUEST_ATTRIBUTE_SIGNATURE_REQUESTED,
347 : &endpoint_info_size, endpoint_info_buffer);
348 2 : signature_size = libspdm_get_asym_signature_size(
349 1 : spdm_context->connection_info.algorithm.req_base_asym_alg);
350 1 : assert_int_equal(response_size,
351 : sizeof(spdm_endpoint_info_response_t) + SPDM_NONCE_SIZE +
352 : sizeof(uint32_t) + endpoint_info_size + signature_size);
353 1 : spdm_response = (void *)response;
354 :
355 : /* response message check */
356 1 : assert_int_equal(spdm_response->header.request_response_code, SPDM_ENDPOINT_INFO);
357 :
358 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
359 : /* transcript.message_encap_e size check */
360 : assert_int_equal(spdm_context->transcript.message_encap_e.buffer_size, 0);
361 : #endif
362 :
363 : /* signature verification */
364 1 : status = libspdm_append_message_encap_e(spdm_context, session_info,
365 : &m_libspdm_get_endpoint_info_request3,
366 : m_libspdm_get_endpoint_info_request3_size);
367 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
368 :
369 1 : status = libspdm_append_message_encap_e(spdm_context, session_info, spdm_response,
370 : response_size - signature_size);
371 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
372 :
373 1 : signature = (void *)((uint8_t *)spdm_response + response_size - signature_size);
374 1 : result = libspdm_verify_endpoint_info_signature(
375 1 : spdm_context, session_info, false, m_libspdm_get_endpoint_info_request3.header.param2,
376 : signature, signature_size);
377 1 : assert_true(result);
378 1 : }
379 :
380 : /**
381 : * Test 4: Successful response to get endpoint_info without signature
382 : * Expected Behavior: get a LIBSPDM_STATUS_SUCCESS return code,
383 : * correct response message size and fields
384 : **/
385 1 : static void req_encap_endpoint_info_case4(void **state)
386 : {
387 : libspdm_return_t status;
388 : libspdm_test_context_t *spdm_test_context;
389 : libspdm_context_t *spdm_context;
390 : size_t response_size;
391 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
392 : spdm_endpoint_info_response_t *spdm_response;
393 : uint32_t endpoint_info_size;
394 : uint8_t endpoint_info_buffer[LIBSPDM_MAX_ENDPOINT_INFO_LENGTH];
395 :
396 1 : spdm_test_context = *state;
397 1 : spdm_context = spdm_test_context->spdm_context;
398 1 : spdm_test_context->case_id = 0x4;
399 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_13 <<
400 : SPDM_VERSION_NUMBER_SHIFT_BIT;
401 1 : spdm_context->local_context.capability.flags = 0;
402 1 : spdm_context->local_context.capability.flags |=
403 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_EP_INFO_CAP_NO_SIG;
404 1 : spdm_context->connection_info.capability.flags = 0;
405 :
406 1 : response_size = sizeof(response);
407 1 : status = libspdm_get_encap_response_endpoint_info(
408 : spdm_context, m_libspdm_get_endpoint_info_request4_size,
409 : &m_libspdm_get_endpoint_info_request4, &response_size, response);
410 :
411 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
412 :
413 : /* response size check */
414 1 : endpoint_info_size = 0;
415 1 : libspdm_generate_device_endpoint_info(
416 : spdm_context, SPDM_GET_ENDPOINT_INFO_REQUEST_SUBCODE_DEVICE_CLASS_IDENTIFIER,
417 : 0, &endpoint_info_size, endpoint_info_buffer);
418 1 : assert_int_equal(response_size,
419 : sizeof(spdm_endpoint_info_response_t) +
420 : sizeof(uint32_t) + endpoint_info_size);
421 1 : spdm_response = (void *)response;
422 :
423 : /* response message check */
424 1 : assert_int_equal(spdm_response->header.request_response_code, SPDM_ENDPOINT_INFO);
425 1 : assert_int_equal(spdm_response->header.param2, 0);
426 1 : }
427 :
428 : /**
429 : * Test 5: Successful response to get session-based endpoint_info with signature
430 : * Expected Behavior: get a LIBSPDM_STATUS_SUCCESS return code,
431 : * correct transcript.message_encap_e size,
432 : * correct response message size and fields
433 : * correct signature verification
434 : **/
435 1 : static void req_encap_endpoint_info_case5(void **state)
436 : {
437 : libspdm_return_t status;
438 : libspdm_test_context_t *spdm_test_context;
439 : libspdm_context_t *spdm_context;
440 : libspdm_session_info_t* session_info;
441 : size_t response_size;
442 : uint8_t response[LIBSPDM_MAX_SPDM_MSG_SIZE];
443 : spdm_endpoint_info_response_t *spdm_response;
444 : uint32_t endpoint_info_size;
445 : uint8_t endpoint_info_buffer[LIBSPDM_MAX_ENDPOINT_INFO_LENGTH];
446 : void* signature;
447 : size_t signature_size;
448 : bool result;
449 : void *data;
450 : size_t data_size;
451 : uint32_t session_id;
452 :
453 1 : spdm_test_context = *state;
454 1 : spdm_context = spdm_test_context->spdm_context;
455 1 : spdm_test_context->case_id = 0x1;
456 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_13 <<
457 : SPDM_VERSION_NUMBER_SHIFT_BIT;
458 1 : spdm_context->local_context.capability.flags = 0;
459 1 : spdm_context->local_context.capability.flags |=
460 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_EP_INFO_CAP_SIG;
461 1 : spdm_context->connection_info.capability.flags = 0;
462 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
463 1 : spdm_context->connection_info.algorithm.base_asym_algo = m_libspdm_use_asym_algo;
464 1 : spdm_context->connection_info.algorithm.req_base_asym_alg = m_libspdm_use_req_asym_algo;
465 :
466 1 : libspdm_read_requester_public_certificate_chain(m_libspdm_use_hash_algo,
467 : m_libspdm_use_req_asym_algo, &data,
468 : &data_size, NULL, NULL);
469 :
470 1 : spdm_context->local_context.local_cert_chain_provision_size[0] = data_size;
471 1 : spdm_context->local_context.local_cert_chain_provision[0] = data;
472 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
473 : spdm_context->connection_info.peer_used_cert_chain[0].buffer_size = data_size;
474 : libspdm_copy_mem(spdm_context->connection_info.peer_used_cert_chain[0].buffer,
475 : sizeof(spdm_context->connection_info.peer_used_cert_chain[0].buffer),
476 : data, data_size);
477 : #else
478 1 : libspdm_hash_all(
479 : spdm_context->connection_info.algorithm.base_hash_algo,
480 : data, data_size,
481 1 : spdm_context->connection_info.peer_used_cert_chain[0].buffer_hash);
482 1 : spdm_context->connection_info.peer_used_cert_chain[0].buffer_hash_size =
483 1 : libspdm_get_hash_size(spdm_context->connection_info.algorithm.base_hash_algo);
484 1 : libspdm_get_leaf_cert_public_key_from_cert_chain(
485 : spdm_context->connection_info.algorithm.base_hash_algo,
486 1 : spdm_context->connection_info.algorithm.req_base_asym_alg,
487 : data, data_size,
488 : &spdm_context->connection_info.peer_used_cert_chain[0].leaf_cert_public_key);
489 : #endif
490 :
491 1 : session_id = 0xFFFFFFFF;
492 1 : spdm_context->latest_session_id = session_id;
493 1 : spdm_context->last_spdm_request_session_id_valid = true;
494 1 : spdm_context->last_spdm_request_session_id = session_id;
495 1 : session_info = &spdm_context->session_info[0];
496 1 : libspdm_session_info_init(spdm_context, session_info, session_id,
497 : SECURED_SPDM_VERSION_11 << SPDM_VERSION_NUMBER_SHIFT_BIT, true);
498 1 : libspdm_secured_message_set_session_state(
499 : session_info->secured_message_context,
500 : LIBSPDM_SESSION_STATE_ESTABLISHED);
501 :
502 1 : libspdm_reset_message_encap_e(spdm_context, session_info);
503 1 : response_size = sizeof(response);
504 1 : libspdm_get_random_number(SPDM_NONCE_SIZE, m_libspdm_get_endpoint_info_request1.nonce);
505 1 : status = libspdm_get_encap_response_endpoint_info(
506 : spdm_context, m_libspdm_get_endpoint_info_request1_size,
507 : &m_libspdm_get_endpoint_info_request1, &response_size, response);
508 :
509 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
510 :
511 : /* response size check */
512 1 : endpoint_info_size = 0;
513 1 : libspdm_generate_device_endpoint_info(
514 : spdm_context, SPDM_GET_ENDPOINT_INFO_REQUEST_SUBCODE_DEVICE_CLASS_IDENTIFIER,
515 : SPDM_GET_ENDPOINT_INFO_REQUEST_ATTRIBUTE_SIGNATURE_REQUESTED,
516 : &endpoint_info_size, endpoint_info_buffer);
517 2 : signature_size = libspdm_get_asym_signature_size(
518 1 : spdm_context->connection_info.algorithm.req_base_asym_alg);
519 1 : assert_int_equal(response_size,
520 : sizeof(spdm_endpoint_info_response_t) + SPDM_NONCE_SIZE +
521 : sizeof(uint32_t) + endpoint_info_size + signature_size);
522 1 : spdm_response = (void *)response;
523 :
524 : /* response message check */
525 1 : assert_int_equal(spdm_response->header.request_response_code, SPDM_ENDPOINT_INFO);
526 :
527 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
528 : /* transcript.message_encap_e size check */
529 : assert_int_equal(session_info->session_transcript.message_encap_e.buffer_size, 0);
530 : #endif
531 :
532 : /* signature verification */
533 1 : status = libspdm_append_message_encap_e(spdm_context, session_info,
534 : &m_libspdm_get_endpoint_info_request1,
535 : m_libspdm_get_endpoint_info_request1_size);
536 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
537 :
538 1 : status = libspdm_append_message_encap_e(spdm_context, session_info, spdm_response,
539 : response_size - signature_size);
540 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
541 :
542 1 : signature = (void *)((uint8_t *)spdm_response + response_size - signature_size);
543 1 : result = libspdm_verify_endpoint_info_signature(
544 1 : spdm_context, session_info, false, m_libspdm_get_endpoint_info_request1.header.param2,
545 : signature, signature_size);
546 1 : assert_true(result);
547 1 : }
548 :
549 1 : int libspdm_req_encap_endpoint_info_test(void)
550 : {
551 1 : const struct CMUnitTest test_cases[] = {
552 : /* Successful response to get endpoint_info with signature */
553 : cmocka_unit_test(req_encap_endpoint_info_case1),
554 : /* Successful response to get endpoint_info with signature, slot_id == 0x1 */
555 : cmocka_unit_test(req_encap_endpoint_info_case2),
556 : /* Successful response to get endpoint_info with signature, slot_id == 0xF */
557 : cmocka_unit_test(req_encap_endpoint_info_case3),
558 : /* Successful response to get endpoint_info without signature */
559 : cmocka_unit_test(req_encap_endpoint_info_case4),
560 : /* Successful response to get session-based endpoint_info with signature */
561 : cmocka_unit_test(req_encap_endpoint_info_case5),
562 : };
563 :
564 1 : libspdm_test_context_t test_context = {
565 : LIBSPDM_TEST_CONTEXT_VERSION,
566 : false,
567 : };
568 :
569 1 : libspdm_setup_test_context(&test_context);
570 :
571 1 : return cmocka_run_group_tests(test_cases,
572 : libspdm_unit_test_group_setup,
573 : libspdm_unit_test_group_teardown);
574 : }
575 :
576 : #endif /* (LIBSPDM_ENABLE_CAPABILITY_ENCAP_CAP) && (...) */
|