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