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