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