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 #if defined(NX_SECURE_ENABLE_ECC_CIPHERSUITE) && !defined(NX_SECURE_DISABLE_X509)
28 static UINT _nx_secure_tls_check_ciphersuite(const NX_SECURE_TLS_CIPHERSUITE_INFO *ciphersuite_info,
29                                              NX_SECURE_X509_CERT *cert, UINT selected_curve,
30                                              UINT cert_curve_supported);
31 
32 #endif /* NX_SECURE_ENABLE_ECC_CIPHERSUITE && !NX_SECURE_DISABLE_X509 */
33 
34 /**************************************************************************/
35 /*                                                                        */
36 /*  FUNCTION                                               RELEASE        */
37 /*                                                                        */
38 /*    _nx_secure_tls_process_clienthello                  PORTABLE C      */
39 /*                                                           6.2.1        */
40 /*  AUTHOR                                                                */
41 /*                                                                        */
42 /*    Timothy Stapko, Microsoft Corporation                               */
43 /*                                                                        */
44 /*  DESCRIPTION                                                           */
45 /*                                                                        */
46 /*    This function processes an incoming ClientHello message from a      */
47 /*    remote host, kicking off a TLS handshake.                           */
48 /*                                                                        */
49 /*  INPUT                                                                 */
50 /*                                                                        */
51 /*    tls_session                           TLS control block             */
52 /*    packet_buffer                         Pointer to message data       */
53 /*    message_length                        Length of message data (bytes)*/
54 /*                                                                        */
55 /*  OUTPUT                                                                */
56 /*                                                                        */
57 /*    status                                Completion status             */
58 /*                                                                        */
59 /*  CALLS                                                                 */
60 /*                                                                        */
61 /*    _nx_secure_tls_ciphersuite_lookup     Lookup current ciphersuite    */
62 /*    _nx_secure_tls_check_protocol_version Check incoming TLS version    */
63 /*    _nx_secure_tls_newest_supported_version                             */
64 /*                                          Get newest TLS version        */
65 /*    _nx_secure_tls_process_clienthello_extensions                       */
66 /*                                          Process ClientHello extensions*/
67 /*    _nx_secure_tls_proc_clienthello_sec_sa_extension                    */
68 /*                                          Process ECC extensions        */
69 /*    _nx_secure_tls_check_ciphersuite      Check if ECC suite is usable  */
70 /*    _nx_secure_tls_remote_certificate_free_all                          */
71 /*                                          Free all remote certificates  */
72 /*    [_nx_secure_tls_session_renegotiate_callback_set]                   */
73 /*                                          Renegotiation callback        */
74 /*    [_nx_secure_tls_session_server_callback_set]                        */
75 /*                                          Server session callback       */
76 /*    _nx_secure_x509_local_device_certificate_get                        */
77 /*                                          Get the local certificate     */
78 /*                                                                        */
79 /*  CALLED BY                                                             */
80 /*                                                                        */
81 /*    _nx_secure_tls_server_handshake       TLS Server state machine      */
82 /*                                                                        */
83 /*  RELEASE HISTORY                                                       */
84 /*                                                                        */
85 /*    DATE              NAME                      DESCRIPTION             */
86 /*                                                                        */
87 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
88 /*  09-30-2020     Timothy Stapko           Modified comment(s), added    */
89 /*                                            priority ciphersuite logic, */
90 /*                                            verified memcpy use cases,  */
91 /*                                            fixed renegotiation bug,    */
92 /*                                            improved negotiation logic, */
93 /*                                            resulting in version 6.1    */
94 /*  10-15-2021     Timothy Stapko           Modified comment(s), added    */
95 /*                                            ability to disable client   */
96 /*                                            initiated renegotiation,    */
97 /*                                            resulting in version 6.1.9  */
98 /*  04-25-2022     Yuxin Zhou               Modified comment(s),  fixed   */
99 /*                                            the bug of processing       */
100 /*                                            extensions,                 */
101 /*                                            resulting in version 6.1.11 */
102 /*  10-31-2022     Yanwu Cai                Modified comment(s), fixed    */
103 /*                                            TLS 1.3 version negotiation,*/
104 /*                                            resulting in version 6.2.0  */
105 /*  03-08-2023     Yanwu Cai                Modified comment(s),          */
106 /*                                            fixed compiler errors when  */
107 /*                                            x509 is disabled,           */
108 /*                                            resulting in version 6.2.1  */
109 /*                                                                        */
110 /**************************************************************************/
_nx_secure_tls_process_clienthello(NX_SECURE_TLS_SESSION * tls_session,UCHAR * packet_buffer,UINT message_length)111 UINT _nx_secure_tls_process_clienthello(NX_SECURE_TLS_SESSION *tls_session, UCHAR *packet_buffer,
112                                         UINT message_length)
113 {
114 UINT                                  length;
115 USHORT                                ciphersuite_list_length;
116 UCHAR                                 compression_methods_length;
117 USHORT                                cipher_entry;
118 UCHAR                                 session_id_length;
119 UINT                                  i;
120 UINT                                  status;
121 USHORT                                protocol_version;
122 USHORT                                newest_version;
123 UINT                                  total_extensions_length;
124 const NX_SECURE_TLS_CIPHERSUITE_INFO *ciphersuite_info;
125 USHORT                                ciphersuite_priority;
126 USHORT                                new_ciphersuite_priority = 0;
127 NX_SECURE_TLS_HELLO_EXTENSION         extension_data[NX_SECURE_TLS_HELLO_EXTENSIONS_MAX];
128 UINT                                  num_extensions = NX_SECURE_TLS_HELLO_EXTENSIONS_MAX;
129 UCHAR                                *ciphersuite_list;
130 #if defined(NX_SECURE_ENABLE_ECC_CIPHERSUITE) && !defined(NX_SECURE_DISABLE_X509)
131 NX_SECURE_X509_CERT                  *cert;
132 UINT                                  selected_curve;
133 UINT                                  cert_curve;
134 UINT                                  cert_curve_supported;
135 NX_SECURE_EC_PUBLIC_KEY              *ec_pubkey;
136 NX_SECURE_TLS_ECDHE_HANDSHAKE_DATA   *ecdhe_data;
137 #endif /* NX_SECURE_ENABLE_ECC_CIPHERSUITE && !NX_SECURE_DISABLE_X509 */
138 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
139 USHORT                                tls_1_3 = tls_session -> nx_secure_tls_1_3;
140 USHORT                                no_extension = NX_FALSE;
141 #endif
142 
143     /* Structure of ClientHello:
144      * |     2       |          4 + 28          |    1       |   <SID len>  |   2    | <CS Len>     |    1    | <Comp Len>  |    2    | <Ext. Len> |
145      * | TLS version |  Random (time + random)  | SID length |  Session ID  | CS Len | Ciphersuites |Comp Len | Compression |Ext. Len | Extensions |
146      */
147 
148     if (message_length < 38)
149     {
150         /* Message was not the minimum required size for a ClientHello. */
151         return(NX_SECURE_TLS_INCORRECT_MESSAGE_LENGTH);
152     }
153 
154     /* Use our length as an index into the buffer. */
155     length = 0;
156 
157     /* If we are currently in a session, we have a renegotiation handshake. */
158     if (tls_session -> nx_secure_tls_local_session_active)
159     {
160 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
161         if (tls_session->nx_secure_tls_1_3 == NX_TRUE)
162         {
163 
164             /* RFC 8446, section 4.1.2, page 27.
165              * Server has negotiated TLS 1.3 and receives a ClientHello again.
166              * Send an unexpected message alert. */
167             return(NX_SECURE_TLS_UNEXPECTED_CLIENTHELLO);
168         }
169 #endif
170 
171 #if !defined(NX_SECURE_TLS_DISABLE_SECURE_RENEGOTIATION)
172         /* If Client initiated renegotiation is enabled, handle the renegotiation
173            handshake if appropriate. Otherwise return "no renegotiation allowed" error. */
174         if (tls_session -> nx_secure_tls_renegotation_enabled && tls_session -> nx_secure_tls_secure_renegotiation
175 #if defined(NX_SECURE_TLS_DISABLE_CLIENT_INITIATED_RENEGOTIATION)
176             /* If client initiated renegotiation is disabled for TLS servers, only allow
177                server-initiated renegotiations requested by the server itself. */
178             && tls_session -> nx_secure_tls_server_renegotiation_requested
179 #endif
180            )
181         {
182             tls_session -> nx_secure_tls_renegotiation_handshake = NX_TRUE;
183 
184 #ifndef NX_SECURE_DISABLE_X509
185 
186             /* On a session resumption free all certificates for the new session.
187              * SESSION RESUMPTION: if session resumption is enabled, don't free!!
188              */
189             status = _nx_secure_tls_remote_certificate_free_all(tls_session);
190 
191             if (status != NX_SUCCESS)
192             {
193                 return(status);
194             }
195 #endif
196 
197             /* Invoke user callback to notify application of renegotiation request. */
198             if (tls_session -> nx_secure_tls_session_renegotiation_callback != NX_NULL)
199             {
200                 status = tls_session -> nx_secure_tls_session_renegotiation_callback(tls_session);
201 
202                 if (status != NX_SUCCESS)
203                 {
204                     return(status);
205                 }
206             }
207 
208             /* We don't want any more clienthellos to come in after this - only the first one
209                in response to our original request. */
210             tls_session -> nx_secure_tls_server_renegotiation_requested = NX_FALSE;
211     }
212         else
213 #endif /* NX_SECURE_TLS_DISABLE_SECURE_RENEGOTIATION */
214         {
215             /* Session renegotiation is disabled, so this is an error! */
216             return(NX_SECURE_TLS_NO_RENEGOTIATION_ERROR);
217         }
218     }
219 
220     /* Client is establishing a TLS session with our server. */
221     /* Extract the protocol version - only part of the ClientHello message. */
222     protocol_version = (USHORT)((packet_buffer[length] << 8) | packet_buffer[length + 1]);
223     length += 2;
224 
225 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
226     if (tls_session->nx_secure_tls_1_3 == NX_FALSE)
227 #endif
228     {
229 
230         /* Check protocol version provided by client. */
231         status = _nx_secure_tls_check_protocol_version(tls_session, protocol_version, NX_SECURE_TLS);
232 
233         if (status != NX_SECURE_TLS_SUCCESS)
234         {
235             /* If we have an active session, this is a renegotiation attempt, treat the protocol error as
236                if we are starting a new session. */
237             if (status == NX_SECURE_TLS_UNSUPPORTED_TLS_VERSION || tls_session -> nx_secure_tls_local_session_active)
238             {
239                 /* If the version isn't supported, it's not an issue - TLS is backward-compatible,
240                  * so negotiate the highest supported version. If the version isn't recognized,
241                  * flag an error. */
242                 _nx_secure_tls_highest_supported_version_negotiate(tls_session, &protocol_version, NX_SECURE_TLS);
243 
244                 if (protocol_version == 0x0)
245                 {
246                     /* Error, no versions enabled. */
247                     return(NX_SECURE_TLS_UNSUPPORTED_TLS_VERSION);
248                 }
249             }
250             else
251             {
252                 /* Protocol version unknown (not TLS or SSL!), return status. */
253                 return(status);
254             }
255         }
256     }
257 
258     /* Assign our protocol version to our socket. This is used for all further communications
259      * in this session. */
260     tls_session -> nx_secure_tls_protocol_version = protocol_version;
261 
262     /* Save off the random value for key generation later. */
263     NX_SECURE_MEMCPY(tls_session -> nx_secure_tls_key_material.nx_secure_tls_client_random, &packet_buffer[length], NX_SECURE_TLS_RANDOM_SIZE); /* Use case of memcpy is verified.  lgtm[cpp/banned-api-usage-required-any] */
264     length += NX_SECURE_TLS_RANDOM_SIZE;
265 
266     /* Extract the session ID if there is one. */
267     session_id_length = packet_buffer[length];
268     length++;
269 
270     if ((length + session_id_length) > message_length)
271     {
272         return(NX_SECURE_TLS_INCORRECT_MESSAGE_LENGTH);
273     }
274 
275     /* If there is a session ID, copy it into our TLS socket structure. */
276     tls_session -> nx_secure_tls_session_id_length = session_id_length;
277     if (session_id_length > 0)
278     {
279         NX_SECURE_MEMCPY(tls_session -> nx_secure_tls_session_id, &packet_buffer[length], session_id_length); /* Use case of memcpy is verified.  lgtm[cpp/banned-api-usage-required-any] */
280         length += session_id_length;
281     }
282 
283     /* Negotiate the ciphersuite we want to use. */
284     ciphersuite_list_length = (USHORT)((packet_buffer[length] << 8) + packet_buffer[length + 1]);
285     length += 2;
286 
287     /* Make sure the list length makes sense. */
288     if (ciphersuite_list_length < 2 || (length + ciphersuite_list_length) > message_length)
289     {
290         return(NX_SECURE_TLS_INCORRECT_MESSAGE_LENGTH);
291     }
292 
293     ciphersuite_list = &packet_buffer[length];
294 
295     length += ciphersuite_list_length;
296 
297     /* Compression methods length - one byte. For now we only support the NULL method. */
298     compression_methods_length = packet_buffer[length];
299     length++;
300 
301     /* Message length overflow. */
302     if ((length + compression_methods_length) > message_length)
303     {
304         return(NX_SECURE_TLS_INCORRECT_MESSAGE_LENGTH);
305     }
306 
307     /* Make sure NULL compression method is supported. */
308     status = NX_SECURE_TLS_BAD_COMPRESSION_METHOD;
309     for (i = 0; i < compression_methods_length; ++i)
310     {
311         if (packet_buffer[length + i] == 0x0)
312         {
313             status = NX_SUCCESS;
314             break;
315         }
316     }
317 
318     /* Check for error. */
319     if (status != NX_SUCCESS)
320     {
321         return(status);
322     }
323 
324     length += compression_methods_length;
325 
326     /* Padding data? */
327     if (message_length >= (length + 2))
328     {
329 
330         /* TLS Extensions come next. Get the total length of all extensions first. */
331         total_extensions_length = (USHORT)((packet_buffer[length] << 8) + packet_buffer[length + 1]);
332         length += 2;
333 
334         /* Message length overflow. */
335         if ((length + total_extensions_length) > message_length)
336         {
337             return(NX_SECURE_TLS_INCORRECT_MESSAGE_LENGTH);
338         }
339 
340         if (total_extensions_length > 0)
341         {
342             /* Process serverhello extensions. */
343             status = _nx_secure_tls_process_clienthello_extensions(tls_session, &packet_buffer[length], total_extensions_length, extension_data, &num_extensions, packet_buffer, message_length);
344 
345             /* Check for error. */
346             if (status != NX_SUCCESS)
347             {
348                 return(status);
349             }
350 
351 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
352             if (tls_session -> nx_secure_tls_1_3 != tls_1_3)
353             {
354 
355                 /* Negotiate a version of TLS prior to TLS 1.3. */
356                 return(status);
357             }
358 #endif
359 
360             /* If the server callback is set, invoke it now with the extensions that require application input. */
361             if (tls_session -> nx_secure_tls_session_server_callback != NX_NULL)
362             {
363                 status = tls_session -> nx_secure_tls_session_server_callback(tls_session, extension_data, num_extensions);
364 
365                 /* Check for error. */
366                 if (status != NX_SUCCESS)
367                 {
368                     return(status);
369                 }
370             }
371         }
372         else
373         {
374             num_extensions = 0;
375 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
376             no_extension = NX_TRUE;
377 #endif
378         }
379     }
380     else
381     {
382         num_extensions = 0;
383 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
384         no_extension = NX_TRUE;
385 #endif
386     }
387 
388 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
389     if ((tls_session -> nx_secure_tls_1_3) && (no_extension == NX_TRUE))
390     {
391 
392         /* Negotiate a version of TLS prior to TLS 1.3. */
393         if (tls_session -> nx_secure_tls_protocol_version_override == 0)
394         {
395             tls_session -> nx_secure_tls_1_3 = NX_FALSE;
396 #if !defined(NX_SECURE_TLS_DISABLE_SECURE_RENEGOTIATION)
397             tls_session -> nx_secure_tls_renegotation_enabled = NX_TRUE;
398 #endif /* NX_SECURE_TLS_DISABLE_SECURE_RENEGOTIATION */
399 
400             return(NX_SUCCESS);
401         }
402         else
403         {
404 
405             /* Protocol version is overridden to TLS 1.3. */
406             return(NX_SECURE_TLS_UNSUPPORTED_TLS_VERSION);
407         }
408     }
409 #endif
410 
411 #if !defined(NX_SECURE_TLS_DISABLE_SECURE_RENEGOTIATION)
412     if ((tls_session -> nx_secure_tls_renegotiation_handshake) && (!tls_session -> nx_secure_tls_secure_renegotiation_verified))
413     {
414 
415         /* The server did not receive the "renegotiation_info" extension, the handshake must be aborted. */
416         return(NX_SECURE_TLS_RENEGOTIATION_EXTENSION_ERROR);
417     }
418 
419     tls_session -> nx_secure_tls_secure_renegotiation_verified = NX_FALSE;
420 #endif /* NX_SECURE_TLS_DISABLE_SECURE_RENEGOTIATION */
421 
422 #if defined(NX_SECURE_ENABLE_ECC_CIPHERSUITE) && !defined(NX_SECURE_DISABLE_X509)
423 
424     /* Get the local certificate. */
425     if (tls_session -> nx_secure_tls_credentials.nx_secure_tls_active_certificate != NX_NULL)
426     {
427         cert = tls_session -> nx_secure_tls_credentials.nx_secure_tls_active_certificate;
428     }
429     else
430     {
431         /* Get reference to local device certificate. NX_NULL is passed for name to get default entry. */
432         status = _nx_secure_x509_local_device_certificate_get(&tls_session -> nx_secure_tls_credentials.nx_secure_tls_certificate_store,
433                                                               NX_NULL, &cert);
434         if (status != NX_SUCCESS)
435         {
436             cert = NX_NULL;
437         }
438     }
439 
440     if (cert != NX_NULL && cert -> nx_secure_x509_public_algorithm == NX_SECURE_TLS_X509_TYPE_EC)
441     {
442         ec_pubkey = &cert -> nx_secure_x509_public_key.ec_public_key;
443         cert_curve = ec_pubkey -> nx_secure_ec_named_curve;
444     }
445     else
446     {
447         cert_curve = 0;
448     }
449 
450     ecdhe_data = (NX_SECURE_TLS_ECDHE_HANDSHAKE_DATA *)tls_session -> nx_secure_tls_key_material.nx_secure_tls_new_key_material_data;
451 
452     /* Parse the ECC extension of supported curve. */
453     status = _nx_secure_tls_proc_clienthello_sec_sa_extension(tls_session,
454                                                               extension_data,
455                                                               num_extensions,
456                                                               &selected_curve,
457                                                               (USHORT)cert_curve, &cert_curve_supported,
458                                                               &ecdhe_data -> nx_secure_tls_ecdhe_signature_algorithm,
459                                                               cert);
460 
461     /* Check for error. */
462     if (status != NX_SUCCESS)
463     {
464         return(status);
465     }
466 
467     ecdhe_data -> nx_secure_tls_ecdhe_named_curve = selected_curve;
468 
469     /* Check if certificate curve is supported. */
470     if (cert != NX_NULL && cert -> nx_secure_x509_public_algorithm == NX_SECURE_TLS_X509_TYPE_EC)
471     {
472         if (cert_curve_supported == NX_FALSE)
473         {
474             /* The named curve in our server certificate is not supported by the client. */
475             return(NX_SECURE_TLS_NO_SUPPORTED_CIPHERS);
476         }
477     }
478 #endif /* NX_SECURE_ENABLE_ECC_CIPHERSUITE && !NX_SECURE_DISABLE_X509 */
479 
480     /* Set our initial priority to the maximum value - the size of our ciphersuite crypto table. */
481     ciphersuite_priority = (USHORT)(0xFFFFFFFF);
482 
483     for (i = 0; i < ciphersuite_list_length; i += 2)
484     {
485         /* Loop through list of acceptable ciphersuites. */
486         cipher_entry = (USHORT)((ciphersuite_list[i] << 8) + ciphersuite_list[i + 1]);
487 
488 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
489         if ((tls_session -> nx_secure_tls_1_3 == NX_TRUE) ^ (ciphersuite_list[i] == 0x13))
490         {
491 
492             /* Ciphersuites for TLS 1.3 can not be used by TLS 1.2. */
493             continue;
494         }
495 #endif
496 
497         /* Look up the ciphersuite in our crypto table, then check the priority of the chosen ciphersuite. */
498         status = _nx_secure_tls_ciphersuite_lookup(tls_session, cipher_entry, &ciphersuite_info, &new_ciphersuite_priority);
499 
500         /* Save the first ciphersuite we find - assume cipher table is in priority order. */
501         if ((status == NX_SUCCESS) && (new_ciphersuite_priority < ciphersuite_priority))
502         {
503 #if defined(NX_SECURE_ENABLE_ECC_CIPHERSUITE) && !defined(NX_SECURE_DISABLE_X509)
504             if (NX_SUCCESS == _nx_secure_tls_check_ciphersuite(ciphersuite_info, cert, selected_curve, cert_curve_supported))
505 #endif /* NX_SECURE_ENABLE_ECC_CIPHERSUITE */
506             {
507                 /* Save the ciphersuite and its priority but continue processing the entire list to see if there
508                    is a better ciphersuite available. */
509                 tls_session -> nx_secure_tls_session_ciphersuite = ciphersuite_info;
510                 ciphersuite_priority = new_ciphersuite_priority;
511             }
512         }
513 
514 #if !defined(NX_SECURE_TLS_DISABLE_SECURE_RENEGOTIATION)
515         if (cipher_entry == TLS_EMPTY_RENEGOTIATION_INFO_SCSV)
516         {
517             if (tls_session -> nx_secure_tls_renegotiation_handshake)
518             {
519 
520                 /* When secure renegotiating, the server MUST verify that it
521                    does not contain the TLS_EMPTY_RENEGOTIATION_INFO_SCSV SCSV. */
522                 return(NX_SECURE_TLS_RENEGOTIATION_EXTENSION_ERROR);
523             }
524             else
525             {
526 
527                 /* Secure Renegotiation signalling ciphersuite value was encountered.
528                    This indicates that the Client supports secure renegotiation. */
529                 tls_session -> nx_secure_tls_secure_renegotiation = NX_TRUE;
530             }
531         }
532 #endif /* NX_SECURE_TLS_DISABLE_SECURE_RENEGOTIATION */
533 
534 
535         /* Check for the fallback notification SCSV. */
536         if (cipher_entry == TLS_FALLBACK_NOTIFY_SCSV)
537         {
538 
539             /* A fallback is indicated by the Client, check the TLS version. */
540             _nx_secure_tls_newest_supported_version(tls_session, &newest_version, NX_SECURE_TLS);
541 
542             if (protocol_version != newest_version)
543             {
544                 return(NX_SECURE_TLS_INAPPROPRIATE_FALLBACK);
545             }
546         }
547         /* Continue searching client ciphersuite list to get highest-priority selection. */
548     }
549 
550 #if !defined(NX_SECURE_TLS_DISABLE_SECURE_RENEGOTIATION) && defined(NX_SECURE_TLS_REQUIRE_RENEGOTIATION_EXT)
551 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
552     if (!tls_session -> nx_secure_tls_1_3)
553 #endif /* NX_SECURE_TLS_TLS_1_3_ENABLED */
554     {
555         if ((tls_session -> nx_secure_tls_renegotation_enabled) && (!tls_session -> nx_secure_tls_secure_renegotiation))
556         {
557 
558             /* No "renegotiation_info" extension present, some servers may want to terminate the handshake. */
559             return(NX_SECURE_TLS_RENEGOTIATION_EXTENSION_ERROR);
560         }
561     }
562 #endif /* !NX_SECURE_TLS_DISABLE_SECURE_RENEGOTIATION && NX_SECURE_TLS_REQUIRE_RENEGOTIATION_EXT */
563 
564     /* See if we found an acceptable ciphersuite. */
565     if (tls_session -> nx_secure_tls_session_ciphersuite == NX_NULL)
566     {
567 
568         /* No supported ciphersuites found. */
569         return(NX_SECURE_TLS_NO_SUPPORTED_CIPHERS);
570     }
571 
572 #ifdef NX_SECURE_TLS_SERVER_DISABLED
573     /* If TLS Server is disabled and we have processed a ClientHello, something is wrong... */
574     tls_session -> nx_secure_tls_client_state = NX_SECURE_TLS_CLIENT_STATE_ERROR;
575     return(NX_SECURE_TLS_INVALID_STATE);
576 #else
577     return(NX_SUCCESS);
578 #endif
579 }
580 
581 /**************************************************************************/
582 /*                                                                        */
583 /*  FUNCTION                                               RELEASE        */
584 /*                                                                        */
585 /*    _nx_secure_tls_check_ciphersuite                    PORTABLE C      */
586 /*                                                           6.1          */
587 /*  AUTHOR                                                                */
588 /*                                                                        */
589 /*    Timothy Stapko, Microsoft Corporation                               */
590 /*                                                                        */
591 /*  DESCRIPTION                                                           */
592 /*                                                                        */
593 /*    This function checks whether the specified ciphersuite is           */
594 /*    suitable for the server certificate, the curve in the certificate   */
595 /*    and the common shared curve.                                        */
596 /*                                                                        */
597 /*  INPUT                                                                 */
598 /*                                                                        */
599 /*    ciphersuite_info                      The specified cipher suite    */
600 /*    cert                                  Local server certificate      */
601 /*    selected_curve                        Curve selected for ECC        */
602 /*    cert_curve_supported                  If cert curve is supported    */
603 /*                                                                        */
604 /*  OUTPUT                                                                */
605 /*                                                                        */
606 /*    status                                Completion status             */
607 /*                                                                        */
608 /*  CALLS                                                                 */
609 /*                                                                        */
610 /*    None                                                                */
611 /*                                                                        */
612 /*  CALLED BY                                                             */
613 /*                                                                        */
614 /*    _nx_secure_tls_server_handshake       TLS Server state machine      */
615 /*                                                                        */
616 /*  RELEASE HISTORY                                                       */
617 /*                                                                        */
618 /*    DATE              NAME                      DESCRIPTION             */
619 /*                                                                        */
620 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
621 /*  09-30-2020     Timothy Stapko           Modified comment(s),          */
622 /*                                            resulting in version 6.1    */
623 /*                                                                        */
624 /**************************************************************************/
625 #if defined(NX_SECURE_ENABLE_ECC_CIPHERSUITE) && !defined(NX_SECURE_DISABLE_X509)
_nx_secure_tls_check_ciphersuite(const NX_SECURE_TLS_CIPHERSUITE_INFO * ciphersuite_info,NX_SECURE_X509_CERT * cert,UINT selected_curve,UINT cert_curve_supported)626 static UINT _nx_secure_tls_check_ciphersuite(const NX_SECURE_TLS_CIPHERSUITE_INFO *ciphersuite_info,
627                                              NX_SECURE_X509_CERT *cert, UINT selected_curve,
628                                              UINT cert_curve_supported)
629 {
630     if (ciphersuite_info -> nx_secure_tls_public_cipher == NX_NULL)
631     {
632         return(NX_SUCCESS);
633     }
634 
635     if (ciphersuite_info -> nx_secure_tls_public_auth == NX_NULL)
636     {
637         return(NX_SUCCESS);
638     }
639 
640     switch (ciphersuite_info -> nx_secure_tls_public_cipher -> nx_crypto_algorithm)
641     {
642     case NX_CRYPTO_KEY_EXCHANGE_ECDHE:
643         if (selected_curve == 0 || cert == NX_NULL)
644         {
645             /* No common named curve supported for ECDHE. */
646             return(NX_SECURE_TLS_UNSUPPORTED_PUBLIC_CIPHER);
647         }
648 
649         if (ciphersuite_info -> nx_secure_tls_public_auth -> nx_crypto_algorithm == NX_CRYPTO_DIGITAL_SIGNATURE_ECDSA)
650         {
651             if (cert -> nx_secure_x509_public_algorithm != NX_SECURE_TLS_X509_TYPE_EC)
652             {
653                 /* ECDSA auth requires EC certificate. */
654                 return(NX_SECURE_TLS_UNSUPPORTED_PUBLIC_CIPHER);
655             }
656         }
657         else
658         {
659             if (cert -> nx_secure_x509_public_algorithm != NX_SECURE_TLS_X509_TYPE_RSA)
660             {
661                 /* RSA auth requires RSA certificate. */
662                 return(NX_SECURE_TLS_UNSUPPORTED_PUBLIC_CIPHER);
663             }
664         }
665 
666         break;
667 
668     case NX_CRYPTO_KEY_EXCHANGE_ECDH:
669         if (selected_curve == 0)
670         {
671             /* No common named curve supported supported. */
672             return(NX_SECURE_TLS_UNSUPPORTED_PUBLIC_CIPHER);
673         }
674 
675         /* Check for ECDH_anon. */
676         if (ciphersuite_info -> nx_secure_tls_public_auth -> nx_crypto_algorithm != NX_CRYPTO_DIGITAL_SIGNATURE_ANONYMOUS)
677         {
678             /* ECDH key exchange requires an EC certificate. */
679             if (cert == NX_NULL || cert -> nx_secure_x509_public_algorithm != NX_SECURE_TLS_X509_TYPE_EC)
680             {
681                 return(NX_SECURE_TLS_UNSUPPORTED_PUBLIC_CIPHER);
682             }
683 
684             if (cert_curve_supported == NX_FALSE)
685             {
686                 return(NX_SECURE_TLS_UNSUPPORTED_PUBLIC_CIPHER);
687             }
688 
689             /* Check the signatureAlgorithm of the certificate to determine the public auth algorithm. */
690             if (ciphersuite_info -> nx_secure_tls_public_auth -> nx_crypto_algorithm == NX_CRYPTO_DIGITAL_SIGNATURE_ECDSA)
691             {
692                 if (cert -> nx_secure_x509_signature_algorithm != NX_SECURE_TLS_X509_TYPE_ECDSA_SHA_1 &&
693                     cert -> nx_secure_x509_signature_algorithm != NX_SECURE_TLS_X509_TYPE_ECDSA_SHA_224 &&
694                     cert -> nx_secure_x509_signature_algorithm != NX_SECURE_TLS_X509_TYPE_ECDSA_SHA_256 &&
695                     cert -> nx_secure_x509_signature_algorithm != NX_SECURE_TLS_X509_TYPE_ECDSA_SHA_384 &&
696                     cert -> nx_secure_x509_signature_algorithm != NX_SECURE_TLS_X509_TYPE_ECDSA_SHA_512)
697                 {
698                     return(NX_SECURE_TLS_UNSUPPORTED_PUBLIC_CIPHER);
699                 }
700             }
701             else
702             {
703                 if (cert -> nx_secure_x509_signature_algorithm != NX_SECURE_TLS_X509_TYPE_RSA_MD5 &&
704                     cert -> nx_secure_x509_signature_algorithm != NX_SECURE_TLS_X509_TYPE_RSA_SHA_1 &&
705                     cert -> nx_secure_x509_signature_algorithm != NX_SECURE_TLS_X509_TYPE_RSA_SHA_256 &&
706                     cert -> nx_secure_x509_signature_algorithm != NX_SECURE_TLS_X509_TYPE_RSA_SHA_384 &&
707                     cert -> nx_secure_x509_signature_algorithm != NX_SECURE_TLS_X509_TYPE_RSA_SHA_512)
708                 {
709                     return(NX_SECURE_TLS_UNSUPPORTED_PUBLIC_CIPHER);
710                 }
711             }
712         }
713         break;
714 
715     case NX_CRYPTO_KEY_EXCHANGE_RSA:
716         if (cert == NX_NULL || cert -> nx_secure_x509_public_algorithm != NX_SECURE_TLS_X509_TYPE_RSA)
717         {
718             /* RSA key exchange requires RSA certificate. */
719             return(NX_SECURE_TLS_UNSUPPORTED_PUBLIC_CIPHER);
720         }
721         break;
722 
723     default:
724         break;
725     }
726 
727     return(NX_SUCCESS);
728 }
729 #endif /* NX_SECURE_ENABLE_ECC_CIPHERSUITE && !NX_SECURE_DISABLE_X509 */
730