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