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 /**    Transport Layer Security (TLS)                                     */
19 /**                                                                       */
20 /**************************************************************************/
21 /**************************************************************************/
22 
23 #define NX_SECURE_SOURCE_CODE
24 
25 #include "nx_secure_tls.h"
26 
27 /**************************************************************************/
28 /*                                                                        */
29 /*  FUNCTION                                               RELEASE        */
30 /*                                                                        */
31 /*    _nx_secure_tls_session_start                        PORTABLE C      */
32 /*                                                           6.2.0        */
33 /*  AUTHOR                                                                */
34 /*                                                                        */
35 /*    Timothy Stapko, Microsoft Corporation                               */
36 /*                                                                        */
37 /*  DESCRIPTION                                                           */
38 /*                                                                        */
39 /*    This function starts a TLS session given a TCP socket. The TCP      */
40 /*    connection must be established before calling this function,        */
41 /*    or the TLS handshake will fail.                                     */
42 /*                                                                        */
43 /*    The type of TLS session is derived automatically from the TCP       */
44 /*    socket, which must have gone through a successful call to           */
45 /*    either nx_tcp_client_socket_connect or nx_tcp_server_socket_accept. */
46 /*                                                                        */
47 /*  INPUT                                                                 */
48 /*                                                                        */
49 /*    tls_session                           TLS control block             */
50 /*    tcp_socket                            TCP socket pointer            */
51 /*    wait_option                           Suspension option             */
52 /*                                                                        */
53 /*  OUTPUT                                                                */
54 /*                                                                        */
55 /*    status                                Completion status             */
56 /*                                                                        */
57 /*  CALLS                                                                 */
58 /*                                                                        */
59 /*    _nx_secure_tls_allocate_handshake_packet                            */
60 /*                                          Allocate TLS packet           */
61 /*    _nx_secure_tls_handshake_process      Process TLS handshake         */
62 /*    _nx_secure_tls_send_clienthello       Send ClientHello              */
63 /*    _nx_secure_tls_send_handshake_record  Send TLS handshake record     */
64 /*    nx_secure_tls_packet_release          Release packet                */
65 /*    tx_mutex_get                          Get protection mutex          */
66 /*    tx_mutex_put                          Put protection mutex          */
67 /*                                                                        */
68 /*  CALLED BY                                                             */
69 /*                                                                        */
70 /*    Application Code                                                    */
71 /*                                                                        */
72 /*  RELEASE HISTORY                                                       */
73 /*                                                                        */
74 /*    DATE              NAME                      DESCRIPTION             */
75 /*                                                                        */
76 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
77 /*  09-30-2020     Timothy Stapko           Modified comment(s),          */
78 /*                                            supported chained packet,   */
79 /*                                            resulting in version 6.1    */
80 /*  04-25-2022     Yuxin Zhou               Modified comment(s), removed  */
81 /*                                            internal unreachable logic, */
82 /*                                            resulting in version 6.1.11 */
83 /*  10-31-2022     Yanwu Cai                Modified comment(s), added    */
84 /*                                            custom packet pool support, */
85 /*                                            resulting in version 6.2.0  */
86 /*                                                                        */
87 /**************************************************************************/
_nx_secure_tls_session_start(NX_SECURE_TLS_SESSION * tls_session,NX_TCP_SOCKET * tcp_socket,UINT wait_option)88 UINT _nx_secure_tls_session_start(NX_SECURE_TLS_SESSION *tls_session, NX_TCP_SOCKET *tcp_socket,
89                                   UINT wait_option)
90 {
91 UINT       status = NX_NOT_SUCCESSFUL;
92 UINT       error_return;
93 #ifndef NX_SECURE_TLS_CLIENT_DISABLED
94 NX_PACKET *send_packet;
95 #endif
96 
97     /* Get the protection. */
98     tx_mutex_get(&_nx_secure_tls_protection, TX_WAIT_FOREVER);
99 
100     if (!tls_session -> nx_secure_tls_packet_pool)
101     {
102         /* Assign the packet pool from which TLS will allocate internal message packets. */
103         tls_session -> nx_secure_tls_packet_pool = tcp_socket -> nx_tcp_socket_ip_ptr -> nx_ip_default_packet_pool;
104     }
105 
106     /* Assign the TCP socket to the TLS session. */
107     tls_session -> nx_secure_tls_tcp_socket = tcp_socket;
108 
109     /* Reset the record queue. */
110     tls_session -> nx_secure_record_queue_header = NX_NULL;
111     tls_session -> nx_secure_record_decrypted_packet = NX_NULL;
112 
113     /* Make sure we are starting with a fresh session. */
114     tls_session -> nx_secure_tls_local_session_active = 0;
115     tls_session -> nx_secure_tls_remote_session_active = 0;
116     tls_session -> nx_secure_tls_received_remote_credentials = NX_FALSE;
117 
118     /* Reset alert tracking. */
119     tls_session -> nx_secure_tls_received_alert_level = 0;
120     tls_session -> nx_secure_tls_received_alert_value = 0;
121 
122 
123     /* See if this is a TCP server started with listen/accept, or a TCP client started with connect. */
124     if (tcp_socket -> nx_tcp_socket_client_type)
125     {
126         /* The TCP socket is a client, so our TLS session is a TLS Client. */
127         tls_session -> nx_secure_tls_socket_type = NX_SECURE_TLS_SESSION_TYPE_CLIENT;
128     }
129     else
130     {
131         /* This session is now being treated as a server - indicate that fact to the TLS stack. */
132         tls_session -> nx_secure_tls_socket_type = NX_SECURE_TLS_SESSION_TYPE_SERVER;
133     }
134 
135 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
136     /* Initialize TLS 1.3 cryptographic primitives. */
137     if(tls_session->nx_secure_tls_1_3)
138     {
139         status = _nx_secure_tls_1_3_crypto_init(tls_session);
140 
141         if(status != NX_SUCCESS)
142         {
143 
144             /* Release the protection. */
145             tx_mutex_put(&_nx_secure_tls_protection);
146             return(status);
147         }
148     }
149 #endif
150 
151     /* Now process the handshake depending on the TLS session type. */
152 #ifndef NX_SECURE_TLS_CLIENT_DISABLED
153     if (tls_session -> nx_secure_tls_socket_type == NX_SECURE_TLS_SESSION_TYPE_CLIENT)
154     {
155 
156         /* Allocate a handshake packet so we can send the ClientHello. */
157         status = _nx_secure_tls_allocate_handshake_packet(tls_session, tls_session -> nx_secure_tls_packet_pool, &send_packet, wait_option);
158 
159         if (status != NX_SUCCESS)
160         {
161 
162             /* Release the protection. */
163             tx_mutex_put(&_nx_secure_tls_protection);
164             return(status);
165         }
166 
167         /* Populate our packet with clienthello data. */
168         status = _nx_secure_tls_send_clienthello(tls_session, send_packet);
169 
170         if (status == NX_SUCCESS)
171         {
172 
173             /* Send the ClientHello to kick things off. */
174             status = _nx_secure_tls_send_handshake_record(tls_session, send_packet, NX_SECURE_TLS_CLIENT_HELLO, wait_option);
175         }
176 
177         /* If anything after the allocate fails, we need to release our packet. */
178         if (status != NX_SUCCESS)
179         {
180 
181             /* Release the protection. */
182             tx_mutex_put(&_nx_secure_tls_protection);
183             nx_secure_tls_packet_release(send_packet);
184             return(status);
185         }
186     }
187 #endif
188 
189     /* Release the protection. */
190     tx_mutex_put(&_nx_secure_tls_protection);
191 
192     /* Now handle our incoming handshake messages. Continue processing until the handshake is complete
193        or an error/timeout occurs. */
194     status = _nx_secure_tls_handshake_process(tls_session, wait_option);
195 
196     if (status == NX_CONTINUE)
197     {
198 
199         /* It is non blocking mode. */
200         return(NX_CONTINUE);
201     }
202 
203     if(status != NX_SUCCESS)
204     {
205         /* Save the return status before resetting the TLS session. */
206         error_return = status;
207 
208         /* Reset the TLS state so this socket can be reused. */
209         status = _nx_secure_tls_session_reset(tls_session);
210 
211         if(status != NX_SUCCESS)
212         {
213             return(status);
214         }
215 
216         return(error_return);
217     }
218 
219     return(status);
220 }
221 
222