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