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