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