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