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