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 #define NX_SECURE_SOURCE_CODE
22 #include "nx_secure_tls.h"
23
24 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
25 /* Defined in nx_secure_tls_send_serverhello.c */
26 extern const UCHAR _nx_secure_tls_hello_retry_request_random[32];
27 #endif
28
29 /**************************************************************************/
30 /* */
31 /* FUNCTION RELEASE */
32 /* */
33 /* _nx_secure_tls_process_serverhello PORTABLE C */
34 /* 6.2.0 */
35 /* AUTHOR */
36 /* */
37 /* Timothy Stapko, Microsoft Corporation */
38 /* */
39 /* DESCRIPTION */
40 /* */
41 /* This function processes an incoming ServerHello message, which is */
42 /* the response to a TLS ClientHello coming from this host. The */
43 /* ServerHello message contains the desired ciphersuite and data used */
44 /* in the key generation process later in the handshake. */
45 /* */
46 /* INPUT */
47 /* */
48 /* tls_session TLS control block */
49 /* packet_buffer Pointer to message data */
50 /* message_length Length of message data (bytes)*/
51 /* */
52 /* OUTPUT */
53 /* */
54 /* status Completion status */
55 /* */
56 /* CALLS */
57 /* */
58 /* _nx_secure_tls_check_protocol_version Checking incoming TLS version */
59 /* _nx_secure_tls_ciphersuite_lookup Lookup current ciphersuite */
60 /* _nx_secure_tls_process_serverhello_extensions */
61 /* Process ServerHello extensions*/
62 /* [nx_secure_tls_session_client_callback */
63 /* Client session callback */
64 /* */
65 /* CALLED BY */
66 /* */
67 /* _nx_secure_dtls_client_handshake DTLS client state machine */
68 /* _nx_secure_tls_client_handshake TLS client state machine */
69 /* */
70 /* RELEASE HISTORY */
71 /* */
72 /* DATE NAME DESCRIPTION */
73 /* */
74 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
75 /* 09-30-2020 Timothy Stapko Modified comment(s), added */
76 /* priority ciphersuite logic, */
77 /* verified memcpy use cases, */
78 /* fixed renegotiation bug, */
79 /* resulting in version 6.1 */
80 /* 10-15-2021 Timothy Stapko Modified comment(s), fixed */
81 /* TLS 1.3 compilation issue, */
82 /* resulting in version 6.1.9 */
83 /* 10-31-2022 Yanwu Cai Modified comment(s), fixed */
84 /* TLS 1.3 version negotiation,*/
85 /* resulting in version 6.2.0 */
86 /* */
87 /**************************************************************************/
_nx_secure_tls_process_serverhello(NX_SECURE_TLS_SESSION * tls_session,UCHAR * packet_buffer,UINT message_length)88 UINT _nx_secure_tls_process_serverhello(NX_SECURE_TLS_SESSION *tls_session, UCHAR *packet_buffer,
89 UINT message_length)
90 {
91 #ifndef NX_SECURE_TLS_CLIENT_DISABLED
92 UINT length;
93 UCHAR compression_method;
94 USHORT version, total_extensions_length;
95 UINT status;
96 USHORT ciphersuite;
97 USHORT ciphersuite_priority;
98 NX_SECURE_TLS_HELLO_EXTENSION extension_data[NX_SECURE_TLS_HELLO_EXTENSIONS_MAX];
99 UINT num_extensions;
100 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
101 USHORT tls_1_3 = tls_session -> nx_secure_tls_1_3;
102 USHORT no_extension = NX_FALSE;
103 NX_SECURE_TLS_SERVER_STATE old_client_state = tls_session -> nx_secure_tls_client_state;
104
105 tls_session -> nx_secure_tls_client_state = NX_SECURE_TLS_CLIENT_STATE_IDLE;
106 #endif
107
108 /* Parse the ServerHello message.
109 * Structure:
110 * | 2 | 4 + 28 | 1 | <SID len> | 2 | 1 | 2 | <Ext. Len> |
111 * | TLS version | Random (time + random) | SID length | Session ID | Ciphersuite | Compression | Ext. Len | Extensions |
112 */
113
114 if (message_length < 38)
115 {
116 /* Message was not the minimum required size for a ServerHello. */
117 return(NX_SECURE_TLS_INCORRECT_MESSAGE_LENGTH);
118 }
119
120 /* Use our length as an index into the buffer. */
121 length = 0;
122
123 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
124 if (tls_session -> nx_secure_tls_1_3 && tls_session -> nx_secure_tls_local_session_active)
125 {
126
127 /* Client has negotiated TLS 1.3 and receives a ServerHello again.
128 * Send an unexpected message alert. */
129 return(NX_SECURE_TLS_UNEXPECTED_MESSAGE);
130 }
131 #endif
132
133 /* First two bytes of the server hello following the header are the TLS major and minor version numbers. */
134 version = (USHORT)((packet_buffer[length] << 8) + packet_buffer[length + 1]);
135 length += 2;
136 /* Verify the version coming from the server. */
137 status = _nx_secure_tls_check_protocol_version(tls_session, version, NX_SECURE_TLS);
138 if (status != NX_SUCCESS)
139 {
140 return(status);
141 }
142
143 /* Set the protocol version to whatever the Server negotiated - we have checked that
144 we support this version in the call above, so it's fine to continue. */
145 tls_session -> nx_secure_tls_protocol_version = version;
146
147 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
148 if (tls_session -> nx_secure_tls_1_3 &&
149 (NX_SECURE_MEMCMP(_nx_secure_tls_hello_retry_request_random, &packet_buffer[length], NX_SECURE_TLS_RANDOM_SIZE) == 0))
150 {
151
152 /* A HelloRetryRequest is received. */
153 if (old_client_state == NX_SECURE_TLS_CLIENT_STATE_HELLO_RETRY)
154 {
155
156 /* A second HelloRetryRequest is received. */
157 return(NX_SECURE_TLS_UNRECOGNIZED_MESSAGE_TYPE);
158 }
159 else
160 {
161 tls_session -> nx_secure_tls_client_state = NX_SECURE_TLS_CLIENT_STATE_HELLO_RETRY;
162 }
163 }
164 else
165 #endif
166 {
167
168 /* Set the Server random data, used in key generation. First 4 bytes is GMT time. */
169 NX_SECURE_MEMCPY(&tls_session -> nx_secure_tls_key_material.nx_secure_tls_server_random[0], &packet_buffer[length], NX_SECURE_TLS_RANDOM_SIZE); /* Use case of memcpy is verified. lgtm[cpp/banned-api-usage-required-any] */
170 }
171 length += NX_SECURE_TLS_RANDOM_SIZE;
172
173 /* Session ID length is one byte. */
174 tls_session -> nx_secure_tls_session_id_length = packet_buffer[length];
175 length++;
176
177 if ((length + tls_session -> nx_secure_tls_session_id_length) > message_length)
178 {
179 return(NX_SECURE_TLS_INCORRECT_MESSAGE_LENGTH);
180 }
181
182 /* Session ID follows. */
183 if (tls_session -> nx_secure_tls_session_id_length > 0)
184 {
185 NX_SECURE_MEMCPY(tls_session -> nx_secure_tls_session_id, &packet_buffer[length], tls_session -> nx_secure_tls_session_id_length); /* Use case of memcpy is verified. lgtm[cpp/banned-api-usage-required-any] */
186 length += tls_session -> nx_secure_tls_session_id_length;
187 }
188
189 /* Finally, the chosen ciphersuite - this is selected by the server from the list we provided in the ClientHello. */
190 ciphersuite = (USHORT)((packet_buffer[length] << 8) + packet_buffer[length + 1]);
191 length += 2;
192
193 /* Find out the ciphersuite info of the chosen ciphersuite. */
194 status = _nx_secure_tls_ciphersuite_lookup(tls_session, ciphersuite, &tls_session -> nx_secure_tls_session_ciphersuite, &ciphersuite_priority);
195 if (status != NX_SUCCESS)
196 {
197 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
198 if (tls_session -> nx_secure_tls_1_3)
199 {
200 return(NX_SECURE_TLS_1_3_UNKNOWN_CIPHERSUITE);
201 }
202 #endif
203
204 return(NX_SECURE_TLS_UNKNOWN_CIPHERSUITE);
205 }
206
207 /* Compression method - for now this should be NULL. */
208 compression_method = packet_buffer[length];
209
210 /* There are no supported compression methods, so non-zero is an error. */
211 if (compression_method != 0x00)
212 {
213 return(NX_SECURE_TLS_BAD_COMPRESSION_METHOD);
214 }
215 length++;
216
217 /* Padding data? */
218 if (message_length >= (length + 2))
219 {
220
221 /* TLS Extensions come next. Get the total length of all extensions first. */
222 total_extensions_length = (USHORT)((packet_buffer[length] << 8) + packet_buffer[length + 1]);
223 length += 2;
224
225 /* Message length overflow. */
226 if ((length + total_extensions_length) > message_length)
227 {
228 return(NX_SECURE_TLS_INCORRECT_MESSAGE_LENGTH);
229 }
230
231 if (total_extensions_length > 0)
232 {
233
234 /* Process serverhello extensions. */
235 status = _nx_secure_tls_process_serverhello_extensions(tls_session, &packet_buffer[length], total_extensions_length, extension_data, &num_extensions);
236
237 /* Check for error. */
238 if (status != NX_SUCCESS)
239 {
240 return(status);
241 }
242
243 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
244 if (tls_session -> nx_secure_tls_1_3 != tls_1_3)
245 {
246
247 /* Server negotiates a version of TLS prior to TLS 1.3. */
248 return(status);
249 }
250 #endif
251
252 /* If the server callback is set, invoke it now with the extensions that require application input. */
253 if (tls_session -> nx_secure_tls_session_client_callback != NX_NULL)
254 {
255 status = tls_session -> nx_secure_tls_session_client_callback(tls_session, extension_data, num_extensions);
256
257 /* Check for error. */
258 if (status != NX_SUCCESS)
259 {
260 return(status);
261 }
262 }
263 }
264 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
265 else
266 {
267 no_extension = NX_TRUE;
268 }
269 #endif
270 }
271 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
272 else
273 {
274 no_extension = NX_TRUE;
275 }
276
277 if ((tls_session -> nx_secure_tls_1_3) && (no_extension == NX_TRUE))
278 {
279
280 /* Server negotiates a version of TLS prior to TLS 1.3. */
281 if (tls_session -> nx_secure_tls_protocol_version_override == 0)
282 {
283 tls_session -> nx_secure_tls_1_3 = NX_FALSE;
284 #ifndef NX_SECURE_TLS_DISABLE_SECURE_RENEGOTIATION
285 tls_session -> nx_secure_tls_renegotation_enabled = NX_TRUE;
286 #endif /* NX_SECURE_TLS_DISABLE_SECURE_RENEGOTIATION */
287
288 return(NX_SUCCESS);
289 }
290 else
291 {
292
293 /* Protocol version is overridden to TLS 1.3. */
294 return(NX_SECURE_TLS_UNSUPPORTED_TLS_VERSION);
295 }
296
297 }
298 #endif
299
300 #ifndef NX_SECURE_TLS_DISABLE_SECURE_RENEGOTIATION
301 #ifdef NX_SECURE_TLS_REQUIRE_RENEGOTIATION_EXT
302 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
303 if (!tls_session -> nx_secure_tls_1_3)
304 #endif /* NX_SECURE_TLS_TLS_1_3_ENABLED */
305 {
306 if ((tls_session -> nx_secure_tls_renegotation_enabled) && (!tls_session -> nx_secure_tls_secure_renegotiation))
307 {
308
309 /* No "renegotiation_info" extension present, some clients may want to terminate the handshake. */
310 return(NX_SECURE_TLS_RENEGOTIATION_EXTENSION_ERROR);
311 }
312 }
313 #endif /* NX_SECURE_TLS_REQUIRE_RENEGOTIATION_EXT */
314
315 if ((tls_session -> nx_secure_tls_local_session_active) && (!tls_session -> nx_secure_tls_secure_renegotiation_verified))
316 {
317
318 /* The client did not receive the "renegotiation_info" extension, the handshake must be aborted. */
319 return(NX_SECURE_TLS_RENEGOTIATION_EXTENSION_ERROR);
320 }
321
322 tls_session -> nx_secure_tls_secure_renegotiation_verified = NX_FALSE;
323 #endif /* NX_SECURE_TLS_DISABLE_SECURE_RENEGOTIATION */
324
325 #ifdef NX_SECURE_TLS_CLIENT_DISABLED
326 /* If TLS Client is disabled and we have processed a ServerHello, something is wrong... */
327 tls_session -> nx_secure_tls_server_state = NX_SECURE_TLS_SERVER_STATE_ERROR;
328
329 return(NX_SECURE_TLS_INVALID_STATE);
330 #else
331
332 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
333 if ((tls_session -> nx_secure_tls_1_3) && (old_client_state == NX_SECURE_TLS_CLIENT_STATE_IDLE))
334 {
335
336 /* We have selected a ciphersuite so now we can initialize the handshake hash. */
337 status = _nx_secure_tls_handshake_hash_init(tls_session);
338
339 if(status != NX_SUCCESS)
340 {
341 return(status);
342 }
343 }
344
345 if (tls_session -> nx_secure_tls_client_state != NX_SECURE_TLS_CLIENT_STATE_HELLO_RETRY)
346 #endif
347 {
348
349 /* Set our state to indicate we sucessfully parsed the ServerHello. */
350 tls_session -> nx_secure_tls_client_state = NX_SECURE_TLS_CLIENT_STATE_SERVERHELLO;
351 }
352
353 return(NX_SUCCESS);
354 #endif
355 #else /* NX_SECURE_TLS_SERVER_DISABLED */
356 /* If Server TLS is disabled and we recieve a serverhello, error! */
357 NX_PARAMETER_NOT_USED(tls_session);
358 NX_PARAMETER_NOT_USED(packet_buffer);
359 NX_PARAMETER_NOT_USED(message_length);
360
361 return(NX_SECURE_TLS_UNEXPECTED_MESSAGE);
362 #endif
363 }
364
365