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