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