Line data Source code
1 : /**
2 : * Copyright Notice:
3 : * Copyright 2024-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 <stdarg.h>
8 : #include <stddef.h>
9 : #include <setjmp.h>
10 : #include <stdint.h>
11 : #include <stdlib.h>
12 : #include <stdio.h>
13 : #include <assert.h>
14 : #include <string.h>
15 :
16 : #include <base.h>
17 : #include "library/memlib.h"
18 : #include "spdm_device_secret_lib_internal.h"
19 : #include "internal/libspdm_common_lib.h"
20 :
21 : #define LIBSPDM_CXL_TSP_2ND_SESSION_0_PSK_DATA_STRING "CxlTsp_2ndSess0_Psk"
22 : #define LIBSPDM_CXL_TSP_2ND_SESSION_1_PSK_DATA_STRING "CxlTsp_2ndSess1_Psk"
23 : #define LIBSPDM_CXL_TSP_2ND_SESSION_2_PSK_DATA_STRING "CxlTsp_2ndSess2_Psk"
24 : #define LIBSPDM_CXL_TSP_2ND_SESSION_3_PSK_DATA_STRING "CxlTsp_2ndSess3_Psk"
25 :
26 : #if LIBSPDM_ENABLE_CAPABILITY_PSK_CAP
27 :
28 : uint8_t m_libspdm_my_zero_filled_buffer[LIBSPDM_MAX_HASH_SIZE];
29 : uint8_t m_libspdm_my_salt0[LIBSPDM_MAX_HASH_SIZE];
30 : uint8_t m_libspdm_bin_str0[0x11] = {
31 : 0x00, 0x00, /* length - to be filled*/
32 : /* SPDM_VERSION_1_1_BIN_CONCAT_LABEL */
33 : 0x73, 0x70, 0x64, 0x6d, 0x31, 0x2e, 0x31, 0x20,
34 : /* SPDM_BIN_STR_0_LABEL */
35 : 0x64, 0x65, 0x72, 0x69, 0x76, 0x65, 0x64,
36 : };
37 :
38 : uint8_t m_cxl_tsp_2nd_session_psk[CXL_TSP_2ND_SESSION_COUNT][CXL_TSP_2ND_SESSION_KEY_SIZE] = {
39 : LIBSPDM_CXL_TSP_2ND_SESSION_0_PSK_DATA_STRING,
40 : LIBSPDM_CXL_TSP_2ND_SESSION_1_PSK_DATA_STRING,
41 : LIBSPDM_CXL_TSP_2ND_SESSION_2_PSK_DATA_STRING,
42 : LIBSPDM_CXL_TSP_2ND_SESSION_3_PSK_DATA_STRING,
43 : };
44 :
45 : uint8_t m_cxl_tsp_current_psk_session_index = 0xFF;
46 :
47 : bool g_generate_psk_exchange_opaque_data = false;
48 : size_t libspdm_secret_lib_psk_finish_opaque_data_size;
49 : bool g_generate_psk_finish_opaque_data = false;
50 :
51 76 : bool libspdm_psk_handshake_secret_hkdf_expand(
52 : spdm_version_number_t spdm_version,
53 : uint32_t base_hash_algo,
54 : const uint8_t *psk_hint,
55 : size_t psk_hint_size,
56 : const uint8_t *info,
57 : size_t info_size,
58 : uint8_t *out, size_t out_size)
59 : {
60 : void *psk;
61 : size_t psk_size;
62 : size_t hash_size;
63 : bool result;
64 : uint8_t handshake_secret[LIBSPDM_MAX_HASH_SIZE];
65 :
66 76 : if ((spdm_version >> SPDM_VERSION_NUMBER_SHIFT_BIT) >= SPDM_MESSAGE_VERSION_13) {
67 0 : libspdm_set_mem(m_libspdm_my_salt0, sizeof(m_libspdm_my_salt0), 0xff);
68 : }
69 :
70 76 : if (psk_hint_size == 0) {
71 4 : psk = LIBSPDM_TEST_PSK_DATA_STRING;
72 4 : psk_size = sizeof(LIBSPDM_TEST_PSK_DATA_STRING);
73 4 : m_cxl_tsp_current_psk_session_index = 0xFF;
74 72 : } else if ((strcmp((const char *)psk_hint, LIBSPDM_TEST_PSK_HINT_STRING) == 0) &&
75 : (psk_hint_size == sizeof(LIBSPDM_TEST_PSK_HINT_STRING))) {
76 72 : psk = LIBSPDM_TEST_PSK_DATA_STRING;
77 72 : psk_size = sizeof(LIBSPDM_TEST_PSK_DATA_STRING);
78 72 : m_cxl_tsp_current_psk_session_index = 0xFF;
79 0 : } else if ((strcmp((const char *)psk_hint, CXL_TSP_2ND_SESSION_0_PSK_HINT_STRING) == 0) &&
80 : (psk_hint_size == sizeof(CXL_TSP_2ND_SESSION_0_PSK_HINT_STRING))) {
81 0 : psk = m_cxl_tsp_2nd_session_psk[0];
82 0 : psk_size = sizeof(m_cxl_tsp_2nd_session_psk[0]);
83 0 : m_cxl_tsp_current_psk_session_index = 0;
84 0 : } else if ((strcmp((const char *)psk_hint, CXL_TSP_2ND_SESSION_1_PSK_HINT_STRING) == 0) &&
85 : (psk_hint_size == sizeof(CXL_TSP_2ND_SESSION_1_PSK_HINT_STRING))) {
86 0 : psk = m_cxl_tsp_2nd_session_psk[1];
87 0 : psk_size = sizeof(m_cxl_tsp_2nd_session_psk[1]);
88 0 : m_cxl_tsp_current_psk_session_index = 1;
89 0 : } else if ((strcmp((const char *)psk_hint, CXL_TSP_2ND_SESSION_2_PSK_HINT_STRING) == 0) &&
90 : (psk_hint_size == sizeof(CXL_TSP_2ND_SESSION_2_PSK_HINT_STRING))) {
91 0 : psk = m_cxl_tsp_2nd_session_psk[2];
92 0 : psk_size = sizeof(m_cxl_tsp_2nd_session_psk[2]);
93 0 : m_cxl_tsp_current_psk_session_index = 2;
94 0 : } else if ((strcmp((const char *)psk_hint, CXL_TSP_2ND_SESSION_3_PSK_HINT_STRING) == 0) &&
95 : (psk_hint_size == sizeof(CXL_TSP_2ND_SESSION_3_PSK_HINT_STRING))) {
96 0 : psk = m_cxl_tsp_2nd_session_psk[3];
97 0 : psk_size = sizeof(m_cxl_tsp_2nd_session_psk[3]);
98 0 : m_cxl_tsp_current_psk_session_index = 3;
99 : } else {
100 0 : return false;
101 : }
102 76 : printf("[PSK]: ");
103 76 : libspdm_dump_hex_str(psk, psk_size);
104 76 : printf("\n");
105 :
106 76 : hash_size = libspdm_get_hash_size(base_hash_algo);
107 :
108 76 : result = libspdm_hkdf_extract(base_hash_algo, psk, psk_size, m_libspdm_my_salt0,
109 : hash_size, handshake_secret, hash_size);
110 76 : if (!result) {
111 0 : return result;
112 : }
113 :
114 76 : result = libspdm_hkdf_expand(base_hash_algo, handshake_secret, hash_size,
115 : info, info_size, out, out_size);
116 76 : libspdm_zero_mem(handshake_secret, hash_size);
117 :
118 76 : return result;
119 : }
120 :
121 42 : bool libspdm_psk_master_secret_hkdf_expand(
122 : spdm_version_number_t spdm_version,
123 : uint32_t base_hash_algo,
124 : const uint8_t *psk_hint,
125 : size_t psk_hint_size,
126 : const uint8_t *info,
127 : size_t info_size, uint8_t *out,
128 : size_t out_size)
129 : {
130 : void *psk;
131 : size_t psk_size;
132 : size_t hash_size;
133 : bool result;
134 : uint8_t handshake_secret[LIBSPDM_MAX_HASH_SIZE];
135 : uint8_t salt1[LIBSPDM_MAX_HASH_SIZE];
136 : uint8_t master_secret[LIBSPDM_MAX_HASH_SIZE];
137 :
138 42 : if (psk_hint_size == 0) {
139 0 : psk = LIBSPDM_TEST_PSK_DATA_STRING;
140 0 : psk_size = sizeof(LIBSPDM_TEST_PSK_DATA_STRING);
141 0 : m_cxl_tsp_current_psk_session_index = 0xFF;
142 42 : } else if ((strcmp((const char *)psk_hint, LIBSPDM_TEST_PSK_HINT_STRING) == 0) &&
143 : (psk_hint_size == sizeof(LIBSPDM_TEST_PSK_HINT_STRING))) {
144 42 : psk = LIBSPDM_TEST_PSK_DATA_STRING;
145 42 : psk_size = sizeof(LIBSPDM_TEST_PSK_DATA_STRING);
146 42 : m_cxl_tsp_current_psk_session_index = 0xFF;
147 0 : } else if ((strcmp((const char *)psk_hint, CXL_TSP_2ND_SESSION_0_PSK_HINT_STRING) == 0) &&
148 : (psk_hint_size == sizeof(CXL_TSP_2ND_SESSION_0_PSK_HINT_STRING))) {
149 0 : psk = m_cxl_tsp_2nd_session_psk[0];
150 0 : psk_size = sizeof(m_cxl_tsp_2nd_session_psk[0]);
151 0 : m_cxl_tsp_current_psk_session_index = 0;
152 0 : } else if ((strcmp((const char *)psk_hint, CXL_TSP_2ND_SESSION_1_PSK_HINT_STRING) == 0) &&
153 : (psk_hint_size == sizeof(CXL_TSP_2ND_SESSION_1_PSK_HINT_STRING))) {
154 0 : psk = m_cxl_tsp_2nd_session_psk[1];
155 0 : psk_size = sizeof(m_cxl_tsp_2nd_session_psk[1]);
156 0 : m_cxl_tsp_current_psk_session_index = 1;
157 0 : } else if ((strcmp((const char *)psk_hint, CXL_TSP_2ND_SESSION_2_PSK_HINT_STRING) == 0) &&
158 : (psk_hint_size == sizeof(CXL_TSP_2ND_SESSION_2_PSK_HINT_STRING))) {
159 0 : psk = m_cxl_tsp_2nd_session_psk[2];
160 0 : psk_size = sizeof(m_cxl_tsp_2nd_session_psk[2]);
161 0 : m_cxl_tsp_current_psk_session_index = 2;
162 0 : } else if ((strcmp((const char *)psk_hint, CXL_TSP_2ND_SESSION_3_PSK_HINT_STRING) == 0) &&
163 : (psk_hint_size == sizeof(CXL_TSP_2ND_SESSION_3_PSK_HINT_STRING))) {
164 0 : psk = m_cxl_tsp_2nd_session_psk[3];
165 0 : psk_size = sizeof(m_cxl_tsp_2nd_session_psk[3]);
166 0 : m_cxl_tsp_current_psk_session_index = 3;
167 : } else {
168 0 : return false;
169 : }
170 :
171 42 : hash_size = libspdm_get_hash_size(base_hash_algo);
172 :
173 42 : result = libspdm_hkdf_extract(base_hash_algo, psk, psk_size, m_libspdm_my_salt0,
174 : hash_size, handshake_secret, hash_size);
175 42 : if (!result) {
176 0 : return result;
177 : }
178 :
179 42 : libspdm_write_uint16((uint8_t *)m_libspdm_bin_str0, (uint16_t)hash_size);
180 : /* patch the version*/
181 42 : m_libspdm_bin_str0[6] = (char)('0' + ((spdm_version >> 12) & 0xF));
182 42 : m_libspdm_bin_str0[8] = (char)('0' + ((spdm_version >> 8) & 0xF));
183 42 : result = libspdm_hkdf_expand(base_hash_algo, handshake_secret, hash_size,
184 : m_libspdm_bin_str0, sizeof(m_libspdm_bin_str0), salt1,
185 : hash_size);
186 42 : libspdm_zero_mem(handshake_secret, hash_size);
187 42 : if (!result) {
188 0 : return result;
189 : }
190 :
191 42 : result = libspdm_hkdf_extract(base_hash_algo, m_libspdm_my_zero_filled_buffer,
192 : hash_size, salt1, hash_size, master_secret, hash_size);
193 42 : libspdm_zero_mem(salt1, hash_size);
194 42 : if (!result) {
195 0 : return result;
196 : }
197 :
198 42 : result = libspdm_hkdf_expand(base_hash_algo, master_secret, hash_size,
199 : info, info_size, out, out_size);
200 42 : libspdm_zero_mem(master_secret, hash_size);
201 :
202 42 : return result;
203 : }
204 :
205 12 : bool libspdm_psk_exchange_rsp_opaque_data(
206 : void *spdm_context,
207 : const void *psk_hint,
208 : uint16_t psk_hint_size,
209 : spdm_version_number_t spdm_version,
210 : uint8_t measurement_hash_type,
211 : const void *req_opaque_data,
212 : size_t req_opaque_data_size,
213 : void *opaque_data,
214 : size_t *opaque_data_size)
215 : {
216 12 : if (g_generate_psk_exchange_opaque_data) {
217 : size_t version_selection_data_size;
218 3 : version_selection_data_size = sizeof(spdm_general_opaque_data_table_header_t) +
219 : sizeof(secured_message_opaque_element_table_header_t) +
220 : sizeof(secured_message_opaque_element_version_selection_t);
221 :
222 3 : LIBSPDM_ASSERT(*opaque_data_size >= version_selection_data_size);
223 3 : *opaque_data_size = version_selection_data_size;
224 :
225 3 : if (opaque_data != NULL) {
226 : spdm_general_opaque_data_table_header_t *spdm_general_opaque_data_table_header;
227 : secured_message_opaque_element_table_header_t *opaque_element_table_header;
228 : secured_message_opaque_element_version_selection_t *opaque_element_version_section;
229 :
230 2 : spdm_general_opaque_data_table_header = opaque_data;
231 2 : spdm_general_opaque_data_table_header->total_elements = 1;
232 2 : libspdm_write_uint24(spdm_general_opaque_data_table_header->reserved, 0);
233 :
234 2 : opaque_element_table_header = (void *)(spdm_general_opaque_data_table_header + 1);
235 2 : opaque_element_table_header->id = SPDM_REGISTRY_ID_DMTF;
236 2 : opaque_element_table_header->vendor_len = 0;
237 2 : opaque_element_table_header->opaque_element_data_len =
238 : sizeof(secured_message_opaque_element_version_selection_t);
239 2 : opaque_element_version_section = (void *)(opaque_element_table_header + 1);
240 2 : opaque_element_version_section->sm_data_version =
241 : SECURED_MESSAGE_OPAQUE_ELEMENT_SMDATA_DATA_VERSION;
242 2 : opaque_element_version_section->sm_data_id =
243 : SECURED_MESSAGE_OPAQUE_ELEMENT_SMDATA_ID_VERSION_SELECTION;
244 2 : opaque_element_version_section->selected_version =
245 : SECURED_SPDM_VERSION_11 << SPDM_VERSION_NUMBER_SHIFT_BIT;
246 : }
247 :
248 3 : return true;
249 : }
250 9 : return false;
251 : }
252 :
253 1 : bool libspdm_psk_finish_rsp_opaque_data(
254 : void *spdm_context,
255 : uint32_t session_id,
256 : spdm_version_number_t spdm_version,
257 : const void *req_opaque_data,
258 : size_t req_opaque_data_size,
259 : void *opaque_data,
260 : size_t *opaque_data_size)
261 : {
262 1 : if (g_generate_psk_finish_opaque_data) {
263 1 : LIBSPDM_ASSERT(libspdm_secret_lib_psk_finish_opaque_data_size <= *opaque_data_size);
264 :
265 1 : *opaque_data_size = libspdm_secret_lib_psk_finish_opaque_data_size;
266 :
267 1 : if (opaque_data != NULL) {
268 9 : for (size_t index = 0; index < *opaque_data_size; index++)
269 : {
270 8 : ((uint8_t *)opaque_data)[index] = (uint8_t)(index + 1);
271 : }
272 : }
273 : } else {
274 0 : *opaque_data_size = 0;
275 : }
276 :
277 1 : return true;
278 : }
279 :
280 : #endif /* LIBSPDM_ENABLE_CAPABILITY_PSK_CAP */
|