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