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