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