1 /**************************************************************************/
2 /*                                                                        */
3 /*       Copyright (c) Microsoft Corporation. All rights reserved.        */
4 /*                                                                        */
5 /*       This software is licensed under the Microsoft Software License   */
6 /*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
7 /*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
8 /*       and in the root directory of this software.                      */
9 /*                                                                        */
10 /**************************************************************************/
11 
12 
13 /**************************************************************************/
14 /**************************************************************************/
15 /**                                                                       */
16 /** NetX Secure Component                                                 */
17 /**                                                                       */
18 /**    Datagram Transport Layer Security (DTLS)                           */
19 /**                                                                       */
20 /**************************************************************************/
21 /**************************************************************************/
22 
23 #define NX_SECURE_SOURCE_CODE
24 
25 #include "nx_secure_dtls.h"
26 
27 /**************************************************************************/
28 /*                                                                        */
29 /*  FUNCTION                                               RELEASE        */
30 /*                                                                        */
31 /*    _nx_secure_dtls_server_create                       PORTABLE C      */
32 /*                                                           6.1          */
33 /*  AUTHOR                                                                */
34 /*                                                                        */
35 /*    Timothy Stapko, Microsoft Corporation                               */
36 /*                                                                        */
37 /*  DESCRIPTION                                                           */
38 /*                                                                        */
39 /*    This function creates an instance of a DTLS server to handle        */
40 /*    incoming DTLS requests on a particular UDP port. Due to the fact    */
41 /*    that UDP is stateless, DTLS requests from multiple clients can come */
42 /*    in on a single port while other DTLS sessions are active. Thus, the */
43 /*    server is needed to maintain active sessions and properly route     */
44 /*    incoming messages to the proper handler.                            */
45 /*                                                                        */
46 /*    The session buffer parameter is used to hold the control blocks for */
47 /*    all the possible simultaneous DTLS sessions for the DTLS server. It */
48 /*    should be allocated with a size that is an even multiple of the     */
49 /*    size of the NX_SECURE_DTLS_SESSION control block structure.         */
50 /*                                                                        */
51 /*    To calculate the necessary metadata size, the API                   */
52 /*    nx_secure_tls_metadata_size_calculate may be used.                  */
53 /*                                                                        */
54 /*  INPUT                                                                 */
55 /*                                                                        */
56 /*    server_ptr                            DTLS server control block     */
57 /*    ip_ptr                                Pointer to IP instance        */
58 /*    port                                  Server port                   */
59 /*    timeout                               Timeout value                 */
60 /*    session_buffer                        DTLS sessions buffer          */
61 /*    session_buffer_size                   Size of DTLS sessions buffer  */
62 /*    crypto_table                          Crypto table                  */
63 /*    crypto_metadata_buffer                Encryption metadata buffer    */
64 /*    crypto_metadata_size                  Encryption metadata size      */
65 /*    packet_reassembly_buffer              DTLS reassembly buffer        */
66 /*    packet_reassembly_buffer_size         Size of reassembly buffer     */
67 /*    connect_notify                        Callback for new connections  */
68 /*    receive_notify                        Callback for received data    */
69 /*                                                                        */
70 /*  OUTPUT                                                                */
71 /*                                                                        */
72 /*    status                                Completion status             */
73 /*                                                                        */
74 /*  CALLS                                                                 */
75 /*                                                                        */
76 /*    _nx_secure_dtls_session_create        Initialize DTLS control block */
77 /*    nx_udp_socket_create                  Set up UDP socket             */
78 /*    tx_mutex_get                          Get protection mutex          */
79 /*    tx_mutex_put                          Put protection mutex          */
80 /*                                                                        */
81 /*  CALLED BY                                                             */
82 /*                                                                        */
83 /*    Application Code                                                    */
84 /*                                                                        */
85 /*  RELEASE HISTORY                                                       */
86 /*                                                                        */
87 /*    DATE              NAME                      DESCRIPTION             */
88 /*                                                                        */
89 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
90 /*  09-30-2020     Timothy Stapko           Modified comment(s),          */
91 /*                                            resulting in version 6.1    */
92 /*                                                                        */
93 /**************************************************************************/
_nx_secure_dtls_server_create(NX_SECURE_DTLS_SERVER * server_ptr,NX_IP * ip_ptr,UINT port,ULONG timeout,VOID * session_buffer,UINT session_buffer_size,const NX_SECURE_TLS_CRYPTO * crypto_table,VOID * crypto_metadata_buffer,ULONG crypto_metadata_size,UCHAR * packet_reassembly_buffer,UINT packet_reassembly_buffer_size,UINT (* connect_notify)(NX_SECURE_DTLS_SESSION * dtls_session,NXD_ADDRESS * ip_address,UINT port),UINT (* receive_notify)(NX_SECURE_DTLS_SESSION * dtls_session))94 UINT _nx_secure_dtls_server_create(NX_SECURE_DTLS_SERVER *server_ptr, NX_IP *ip_ptr, UINT port, ULONG timeout,
95                                    VOID *session_buffer, UINT session_buffer_size,
96                                    const NX_SECURE_TLS_CRYPTO *crypto_table,
97                                    VOID *crypto_metadata_buffer, ULONG crypto_metadata_size,
98                                    UCHAR *packet_reassembly_buffer, UINT packet_reassembly_buffer_size,
99                                    UINT (*connect_notify)(NX_SECURE_DTLS_SESSION *dtls_session, NXD_ADDRESS *ip_address, UINT port),
100                                    UINT (*receive_notify)(NX_SECURE_DTLS_SESSION *dtls_session))
101 {
102 #ifdef NX_SECURE_ENABLE_DTLS
103 UINT status;
104 UINT i;
105 NX_SECURE_DTLS_SESSION *current_session;
106 ULONG session_metadata_size;
107 UINT  session_pkt_buffer_size;
108 UCHAR *session_pkt_buffer;
109 UCHAR *session_metadata;
110 UINT num_sessions;
111 NX_SECURE_DTLS_SERVER *tail_ptr;
112 
113     /* Figure out number of sessions. */
114     num_sessions = session_buffer_size / sizeof(NX_SECURE_DTLS_SESSION);
115 
116     /* Check sessions buffer size. */
117     if(num_sessions == 0)
118     {
119         return(NX_INVALID_PARAMETERS);
120     }
121 
122     /* Set server parameters. */
123     server_ptr->nx_dtls_server_ip_ptr = ip_ptr;
124     server_ptr->nx_dtls_server_listen_port = port;
125     server_ptr->nx_dtls_server_sessions_count = num_sessions;
126     server_ptr->nx_dtls_server_timeout = timeout;
127 
128     /* Set up session buffer. */
129     server_ptr->nx_dtls_server_sessions = (NX_SECURE_DTLS_SESSION*)session_buffer;
130 
131     /* Setup per-session packet buffer. */
132     session_pkt_buffer_size = packet_reassembly_buffer_size / num_sessions;
133     session_pkt_buffer = packet_reassembly_buffer;
134 
135     /* Get our per-session metadata. */
136     session_metadata = crypto_metadata_buffer;
137     session_metadata_size = crypto_metadata_size / num_sessions;
138 
139     /* Set up UDP socket. */
140     status = nx_udp_socket_create(ip_ptr, &(server_ptr->nx_dtls_server_udp_socket), "DTLS Server",
141                                   NX_IP_NORMAL, NX_FRAGMENT_OKAY, timeout, 8192);
142 
143     /* Store a pointer to our DTLS server instance in our UDP socket.
144        This enables the receive callback to access the right server. */
145     server_ptr->nx_dtls_server_udp_socket.nx_udp_socket_reserved_ptr = server_ptr;
146 
147     if(status != NX_SUCCESS)
148     {
149         return(status);
150     }
151 
152     /* Assign callbacks. */
153     server_ptr->nx_secure_dtls_receive_notify = receive_notify;
154     server_ptr->nx_secure_dtls_connect_notify = connect_notify;
155 
156     /* Reset the protocol version override. */
157     server_ptr -> nx_dtls_server_protocol_version_override = 0;
158 
159     /* Initialize sessions. */
160     for(i = 0; i < num_sessions; ++i)
161     {
162         /* Get the current session. */
163         current_session = &(server_ptr->nx_dtls_server_sessions[i]);
164 
165         /* Initialize each DTLS session - don't add remote certificate data here. */
166         status = _nx_secure_dtls_session_create(current_session, crypto_table, session_metadata, session_metadata_size,
167                                                 session_pkt_buffer, session_pkt_buffer_size, 0, NX_NULL, 0);
168 
169         if(status != NX_SUCCESS)
170         {
171 
172             /* Delete the created UDP socket.  */
173             nx_udp_socket_delete(&(server_ptr->nx_dtls_server_udp_socket));
174             return(status);
175         }
176 
177         /* Assign the parent server instance. */
178         current_session->nx_secure_dtls_server_parent = server_ptr;
179 
180         /* Assign other parameters. */
181         current_session->nx_secure_dtls_local_port = port;
182         current_session->nx_secure_dtls_udp_socket = &(server_ptr->nx_dtls_server_udp_socket);
183 
184         /* Advance metadata buffer. */
185         session_metadata = &session_metadata[session_metadata_size];
186 
187         /* Advance packet buffer. */
188         session_pkt_buffer = &session_pkt_buffer[session_pkt_buffer_size];
189     }
190 
191     /* Get the protection. */
192     tx_mutex_get(&_nx_secure_tls_protection, TX_WAIT_FOREVER);
193 
194     /* Place the new DTLS server control block on the list of created DTLS server. */
195     if (_nx_secure_dtls_server_created_ptr)
196     {
197 
198         /* Pickup tail pointer. */
199         tail_ptr = _nx_secure_dtls_server_created_ptr -> nx_dtls_server_created_previous;
200 
201         /* Place the new DTLS server control block in the list. */
202         _nx_secure_dtls_server_created_ptr -> nx_dtls_server_created_previous = server_ptr;
203         tail_ptr -> nx_dtls_server_created_next = server_ptr;
204 
205         /* Setup this DTLS server's created links. */
206         server_ptr -> nx_dtls_server_created_previous = tail_ptr;
207         server_ptr -> nx_dtls_server_created_next = _nx_secure_dtls_server_created_ptr;
208     }
209     else
210     {
211 
212         /* The created DTLS server list is empty. Add DTLS server control block to empty list. */
213         _nx_secure_dtls_server_created_ptr = server_ptr;
214         server_ptr -> nx_dtls_server_created_previous = server_ptr;
215         server_ptr -> nx_dtls_server_created_next = server_ptr;
216     }
217     _nx_secure_dtls_server_created_count++;
218 
219     /* Release the protection. */
220     tx_mutex_put(&_nx_secure_tls_protection);
221 
222     return(NX_SUCCESS);
223 #else
224     NX_PARAMETER_NOT_USED(server_ptr);
225     NX_PARAMETER_NOT_USED(ip_ptr);
226     NX_PARAMETER_NOT_USED(port);
227     NX_PARAMETER_NOT_USED(timeout);
228     NX_PARAMETER_NOT_USED(session_buffer);
229     NX_PARAMETER_NOT_USED(session_buffer_size);
230     NX_PARAMETER_NOT_USED(crypto_table);
231     NX_PARAMETER_NOT_USED(crypto_metadata_buffer);
232     NX_PARAMETER_NOT_USED(crypto_metadata_size);
233     NX_PARAMETER_NOT_USED(packet_reassembly_buffer);
234     NX_PARAMETER_NOT_USED(packet_reassembly_buffer_size);
235     NX_PARAMETER_NOT_USED(connect_notify);
236     NX_PARAMETER_NOT_USED(receive_notify);
237 
238 
239     return(NX_NOT_SUPPORTED);
240 #endif /* NX_SECURE_ENABLE_DTLS */
241 }
242 
243