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 740 : void libspdm_session_info_init(libspdm_context_t *spdm_context,
16 : libspdm_session_info_t *session_info,
17 : uint32_t session_id, spdm_version_number_t secured_message_version,
18 : bool use_psk)
19 : {
20 : libspdm_session_type_t session_type;
21 : uint32_t capabilities_flag;
22 :
23 740 : if (session_id != INVALID_SESSION_ID) {
24 451 : if (use_psk) {
25 335 : LIBSPDM_ASSERT((spdm_context->max_psk_session_count == 0) ||
26 : (spdm_context->current_psk_session_count <
27 : spdm_context->max_psk_session_count));
28 335 : spdm_context->current_psk_session_count++;
29 : } else {
30 116 : LIBSPDM_ASSERT((spdm_context->max_dhe_session_count == 0) ||
31 : (spdm_context->current_dhe_session_count <
32 : spdm_context->max_dhe_session_count));
33 116 : spdm_context->current_dhe_session_count++;
34 : }
35 : } else {
36 289 : if (use_psk) {
37 58 : if (spdm_context->current_psk_session_count > 0) {
38 58 : spdm_context->current_psk_session_count--;
39 : }
40 : } else {
41 231 : if (spdm_context->current_dhe_session_count > 0) {
42 60 : spdm_context->current_dhe_session_count--;
43 : }
44 : }
45 : }
46 :
47 740 : capabilities_flag = spdm_context->connection_info.capability.flags &
48 740 : spdm_context->local_context.capability.flags;
49 740 : switch (capabilities_flag &
50 : (SPDM_GET_CAPABILITIES_REQUEST_FLAGS_ENCRYPT_CAP |
51 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MAC_CAP)) {
52 249 : case 0:
53 249 : session_type = LIBSPDM_SESSION_TYPE_NONE;
54 249 : break;
55 379 : case (SPDM_GET_CAPABILITIES_REQUEST_FLAGS_ENCRYPT_CAP |
56 : SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MAC_CAP):
57 379 : session_type = LIBSPDM_SESSION_TYPE_ENC_MAC;
58 379 : break;
59 112 : case SPDM_GET_CAPABILITIES_REQUEST_FLAGS_MAC_CAP:
60 112 : session_type = LIBSPDM_SESSION_TYPE_MAC_ONLY;
61 112 : break;
62 0 : default:
63 0 : LIBSPDM_ASSERT(false);
64 0 : session_type = LIBSPDM_SESSION_TYPE_MAX;
65 0 : break;
66 : }
67 :
68 : #if !(LIBSPDM_RECORD_TRANSCRIPT_DATA_SUPPORT)
69 740 : if (session_info->session_transcript.digest_context_th != NULL) {
70 132 : libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
71 : session_info->session_transcript.digest_context_th);
72 132 : session_info->session_transcript.digest_context_th = NULL;
73 : }
74 740 : if (session_info->session_transcript.digest_context_th_backup != NULL) {
75 63 : libspdm_hash_free (spdm_context->connection_info.algorithm.base_hash_algo,
76 : session_info->session_transcript.digest_context_th_backup);
77 63 : session_info->session_transcript.digest_context_th_backup = NULL;
78 : }
79 : #endif
80 :
81 740 : libspdm_zero_mem (&(session_info->last_key_update_request), sizeof(spdm_key_update_request_t));
82 740 : libspdm_zero_mem(session_info, offsetof(libspdm_session_info_t, secured_message_context));
83 740 : libspdm_secured_message_init_context(session_info->secured_message_context);
84 740 : session_info->session_id = session_id;
85 740 : session_info->use_psk = use_psk;
86 740 : libspdm_secured_message_set_use_psk(session_info->secured_message_context, use_psk);
87 740 : libspdm_secured_message_set_session_type(session_info->secured_message_context, session_type);
88 :
89 : /* DSP0277 1.2 explicitly specifies a little-endian sequence number. 1.0 and 1.1 leave it up to
90 : * the Integrator to specify. */
91 740 : if ((secured_message_version >> SPDM_VERSION_NUMBER_SHIFT_BIT) >= SECURED_SPDM_VERSION_12) {
92 13 : 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 727 : libspdm_secured_message_set_sequence_number_endian(session_info->secured_message_context,
97 727 : spdm_context->sequence_number_endian);
98 : }
99 :
100 740 : libspdm_secured_message_set_max_spdm_session_sequence_number(
101 : session_info->secured_message_context, spdm_context->max_spdm_session_sequence_number);
102 740 : libspdm_secured_message_set_algorithms(
103 : session_info->secured_message_context,
104 740 : spdm_context->connection_info.version,
105 : secured_message_version,
106 : spdm_context->connection_info.algorithm.base_hash_algo,
107 740 : spdm_context->connection_info.algorithm.dhe_named_group,
108 : spdm_context->connection_info.algorithm.kem_alg,
109 740 : spdm_context->connection_info.algorithm.aead_cipher_suite,
110 740 : spdm_context->connection_info.algorithm.key_schedule);
111 740 : 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 740 : }
126 :
127 : #if LIBSPDM_ENABLE_CAPABILITY_PSK_CAP
128 77 : 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 77 : libspdm_secured_message_set_psk_hint(
133 : session_info->secured_message_context,
134 : psk_hint,
135 : psk_hint_size);
136 77 : }
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 1648 : 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 1648 : 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 1648 : context = spdm_context;
161 :
162 1648 : session_info = (libspdm_session_info_t *)context->session_info;
163 1649 : for (index = 0; index < LIBSPDM_MAX_SESSION_COUNT; index++) {
164 1649 : if (session_info[index].session_id == session_id) {
165 1648 : 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 845 : 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 845 : session_info = libspdm_get_session_info_via_session_id(spdm_context, session_id);
187 845 : if (session_info == NULL) {
188 0 : return NULL;
189 : } else {
190 845 : 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 84 : uint32_t libspdm_generate_session_id(uint16_t req_session_id, uint16_t rsp_session_id)
222 : {
223 : uint32_t session_id;
224 84 : session_id = (rsp_session_id << 16) | req_session_id;
225 84 : return session_id;
226 : }
227 :
228 84 : libspdm_session_info_t *libspdm_assign_session_id(libspdm_context_t *spdm_context,
229 : uint32_t session_id,
230 : spdm_version_number_t secured_message_version,
231 : bool use_psk)
232 : {
233 : libspdm_session_info_t *session_info;
234 : size_t index;
235 :
236 84 : if (session_id == INVALID_SESSION_ID) {
237 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR, "libspdm_assign_session_id - Invalid session_id\n"));
238 0 : LIBSPDM_ASSERT(false);
239 0 : return NULL;
240 : }
241 :
242 84 : session_info = spdm_context->session_info;
243 :
244 420 : for (index = 0; index < LIBSPDM_MAX_SESSION_COUNT; index++) {
245 336 : if (session_info[index].session_id == session_id) {
246 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR,
247 : "libspdm_assign_session_id - Duplicated session_id\n"));
248 0 : LIBSPDM_ASSERT(false);
249 0 : return NULL;
250 : }
251 : }
252 :
253 131 : for (index = 0; index < LIBSPDM_MAX_SESSION_COUNT; index++) {
254 131 : if (session_info[index].session_id == INVALID_SESSION_ID) {
255 84 : libspdm_session_info_init(spdm_context,
256 84 : &session_info[index], session_id, secured_message_version,
257 : use_psk);
258 84 : spdm_context->latest_session_id = session_id;
259 84 : return &session_info[index];
260 : }
261 : }
262 :
263 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR, "libspdm_assign_session_id - MAX session_id\n"));
264 0 : return NULL;
265 : }
266 :
267 : /**
268 : * This function frees a session ID.
269 : *
270 : * @param spdm_context A pointer to the SPDM context.
271 : * @param session_id The SPDM session ID.
272 : **/
273 110 : void libspdm_free_session_id(libspdm_context_t *spdm_context, uint32_t session_id)
274 : {
275 : libspdm_session_info_t *session_info;
276 : size_t index;
277 :
278 110 : if (session_id == INVALID_SESSION_ID) {
279 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR, "libspdm_free_session_id - Invalid session_id\n"));
280 0 : LIBSPDM_ASSERT(false);
281 0 : return;
282 : }
283 :
284 110 : if (spdm_context->latest_session_id == session_id) {
285 40 : spdm_context->latest_session_id = INVALID_SESSION_ID;
286 : }
287 :
288 110 : session_info = spdm_context->session_info;
289 110 : for (index = 0; index < LIBSPDM_MAX_SESSION_COUNT; index++) {
290 110 : if (session_info[index].session_id == session_id) {
291 110 : libspdm_session_info_init(spdm_context,
292 110 : &session_info[index],
293 : INVALID_SESSION_ID, 0,
294 110 : session_info[index].use_psk);
295 110 : return;
296 : }
297 : }
298 :
299 0 : LIBSPDM_DEBUG((LIBSPDM_DEBUG_ERROR, "libspdm_free_session_id - MAX session_id\n"));
300 0 : LIBSPDM_ASSERT(false);
301 : }
|