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 #ifdef NX_SECURE_ENABLE_DTLS
29 
30 
31 /**************************************************************************/
32 /*                                                                        */
33 /*  FUNCTION                                               RELEASE        */
34 /*                                                                        */
35 /*    _nx_secure_dtls_server_handshake                    PORTABLE C      */
36 /*                                                           6.1.12       */
37 /*  AUTHOR                                                                */
38 /*                                                                        */
39 /*    Timothy Stapko, Microsoft Corporation                               */
40 /*                                                                        */
41 /*  DESCRIPTION                                                           */
42 /*                                                                        */
43 /*    This function runs the DTLS Server mode state machine. It processes */
44 /*    an incoming handshake record and takes appropriate action to        */
45 /*    advance the DTLS Server handshake.                                  */
46 /*                                                                        */
47 /*  INPUT                                                                 */
48 /*                                                                        */
49 /*    dtls_session                          TLS control block             */
50 /*    packet_buffer                         Pointer into record buffer    */
51 /*    data_length                           Length of data                */
52 /*    wait_option                           Controls timeout actions      */
53 /*                                                                        */
54 /*  OUTPUT                                                                */
55 /*                                                                        */
56 /*    status                                Completion status             */
57 /*                                                                        */
58 /*  CALLS                                                                 */
59 /*                                                                        */
60 /*    _nx_secure_dtls_allocate_handshake_packet                           */
61 /*                                          Allocate DTLS handshake packet*/
62 /*    _nx_secure_dtls_packet_allocate       Allocate internal DTLS packet */
63 /*    _nx_secure_dtls_process_clienthello   Process ClientHello           */
64 /*    _nx_secure_dtls_process_handshake_header                            */
65 /*                                          Process handshake header      */
66 /*    _nx_secure_dtls_retransmit_queue_flush                              */
67 /*                                          Flush retransmit queue        */
68 /*    _nx_secure_dtls_send_handshake_record Send DTLS handshake record    */
69 /*    _nx_secure_dtls_send_helloverifyrequest                             */
70 /*                                          Send DTLS HelloVerifyRequest  */
71 /*    _nx_secure_dtls_send_record           Send DTLS records             */
72 /*    _nx_secure_dtls_send_serverhello      Send DTLS ServerHello         */
73 /*    _nx_secure_tls_generate_keys          Generate session keys         */
74 /*    _nx_secure_tls_handshake_hash_init    Initialize Finished hash      */
75 /*    _nx_secure_tls_handshake_hash_update  Update Finished hash          */
76 /*    _nx_secure_tls_process_client_key_exchange                          */
77 /*                                          Process key exchange          */
78 /*    _nx_secure_tls_process_finished       Process Finished message      */
79 /*    _nx_secure_tls_send_certificate       Send TLS certificate          */
80 /*    _nx_secure_tls_send_changecipherspec  Send ChangeCipherSpec         */
81 /*    _nx_secure_tls_send_finished          Send Finished message         */
82 /*    _nx_secure_tls_send_server_key_exchange                             */
83 /*                                          Send ServerKeyExchange        */
84 /*    _nx_secure_tls_session_keys_set       Set session keys              */
85 /*    _nx_secure_tls_process_remote_certificate                           */
86 /*                                          Process remote certificate    */
87 /*    _nx_secure_tls_process_certificate_verify                           */
88 /*                                          Process certificate verify    */
89 /*    _nx_secure_tls_send_certificate_request                             */
90 /*                                          Send certificate request      */
91 /*    tx_mutex_get                          Get protection mutex          */
92 /*    tx_mutex_put                          Put protection mutex          */
93 /*    [nx_secure_dtls_receive_notify]       Notify aaplication of packet  */
94 /*                                            receive                     */
95 /*                                                                        */
96 /*  CALLED BY                                                             */
97 /*                                                                        */
98 /*    _nx_secure_dtls_process_record        Process DTLS record data      */
99 /*                                                                        */
100 /*  RELEASE HISTORY                                                       */
101 /*                                                                        */
102 /*    DATE              NAME                      DESCRIPTION             */
103 /*                                                                        */
104 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
105 /*  09-30-2020     Timothy Stapko           Modified comment(s),          */
106 /*                                            verified memcpy use cases,  */
107 /*                                            verified memmove use cases, */
108 /*                                            fixed renegotiation bug,    */
109 /*                                            fixed certificate buffer    */
110 /*                                            allocation,                 */
111 /*                                            resulting in version 6.1    */
112 /*  12-31-2020     Timothy Stapko           Modified comment(s),          */
113 /*                                            improved buffer length      */
114 /*                                            verification,               */
115 /*                                            resulting in version 6.1.3  */
116 /*  01-31-2022     Timothy Stapko           Modified comment(s),          */
117 /*                                            fixed out-of-order handling,*/
118 /*                                            resulting in version 6.1.10 */
119 /*  07-29-2022     Yuxin Zhou               Modified comment(s),          */
120 /*                                            removed duplicated alert,   */
121 /*                                            resulting in version 6.1.12 */
122 /*                                                                        */
123 /**************************************************************************/
_nx_secure_dtls_server_handshake(NX_SECURE_DTLS_SESSION * dtls_session,UCHAR * packet_buffer,UINT data_length,ULONG wait_option)124 UINT _nx_secure_dtls_server_handshake(NX_SECURE_DTLS_SESSION *dtls_session, UCHAR *packet_buffer,
125                                       UINT data_length, ULONG wait_option)
126 {
127 #ifndef NX_SECURE_TLS_SERVER_DISABLED
128 UINT                                  status;
129 USHORT                                message_type;
130 UINT                                  header_bytes;
131 UINT                                  message_length;
132 UINT                                  message_seq;
133 UINT                                  fragment_offset;
134 UINT                                  fragment_length;
135 NX_PACKET                            *send_packet;
136 NX_PACKET_POOL                       *packet_pool;
137 UCHAR                                *packet_start;
138 NX_SECURE_TLS_SESSION                *tls_session;
139 UCHAR                                *fragment_buffer;
140 
141 
142     /* Basic state machine for handshake:
143      * 1. We have received a handshake message, now process the header.
144      * 2. Then process the message itself and populate the TLS socket structure.
145      * 3. Follow up with whatever actions are needed.
146      */
147 
148     /* Save a pointer to the start of our packet for the hash that happens below. */
149     packet_start = packet_buffer;
150 
151 
152 
153     /* Get a reference to TLS state. */
154     tls_session = &dtls_session -> nx_secure_dtls_tls_session;
155 
156     /* Use the TLS packet buffer for fragment processing. */
157     fragment_buffer = tls_session->nx_secure_tls_packet_buffer;
158 
159     header_bytes = data_length;
160 
161     /* First, process the handshake message to get our state and any data therein. */
162     status = _nx_secure_dtls_process_handshake_header(packet_buffer, &message_type, &header_bytes,
163                                                       &message_length, &message_seq, &fragment_offset, &fragment_length);
164 
165     if (status == NX_SUCCESS)
166     {
167         /* For now, if we see a repeated message sequence, assume an unnecessary retransmission and ignore. */
168         /* Don't ignore sequence 0 - it's a new handshake request! */
169         if (message_seq < dtls_session -> nx_secure_dtls_remote_handshake_sequence)
170         {
171             /* Re-transmitted message. */
172             return(NX_CONTINUE);
173         }
174 
175         /* When we receive a message fragment, subtract it from the current fragment length. */
176         if ((header_bytes + fragment_length) > data_length)
177         {
178             return(NX_SECURE_TLS_INCORRECT_MESSAGE_LENGTH);
179         }
180 
181         /* Check the fragment_length with the lenght of packet buffer. */
182         if ((header_bytes + fragment_length) > data_length)
183         {
184             return(NX_SECURE_TLS_INCORRECT_MESSAGE_LENGTH);
185         }
186 
187         /* Check available area of buffer. */
188         if ((fragment_offset + fragment_length) > tls_session -> nx_secure_tls_packet_buffer_size ||
189             (header_bytes + message_length) > tls_session -> nx_secure_tls_packet_buffer_size)
190         {
191             return(NX_SECURE_TLS_PACKET_BUFFER_TOO_SMALL);
192         }
193 
194         /* If this message sequence isn't what we expect, continue reading packets. */
195         if(message_seq != dtls_session -> nx_secure_dtls_expected_handshake_sequence)
196         {
197             return(NX_SECURE_TLS_OUT_OF_ORDER_MESSAGE);
198         }
199 
200         /* If we have a new sequence number, we have a new record (may be fragmented). Unless
201             the sequence number is 0, which means it is the first record. */
202         if (message_seq > dtls_session -> nx_secure_dtls_remote_handshake_sequence || (message_seq == 0 && fragment_offset == 0))
203         {
204             /* New record starting, reset the fragment length and handshake sequence number. */
205             dtls_session -> nx_secure_dtls_remote_handshake_sequence = message_seq;
206             dtls_session -> nx_secure_dtls_fragment_length = message_length;
207         }
208 
209         if (fragment_length > dtls_session -> nx_secure_dtls_fragment_length)
210         {
211             return(NX_SECURE_TLS_INVALID_PACKET);
212         }
213 
214         /* When we receive a message fragment, subtract it from the current fragment length. */
215         dtls_session -> nx_secure_dtls_fragment_length -= fragment_length;
216 
217         /* Copy the fragment data (minus the header) into the reassembly buffer. */
218         NX_SECURE_MEMCPY(&fragment_buffer[fragment_offset], &packet_buffer[header_bytes], fragment_length); /* Use case of memcpy is verified. */
219 
220         /* If we still have fragments to add, just return success. */
221         if (dtls_session -> nx_secure_dtls_fragment_length > 0)
222         {
223             return(NX_SUCCESS);
224         }
225         else
226         {
227             /* At beginning of handshake, reset the expected sequence number. */
228             if (message_seq == 0)
229             {
230                 dtls_session -> nx_secure_dtls_expected_handshake_sequence = 0;
231             }
232 
233             /* If the recontructed message has a sequence number not equal to the expected, it's
234                a retransmission or out-of-order message we need to ignore. */
235             if (message_seq != dtls_session -> nx_secure_dtls_expected_handshake_sequence)
236             {
237                 return(NX_CONTINUE);
238             }
239 
240             /* Our next expected handshake message sequence number is 1 greater than this one. */
241             dtls_session -> nx_secure_dtls_expected_handshake_sequence = message_seq + 1;
242 
243             /* Put the header into the packet buffer, adjusting the fields to create a seam-less
244              * DTLS record. */
245             NX_SECURE_MEMMOVE(&fragment_buffer[header_bytes], fragment_buffer, message_length); /* Use case of memmove is verified. */
246 
247             /* Reconstruct the header in the fragment buffer so we can hash the
248                reconstructed record as if it were never fragmented. */
249 
250             /* Type. */
251             fragment_buffer[0] = (UCHAR)message_type;
252 
253             /* Length. */
254             fragment_buffer[1] = (UCHAR)(message_length >> 16);
255             fragment_buffer[2] = (UCHAR)(message_length >> 8);
256             fragment_buffer[3] = (UCHAR)(message_length);
257 
258             /* Sequence. */
259             fragment_buffer[4] = (UCHAR)(message_seq  >> 8);
260             fragment_buffer[5] = (UCHAR)(message_seq);
261 
262             /* Fragment offset is now 0. */
263             fragment_buffer[6] = 0;
264             fragment_buffer[7] = 0;
265             fragment_buffer[8] = 0;
266 
267             /* Fragment length is now == message length. */
268             fragment_buffer[9] = (UCHAR)(message_length >> 16);
269             fragment_buffer[10] = (UCHAR)(message_length >> 8);
270             fragment_buffer[11] = (UCHAR)(message_length);
271 
272             /* We have a reassembled DTLS record, use that for the handshake. */
273             packet_buffer = fragment_buffer + header_bytes;
274             packet_start =  fragment_buffer;
275         }
276     }
277 
278     if (status != NX_SECURE_TLS_SUCCESS)
279     {
280         return(status);
281     }
282 
283     /* Get reference to the packet pool so we can allocate a packet for all send operations.  */
284     packet_pool = tls_session -> nx_secure_tls_packet_pool;
285 
286     /* We need to hash all of the handshake messages that we receive and send. If this message is a ClientHello,
287        then we need to initialize the hashes (TLS 1.1 uses both MD5 and SHA-1). The final hash is generated
288        in the "Finished" message.  */
289     if (message_type == NX_SECURE_TLS_CLIENT_HELLO)
290     {
291         /* Initialize the handshake hashes used for the Finished message. */
292         _nx_secure_tls_handshake_hash_init(tls_session);
293     }
294 
295     /* Process the message itself information from the header. */
296     switch (message_type)
297     {
298     case NX_SECURE_TLS_CLIENT_HELLO:
299         /* Client is establishing a TLS session with our server. */
300         status = _nx_secure_dtls_process_clienthello(dtls_session, packet_buffer, message_length);
301 
302         /* This is the end of a flight, clear out the transmit queue. */
303         _nx_secure_dtls_retransmit_queue_flush(dtls_session);
304         break;
305 #ifdef NX_SECURE_ENABLE_CLIENT_CERTIFICATE_VERIFY
306     case NX_SECURE_TLS_CERTIFICATE_MSG:
307         /* Client sent certificate message (in response to a request from us. Process it now. */
308         status = _nx_secure_tls_process_remote_certificate(tls_session, packet_buffer, message_length, message_length);
309         tls_session -> nx_secure_tls_server_state = NX_SECURE_TLS_SERVER_STATE_CLIENT_CERTIFICATE;
310         break;
311     case NX_SECURE_TLS_CERTIFICATE_VERIFY:
312         /* Client has responded to a certificate request with a CertificateVerify message. */
313         status = _nx_secure_tls_process_certificate_verify(tls_session, packet_buffer, message_length);
314 
315         if(status == NX_SUCCESS)
316         {
317             /* If remote certificate verification was a success, we have received credentials
318                from the remote host and may now pass Finished message processing once received. */
319             tls_session -> nx_secure_tls_received_remote_credentials = NX_TRUE;
320         }
321 
322         tls_session -> nx_secure_tls_server_state = NX_SECURE_TLS_SERVER_STATE_CERTIFICATE_VERIFY;
323         break;
324 #endif /* NX_SECURE_ENABLE_CLIENT_CERTIFICATE_VERIFY */
325     case NX_SECURE_TLS_CLIENT_KEY_EXCHANGE:
326         /* Received a client key exchange message, meaning it is time to generate keys if we can. */
327         status = _nx_secure_tls_process_client_key_exchange(tls_session, packet_buffer, message_length, NX_SECURE_DTLS);
328         tls_session -> nx_secure_tls_server_state = NX_SECURE_TLS_SERVER_STATE_KEY_EXCHANGE;
329 
330         if (status == NX_SECURE_TLS_SUCCESS)
331         {
332             /* Generate our key material from the data collected thus far and put it all into our
333                socket structure. */
334             status = _nx_secure_tls_generate_keys(tls_session);
335         }
336         break;
337     case NX_SECURE_TLS_FINISHED:
338         /* Final handshake message from the client, process it (verify the client handshake hash). */
339         status = _nx_secure_tls_process_finished(tls_session, packet_buffer, message_length);
340         tls_session -> nx_secure_tls_server_state = NX_SECURE_TLS_SERVER_STATE_FINISH_HANDSHAKE;
341 
342         /* This is the end of a flight, clear out the transmit queue. */
343         _nx_secure_dtls_retransmit_queue_flush(dtls_session);
344         break;
345     case NX_SECURE_TLS_HELLO_VERIFY_REQUEST:
346     case NX_SECURE_TLS_HELLO_REQUEST:
347     case NX_SECURE_TLS_SERVER_HELLO:
348     case NX_SECURE_TLS_SERVER_KEY_EXCHANGE:
349     case NX_SECURE_TLS_CERTIFICATE_REQUEST:
350     case NX_SECURE_TLS_SERVER_HELLO_DONE:
351     case NX_SECURE_TLS_CERTIFICATE_URL:
352     case NX_SECURE_TLS_CERTIFICATE_STATUS:
353     default:
354         /* The message received was not a valid TLS server handshake message, send alert and return. */
355         status = NX_SECURE_TLS_UNEXPECTED_MESSAGE;
356         break;
357     }
358 
359     /* Check for errors in processing messages. */
360     if (status != NX_SECURE_TLS_SUCCESS)
361     {
362 
363         return(status);
364     }
365 
366     /* Hash this handshake message. We do not hash HelloRequest messages, but since only the server will send them,
367        we do not worry about them here because these are only messages received from the client at this point.
368        Hashes include the handshake layer header but not the record layer header. */
369     _nx_secure_tls_handshake_hash_update(tls_session, packet_start, (UINT)(message_length + header_bytes));
370 
371     /* Now take any actions based on state set in the message processing. */
372     switch (tls_session -> nx_secure_tls_server_state)
373     {
374     case NX_SECURE_TLS_SERVER_STATE_ALERT_SENT:
375         /* This means an error was encountered at some point in processing a valid message. At this point
376            the alert was sent, so just return a status indicating as much. */
377         return(NX_SECURE_TLS_HANDSHAKE_FAILURE);
378         break;
379     case NX_SECURE_TLS_SERVER_STATE_SEND_HELLO_VERIFY:
380         /* We have received and processed a client hello. Now respond to the client appropriately. */
381         status = _nx_secure_dtls_allocate_handshake_packet(dtls_session, packet_pool, &send_packet, wait_option);
382 
383         if (status != NX_SUCCESS)
384         {
385             break;
386         }
387 
388         _nx_secure_dtls_send_helloverifyrequest(dtls_session, send_packet);
389         status = _nx_secure_dtls_send_handshake_record(dtls_session, send_packet, NX_SECURE_TLS_HELLO_VERIFY_REQUEST, wait_option, 1);
390 
391         if (status != NX_SUCCESS)
392         {
393             break;
394         }
395 
396         if (!dtls_session -> nx_secure_dtls_tls_session.nx_secure_tls_local_session_active)
397         {
398 
399             /* Ignore the protocol version in a ClientHello without cookies. */
400             dtls_session -> nx_secure_dtls_tls_session.nx_secure_tls_protocol_version = 0;
401         }
402 
403         break;
404     case NX_SECURE_TLS_SERVER_STATE_SEND_HELLO:
405         /* We have received and processed a client hello. Now respond to the client appropriately. */
406         status = _nx_secure_dtls_allocate_handshake_packet(dtls_session, packet_pool, &send_packet, wait_option);
407 
408         if (status != NX_SUCCESS)
409         {
410             break;
411         }
412 
413         _nx_secure_dtls_send_serverhello(dtls_session, send_packet);
414         status = _nx_secure_dtls_send_handshake_record(dtls_session, send_packet, NX_SECURE_TLS_SERVER_HELLO, wait_option, 1);
415 
416         if (status != NX_SUCCESS)
417         {
418             break;
419         }
420 
421         /* For PSK and ECJPAKE ciphersuites, don't send the certificate message. */
422         if (tls_session -> nx_secure_tls_session_ciphersuite -> nx_secure_tls_public_auth -> nx_crypto_algorithm != NX_CRYPTO_KEY_EXCHANGE_PSK &&
423             tls_session -> nx_secure_tls_session_ciphersuite -> nx_secure_tls_public_auth -> nx_crypto_algorithm != NX_CRYPTO_KEY_EXCHANGE_ECJPAKE)
424         {
425             status = _nx_secure_dtls_allocate_handshake_packet(dtls_session, packet_pool, &send_packet, wait_option);
426 
427             if (status != NX_SUCCESS)
428             {
429                 break;
430             }
431 
432             _nx_secure_tls_send_certificate(tls_session, send_packet, wait_option);
433             status = _nx_secure_dtls_send_handshake_record(dtls_session, send_packet, NX_SECURE_TLS_CERTIFICATE_MSG, wait_option, 1);
434             if (status != NX_SUCCESS)
435             {
436                 break;
437             }
438         }
439 
440 #if defined(NX_SECURE_ENABLE_PSK_CIPHERSUITES) || defined(NX_SECURE_ENABLE_ECJPAKE_CIPHERSUITE) || defined(NX_SECURE_ENABLE_ECC_CIPHERSUITE)
441         if (tls_session -> nx_secure_tls_session_ciphersuite -> nx_secure_tls_public_auth -> nx_crypto_algorithm == NX_CRYPTO_KEY_EXCHANGE_PSK ||
442             tls_session -> nx_secure_tls_session_ciphersuite -> nx_secure_tls_public_auth -> nx_crypto_algorithm == NX_CRYPTO_KEY_EXCHANGE_ECJPAKE ||
443             tls_session -> nx_secure_tls_session_ciphersuite -> nx_secure_tls_public_cipher -> nx_crypto_algorithm == NX_CRYPTO_KEY_EXCHANGE_ECDHE)
444         {
445             /* PSK or ECJPAKE ciphersuites use the ServerKeyExchange message to send cryptographic information. */
446             status = _nx_secure_dtls_allocate_handshake_packet(dtls_session, packet_pool, &send_packet, wait_option);
447 
448             if (status != NX_SUCCESS)
449             {
450                 break;
451             }
452 
453             /* This is a PSK or ECJPAKE ciphersuite so we always send a ServerKeyExchange message. */
454             status = _nx_secure_tls_send_server_key_exchange(tls_session, send_packet);
455             if (status != NX_SUCCESS)
456             {
457                 break;
458             }
459 
460             status = _nx_secure_dtls_send_handshake_record(dtls_session, send_packet, NX_SECURE_TLS_SERVER_KEY_EXCHANGE, wait_option, 1);
461             if (status != NX_SUCCESS)
462             {
463                 break;
464             }
465         }
466 #endif
467 
468 #ifdef NX_SECURE_ENABLE_CLIENT_CERTIFICATE_VERIFY
469         /* Application has requested that we request and verify the remote Client certificate. */
470         if (tls_session -> nx_secure_tls_verify_client_certificate)
471         {
472             /* Allocate a packet for our certificate request message.  */
473             status = _nx_secure_dtls_allocate_handshake_packet(dtls_session, packet_pool, &send_packet, wait_option);
474 
475             if (status != NX_SUCCESS)
476             {
477                 break;
478             }
479 
480             /* Populate our packet with the desired message (CertificateRequest). */
481             status = _nx_secure_tls_send_certificate_request(tls_session, send_packet);
482             NX_ASSERT(status == NX_SUCCESS);
483 
484             status = _nx_secure_dtls_send_handshake_record(dtls_session, send_packet, NX_SECURE_TLS_CERTIFICATE_REQUEST, wait_option, 1);
485             if (status != NX_SUCCESS)
486             {
487                 break;
488             }
489         }
490         else
491 #endif
492         {
493             /* Server is not expecting credentials, so indicate that we have received the client's credentials
494                to pass Finished processing. */
495             tls_session -> nx_secure_tls_received_remote_credentials = NX_TRUE;
496         }
497 
498         status = _nx_secure_dtls_allocate_handshake_packet(dtls_session, packet_pool, &send_packet, wait_option);
499 
500         if (status != NX_SUCCESS)
501         {
502             break;
503         }
504 
505         /* Server hello done message is 0 bytes, but it still has a TLS header so don't modify the length here. */
506         status = _nx_secure_dtls_send_handshake_record(dtls_session, send_packet, NX_SECURE_TLS_SERVER_HELLO_DONE, wait_option, 1);
507 
508         if (status != NX_SUCCESS)
509         {
510             break;
511         }
512 
513 
514         tls_session -> nx_secure_tls_server_state = NX_SECURE_TLS_SERVER_STATE_HELLO_SENT;
515 
516         break;
517     case NX_SECURE_TLS_SERVER_STATE_CLIENT_CERTIFICATE:
518         /* We processed the certificate above, do nothing. */
519         break;
520     case NX_SECURE_TLS_SERVER_STATE_CERTIFICATE_VERIFY:
521         /* We processed the certificate above, do nothing. */
522         break;
523     case NX_SECURE_TLS_SERVER_STATE_HELLO_SENT:
524         /* We sent a serverhellodone message, but we haven't received the next client message - this
525            is likely an error.  */
526         break;
527     case NX_SECURE_TLS_SERVER_STATE_KEY_EXCHANGE:
528         break;
529     case NX_SECURE_TLS_SERVER_STATE_FINISH_HANDSHAKE:
530         /* Release the protection before suspending on nx_packet_allocate. */
531         tx_mutex_put(&_nx_secure_tls_protection);
532 
533         /* We have received everything we need to complete the handshake and keys have been
534          * generated above. Now end the handshake with a ChangeCipherSpec (indicating following
535          * messages are encrypted) and the encrypted Finished message. */
536 
537         status = _nx_secure_dtls_packet_allocate(dtls_session, packet_pool, &send_packet, wait_option);
538 
539         /* Get the protection after nx_packet_allocate. */
540         tx_mutex_get(&_nx_secure_tls_protection, TX_WAIT_FOREVER);
541 
542         if (status != NX_SUCCESS)
543         {
544             break;
545         }
546 
547         _nx_secure_tls_send_changecipherspec(tls_session, send_packet);
548 
549         /* ChangeCipherSpec is NOT a handshake message, so send as a normal TLS record. */
550         status = _nx_secure_dtls_send_record(dtls_session, send_packet, NX_SECURE_TLS_CHANGE_CIPHER_SPEC, wait_option);
551 
552         if (status != NX_SUCCESS)
553         {
554             break;
555         }
556 
557         /* The local session is now active since we sent the changecipherspec message.
558            NOTE: Do not set this flag until after the changecipherspec message has been passed to the send record
559            routine - this flag causes encryption and hashing to happen on records. ChangeCipherSpec should be the last
560            un-encrypted/un-hashed record sent. */
561         tls_session -> nx_secure_tls_local_session_active = 1;
562 
563         /* For DTLS, reset sequence number and advance epoch right after CCS message is sent. */
564         NX_SECURE_MEMSET(tls_session -> nx_secure_tls_local_sequence_number, 0, sizeof(tls_session -> nx_secure_tls_local_sequence_number));
565 
566         status = _nx_secure_tls_session_keys_set(tls_session, NX_SECURE_TLS_KEY_SET_LOCAL);
567 
568         if (status != NX_SUCCESS)
569         {
570             break;
571         }
572 
573         /* Advance the DTLS epoch - all messages after the ChangeCipherSpec are in a new epoch. */
574         dtls_session -> nx_secure_dtls_local_epoch = (USHORT)(dtls_session -> nx_secure_dtls_local_epoch + 1);
575 
576         /* We processed the incoming finished message above, so now we can send our own finished message. */
577         status = _nx_secure_dtls_allocate_handshake_packet(dtls_session, packet_pool, &send_packet, wait_option);
578         if (status != NX_SUCCESS)
579         {
580             break;
581         }
582 
583         _nx_secure_tls_send_finished(tls_session, send_packet);
584         status = _nx_secure_dtls_send_handshake_record(dtls_session, send_packet, NX_SECURE_TLS_FINISHED, wait_option, 1);
585 
586 
587         tls_session -> nx_secure_tls_server_state = NX_SECURE_TLS_SERVER_STATE_HANDSHAKE_FINISHED;
588 
589         /* Check if application data is received before state change to NX_SECURE_TLS_SERVER_STATE_HANDSHAKE_FINISHED.  */
590         if (dtls_session -> nx_secure_dtls_receive_queue_head)
591         {
592 
593             /* Notify application.  */
594             dtls_session -> nx_secure_dtls_server_parent -> nx_secure_dtls_receive_notify(dtls_session);
595         }
596 
597         break;
598     case NX_SECURE_TLS_SERVER_STATE_HANDSHAKE_FINISHED:
599         /* Handshake is complete. */
600         break;
601     default:
602         status = NX_SECURE_TLS_INVALID_STATE;
603     }
604 
605 
606     return(status);
607 #else /* TLS Server disabled. */
608 
609     /* We don't use the parameters since this is an error case. */
610     NX_PARAMETER_NOT_USED(packet_buffer);
611     NX_PARAMETER_NOT_USED(wait_option);
612 
613     /* If TLS Server is disabled and we are in the server state machine, something is wrong... */
614     dtls_session -> nx_secure_dtls_tls_session.nx_secure_tls_client_state = NX_SECURE_TLS_CLIENT_STATE_ERROR;
615     return(NX_SECURE_TLS_INVALID_STATE);
616 #endif
617 }
618 #endif /* NX_SECURE_ENABLE_DTLS */
619 
620