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_requester_lib.h"
9 : #include "internal/libspdm_secured_message_lib.h"
10 :
11 : #if (LIBSPDM_SEND_GET_ENDPOINT_INFO_SUPPORT) && (LIBSPDM_ENABLE_CAPABILITY_ENDPOINT_INFO_CAP)
12 :
13 : static size_t m_libspdm_local_buffer_size;
14 : static uint8_t m_libspdm_local_buffer[LIBSPDM_MAX_MESSAGE_IL1IL2_BUFFER_SIZE];
15 :
16 : #define LIBSPDM_TEST_ENDPOINT_INFO_BUFFER_SIZE 0x20
17 : static uint8_t m_endpoint_info_buffer[LIBSPDM_TEST_ENDPOINT_INFO_BUFFER_SIZE];
18 :
19 9 : static libspdm_return_t send_message(
20 : void *spdm_context, size_t request_size, const void *request, uint64_t timeout)
21 : {
22 : libspdm_test_context_t *spdm_test_context;
23 : size_t header_size;
24 : uint8_t message_buffer[LIBSPDM_SENDER_BUFFER_SIZE];
25 :
26 9 : memcpy(message_buffer, request, request_size);
27 :
28 9 : spdm_test_context = libspdm_get_test_context();
29 9 : header_size = sizeof(libspdm_test_message_header_t);
30 9 : switch (spdm_test_context->case_id) {
31 3 : case 0x1:
32 : case 0x2:
33 3 : m_libspdm_local_buffer_size = 0;
34 3 : libspdm_copy_mem(m_libspdm_local_buffer, sizeof(m_libspdm_local_buffer),
35 : (const uint8_t *)request + header_size, request_size - header_size);
36 3 : m_libspdm_local_buffer_size += request_size - header_size;
37 3 : return LIBSPDM_STATUS_SUCCESS;
38 2 : case 0x3: {
39 : static size_t sub_index = 0;
40 2 : if (sub_index == 0) {
41 1 : m_libspdm_local_buffer_size = 0;
42 1 : libspdm_copy_mem(m_libspdm_local_buffer, sizeof(m_libspdm_local_buffer),
43 : (const uint8_t *)request + header_size, request_size - header_size);
44 1 : m_libspdm_local_buffer_size += request_size - header_size;
45 1 : sub_index++;
46 : }
47 : }
48 2 : return LIBSPDM_STATUS_SUCCESS;
49 2 : case 0x4:
50 : case 0x5:
51 2 : m_libspdm_local_buffer_size = 0;
52 2 : libspdm_copy_mem(m_libspdm_local_buffer, sizeof(m_libspdm_local_buffer),
53 : (const uint8_t *)request + header_size, request_size - header_size);
54 2 : m_libspdm_local_buffer_size += request_size - header_size;
55 2 : return LIBSPDM_STATUS_SUCCESS;
56 1 : case 0x6:
57 1 : return LIBSPDM_STATUS_SUCCESS;
58 1 : case 0x7: {
59 : uint32_t *session_id;
60 : libspdm_session_info_t *session_info;
61 : bool is_app_message;
62 : uint8_t *app_message;
63 : size_t app_message_size;
64 :
65 1 : m_libspdm_local_buffer_size = 0;
66 1 : session_id = NULL;
67 1 : session_info = libspdm_get_session_info_via_session_id(spdm_context, 0xFFFFFFFF);
68 1 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "Request (0x%zx):\n", request_size));
69 1 : libspdm_dump_hex(request, request_size);
70 1 : libspdm_get_scratch_buffer (spdm_context, (void **)&app_message, &app_message_size);
71 1 : libspdm_transport_test_decode_message(
72 : spdm_context, &session_id, &is_app_message,
73 : false, request_size, message_buffer,
74 : &app_message_size, (void **)&app_message);
75 : ((libspdm_secured_message_context_t
76 1 : *)(session_info->secured_message_context))
77 1 : ->application_secret.response_data_sequence_number--;
78 1 : libspdm_copy_mem(m_libspdm_local_buffer, sizeof(m_libspdm_local_buffer),
79 : app_message, app_message_size);
80 1 : m_libspdm_local_buffer_size += app_message_size;
81 : }
82 1 : return LIBSPDM_STATUS_SUCCESS;
83 0 : default:
84 0 : return LIBSPDM_STATUS_SEND_FAIL;
85 : }
86 : }
87 :
88 9 : static libspdm_return_t receive_message(
89 : void *spdm_context, size_t *response_size, void **response, uint64_t timeout)
90 : {
91 : libspdm_test_context_t *spdm_test_context;
92 : uint32_t endpoint_info_buffer_size;
93 :
94 9 : endpoint_info_buffer_size = LIBSPDM_TEST_ENDPOINT_INFO_BUFFER_SIZE;
95 9 : spdm_test_context = libspdm_get_test_context();
96 9 : libspdm_generate_device_endpoint_info(
97 : spdm_context, SPDM_GET_ENDPOINT_INFO_REQUEST_SUBCODE_DEVICE_CLASS_IDENTIFIER,
98 : SPDM_GET_ENDPOINT_INFO_REQUEST_ATTRIBUTE_SIGNATURE_REQUESTED,
99 : &endpoint_info_buffer_size, m_endpoint_info_buffer);
100 9 : switch (spdm_test_context->case_id) {
101 1 : case 0x1: { /*correct ENDPOINT_INFO message with signature*/
102 : spdm_endpoint_info_response_t *spdm_response;
103 : uint8_t *ptr;
104 : uint8_t hash_data[LIBSPDM_MAX_HASH_SIZE];
105 : size_t sig_size;
106 : size_t spdm_response_size;
107 : size_t transport_header_size;
108 :
109 : ((libspdm_context_t *)spdm_context)
110 1 : ->connection_info.algorithm.base_asym_algo = m_libspdm_use_asym_algo;
111 : ((libspdm_context_t *)spdm_context)
112 1 : ->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
113 :
114 1 : spdm_response_size = sizeof(spdm_endpoint_info_response_t) +
115 : SPDM_NONCE_SIZE + sizeof(uint32_t) +
116 2 : endpoint_info_buffer_size +
117 1 : libspdm_get_asym_signature_size(m_libspdm_use_asym_algo);
118 :
119 1 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
120 1 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
121 :
122 1 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_13;
123 1 : spdm_response->header.request_response_code = SPDM_ENDPOINT_INFO;
124 1 : spdm_response->header.param1 = 0;
125 1 : spdm_response->header.param2 = 0; /* slot_id */
126 1 : ptr = (uint8_t *)(spdm_response + 1);
127 :
128 1 : libspdm_get_random_number(SPDM_NONCE_SIZE, ptr);
129 1 : ptr += SPDM_NONCE_SIZE;
130 :
131 1 : *(uint32_t *)ptr = endpoint_info_buffer_size; /* ep_info_len */
132 1 : ptr += sizeof(uint32_t);
133 :
134 1 : libspdm_copy_mem(ptr, endpoint_info_buffer_size,
135 : m_endpoint_info_buffer, endpoint_info_buffer_size);
136 1 : ptr += endpoint_info_buffer_size;
137 :
138 1 : libspdm_copy_mem(&m_libspdm_local_buffer[m_libspdm_local_buffer_size],
139 : sizeof(m_libspdm_local_buffer) -
140 1 : (&m_libspdm_local_buffer[m_libspdm_local_buffer_size] -
141 : m_libspdm_local_buffer),
142 1 : spdm_response, (size_t)ptr - (size_t)spdm_response);
143 1 : m_libspdm_local_buffer_size += ((size_t)ptr - (size_t)spdm_response);
144 1 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "m_libspdm_local_buffer_size (0x%zx):\n",
145 : m_libspdm_local_buffer_size));
146 1 : libspdm_dump_hex(m_libspdm_local_buffer, m_libspdm_local_buffer_size);
147 1 : libspdm_hash_all(m_libspdm_use_hash_algo, m_libspdm_local_buffer,
148 : m_libspdm_local_buffer_size, hash_data);
149 1 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "HashDataSize (0x%x):\n",
150 : libspdm_get_hash_size(m_libspdm_use_hash_algo)));
151 1 : libspdm_dump_hex(hash_data, libspdm_get_hash_size(m_libspdm_use_hash_algo));
152 1 : sig_size = libspdm_get_asym_signature_size(m_libspdm_use_asym_algo);
153 1 : libspdm_responder_data_sign(
154 : spdm_context,
155 1 : spdm_response->header.spdm_version << SPDM_VERSION_NUMBER_SHIFT_BIT,
156 : 0, SPDM_ENDPOINT_INFO,
157 : m_libspdm_use_asym_algo, m_libspdm_use_pqc_asym_algo, m_libspdm_use_hash_algo,
158 : false, m_libspdm_local_buffer, m_libspdm_local_buffer_size,
159 : ptr, &sig_size);
160 1 : ptr += sig_size;
161 :
162 1 : libspdm_transport_test_encode_message(spdm_context, NULL, false,
163 : false, spdm_response_size,
164 : spdm_response, response_size,
165 : response);
166 : }
167 1 : return LIBSPDM_STATUS_SUCCESS;
168 :
169 2 : case 0x2: { /*ERROR BUSY + ENDPOINT_INFO w/ signature*/
170 : static size_t sub_index1 = 0;
171 2 : if (sub_index1 == 0) {
172 : /*SPDM_ERROR with SPDM_ERROR_CODE_BUSY*/
173 : spdm_error_response_t *spdm_response;
174 : size_t spdm_response_size;
175 : size_t transport_header_size;
176 :
177 1 : spdm_response_size = sizeof(spdm_error_response_t);
178 1 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
179 1 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
180 :
181 1 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_13;
182 1 : spdm_response->header.request_response_code = SPDM_ERROR;
183 1 : spdm_response->header.param1 = SPDM_ERROR_CODE_BUSY;
184 1 : spdm_response->header.param2 = 0;
185 :
186 1 : libspdm_transport_test_encode_message(
187 : spdm_context, NULL, false, false,
188 : spdm_response_size, spdm_response,
189 : response_size, response);
190 1 : sub_index1++;
191 1 : } else if (sub_index1 == 1) {
192 : /*correct ENDPOINT_INFO message with signature*/
193 : spdm_endpoint_info_response_t *spdm_response;
194 : uint8_t *ptr;
195 : uint8_t hash_data[LIBSPDM_MAX_HASH_SIZE];
196 : size_t sig_size;
197 : size_t spdm_response_size;
198 : size_t transport_header_size;
199 :
200 : ((libspdm_context_t *)spdm_context)
201 1 : ->connection_info.algorithm.base_asym_algo = m_libspdm_use_asym_algo;
202 : ((libspdm_context_t *)spdm_context)
203 1 : ->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
204 :
205 1 : spdm_response_size = sizeof(spdm_endpoint_info_response_t) +
206 : SPDM_NONCE_SIZE + sizeof(uint32_t) +
207 2 : endpoint_info_buffer_size +
208 1 : libspdm_get_asym_signature_size(m_libspdm_use_asym_algo);
209 :
210 1 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
211 1 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
212 :
213 1 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_13;
214 1 : spdm_response->header.request_response_code = SPDM_ENDPOINT_INFO;
215 1 : spdm_response->header.param1 = 0;
216 1 : spdm_response->header.param2 = 0; /* slot_id */
217 1 : ptr = (uint8_t *)(spdm_response + 1);
218 :
219 1 : libspdm_get_random_number(SPDM_NONCE_SIZE, ptr);
220 1 : ptr += SPDM_NONCE_SIZE;
221 :
222 1 : *(uint32_t *)ptr = endpoint_info_buffer_size; /* ep_info_len */
223 1 : ptr += sizeof(uint32_t);
224 :
225 1 : libspdm_copy_mem(ptr, endpoint_info_buffer_size,
226 : m_endpoint_info_buffer, endpoint_info_buffer_size);
227 1 : ptr += endpoint_info_buffer_size;
228 :
229 1 : libspdm_copy_mem(&m_libspdm_local_buffer[m_libspdm_local_buffer_size],
230 : sizeof(m_libspdm_local_buffer) -
231 1 : (&m_libspdm_local_buffer[m_libspdm_local_buffer_size] -
232 : m_libspdm_local_buffer),
233 1 : spdm_response, (size_t)ptr - (size_t)spdm_response);
234 1 : m_libspdm_local_buffer_size += ((size_t)ptr - (size_t)spdm_response);
235 1 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "m_libspdm_local_buffer_size (0x%zx):\n",
236 : m_libspdm_local_buffer_size));
237 1 : libspdm_dump_hex(m_libspdm_local_buffer, m_libspdm_local_buffer_size);
238 1 : libspdm_hash_all(m_libspdm_use_hash_algo, m_libspdm_local_buffer,
239 : m_libspdm_local_buffer_size, hash_data);
240 1 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "HashDataSize (0x%x):\n",
241 : libspdm_get_hash_size(m_libspdm_use_hash_algo)));
242 1 : libspdm_dump_hex(hash_data, libspdm_get_hash_size(m_libspdm_use_hash_algo));
243 1 : sig_size = libspdm_get_asym_signature_size(m_libspdm_use_asym_algo);
244 1 : libspdm_responder_data_sign(
245 : spdm_context,
246 1 : spdm_response->header.spdm_version << SPDM_VERSION_NUMBER_SHIFT_BIT,
247 : 0, SPDM_ENDPOINT_INFO,
248 : m_libspdm_use_asym_algo, m_libspdm_use_pqc_asym_algo, m_libspdm_use_hash_algo,
249 : false, m_libspdm_local_buffer, m_libspdm_local_buffer_size,
250 : ptr, &sig_size);
251 1 : ptr += sig_size;
252 :
253 1 : libspdm_transport_test_encode_message(spdm_context, NULL, false,
254 : false, spdm_response_size,
255 : spdm_response, response_size,
256 : response);
257 : }
258 : }
259 2 : return LIBSPDM_STATUS_SUCCESS;
260 :
261 2 : case 0x3: { /*ERROR NOT_READY + ENDPOINT_INFO w/ signature*/
262 : static size_t sub_index2 = 0;
263 2 : if (sub_index2 == 0) {
264 : /*SPDM_ERROR with SPDM_ERROR_CODE_RESPONSE_NOT_READY*/
265 : spdm_error_response_data_response_not_ready_t *spdm_response;
266 : size_t spdm_response_size;
267 : size_t transport_header_size;
268 :
269 1 : spdm_response_size = sizeof(spdm_error_response_data_response_not_ready_t);
270 1 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
271 1 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
272 :
273 1 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_13;
274 1 : spdm_response->header.request_response_code = SPDM_ERROR;
275 1 : spdm_response->header.param1 = SPDM_ERROR_CODE_RESPONSE_NOT_READY;
276 1 : spdm_response->header.param2 = 0;
277 1 : spdm_response->extend_error_data.rd_exponent = 1;
278 1 : spdm_response->extend_error_data.rd_tm = 2;
279 1 : spdm_response->extend_error_data.request_code = SPDM_GET_ENDPOINT_INFO;
280 1 : spdm_response->extend_error_data.token = 1;
281 :
282 1 : libspdm_transport_test_encode_message(
283 : spdm_context, NULL, false, false,
284 : spdm_response_size, spdm_response,
285 : response_size, response);
286 1 : sub_index2++;
287 1 : } else if (sub_index2 == 1) {
288 : /*correct ENDPOINT_INFO message with signature*/
289 : spdm_endpoint_info_response_t *spdm_response;
290 : uint8_t *ptr;
291 : uint8_t hash_data[LIBSPDM_MAX_HASH_SIZE];
292 : size_t sig_size;
293 : size_t spdm_response_size;
294 : size_t transport_header_size;
295 :
296 : ((libspdm_context_t *)spdm_context)
297 1 : ->connection_info.algorithm.base_asym_algo = m_libspdm_use_asym_algo;
298 : ((libspdm_context_t *)spdm_context)
299 1 : ->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
300 :
301 1 : spdm_response_size = sizeof(spdm_endpoint_info_response_t) +
302 : SPDM_NONCE_SIZE + sizeof(uint32_t) +
303 2 : endpoint_info_buffer_size +
304 1 : libspdm_get_asym_signature_size(m_libspdm_use_asym_algo);
305 :
306 1 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
307 1 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
308 :
309 1 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_13;
310 1 : spdm_response->header.request_response_code = SPDM_ENDPOINT_INFO;
311 1 : spdm_response->header.param1 = 0;
312 1 : spdm_response->header.param2 = 0; /* slot_id */
313 1 : ptr = (uint8_t *)(spdm_response + 1);
314 :
315 1 : libspdm_get_random_number(SPDM_NONCE_SIZE, ptr);
316 1 : ptr += SPDM_NONCE_SIZE;
317 :
318 1 : *(uint32_t *)ptr = endpoint_info_buffer_size; /* ep_info_len */
319 1 : ptr += sizeof(uint32_t);
320 :
321 1 : libspdm_copy_mem(ptr, endpoint_info_buffer_size,
322 : m_endpoint_info_buffer, endpoint_info_buffer_size);
323 1 : ptr += endpoint_info_buffer_size;
324 :
325 1 : libspdm_copy_mem(&m_libspdm_local_buffer[m_libspdm_local_buffer_size],
326 : sizeof(m_libspdm_local_buffer) -
327 1 : (&m_libspdm_local_buffer[m_libspdm_local_buffer_size] -
328 : m_libspdm_local_buffer),
329 1 : spdm_response, (size_t)ptr - (size_t)spdm_response);
330 1 : m_libspdm_local_buffer_size += ((size_t)ptr - (size_t)spdm_response);
331 1 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "m_libspdm_local_buffer_size (0x%zx):\n",
332 : m_libspdm_local_buffer_size));
333 1 : libspdm_dump_hex(m_libspdm_local_buffer, m_libspdm_local_buffer_size);
334 1 : libspdm_hash_all(m_libspdm_use_hash_algo, m_libspdm_local_buffer,
335 : m_libspdm_local_buffer_size, hash_data);
336 1 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "HashDataSize (0x%x):\n",
337 : libspdm_get_hash_size(m_libspdm_use_hash_algo)));
338 1 : libspdm_dump_hex(hash_data, libspdm_get_hash_size(m_libspdm_use_hash_algo));
339 1 : sig_size = libspdm_get_asym_signature_size(m_libspdm_use_asym_algo);
340 1 : libspdm_responder_data_sign(
341 : spdm_context,
342 1 : spdm_response->header.spdm_version << SPDM_VERSION_NUMBER_SHIFT_BIT,
343 : 0, SPDM_ENDPOINT_INFO,
344 : m_libspdm_use_asym_algo, m_libspdm_use_pqc_asym_algo, m_libspdm_use_hash_algo,
345 : false, m_libspdm_local_buffer, m_libspdm_local_buffer_size,
346 : ptr, &sig_size);
347 1 : ptr += sig_size;
348 :
349 1 : libspdm_transport_test_encode_message(spdm_context, NULL, false,
350 : false, spdm_response_size,
351 : spdm_response, response_size,
352 : response);
353 : }
354 : }
355 2 : return LIBSPDM_STATUS_SUCCESS;
356 :
357 1 : case 0x4: { /*correct ENDPOINT_INFO message with signature and slot_id = 1*/
358 : spdm_endpoint_info_response_t *spdm_response;
359 : uint8_t *ptr;
360 : uint8_t hash_data[LIBSPDM_MAX_HASH_SIZE];
361 : size_t sig_size;
362 : size_t spdm_response_size;
363 : size_t transport_header_size;
364 :
365 : ((libspdm_context_t *)spdm_context)
366 1 : ->connection_info.algorithm.base_asym_algo = m_libspdm_use_asym_algo;
367 : ((libspdm_context_t *)spdm_context)
368 1 : ->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
369 :
370 1 : spdm_response_size = sizeof(spdm_endpoint_info_response_t) +
371 : SPDM_NONCE_SIZE + sizeof(uint32_t) +
372 2 : endpoint_info_buffer_size +
373 1 : libspdm_get_asym_signature_size(m_libspdm_use_asym_algo);
374 :
375 1 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
376 1 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
377 :
378 1 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_13;
379 1 : spdm_response->header.request_response_code = SPDM_ENDPOINT_INFO;
380 1 : spdm_response->header.param1 = 0;
381 1 : spdm_response->header.param2 = 1; /* slot_id */
382 1 : ptr = (uint8_t *)(spdm_response + 1);
383 :
384 1 : libspdm_get_random_number(SPDM_NONCE_SIZE, ptr);
385 1 : ptr += SPDM_NONCE_SIZE;
386 :
387 1 : *(uint32_t *)ptr = endpoint_info_buffer_size; /* ep_info_len */
388 1 : ptr += sizeof(uint32_t);
389 :
390 1 : libspdm_copy_mem(ptr, endpoint_info_buffer_size,
391 : m_endpoint_info_buffer, endpoint_info_buffer_size);
392 1 : ptr += endpoint_info_buffer_size;
393 :
394 1 : libspdm_copy_mem(&m_libspdm_local_buffer[m_libspdm_local_buffer_size],
395 : sizeof(m_libspdm_local_buffer) -
396 1 : (&m_libspdm_local_buffer[m_libspdm_local_buffer_size] -
397 : m_libspdm_local_buffer),
398 1 : spdm_response, (size_t)ptr - (size_t)spdm_response);
399 1 : m_libspdm_local_buffer_size += ((size_t)ptr - (size_t)spdm_response);
400 1 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "m_libspdm_local_buffer_size (0x%zx):\n",
401 : m_libspdm_local_buffer_size));
402 1 : libspdm_dump_hex(m_libspdm_local_buffer, m_libspdm_local_buffer_size);
403 1 : libspdm_hash_all(m_libspdm_use_hash_algo, m_libspdm_local_buffer,
404 : m_libspdm_local_buffer_size, hash_data);
405 1 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "HashDataSize (0x%x):\n",
406 : libspdm_get_hash_size(m_libspdm_use_hash_algo)));
407 1 : libspdm_dump_hex(hash_data, libspdm_get_hash_size(m_libspdm_use_hash_algo));
408 1 : sig_size = libspdm_get_asym_signature_size(m_libspdm_use_asym_algo);
409 1 : libspdm_responder_data_sign(
410 : spdm_context,
411 1 : spdm_response->header.spdm_version << SPDM_VERSION_NUMBER_SHIFT_BIT,
412 : 0, SPDM_ENDPOINT_INFO,
413 : m_libspdm_use_asym_algo, m_libspdm_use_pqc_asym_algo, m_libspdm_use_hash_algo,
414 : false, m_libspdm_local_buffer, m_libspdm_local_buffer_size,
415 : ptr, &sig_size);
416 1 : ptr += sig_size;
417 :
418 1 : libspdm_transport_test_encode_message(spdm_context, NULL, false,
419 : false, spdm_response_size,
420 : spdm_response, response_size,
421 : response);
422 : }
423 1 : return LIBSPDM_STATUS_SUCCESS;
424 :
425 1 : case 0x5: { /*correct ENDPOINT_INFO message with signature and use provisioned key*/
426 : spdm_endpoint_info_response_t *spdm_response;
427 : uint8_t *ptr;
428 : uint8_t hash_data[LIBSPDM_MAX_HASH_SIZE];
429 : size_t sig_size;
430 : size_t spdm_response_size;
431 : size_t transport_header_size;
432 :
433 : ((libspdm_context_t *)spdm_context)
434 1 : ->connection_info.algorithm.base_asym_algo = m_libspdm_use_asym_algo;
435 : ((libspdm_context_t *)spdm_context)
436 1 : ->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
437 :
438 1 : spdm_response_size = sizeof(spdm_endpoint_info_response_t) +
439 : SPDM_NONCE_SIZE + sizeof(uint32_t) +
440 2 : endpoint_info_buffer_size +
441 1 : libspdm_get_asym_signature_size(m_libspdm_use_asym_algo);
442 :
443 1 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
444 1 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
445 :
446 1 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_13;
447 1 : spdm_response->header.request_response_code = SPDM_ENDPOINT_INFO;
448 1 : spdm_response->header.param1 = 0;
449 1 : spdm_response->header.param2 = 0xF; /* slot_id */
450 1 : ptr = (uint8_t *)(spdm_response + 1);
451 :
452 1 : libspdm_get_random_number(SPDM_NONCE_SIZE, ptr);
453 1 : ptr += SPDM_NONCE_SIZE;
454 :
455 1 : *(uint32_t *)ptr = endpoint_info_buffer_size; /* ep_info_len */
456 1 : ptr += sizeof(uint32_t);
457 :
458 1 : libspdm_copy_mem(ptr, endpoint_info_buffer_size,
459 : m_endpoint_info_buffer, endpoint_info_buffer_size);
460 1 : ptr += endpoint_info_buffer_size;
461 :
462 1 : libspdm_copy_mem(&m_libspdm_local_buffer[m_libspdm_local_buffer_size],
463 : sizeof(m_libspdm_local_buffer) -
464 1 : (&m_libspdm_local_buffer[m_libspdm_local_buffer_size] -
465 : m_libspdm_local_buffer),
466 1 : spdm_response, (size_t)ptr - (size_t)spdm_response);
467 1 : m_libspdm_local_buffer_size += ((size_t)ptr - (size_t)spdm_response);
468 1 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "m_libspdm_local_buffer_size (0x%zx):\n",
469 : m_libspdm_local_buffer_size));
470 1 : libspdm_dump_hex(m_libspdm_local_buffer, m_libspdm_local_buffer_size);
471 1 : libspdm_hash_all(m_libspdm_use_hash_algo, m_libspdm_local_buffer,
472 : m_libspdm_local_buffer_size, hash_data);
473 1 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "HashDataSize (0x%x):\n",
474 : libspdm_get_hash_size(m_libspdm_use_hash_algo)));
475 1 : libspdm_dump_hex(hash_data, libspdm_get_hash_size(m_libspdm_use_hash_algo));
476 1 : sig_size = libspdm_get_asym_signature_size(m_libspdm_use_asym_algo);
477 1 : libspdm_responder_data_sign(
478 : spdm_context,
479 1 : spdm_response->header.spdm_version << SPDM_VERSION_NUMBER_SHIFT_BIT,
480 : 0, SPDM_ENDPOINT_INFO,
481 : m_libspdm_use_asym_algo, m_libspdm_use_pqc_asym_algo, m_libspdm_use_hash_algo,
482 : false, m_libspdm_local_buffer, m_libspdm_local_buffer_size,
483 : ptr, &sig_size);
484 1 : ptr += sig_size;
485 :
486 1 : libspdm_transport_test_encode_message(spdm_context, NULL, false,
487 : false, spdm_response_size,
488 : spdm_response, response_size,
489 : response);
490 : }
491 1 : return LIBSPDM_STATUS_SUCCESS;
492 :
493 1 : case 0x6: { /*correct ENDPOINT_INFO message without signature*/
494 : spdm_endpoint_info_response_t *spdm_response;
495 : uint8_t *ptr;
496 : size_t spdm_response_size;
497 : size_t transport_header_size;
498 :
499 : ((libspdm_context_t *)spdm_context)
500 1 : ->connection_info.algorithm.base_asym_algo = m_libspdm_use_asym_algo;
501 : ((libspdm_context_t *)spdm_context)
502 1 : ->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
503 :
504 1 : spdm_response_size = sizeof(spdm_endpoint_info_response_t) +
505 1 : +sizeof(uint32_t) +
506 : endpoint_info_buffer_size;
507 :
508 1 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
509 1 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
510 :
511 1 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_13;
512 1 : spdm_response->header.request_response_code = SPDM_ENDPOINT_INFO;
513 1 : spdm_response->header.param1 = 0;
514 1 : spdm_response->header.param2 = 0; /* slot_id */
515 1 : ptr = (uint8_t *)(spdm_response + 1);
516 :
517 1 : *(uint32_t *)ptr = endpoint_info_buffer_size; /* ep_info_len */
518 1 : ptr += sizeof(uint32_t);
519 :
520 1 : libspdm_copy_mem(ptr, endpoint_info_buffer_size,
521 : m_endpoint_info_buffer, endpoint_info_buffer_size);
522 1 : ptr += endpoint_info_buffer_size;
523 :
524 1 : libspdm_transport_test_encode_message(spdm_context, NULL, false,
525 : false, spdm_response_size,
526 : spdm_response, response_size,
527 : response);
528 : }
529 1 : return LIBSPDM_STATUS_SUCCESS;
530 :
531 1 : case 0x7: { /*correct session based ENDPOINT_INFO message with signature*/
532 : spdm_endpoint_info_response_t *spdm_response;
533 : uint8_t *ptr;
534 : uint8_t hash_data[LIBSPDM_MAX_HASH_SIZE];
535 : size_t sig_size;
536 : size_t spdm_response_size;
537 : size_t transport_header_size;
538 : uint32_t session_id;
539 : libspdm_session_info_t *session_info;
540 : uint8_t *scratch_buffer;
541 : size_t scratch_buffer_size;
542 :
543 1 : session_id = 0xFFFFFFFF;
544 : ((libspdm_context_t *)spdm_context)
545 1 : ->connection_info.algorithm.base_asym_algo = m_libspdm_use_asym_algo;
546 : ((libspdm_context_t *)spdm_context)
547 1 : ->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
548 :
549 1 : spdm_response_size = sizeof(spdm_endpoint_info_response_t) +
550 : SPDM_NONCE_SIZE + sizeof(uint32_t) +
551 2 : endpoint_info_buffer_size +
552 1 : libspdm_get_asym_signature_size(m_libspdm_use_asym_algo);
553 :
554 1 : transport_header_size = LIBSPDM_TEST_TRANSPORT_HEADER_SIZE;
555 1 : spdm_response = (void *)((uint8_t *)*response + transport_header_size);
556 :
557 1 : spdm_response->header.spdm_version = SPDM_MESSAGE_VERSION_13;
558 1 : spdm_response->header.request_response_code = SPDM_ENDPOINT_INFO;
559 1 : spdm_response->header.param1 = 0;
560 1 : spdm_response->header.param2 = 0; /* slot_id */
561 1 : ptr = (uint8_t *)(spdm_response + 1);
562 :
563 1 : libspdm_get_random_number(SPDM_NONCE_SIZE, ptr);
564 1 : ptr += SPDM_NONCE_SIZE;
565 :
566 1 : *(uint32_t *)ptr = endpoint_info_buffer_size; /* ep_info_len */
567 1 : ptr += sizeof(uint32_t);
568 :
569 1 : libspdm_copy_mem(ptr, endpoint_info_buffer_size,
570 : m_endpoint_info_buffer, endpoint_info_buffer_size);
571 1 : ptr += endpoint_info_buffer_size;
572 :
573 1 : libspdm_copy_mem(&m_libspdm_local_buffer[m_libspdm_local_buffer_size],
574 : sizeof(m_libspdm_local_buffer) -
575 1 : (&m_libspdm_local_buffer[m_libspdm_local_buffer_size] -
576 : m_libspdm_local_buffer),
577 1 : spdm_response, (size_t)ptr - (size_t)spdm_response);
578 1 : m_libspdm_local_buffer_size += ((size_t)ptr - (size_t)spdm_response);
579 1 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "m_libspdm_local_buffer_size (0x%zx):\n",
580 : m_libspdm_local_buffer_size));
581 1 : libspdm_dump_hex(m_libspdm_local_buffer, m_libspdm_local_buffer_size);
582 1 : libspdm_hash_all(m_libspdm_use_hash_algo, m_libspdm_local_buffer,
583 : m_libspdm_local_buffer_size, hash_data);
584 1 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_INFO, "HashDataSize (0x%x):\n",
585 : libspdm_get_hash_size(m_libspdm_use_hash_algo)));
586 1 : libspdm_dump_hex(hash_data, libspdm_get_hash_size(m_libspdm_use_hash_algo));
587 1 : sig_size = libspdm_get_asym_signature_size(m_libspdm_use_asym_algo);
588 1 : libspdm_responder_data_sign(
589 : spdm_context,
590 1 : spdm_response->header.spdm_version << SPDM_VERSION_NUMBER_SHIFT_BIT,
591 : 0, SPDM_ENDPOINT_INFO,
592 : m_libspdm_use_asym_algo, m_libspdm_use_pqc_asym_algo, m_libspdm_use_hash_algo,
593 : false, m_libspdm_local_buffer, m_libspdm_local_buffer_size,
594 : ptr, &sig_size);
595 1 : ptr += sig_size;
596 :
597 : /* For secure message, message is in sender buffer, we need copy it to scratch buffer.
598 : * transport_message is always in sender buffer. */
599 1 : libspdm_get_scratch_buffer (spdm_context, (void **)&scratch_buffer, &scratch_buffer_size);
600 1 : libspdm_copy_mem (scratch_buffer + transport_header_size,
601 : scratch_buffer_size - transport_header_size,
602 : spdm_response, spdm_response_size);
603 1 : spdm_response = (void *)(scratch_buffer + transport_header_size);
604 :
605 1 : libspdm_transport_test_encode_message(spdm_context, &session_id, false,
606 : false, spdm_response_size,
607 : spdm_response, response_size,
608 : response);
609 1 : session_info = libspdm_get_session_info_via_session_id( spdm_context, session_id);
610 1 : if (session_info == NULL) {
611 0 : return LIBSPDM_STATUS_RECEIVE_FAIL;
612 : }
613 : /* WALKAROUND: If just use single context to encode message and then decode message */
614 1 : ((libspdm_secured_message_context_t *)(session_info->secured_message_context))
615 1 : ->application_secret.response_data_sequence_number--;
616 : }
617 1 : return LIBSPDM_STATUS_SUCCESS;
618 0 : default:
619 0 : return LIBSPDM_STATUS_RECEIVE_FAIL;
620 : }
621 : }
622 :
623 : /**
624 : * Test 1: Successful response to get a endpoint info with signature
625 : * Expected Behavior: get a LIBSPDM_STATUS_SUCCESS return code, with an empty transcript.message_e
626 : **/
627 1 : static void req_get_endpoint_info_case1(void **state)
628 : {
629 : libspdm_return_t status;
630 : libspdm_test_context_t *spdm_test_context;
631 : libspdm_context_t *spdm_context;
632 : void *data;
633 : size_t data_size;
634 : void *hash;
635 : size_t hash_size;
636 : uint8_t sub_code;
637 : uint8_t request_attributes;
638 : uint8_t slot_id;
639 : uint32_t ep_info_length;
640 : uint8_t ep_info_record[LIBSPDM_MAX_ENDPOINT_INFO_LENGTH];
641 : uint8_t requester_nonce_in[SPDM_NONCE_SIZE];
642 : uint8_t requester_nonce[SPDM_NONCE_SIZE];
643 : uint8_t responder_nonce[SPDM_NONCE_SIZE];
644 :
645 1 : spdm_test_context = *state;
646 1 : spdm_context = spdm_test_context->spdm_context;
647 1 : spdm_test_context->case_id = 0x1;
648 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_13 <<
649 : SPDM_VERSION_NUMBER_SHIFT_BIT;
650 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
651 1 : spdm_context->connection_info.capability.flags = 0;
652 1 : spdm_context->connection_info.capability.flags |=
653 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_EP_INFO_CAP_SIG;
654 1 : if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
655 : m_libspdm_use_asym_algo, &data,
656 : &data_size, &hash, &hash_size)) {
657 0 : assert(false);
658 : }
659 1 : libspdm_reset_message_a(spdm_context);
660 1 : libspdm_reset_message_e(spdm_context, NULL);
661 :
662 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
663 1 : spdm_context->connection_info.algorithm.base_asym_algo = m_libspdm_use_asym_algo;
664 :
665 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
666 : spdm_context->connection_info.peer_used_cert_chain[0].buffer_size = data_size;
667 : libspdm_copy_mem(spdm_context->connection_info.peer_used_cert_chain[0].buffer,
668 : sizeof(spdm_context->connection_info.peer_used_cert_chain[0].buffer),
669 : data, data_size);
670 : #else
671 1 : libspdm_hash_all(
672 : spdm_context->connection_info.algorithm.base_hash_algo,
673 : data, data_size,
674 1 : spdm_context->connection_info.peer_used_cert_chain[0].buffer_hash);
675 1 : spdm_context->connection_info.peer_used_cert_chain[0].buffer_hash_size =
676 1 : libspdm_get_hash_size(spdm_context->connection_info.algorithm.base_hash_algo);
677 1 : libspdm_get_leaf_cert_public_key_from_cert_chain(
678 : spdm_context->connection_info.algorithm.base_hash_algo,
679 : spdm_context->connection_info.algorithm.base_asym_algo,
680 : data, data_size,
681 : &spdm_context->connection_info.peer_used_cert_chain[0].leaf_cert_public_key);
682 : #endif
683 :
684 1 : slot_id = 0;
685 1 : sub_code = SPDM_GET_ENDPOINT_INFO_REQUEST_SUBCODE_DEVICE_CLASS_IDENTIFIER;
686 1 : request_attributes = SPDM_GET_ENDPOINT_INFO_REQUEST_ATTRIBUTE_SIGNATURE_REQUESTED;
687 1 : ep_info_length = LIBSPDM_MAX_ENDPOINT_INFO_LENGTH;
688 :
689 1 : libspdm_get_random_number(SPDM_NONCE_SIZE, requester_nonce_in);
690 33 : for (int index = 0; index < SPDM_NONCE_SIZE; index++) {
691 32 : requester_nonce[index] = 0x00;
692 32 : responder_nonce[index] = 0x00;
693 : }
694 :
695 1 : status = libspdm_get_endpoint_info(spdm_context, NULL, request_attributes,
696 : sub_code, slot_id,
697 : &ep_info_length, ep_info_record,
698 : requester_nonce_in, requester_nonce,
699 : responder_nonce);
700 :
701 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
702 33 : for (int index = 0; index < SPDM_NONCE_SIZE; index++) {
703 32 : assert_int_equal (requester_nonce_in[index], requester_nonce[index]);
704 : }
705 : /* Completion of GET_ENDPOINT_INFO sets IL1/IL2 to null. */
706 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
707 : assert_int_equal(spdm_context->transcript.message_e.buffer_size, 0);
708 : #else
709 1 : assert_null(spdm_context->transcript.digest_context_il1il2);
710 : #endif
711 1 : free(data);
712 1 : }
713 :
714 : /**
715 : * Test 2: Successful response to get a endpoint info with signature,
716 : * after getting SPDM_ERROR_CODE_BUSY on first attempt
717 : * Expected Behavior: get a LIBSPDM_STATUS_SUCCESS return code, with an empty transcript.message_e
718 : **/
719 1 : static void req_get_endpoint_info_case2(void **state)
720 : {
721 : libspdm_return_t status;
722 : libspdm_test_context_t *spdm_test_context;
723 : libspdm_context_t *spdm_context;
724 : void *data;
725 : size_t data_size;
726 : void *hash;
727 : size_t hash_size;
728 : uint8_t sub_code;
729 : uint8_t request_attributes;
730 : uint8_t slot_id;
731 : uint32_t ep_info_length;
732 : uint8_t ep_info_record[LIBSPDM_MAX_ENDPOINT_INFO_LENGTH];
733 : uint8_t requester_nonce_in[SPDM_NONCE_SIZE];
734 : uint8_t requester_nonce[SPDM_NONCE_SIZE];
735 : uint8_t responder_nonce[SPDM_NONCE_SIZE];
736 :
737 1 : spdm_test_context = *state;
738 1 : spdm_context = spdm_test_context->spdm_context;
739 1 : spdm_test_context->case_id = 0x2;
740 1 : spdm_context->retry_times = 3;
741 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_13 <<
742 : SPDM_VERSION_NUMBER_SHIFT_BIT;
743 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
744 1 : spdm_context->connection_info.capability.flags = 0;
745 1 : spdm_context->connection_info.capability.flags |=
746 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_EP_INFO_CAP_SIG;
747 1 : if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
748 : m_libspdm_use_asym_algo, &data,
749 : &data_size, &hash, &hash_size)) {
750 0 : assert(false);
751 : }
752 1 : libspdm_reset_message_a(spdm_context);
753 1 : libspdm_reset_message_e(spdm_context, NULL);
754 :
755 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
756 1 : spdm_context->connection_info.algorithm.base_asym_algo = m_libspdm_use_asym_algo;
757 :
758 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
759 : spdm_context->connection_info.peer_used_cert_chain[0].buffer_size = data_size;
760 : libspdm_copy_mem(spdm_context->connection_info.peer_used_cert_chain[0].buffer,
761 : sizeof(spdm_context->connection_info.peer_used_cert_chain[0].buffer),
762 : data, data_size);
763 : #else
764 1 : libspdm_hash_all(
765 : spdm_context->connection_info.algorithm.base_hash_algo,
766 : data, data_size,
767 1 : spdm_context->connection_info.peer_used_cert_chain[0].buffer_hash);
768 1 : spdm_context->connection_info.peer_used_cert_chain[0].buffer_hash_size =
769 1 : libspdm_get_hash_size(spdm_context->connection_info.algorithm.base_hash_algo);
770 1 : libspdm_get_leaf_cert_public_key_from_cert_chain(
771 : spdm_context->connection_info.algorithm.base_hash_algo,
772 : spdm_context->connection_info.algorithm.base_asym_algo,
773 : data, data_size,
774 : &spdm_context->connection_info.peer_used_cert_chain[0].leaf_cert_public_key);
775 : #endif
776 :
777 1 : slot_id = 0;
778 1 : sub_code = SPDM_GET_ENDPOINT_INFO_REQUEST_SUBCODE_DEVICE_CLASS_IDENTIFIER;
779 1 : request_attributes = SPDM_GET_ENDPOINT_INFO_REQUEST_ATTRIBUTE_SIGNATURE_REQUESTED;
780 1 : ep_info_length = LIBSPDM_MAX_ENDPOINT_INFO_LENGTH;
781 :
782 1 : libspdm_get_random_number(SPDM_NONCE_SIZE, requester_nonce_in);
783 33 : for (int index = 0; index < SPDM_NONCE_SIZE; index++) {
784 32 : requester_nonce[index] = 0x00;
785 32 : responder_nonce[index] = 0x00;
786 : }
787 :
788 1 : status = libspdm_get_endpoint_info(spdm_context, NULL, request_attributes,
789 : sub_code, slot_id,
790 : &ep_info_length, ep_info_record,
791 : requester_nonce_in, requester_nonce,
792 : responder_nonce);
793 :
794 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
795 33 : for (int index = 0; index < SPDM_NONCE_SIZE; index++) {
796 32 : assert_int_equal (requester_nonce_in[index], requester_nonce[index]);
797 : }
798 : /* Completion of GET_ENDPOINT_INFO sets IL1/IL2 to null. */
799 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
800 : assert_int_equal(spdm_context->transcript.message_e.buffer_size, 0);
801 : #else
802 1 : assert_null(spdm_context->transcript.digest_context_il1il2);
803 : #endif
804 1 : free(data);
805 1 : }
806 :
807 : /**
808 : * Test 3: Successful response to get a endpoint info with signature,
809 : * after getting SPDM_ERROR_CODE_RESPONSE_NOT_READY on first attempt
810 : * Expected Behavior: get a LIBSPDM_STATUS_SUCCESS return code, with an empty transcript.message_e
811 : **/
812 1 : static void req_get_endpoint_info_case3(void **state)
813 : {
814 : libspdm_return_t status;
815 : libspdm_test_context_t *spdm_test_context;
816 : libspdm_context_t *spdm_context;
817 : void *data;
818 : size_t data_size;
819 : void *hash;
820 : size_t hash_size;
821 : uint8_t sub_code;
822 : uint8_t request_attributes;
823 : uint8_t slot_id;
824 : uint32_t ep_info_length;
825 : uint8_t ep_info_record[LIBSPDM_MAX_ENDPOINT_INFO_LENGTH];
826 : uint8_t requester_nonce_in[SPDM_NONCE_SIZE];
827 : uint8_t requester_nonce[SPDM_NONCE_SIZE];
828 : uint8_t responder_nonce[SPDM_NONCE_SIZE];
829 :
830 1 : spdm_test_context = *state;
831 1 : spdm_context = spdm_test_context->spdm_context;
832 1 : spdm_test_context->case_id = 0x3;
833 1 : spdm_context->retry_times = 3;
834 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_13 <<
835 : SPDM_VERSION_NUMBER_SHIFT_BIT;
836 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
837 1 : spdm_context->connection_info.capability.flags = 0;
838 1 : spdm_context->connection_info.capability.flags |=
839 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_EP_INFO_CAP_SIG;
840 1 : if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
841 : m_libspdm_use_asym_algo, &data,
842 : &data_size, &hash, &hash_size)) {
843 0 : assert(false);
844 : }
845 1 : libspdm_reset_message_a(spdm_context);
846 1 : libspdm_reset_message_e(spdm_context, NULL);
847 :
848 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
849 1 : spdm_context->connection_info.algorithm.base_asym_algo = m_libspdm_use_asym_algo;
850 :
851 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
852 : spdm_context->connection_info.peer_used_cert_chain[0].buffer_size = data_size;
853 : libspdm_copy_mem(spdm_context->connection_info.peer_used_cert_chain[0].buffer,
854 : sizeof(spdm_context->connection_info.peer_used_cert_chain[0].buffer),
855 : data, data_size);
856 : #else
857 1 : libspdm_hash_all(
858 : spdm_context->connection_info.algorithm.base_hash_algo,
859 : data, data_size,
860 1 : spdm_context->connection_info.peer_used_cert_chain[0].buffer_hash);
861 1 : spdm_context->connection_info.peer_used_cert_chain[0].buffer_hash_size =
862 1 : libspdm_get_hash_size(spdm_context->connection_info.algorithm.base_hash_algo);
863 1 : libspdm_get_leaf_cert_public_key_from_cert_chain(
864 : spdm_context->connection_info.algorithm.base_hash_algo,
865 : spdm_context->connection_info.algorithm.base_asym_algo,
866 : data, data_size,
867 : &spdm_context->connection_info.peer_used_cert_chain[0].leaf_cert_public_key);
868 : #endif
869 :
870 1 : slot_id = 0;
871 1 : sub_code = SPDM_GET_ENDPOINT_INFO_REQUEST_SUBCODE_DEVICE_CLASS_IDENTIFIER;
872 1 : request_attributes = SPDM_GET_ENDPOINT_INFO_REQUEST_ATTRIBUTE_SIGNATURE_REQUESTED;
873 1 : ep_info_length = LIBSPDM_MAX_ENDPOINT_INFO_LENGTH;
874 :
875 1 : libspdm_get_random_number(SPDM_NONCE_SIZE, requester_nonce_in);
876 33 : for (int index = 0; index < SPDM_NONCE_SIZE; index++) {
877 32 : requester_nonce[index] = 0x00;
878 32 : responder_nonce[index] = 0x00;
879 : }
880 :
881 1 : status = libspdm_get_endpoint_info(spdm_context, NULL, request_attributes,
882 : sub_code, slot_id,
883 : &ep_info_length, ep_info_record,
884 : requester_nonce_in, requester_nonce,
885 : responder_nonce);
886 :
887 : if (LIBSPDM_RESPOND_IF_READY_SUPPORT) {
888 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
889 33 : for (int index = 0; index < SPDM_NONCE_SIZE; index++) {
890 32 : assert_int_equal (requester_nonce_in[index], requester_nonce[index]);
891 : }
892 : /* Completion of GET_ENDPOINT_INFO sets IL1/IL2 to null. */
893 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
894 : assert_int_equal(spdm_context->transcript.message_e.buffer_size, 0);
895 : #else
896 1 : assert_null(spdm_context->transcript.digest_context_il1il2);
897 : #endif
898 : } else {
899 : assert_int_equal(status, LIBSPDM_STATUS_NOT_READY_PEER);
900 : }
901 1 : free(data);
902 1 : }
903 :
904 : /**
905 : * Test 4: Successful response to get a endpoint info with signature with slot_id = 1
906 : * Expected Behavior: get a LIBSPDM_STATUS_SUCCESS return code, with an empty transcript.message_e
907 : **/
908 1 : static void req_get_endpoint_info_case4(void **state)
909 : {
910 : libspdm_return_t status;
911 : libspdm_test_context_t *spdm_test_context;
912 : libspdm_context_t *spdm_context;
913 : void *data;
914 : size_t data_size;
915 : void *hash;
916 : size_t hash_size;
917 : uint8_t sub_code;
918 : uint8_t request_attributes;
919 : uint8_t slot_id;
920 : uint32_t ep_info_length;
921 : uint8_t ep_info_record[LIBSPDM_MAX_ENDPOINT_INFO_LENGTH];
922 : uint8_t requester_nonce_in[SPDM_NONCE_SIZE];
923 : uint8_t requester_nonce[SPDM_NONCE_SIZE];
924 : uint8_t responder_nonce[SPDM_NONCE_SIZE];
925 :
926 1 : spdm_test_context = *state;
927 1 : spdm_context = spdm_test_context->spdm_context;
928 1 : spdm_test_context->case_id = 0x4;
929 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_13 <<
930 : SPDM_VERSION_NUMBER_SHIFT_BIT;
931 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
932 1 : spdm_context->connection_info.capability.flags = 0;
933 1 : spdm_context->connection_info.capability.flags |=
934 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_EP_INFO_CAP_SIG;
935 1 : spdm_context->connection_info.capability.flags |=
936 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MULTI_KEY_CAP;
937 1 : libspdm_read_responder_public_certificate_chain_per_slot(1, m_libspdm_use_hash_algo,
938 : m_libspdm_use_asym_algo, &data,
939 : &data_size, &hash, &hash_size);
940 1 : libspdm_reset_message_a(spdm_context);
941 1 : libspdm_reset_message_e(spdm_context, NULL);
942 :
943 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
944 1 : spdm_context->connection_info.algorithm.base_asym_algo = m_libspdm_use_asym_algo;
945 :
946 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
947 : spdm_context->connection_info.peer_used_cert_chain[1].buffer_size = data_size;
948 : libspdm_copy_mem(spdm_context->connection_info.peer_used_cert_chain[1].buffer,
949 : sizeof(spdm_context->connection_info.peer_used_cert_chain[1].buffer),
950 : data, data_size);
951 : #else
952 1 : libspdm_hash_all(
953 : spdm_context->connection_info.algorithm.base_hash_algo,
954 : data, data_size,
955 1 : spdm_context->connection_info.peer_used_cert_chain[1].buffer_hash);
956 1 : spdm_context->connection_info.peer_used_cert_chain[1].buffer_hash_size =
957 1 : libspdm_get_hash_size(spdm_context->connection_info.algorithm.base_hash_algo);
958 1 : libspdm_get_leaf_cert_public_key_from_cert_chain(
959 : spdm_context->connection_info.algorithm.base_hash_algo,
960 : spdm_context->connection_info.algorithm.base_asym_algo,
961 : data, data_size,
962 : &spdm_context->connection_info.peer_used_cert_chain[1].leaf_cert_public_key);
963 : #endif
964 :
965 1 : slot_id = 1;
966 1 : sub_code = SPDM_GET_ENDPOINT_INFO_REQUEST_SUBCODE_DEVICE_CLASS_IDENTIFIER;
967 1 : request_attributes = SPDM_GET_ENDPOINT_INFO_REQUEST_ATTRIBUTE_SIGNATURE_REQUESTED;
968 1 : ep_info_length = LIBSPDM_MAX_ENDPOINT_INFO_LENGTH;
969 :
970 1 : libspdm_get_random_number(SPDM_NONCE_SIZE, requester_nonce_in);
971 33 : for (int index = 0; index < SPDM_NONCE_SIZE; index++) {
972 32 : requester_nonce[index] = 0x00;
973 32 : responder_nonce[index] = 0x00;
974 : }
975 :
976 1 : status = libspdm_get_endpoint_info(spdm_context, NULL, request_attributes,
977 : sub_code, slot_id,
978 : &ep_info_length, ep_info_record,
979 : requester_nonce_in, requester_nonce,
980 : responder_nonce);
981 :
982 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
983 33 : for (int index = 0; index < SPDM_NONCE_SIZE; index++) {
984 32 : assert_int_equal (requester_nonce_in[index], requester_nonce[index]);
985 : }
986 : /* Completion of GET_ENDPOINT_INFO sets IL1/IL2 to null. */
987 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
988 : assert_int_equal(spdm_context->transcript.message_e.buffer_size, 0);
989 : #else
990 1 : assert_null(spdm_context->transcript.digest_context_il1il2);
991 : #endif
992 1 : free(data);
993 1 : }
994 :
995 : /**
996 : * Test 5: Successful response to get a endpoint info with signature
997 : * Using provisioned public key (slot_id = 0xF)
998 : * Expected Behavior: get a LIBSPDM_STATUS_SUCCESS return code, with an empty transcript.message_e
999 : **/
1000 1 : static void req_get_endpoint_info_case5(void **state)
1001 : {
1002 : libspdm_return_t status;
1003 : libspdm_test_context_t *spdm_test_context;
1004 : libspdm_context_t *spdm_context;
1005 : void *data;
1006 : size_t data_size;
1007 : uint8_t sub_code;
1008 : uint8_t request_attributes;
1009 : uint8_t slot_id;
1010 : uint32_t ep_info_length;
1011 : uint8_t ep_info_record[LIBSPDM_MAX_ENDPOINT_INFO_LENGTH];
1012 : uint8_t requester_nonce_in[SPDM_NONCE_SIZE];
1013 : uint8_t requester_nonce[SPDM_NONCE_SIZE];
1014 : uint8_t responder_nonce[SPDM_NONCE_SIZE];
1015 :
1016 1 : spdm_test_context = *state;
1017 1 : spdm_context = spdm_test_context->spdm_context;
1018 1 : spdm_test_context->case_id = 0x5;
1019 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_13 <<
1020 : SPDM_VERSION_NUMBER_SHIFT_BIT;
1021 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
1022 1 : spdm_context->connection_info.capability.flags = 0;
1023 1 : spdm_context->connection_info.capability.flags |=
1024 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_EP_INFO_CAP_SIG;
1025 1 : spdm_context->connection_info.capability.flags |=
1026 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_PUB_KEY_ID_CAP;
1027 1 : libspdm_read_responder_public_key(m_libspdm_use_asym_algo, &data, &data_size);
1028 1 : spdm_context->local_context.peer_public_key_provision = data;
1029 1 : spdm_context->local_context.peer_public_key_provision_size = data_size;
1030 :
1031 1 : libspdm_reset_message_a(spdm_context);
1032 1 : libspdm_reset_message_e(spdm_context, NULL);
1033 :
1034 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
1035 1 : spdm_context->connection_info.algorithm.base_asym_algo = m_libspdm_use_asym_algo;
1036 :
1037 1 : slot_id = 0xF;
1038 1 : sub_code = SPDM_GET_ENDPOINT_INFO_REQUEST_SUBCODE_DEVICE_CLASS_IDENTIFIER;
1039 1 : request_attributes = SPDM_GET_ENDPOINT_INFO_REQUEST_ATTRIBUTE_SIGNATURE_REQUESTED;
1040 1 : ep_info_length = LIBSPDM_MAX_ENDPOINT_INFO_LENGTH;
1041 :
1042 1 : libspdm_get_random_number(SPDM_NONCE_SIZE, requester_nonce_in);
1043 33 : for (int index = 0; index < SPDM_NONCE_SIZE; index++) {
1044 32 : requester_nonce[index] = 0x00;
1045 32 : responder_nonce[index] = 0x00;
1046 : }
1047 :
1048 1 : status = libspdm_get_endpoint_info(spdm_context, NULL, request_attributes,
1049 : sub_code, slot_id,
1050 : &ep_info_length, ep_info_record,
1051 : requester_nonce_in, requester_nonce,
1052 : responder_nonce);
1053 :
1054 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
1055 33 : for (int index = 0; index < SPDM_NONCE_SIZE; index++) {
1056 32 : assert_int_equal (requester_nonce_in[index], requester_nonce[index]);
1057 : }
1058 : /* Completion of GET_ENDPOINT_INFO sets IL1/IL2 to null. */
1059 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
1060 : assert_int_equal(spdm_context->transcript.message_e.buffer_size, 0);
1061 : #else
1062 1 : assert_null(spdm_context->transcript.digest_context_il1il2);
1063 : #endif
1064 1 : free(data);
1065 1 : }
1066 :
1067 : /**
1068 : * Test 6: Successful response to get a endpoint info without signature
1069 : * Expected Behavior: get a LIBSPDM_STATUS_SUCCESS return code
1070 : **/
1071 1 : static void req_get_endpoint_info_case6(void **state)
1072 : {
1073 : libspdm_return_t status;
1074 : libspdm_test_context_t *spdm_test_context;
1075 : libspdm_context_t *spdm_context;
1076 : uint8_t sub_code;
1077 : uint8_t request_attributes;
1078 : uint8_t slot_id;
1079 : uint32_t ep_info_length;
1080 : uint8_t ep_info_record[LIBSPDM_MAX_ENDPOINT_INFO_LENGTH];
1081 :
1082 1 : spdm_test_context = *state;
1083 1 : spdm_context = spdm_test_context->spdm_context;
1084 1 : spdm_test_context->case_id = 0x6;
1085 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_13 <<
1086 : SPDM_VERSION_NUMBER_SHIFT_BIT;
1087 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_NEGOTIATED;
1088 1 : spdm_context->connection_info.capability.flags = 0;
1089 1 : spdm_context->connection_info.capability.flags |=
1090 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_EP_INFO_CAP_NO_SIG;
1091 :
1092 1 : slot_id = 0;
1093 1 : sub_code = SPDM_GET_ENDPOINT_INFO_REQUEST_SUBCODE_DEVICE_CLASS_IDENTIFIER;
1094 1 : request_attributes = 0;
1095 1 : ep_info_length = LIBSPDM_MAX_ENDPOINT_INFO_LENGTH;
1096 :
1097 1 : status = libspdm_get_endpoint_info(spdm_context, NULL, request_attributes,
1098 : sub_code, slot_id,
1099 : &ep_info_length, ep_info_record,
1100 : NULL, NULL, NULL);
1101 :
1102 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
1103 1 : }
1104 :
1105 : /**
1106 : * Test 7: Successful response to get a session based endpoint info with signature
1107 : * Expected Behavior: get a LIBSPDM_STATUS_SUCCESS return code, with an empty session_transcript.message_e
1108 : **/
1109 1 : static void req_get_endpoint_info_case7(void **state)
1110 : {
1111 : libspdm_return_t status;
1112 : libspdm_test_context_t *spdm_test_context;
1113 : libspdm_context_t *spdm_context;
1114 : uint32_t session_id;
1115 : libspdm_session_info_t *session_info;
1116 : void *data;
1117 : size_t data_size;
1118 : void *hash;
1119 : size_t hash_size;
1120 : uint8_t sub_code;
1121 : uint8_t request_attributes;
1122 : uint8_t slot_id;
1123 : uint32_t ep_info_length;
1124 : uint8_t ep_info_record[LIBSPDM_MAX_ENDPOINT_INFO_LENGTH];
1125 : uint8_t requester_nonce_in[SPDM_NONCE_SIZE];
1126 : uint8_t requester_nonce[SPDM_NONCE_SIZE];
1127 : uint8_t responder_nonce[SPDM_NONCE_SIZE];
1128 :
1129 1 : spdm_test_context = *state;
1130 1 : spdm_context = spdm_test_context->spdm_context;
1131 1 : spdm_test_context->case_id = 0x7;
1132 1 : spdm_context->connection_info.version = SPDM_MESSAGE_VERSION_13 <<
1133 : SPDM_VERSION_NUMBER_SHIFT_BIT;
1134 1 : spdm_context->connection_info.connection_state = LIBSPDM_CONNECTION_STATE_AUTHENTICATED;
1135 1 : spdm_context->connection_info.capability.flags = 0;
1136 1 : spdm_context->connection_info.capability.flags |=
1137 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_EP_INFO_CAP_SIG;
1138 1 : if (!libspdm_read_responder_public_certificate_chain(m_libspdm_use_hash_algo,
1139 : m_libspdm_use_asym_algo, &data,
1140 : &data_size, &hash, &hash_size)) {
1141 0 : assert(false);
1142 : }
1143 :
1144 1 : spdm_context->connection_info.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_PSK_CAP;
1145 1 : spdm_context->connection_info.capability.flags |=
1146 : SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_ENCRYPT_CAP;
1147 1 : spdm_context->connection_info.capability.flags |= SPDM_GET_CAPABILITIES_RESPONSE_FLAGS_MAC_CAP;
1148 1 : spdm_context->local_context.capability.flags = 0;
1149 1 : spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_PSK_CAP;
1150 1 : spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_ENCRYPT_CAP;
1151 1 : spdm_context->local_context.capability.flags |= SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MAC_CAP;
1152 1 : spdm_context->connection_info.algorithm.dhe_named_group = m_libspdm_use_dhe_algo;
1153 1 : spdm_context->connection_info.algorithm.aead_cipher_suite = m_libspdm_use_aead_algo;
1154 :
1155 1 : session_id = 0xFFFFFFFF;
1156 1 : session_info = &spdm_context->session_info[0];
1157 1 : libspdm_session_info_init(spdm_context, session_info, session_id,
1158 : SECURED_SPDM_VERSION_11 << SPDM_VERSION_NUMBER_SHIFT_BIT, true);
1159 1 : libspdm_secured_message_set_session_state(
1160 : session_info->secured_message_context,
1161 : LIBSPDM_SESSION_STATE_ESTABLISHED);
1162 :
1163 1 : libspdm_reset_message_a(spdm_context);
1164 1 : libspdm_reset_message_e(spdm_context, session_info);
1165 :
1166 1 : spdm_context->connection_info.algorithm.base_hash_algo = m_libspdm_use_hash_algo;
1167 1 : spdm_context->connection_info.algorithm.base_asym_algo = m_libspdm_use_asym_algo;
1168 :
1169 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
1170 : spdm_context->connection_info.peer_used_cert_chain[0].buffer_size = data_size;
1171 : libspdm_copy_mem(spdm_context->connection_info.peer_used_cert_chain[0].buffer,
1172 : sizeof(spdm_context->connection_info.peer_used_cert_chain[0].buffer),
1173 : data, data_size);
1174 : #else
1175 1 : libspdm_hash_all(
1176 : spdm_context->connection_info.algorithm.base_hash_algo,
1177 : data, data_size,
1178 1 : spdm_context->connection_info.peer_used_cert_chain[0].buffer_hash);
1179 1 : spdm_context->connection_info.peer_used_cert_chain[0].buffer_hash_size =
1180 1 : libspdm_get_hash_size(spdm_context->connection_info.algorithm.base_hash_algo);
1181 1 : libspdm_get_leaf_cert_public_key_from_cert_chain(
1182 : spdm_context->connection_info.algorithm.base_hash_algo,
1183 : spdm_context->connection_info.algorithm.base_asym_algo,
1184 : data, data_size,
1185 : &spdm_context->connection_info.peer_used_cert_chain[0].leaf_cert_public_key);
1186 : #endif
1187 :
1188 1 : slot_id = 0;
1189 1 : sub_code = SPDM_GET_ENDPOINT_INFO_REQUEST_SUBCODE_DEVICE_CLASS_IDENTIFIER;
1190 1 : request_attributes = SPDM_GET_ENDPOINT_INFO_REQUEST_ATTRIBUTE_SIGNATURE_REQUESTED;
1191 1 : ep_info_length = LIBSPDM_MAX_ENDPOINT_INFO_LENGTH;
1192 :
1193 1 : libspdm_get_random_number(SPDM_NONCE_SIZE, requester_nonce_in);
1194 33 : for (int index = 0; index < SPDM_NONCE_SIZE; index++) {
1195 32 : requester_nonce[index] = 0x00;
1196 32 : responder_nonce[index] = 0x00;
1197 : }
1198 :
1199 1 : status = libspdm_get_endpoint_info(spdm_context, &session_id, request_attributes,
1200 : sub_code, slot_id,
1201 : &ep_info_length, ep_info_record,
1202 : requester_nonce_in, requester_nonce,
1203 : responder_nonce);
1204 :
1205 1 : assert_int_equal(status, LIBSPDM_STATUS_SUCCESS);
1206 33 : for (int index = 0; index < SPDM_NONCE_SIZE; index++) {
1207 32 : assert_int_equal (requester_nonce_in[index], requester_nonce[index]);
1208 : }
1209 : /* Completion of GET_ENDPOINT_INFO sets IL1/IL2 to null. */
1210 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
1211 : assert_int_equal(session_info->session_transcript.message_e.buffer_size, 0);
1212 : #else
1213 1 : assert_null(session_info->session_transcript.digest_context_il1il2);
1214 : #endif
1215 1 : free(data);
1216 1 : }
1217 :
1218 1 : int libspdm_req_get_endpoint_info_test(void)
1219 : {
1220 1 : const struct CMUnitTest test_cases[] = {
1221 : cmocka_unit_test(req_get_endpoint_info_case1),
1222 : cmocka_unit_test(req_get_endpoint_info_case2),
1223 : cmocka_unit_test(req_get_endpoint_info_case3),
1224 : cmocka_unit_test(req_get_endpoint_info_case4),
1225 : cmocka_unit_test(req_get_endpoint_info_case5),
1226 : cmocka_unit_test(req_get_endpoint_info_case6),
1227 : cmocka_unit_test(req_get_endpoint_info_case7),
1228 : };
1229 :
1230 1 : libspdm_test_context_t test_context = {
1231 : LIBSPDM_TEST_CONTEXT_VERSION,
1232 : true,
1233 : send_message,
1234 : receive_message,
1235 : };
1236 :
1237 1 : libspdm_setup_test_context(&test_context);
1238 :
1239 1 : return cmocka_run_group_tests(test_cases,
1240 : libspdm_unit_test_group_setup,
1241 : libspdm_unit_test_group_teardown);
1242 : }
1243 :
1244 : #endif /* LIBSPDM_SEND_GET_ENDPOINT_INFO_SUPPORT */
|