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