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