1 /***************************************************************************
2 * Copyright (c) 2024 Microsoft Corporation
3 *
4 * This program and the accompanying materials are made available under the
5 * terms of the MIT License which is available at
6 * https://opensource.org/licenses/MIT.
7 *
8 * SPDX-License-Identifier: MIT
9 **************************************************************************/
10
11
12 /**************************************************************************/
13 /**************************************************************************/
14 /** */
15 /** NetX Secure Component */
16 /** */
17 /** Datagram Transport Layer Security (DTLS) */
18 /** */
19 /**************************************************************************/
20 /**************************************************************************/
21
22 #define NX_SECURE_SOURCE_CODE
23
24 #include "nx_secure_dtls.h"
25
26 #ifdef NX_SECURE_ENABLE_DTLS
27 /**************************************************************************/
28 /* */
29 /* FUNCTION RELEASE */
30 /* */
31 /* nx_secure_dtls_session_cache_delete PORTABLE C */
32 /* 6.1.12 */
33 /* AUTHOR */
34 /* */
35 /* Timothy Stapko, Microsoft Corporation */
36 /* */
37 /* DESCRIPTION */
38 /* */
39 /* This function deletes DTLS session with specific IP address and */
40 /* port. */
41 /* */
42 /* INPUT */
43 /* */
44 /* dtls_server DTLS server control block */
45 /* ip_address IP address to match */
46 /* remote_port Remote port to match */
47 /* local_port Local port to match */
48 /* */
49 /* OUTPUT */
50 /* */
51 /* status Completion status */
52 /* */
53 /* CALLS */
54 /* */
55 /* _nx_secure_dtls_session_reset Reset DTLS session */
56 /* */
57 /* CALLED BY */
58 /* */
59 /* Application Code */
60 /* */
61 /* RELEASE HISTORY */
62 /* */
63 /* DATE NAME DESCRIPTION */
64 /* */
65 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
66 /* 09-30-2020 Timothy Stapko Modified comment(s), */
67 /* resulting in version 6.1 */
68 /* 07-29-2022 Yuxin Zhou Modified comment(s), */
69 /* fixed compiler errors when */
70 /* IPv4 is disabled, */
71 /* resulting in version 6.1.12 */
72 /* */
73 /**************************************************************************/
nx_secure_dtls_session_cache_delete(NX_SECURE_DTLS_SERVER * dtls_server,NXD_ADDRESS * ip_address,UINT remote_port,UINT local_port)74 VOID nx_secure_dtls_session_cache_delete(NX_SECURE_DTLS_SERVER *dtls_server, NXD_ADDRESS *ip_address, UINT remote_port, UINT local_port)
75 {
76 NX_SECURE_DTLS_SESSION *session_array;
77 UINT num_sessions;
78 UINT i;
79
80 /* Get our session cache information from the DTLS server instance. */
81 num_sessions = dtls_server->nx_dtls_server_sessions_count;
82 session_array = dtls_server->nx_dtls_server_sessions;
83
84 /* Get the protection. */
85 tx_mutex_get(&_nx_secure_tls_protection, TX_WAIT_FOREVER);
86
87 /* Reset all entries with matching IP address and port. */
88 for (i = 0; i < num_sessions; ++i)
89 {
90 /* If the IP address and port match, then reset the entry. */
91 if (session_array[i].nx_secure_dtls_remote_port != remote_port ||
92 session_array[i].nx_secure_dtls_local_port != local_port)
93 {
94 continue;
95 }
96 if (session_array[i].nx_secure_dtls_remote_ip_address.nxd_ip_version !=
97 ip_address -> nxd_ip_version)
98 {
99 continue;
100 }
101 #ifndef NX_DISABLE_IPV4
102 if (ip_address -> nxd_ip_version == NX_IP_VERSION_V4)
103 {
104 if (session_array[i].nx_secure_dtls_remote_ip_address.nxd_ip_address.v4 !=
105 ip_address -> nxd_ip_address.v4)
106 {
107 continue;
108 }
109 }
110 #endif /* !NX_DISABLE_IPV4 */
111
112 #ifdef FEATURE_NX_IPV6
113 if (ip_address -> nxd_ip_version == NX_IP_VERSION_V6)
114 {
115 if ((session_array[i].nx_secure_dtls_remote_ip_address.nxd_ip_address.v6[0] != ip_address -> nxd_ip_address.v6[0]) ||
116 (session_array[i].nx_secure_dtls_remote_ip_address.nxd_ip_address.v6[1] != ip_address -> nxd_ip_address.v6[1]) ||
117 (session_array[i].nx_secure_dtls_remote_ip_address.nxd_ip_address.v6[2] != ip_address -> nxd_ip_address.v6[2]) ||
118 (session_array[i].nx_secure_dtls_remote_ip_address.nxd_ip_address.v6[3] != ip_address -> nxd_ip_address.v6[3]))
119 {
120 continue;
121 }
122 }
123 #endif /* FEATURE_NX_IPV6 */
124
125 /* Release the protection. */
126 tx_mutex_put(&_nx_secure_tls_protection);
127
128 _nx_secure_dtls_session_reset(&session_array[i]);
129
130 /* Get the protection. */
131 tx_mutex_get(&_nx_secure_tls_protection, TX_WAIT_FOREVER);
132 }
133
134 /* Release the protection. */
135 tx_mutex_put(&_nx_secure_tls_protection);
136 }
137
138 /**************************************************************************/
139 /* */
140 /* FUNCTION RELEASE */
141 /* */
142 /* nx_secure_dtls_session_cache_get_new PORTABLE C */
143 /* 6.1 */
144 /* AUTHOR */
145 /* */
146 /* Timothy Stapko, Microsoft Corporation */
147 /* */
148 /* DESCRIPTION */
149 /* */
150 /* This function allows the DTLS implementation to associate a DTLS */
151 /* session control block with a particular IP Address and Port, */
152 /* enabling multiple DTLS sessions on a single UDP socket. */
153 /* */
154 /* INPUT */
155 /* */
156 /* dtls_server DTLS server control block */
157 /* dtls_session Returned DTLS session */
158 /* ip_address IP address */
159 /* remote_port Remote port */
160 /* local_port Local port */
161 /* */
162 /* OUTPUT */
163 /* */
164 /* status Completion status */
165 /* */
166 /* CALLS */
167 /* */
168 /* None */
169 /* */
170 /* CALLED BY */
171 /* */
172 /* _nx_secure_dtls_receive_callback DTLS receive callback function*/
173 /* */
174 /* RELEASE HISTORY */
175 /* */
176 /* DATE NAME DESCRIPTION */
177 /* */
178 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
179 /* 09-30-2020 Timothy Stapko Modified comment(s), */
180 /* verified memcpy use cases, */
181 /* resulting in version 6.1 */
182 /* */
183 /**************************************************************************/
nx_secure_dtls_session_cache_get_new(NX_SECURE_DTLS_SERVER * dtls_server,NX_SECURE_DTLS_SESSION ** dtls_session,NXD_ADDRESS * ip_address,UINT remote_port,UINT local_port)184 UINT nx_secure_dtls_session_cache_get_new(NX_SECURE_DTLS_SERVER *dtls_server, NX_SECURE_DTLS_SESSION **dtls_session, NXD_ADDRESS *ip_address, UINT remote_port, UINT local_port)
185 {
186 NX_SECURE_DTLS_SESSION *session_array;
187 UINT num_sessions;
188 UINT i;
189
190 /* Get our session cache information from the DTLS server instance. */
191 num_sessions = dtls_server->nx_dtls_server_sessions_count;
192 session_array = dtls_server->nx_dtls_server_sessions;
193
194 /* Get the protection. */
195 tx_mutex_get(&_nx_secure_tls_protection, TX_WAIT_FOREVER);
196
197 /* See if there are any free entries. */
198 for (i = 0; i < num_sessions; ++i)
199 {
200 /* See if there is a session available. */
201 if (session_array[i].nx_secure_dtls_session_in_use == NX_FALSE)
202 {
203 /* Set the IP and port to the passed-in values. */
204 NX_SECURE_MEMCPY(&session_array[i].nx_secure_dtls_remote_ip_address, ip_address, sizeof(NXD_ADDRESS)); /* Use case of memcpy is verified. */
205 session_array[i].nx_secure_dtls_local_port = local_port;
206 session_array[i].nx_secure_dtls_remote_port = remote_port;
207 session_array[i].nx_secure_dtls_session_in_use = NX_TRUE;
208
209 /* Check if ptotocol version is overrided. */
210 if (dtls_server -> nx_dtls_server_protocol_version_override)
211 {
212 _nx_secure_tls_session_protocol_version_override(&(session_array[i].nx_secure_dtls_tls_session), dtls_server -> nx_dtls_server_protocol_version_override);
213 }
214
215 /* Release the protection. */
216 tx_mutex_put(&_nx_secure_tls_protection);
217
218 /* Return the session. */
219 *dtls_session = &session_array[i];
220 return(NX_SUCCESS);
221 }
222 }
223
224 /* Release the protection. */
225 tx_mutex_put(&_nx_secure_tls_protection);
226
227 /* No session found, return NULL and an error. */
228 *dtls_session = NULL;
229 return(NX_SECURE_TLS_NO_FREE_DTLS_SESSIONS);
230 }
231
232 /**************************************************************************/
233 /* */
234 /* FUNCTION RELEASE */
235 /* */
236 /* nx_secure_dtls_session_cache_find PORTABLE C */
237 /* 6.1.12 */
238 /* AUTHOR */
239 /* */
240 /* Timothy Stapko, Microsoft Corporation */
241 /* */
242 /* DESCRIPTION */
243 /* */
244 /* This function allows the DTLS implementation to associate a DTLS */
245 /* session control block with a particular IP Address and Port, */
246 /* enabling multiple DTLS sessions on a single UDP socket. */
247 /* */
248 /* INPUT */
249 /* */
250 /* dtls_server DTLS server control block */
251 /* dtls_session Returned DTLS session */
252 /* ip_address IP address to match */
253 /* remote_port Remote port to match */
254 /* local_port Local port to match */
255 /* */
256 /* OUTPUT */
257 /* */
258 /* status Completion status */
259 /* */
260 /* CALLS */
261 /* */
262 /* None */
263 /* */
264 /* CALLED BY */
265 /* */
266 /* _nx_secure_dtls_receive_callback DTLS receive callback function*/
267 /* */
268 /* RELEASE HISTORY */
269 /* */
270 /* DATE NAME DESCRIPTION */
271 /* */
272 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
273 /* 09-30-2020 Timothy Stapko Modified comment(s), */
274 /* resulting in version 6.1 */
275 /* 07-29-2022 Yuxin Zhou Modified comment(s), */
276 /* fixed compiler errors when */
277 /* IPv4 is disabled, */
278 /* resulting in version 6.1.12 */
279 /* */
280 /**************************************************************************/
nx_secure_dtls_session_cache_find(NX_SECURE_DTLS_SERVER * dtls_server,NX_SECURE_DTLS_SESSION ** dtls_session,NXD_ADDRESS * ip_address,UINT remote_port,UINT local_port)281 UINT nx_secure_dtls_session_cache_find(NX_SECURE_DTLS_SERVER *dtls_server, NX_SECURE_DTLS_SESSION **dtls_session, NXD_ADDRESS *ip_address, UINT remote_port, UINT local_port)
282 {
283 NX_SECURE_DTLS_SESSION *session_array;
284 UINT num_sessions;
285 UINT i;
286
287 /* Get our session cache information from the DTLS server instance. */
288 num_sessions = dtls_server->nx_dtls_server_sessions_count;
289 session_array = dtls_server->nx_dtls_server_sessions;
290
291 /* Get the protection. */
292 tx_mutex_get(&_nx_secure_tls_protection, TX_WAIT_FOREVER);
293
294 /* See if there are any matches. */
295 for (i = 0; i < num_sessions; ++i)
296 {
297 /* Check remote port. */
298 if (session_array[i].nx_secure_dtls_remote_port != remote_port)
299 {
300 continue;
301 }
302
303 /* Check local port. */
304 if (session_array[i].nx_secure_dtls_local_port != local_port)
305 {
306 continue;
307 }
308
309 /* Check remote IP address version. */
310 if (session_array[i].nx_secure_dtls_remote_ip_address.nxd_ip_version !=
311 ip_address -> nxd_ip_version)
312 {
313 continue;
314 }
315
316 /* Check actual remote IP address value. */
317 #ifndef NX_DISABLE_IPV4
318 if (ip_address -> nxd_ip_version == NX_IP_VERSION_V4)
319 {
320 if (session_array[i].nx_secure_dtls_remote_ip_address.nxd_ip_address.v4 ==
321 ip_address -> nxd_ip_address.v4)
322 {
323
324 /* Release the protection. */
325 tx_mutex_put(&_nx_secure_tls_protection);
326
327 /* Return the session. */
328 *dtls_session = &session_array[i];
329 return(NX_SUCCESS);
330 }
331 }
332 #endif /* !NX_DISABLE_IPV4 */
333
334 #ifdef FEATURE_NX_IPV6
335 if (ip_address -> nxd_ip_version == NX_IP_VERSION_V6)
336 {
337 if ((session_array[i].nx_secure_dtls_remote_ip_address.nxd_ip_address.v6[0] == ip_address -> nxd_ip_address.v6[0]) &&
338 (session_array[i].nx_secure_dtls_remote_ip_address.nxd_ip_address.v6[1] == ip_address -> nxd_ip_address.v6[1]) &&
339 (session_array[i].nx_secure_dtls_remote_ip_address.nxd_ip_address.v6[2] == ip_address -> nxd_ip_address.v6[2]) &&
340 (session_array[i].nx_secure_dtls_remote_ip_address.nxd_ip_address.v6[3] == ip_address -> nxd_ip_address.v6[3]))
341 {
342
343 /* Release the protection. */
344 tx_mutex_put(&_nx_secure_tls_protection);
345
346 /* Return the session. */
347 *dtls_session = &session_array[i];
348 return(NX_SUCCESS);
349 }
350 }
351 #endif /* FEATURE_NX_IPV6 */
352 }
353
354 /* Release the protection. */
355 tx_mutex_put(&_nx_secure_tls_protection);
356
357 /* No session found, return NULL and an error. */
358 *dtls_session = NULL;
359 return(NX_SECURE_DTLS_SESSION_NOT_FOUND);
360 }
361 #endif /* NX_SECURE_ENABLE_DTLS */
362
363