Line data Source code
1 : /**
2 : * Copyright Notice:
3 : * Copyright 2021-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 "internal/libspdm_secured_message_lib.h"
8 :
9 : /**
10 : * This function initializes the session info.
11 : *
12 : * @param spdm_context A pointer to the SPDM context.
13 : * @param session_id The SPDM session ID.
14 : **/
15 696 : void libspdm_session_info_init(libspdm_context_t *spdm_context,
16 : libspdm_session_info_t *session_info,
17 : uint32_t session_id, bool use_psk)
18 : {
19 : libspdm_session_type_t session_type;
20 : uint32_t capabilities_flag;
21 :
22 696 : if (session_id != INVALID_SESSION_ID) {
23 407 : if (use_psk) {
24 291 : LIBSPDM_ASSERT((spdm_context->max_psk_session_count == 0) ||
25 : (spdm_context->current_psk_session_count <
26 : spdm_context->max_psk_session_count));
27 291 : spdm_context->current_psk_session_count++;
28 : } else {
29 116 : LIBSPDM_ASSERT((spdm_context->max_dhe_session_count == 0) ||
30 : (spdm_context->current_dhe_session_count <
31 : spdm_context->max_dhe_session_count));
32 116 : spdm_context->current_dhe_session_count++;
33 : }
34 : } else {
35 289 : if (use_psk) {
36 56 : if (spdm_context->current_psk_session_count > 0) {
37 56 : spdm_context->current_psk_session_count--;
38 : }
39 : } else {
40 233 : if (spdm_context->current_dhe_session_count > 0) {
41 60 : spdm_context->current_dhe_session_count--;
42 : }
43 : }
44 : }
45 :
46 696 : capabilities_flag = spdm_context->connection_info.capability.flags &
47 696 : spdm_context->local_context.capability.flags;
48 696 : switch (capabilities_flag &
49 : (SPDM_GET_CAPABILITIES_REQUEST_FLAGS_ENCRYPT_CAP |
50 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MAC_CAP)) {
51 248 : case 0:
52 248 : session_type = LIBSPDM_SESSION_TYPE_NONE;
53 248 : break;
54 337 : case (SPDM_GET_CAPABILITIES_REQUEST_FLAGS_ENCRYPT_CAP |
55 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MAC_CAP):
56 337 : session_type = LIBSPDM_SESSION_TYPE_ENC_MAC;
57 337 : break;
58 111 : case SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MAC_CAP:
59 111 : session_type = LIBSPDM_SESSION_TYPE_MAC_ONLY;
60 111 : break;
61 0 : default:
62 0 : LIBSPDM_ASSERT(false);
63 0 : session_type = LIBSPDM_SESSION_TYPE_MAX;
64 0 : break;
65 : }
66 :
67 : #if !(LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT)
68 696 : if (session_info->session_transcript.digest_context_th != NULL) {
69 132 : libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
70 : session_info->session_transcript.digest_context_th);
71 132 : session_info->session_transcript.digest_context_th = NULL;
72 : }
73 696 : if (session_info->session_transcript.digest_context_th_backup != NULL) {
74 63 : libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
75 : session_info->session_transcript.digest_context_th_backup);
76 63 : session_info->session_transcript.digest_context_th_backup = NULL;
77 : }
78 : #endif
79 :
80 696 : libspdm_zero_mem (&(session_info->last_key_update_request), sizeof(spdm_key_update_request_t));
81 696 : libspdm_zero_mem(session_info, offsetof(libspdm_session_info_t, secured_message_context));
82 696 : libspdm_secured_message_init_context(session_info->secured_message_context);
83 696 : session_info->session_id = session_id;
84 696 : session_info->use_psk = use_psk;
85 696 : libspdm_secured_message_set_use_psk(session_info->secured_message_context, use_psk);
86 696 : libspdm_secured_message_set_session_type(session_info->secured_message_context, session_type);
87 :
88 : /* DSP0277 1.2 explicitly specifies a little-endian sequence number. 1.0 and 1.1 leave it up to
89 : * the Integrator to specify. */
90 696 : if ((spdm_context->connection_info.secured_message_version >> SPDM_VERSION_NUMBER_SHIFT_BIT) >=
91 : SECURED_SPDM_VERSION_12) {
92 27 : libspdm_secured_message_set_sequence_number_endian(
93 : session_info->secured_message_context,
94 : LIBSPDM_DATA_SESSION_SEQ_NUM_ENC_LITTLE_DEC_LITTLE);
95 : } else {
96 669 : libspdm_secured_message_set_sequence_number_endian(session_info->secured_message_context,
97 669 : spdm_context->sequence_number_endian);
98 : }
99 :
100 696 : libspdm_secured_message_set_max_spdm_session_sequence_number(
101 : session_info->secured_message_context, spdm_context->max_spdm_session_sequence_number);
102 696 : libspdm_secured_message_set_algorithms(
103 : session_info->secured_message_context,
104 696 : spdm_context->connection_info.version,
105 696 : spdm_context->connection_info.secured_message_version,
106 : spdm_context->connection_info.algorithm.base_hash_algo,
107 696 : spdm_context->connection_info.algorithm.dhe_named_group,
108 : spdm_context->connection_info.algorithm.kem_alg,
109 696 : spdm_context->connection_info.algorithm.aead_cipher_suite,
110 696 : spdm_context->connection_info.algorithm.key_schedule);
111 696 : session_info->session_transcript.message_encap_d.max_buffer_size =
112 : sizeof(session_info->session_transcript.message_encap_d.buffer);
113 : #if LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT
114 : session_info->session_transcript.message_k.max_buffer_size =
115 : sizeof(session_info->session_transcript.message_k.buffer);
116 : session_info->session_transcript.message_f.max_buffer_size =
117 : sizeof(session_info->session_transcript.message_f.buffer);
118 : session_info->session_transcript.message_m.max_buffer_size =
119 : sizeof(session_info->session_transcript.message_m.buffer);
120 : session_info->session_transcript.message_e.max_buffer_size =
121 : sizeof(session_info->session_transcript.message_e.buffer);
122 : session_info->session_transcript.message_encap_e.max_buffer_size =
123 : sizeof(session_info->session_transcript.message_encap_e.buffer);
124 : #endif
125 696 : }
126 :
127 : #if LIBSPDM_ENABLE_CAPABILITY_PSK_CAP
128 76 : void libspdm_session_info_set_psk_hint(libspdm_session_info_t *session_info,
129 : const void *psk_hint,
130 : size_t psk_hint_size)
131 : {
132 76 : libspdm_secured_message_set_psk_hint(
133 : session_info->secured_message_context,
134 : psk_hint,
135 : psk_hint_size);
136 76 : }
137 : #endif /* LIBSPDM_ENABLE_CAPABILITY_PSK_CAP */
138 :
139 : /**
140 : * This function gets the session info via session ID.
141 : *
142 : * @param spdm_context A pointer to the SPDM context.
143 : * @param session_id The SPDM session ID.
144 : *
145 : * @return session info.
146 : **/
147 1591 : void *libspdm_get_session_info_via_session_id(void *spdm_context, uint32_t session_id)
148 : {
149 : libspdm_context_t *context;
150 : libspdm_session_info_t *session_info;
151 : size_t index;
152 :
153 1591 : if (session_id == INVALID_SESSION_ID) {
154 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR,
155 : "libspdm_get_session_info_via_session_id - Invalid session_id\n"));
156 0 : LIBSPDM_ASSERT(false);
157 0 : return NULL;
158 : }
159 :
160 1591 : context = spdm_context;
161 :
162 1591 : session_info = (libspdm_session_info_t *)context->session_info;
163 1592 : for (index = 0; index < LIBSPDM_MAX_SESSION_COUNT; index++) {
164 1592 : if (session_info[index].session_id == session_id) {
165 1591 : return &session_info[index];
166 : }
167 : }
168 :
169 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR,
170 : "libspdm_get_session_info_via_session_id - not found session_id\n"));
171 0 : return NULL;
172 : }
173 :
174 : /**
175 : * This function gets the secured message context via session ID.
176 : *
177 : * @param spdm_context A pointer to the SPDM context.
178 : * @param session_id The SPDM session ID.
179 : *
180 : * @return secured message context.
181 : **/
182 828 : void *libspdm_get_secured_message_context_via_session_id(void *spdm_context, uint32_t session_id)
183 : {
184 : libspdm_session_info_t *session_info;
185 :
186 828 : session_info = libspdm_get_session_info_via_session_id(spdm_context, session_id);
187 828 : if (session_info == NULL) {
188 0 : return NULL;
189 : } else {
190 828 : return session_info->secured_message_context;
191 : }
192 : }
193 :
194 : /**
195 : * This function gets the secured message context via session ID.
196 : *
197 : * @param spdm_session_info A pointer to the SPDM context.
198 : *
199 : * @return secured message context.
200 : **/
201 0 : void *libspdm_get_secured_message_context_via_session_info(void *spdm_session_info)
202 : {
203 : libspdm_session_info_t *session_info;
204 :
205 0 : session_info = spdm_session_info;
206 0 : if (session_info == NULL) {
207 0 : return NULL;
208 : } else {
209 0 : return session_info->secured_message_context;
210 : }
211 : }
212 :
213 : /**
214 : * This function generate a new session ID by concatenating req_session_id and rsp_session_id.
215 : *
216 : * @param[in] req_session_id
217 : * @param[in] rsp_session_id
218 : *
219 : * @return this new session ID.
220 : **/
221 83 : uint32_t libspdm_generate_session_id(uint16_t req_session_id, uint16_t rsp_session_id)
222 : {
223 : uint32_t session_id;
224 83 : session_id = (rsp_session_id << 16) | req_session_id;
225 83 : return session_id;
226 : }
227 :
228 : /**
229 : * This function assigns a new session ID.
230 : *
231 : * @param spdm_context A pointer to the SPDM context.
232 : * @param session_id The SPDM session ID.
233 : *
234 : * @return session info associated with this new session ID.
235 : **/
236 83 : void *libspdm_assign_session_id(libspdm_context_t *spdm_context, uint32_t session_id, bool use_psk)
237 : {
238 : libspdm_session_info_t *session_info;
239 : size_t index;
240 :
241 83 : if (session_id == INVALID_SESSION_ID) {
242 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR, "libspdm_assign_session_id - Invalid session_id\n"));
243 0 : LIBSPDM_ASSERT(false);
244 0 : return NULL;
245 : }
246 :
247 83 : session_info = spdm_context->session_info;
248 :
249 415 : for (index = 0; index < LIBSPDM_MAX_SESSION_COUNT; index++) {
250 332 : if (session_info[index].session_id == session_id) {
251 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR,
252 : "libspdm_assign_session_id - Duplicated session_id\n"));
253 0 : LIBSPDM_ASSERT(false);
254 0 : return NULL;
255 : }
256 : }
257 :
258 127 : for (index = 0; index < LIBSPDM_MAX_SESSION_COUNT; index++) {
259 127 : if (session_info[index].session_id == INVALID_SESSION_ID) {
260 83 : libspdm_session_info_init(spdm_context,
261 83 : &session_info[index], session_id,
262 : use_psk);
263 83 : spdm_context->latest_session_id = session_id;
264 83 : return &session_info[index];
265 : }
266 : }
267 :
268 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR, "libspdm_assign_session_id - MAX session_id\n"));
269 0 : return NULL;
270 : }
271 :
272 : /**
273 : * This function frees a session ID.
274 : *
275 : * @param spdm_context A pointer to the SPDM context.
276 : * @param session_id The SPDM session ID.
277 : **/
278 110 : void libspdm_free_session_id(libspdm_context_t *spdm_context, uint32_t session_id)
279 : {
280 : libspdm_session_info_t *session_info;
281 : size_t index;
282 :
283 110 : if (session_id == INVALID_SESSION_ID) {
284 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR, "libspdm_free_session_id - Invalid session_id\n"));
285 0 : LIBSPDM_ASSERT(false);
286 0 : return;
287 : }
288 :
289 110 : if (spdm_context->latest_session_id == session_id) {
290 40 : spdm_context->latest_session_id = INVALID_SESSION_ID;
291 : }
292 :
293 110 : session_info = spdm_context->session_info;
294 110 : for (index = 0; index < LIBSPDM_MAX_SESSION_COUNT; index++) {
295 110 : if (session_info[index].session_id == session_id) {
296 110 : libspdm_session_info_init(spdm_context,
297 110 : &session_info[index],
298 : INVALID_SESSION_ID,
299 110 : session_info[index].use_psk);
300 110 : return;
301 : }
302 : }
303 :
304 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR, "libspdm_free_session_id - MAX session_id\n"));
305 0 : LIBSPDM_ASSERT(false);
306 : }
|