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