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 
22 #define NX_SECURE_SOURCE_CODE
23 
24 #include "nx_secure_tls.h"
25 
26 #ifndef NX_SECURE_TLS_CLIENT_DISABLED
27 
28 
29 #ifndef NX_SECURE_TLS_DISABLE_SECURE_RENEGOTIATION
30 static UINT _nx_secure_tls_proc_serverhello_sec_reneg_extension(NX_SECURE_TLS_SESSION *tls_session,
31                                                                 UCHAR *packet_buffer,
32                                                                 USHORT *extension_length, UINT message_length);
33 #endif
34 
35 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
36 #ifdef NX_SECURE_ENABLE_ECC_CIPHERSUITE
37 static UINT _nx_secure_tls_proc_serverhello_keyshare_extension(NX_SECURE_TLS_SESSION *tls_session,
38                                                                 UCHAR *packet_buffer,
39                                                                 USHORT *extension_length, UINT message_length);
40 #endif
41 static UINT _nx_secure_tls_proc_serverhello_supported_versions_extension(NX_SECURE_TLS_SESSION *tls_session,
42                                                                          UCHAR *packet_buffer,
43                                                                          USHORT *supported_version,
44                                                                          USHORT *extension_length, UINT message_length);
45 #endif
46 
47 #ifdef NX_SECURE_ENABLE_ECJPAKE_CIPHERSUITE
48 static UINT _nx_secure_tls_proc_serverhello_ecc_point_formats(NX_SECURE_TLS_SESSION *tls_session,
49                                                               UCHAR *packet_buffer,
50                                                               USHORT *extension_length, UINT message_length);
51 static UINT _nx_secure_tls_proc_serverhello_ecjpake_key_kp_pair(NX_SECURE_TLS_SESSION *tls_session,
52                                                                 UCHAR *packet_buffer,
53                                                                 USHORT *extension_length, UINT message_length);
54 #endif
55 
56 #endif /* NX_SECURE_TLS_CLIENT_DISABLED */
57 
58 /**************************************************************************/
59 /*                                                                        */
60 /*  FUNCTION                                               RELEASE        */
61 /*                                                                        */
62 /*    _nx_secure_tls_process_serverhello_extensions       PORTABLE C      */
63 /*                                                           6.1.9        */
64 /*  AUTHOR                                                                */
65 /*                                                                        */
66 /*    Timothy Stapko, Microsoft Corporation                               */
67 /*                                                                        */
68 /*  DESCRIPTION                                                           */
69 /*                                                                        */
70 /*    This function processes any extensions included in an incoming      */
71 /*    ServerHello message from a remote host.                             */
72 /*                                                                        */
73 /*  INPUT                                                                 */
74 /*                                                                        */
75 /*    tls_session                           TLS control block             */
76 /*    packet_buffer                         Pointer to message data       */
77 /*    message_length                        Length of message data (bytes)*/
78 /*    extensions                            Extensions for output         */
79 /*    num_extensions                        Number of extensions          */
80 /*                                                                        */
81 /*  OUTPUT                                                                */
82 /*                                                                        */
83 /*    status                                Completion status             */
84 /*                                                                        */
85 /*  CALLS                                                                 */
86 /*                                                                        */
87 /*    _nx_secure_tls_proc_serverhello_ecc_point_formats                   */
88 /*                                          Process ServerHello ECC       */
89 /*                                            point formats extension     */
90 /*    _nx_secure_tls_proc_serverhello_ecjpake_key_kp_pair                 */
91 /*                                          Process ServerHello ECJPAKE   */
92 /*                                            key kp pair extension       */
93 /*    _nx_secure_tls_proc_serverhello_sec_reneg_extension                 */
94 /*                                          Process ServerHello           */
95 /*                                            Renegotiation extension     */
96 /*                                                                        */
97 /*  CALLED BY                                                             */
98 /*                                                                        */
99 /*    _nx_secure_tls_server_handshake       Process ServerHello           */
100 /*                                                                        */
101 /*  RELEASE HISTORY                                                       */
102 /*                                                                        */
103 /*    DATE              NAME                      DESCRIPTION             */
104 /*                                                                        */
105 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
106 /*  09-30-2020     Timothy Stapko           Modified comment(s),          */
107 /*                                            fixed renegotiation bug,    */
108 /*                                            resulting in version 6.1    */
109 /*  10-15-2021     Timothy Stapko           Modified comment(s), fixed    */
110 /*                                            TLS 1.3 compilation issue,  */
111 /*                                            resulting in version 6.1.9  */
112 /*                                                                        */
113 /**************************************************************************/
_nx_secure_tls_process_serverhello_extensions(NX_SECURE_TLS_SESSION * tls_session,UCHAR * packet_buffer,UINT message_length,NX_SECURE_TLS_HELLO_EXTENSION * extensions,UINT * num_extensions)114 UINT _nx_secure_tls_process_serverhello_extensions(NX_SECURE_TLS_SESSION *tls_session,
115                                                    UCHAR *packet_buffer, UINT message_length,
116                                                    NX_SECURE_TLS_HELLO_EXTENSION *extensions,
117                                                    UINT *num_extensions)
118 {
119 #ifndef NX_SECURE_TLS_CLIENT_DISABLED
120 
121 UINT status;
122 
123 #ifdef NX_SECURE_ENABLE_ECJPAKE_CIPHERSUITE
124 USHORT                                ec_point_formats_match, zkp_verified;
125 #endif
126 UINT                                  offset;
127 USHORT                                extension_id;
128 USHORT                                extension_length;
129 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
130 USHORT                                supported_version = tls_session -> nx_secure_tls_protocol_version;
131 #endif
132 
133 #ifdef NX_SECURE_TLS_DISABLE_SECURE_RENEGOTIATION
134 #ifndef NX_SECURE_ENABLE_ECJPAKE_CIPHERSUITE
135     NX_PARAMETER_NOT_USED(tls_session);
136 #endif
137 #endif
138 
139 #ifdef NX_SECURE_ENABLE_ECJPAKE_CIPHERSUITE
140     if (tls_session -> nx_secure_tls_session_ciphersuite == NX_NULL)
141     {
142         return(NX_SECURE_TLS_UNKNOWN_CIPHERSUITE);
143     }
144 
145     ec_point_formats_match = NX_FALSE;
146     zkp_verified = NX_FALSE;
147 #endif
148 
149     offset = 0;
150     status = NX_SUCCESS;
151     *num_extensions = 0;
152 
153     /* Process extensions until we run out. */
154     while (offset < message_length)
155     {
156 
157         /* Make sure there are at least 4 bytes available so we can read extension_id and
158            extension_length. */
159         if (offset + 4 > message_length)
160         {
161             return(NX_SECURE_TLS_INCORRECT_MESSAGE_LENGTH);
162         }
163 
164         /* See what the extension is. */
165         extension_id = (USHORT)((packet_buffer[offset] << 8) + packet_buffer[offset + 1]);
166 
167         /* Skip type id of extentions. */
168         offset += 2;
169 
170         /* Parse the extension. */
171         switch (extension_id)
172         {
173 #ifndef NX_SECURE_TLS_DISABLE_SECURE_RENEGOTIATION
174         case NX_SECURE_TLS_EXTENSION_SECURE_RENEGOTIATION:
175             status = _nx_secure_tls_proc_serverhello_sec_reneg_extension(tls_session, &packet_buffer[offset], &extension_length, message_length - offset);
176 
177             if (status)
178             {
179                 return(status);
180             }
181             break;
182 #endif /* NX_SECURE_TLS_DISABLE_SECURE_RENEGOTIATION */
183 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
184 #ifdef NX_SECURE_ENABLE_ECC_CIPHERSUITE
185         case NX_SECURE_TLS_EXTENSION_KEY_SHARE:
186 
187             if (tls_session -> nx_secure_tls_1_3)
188             {
189                 /* Process the TLS 1.3 key share extension. */
190                 status = _nx_secure_tls_proc_serverhello_keyshare_extension(tls_session, &packet_buffer[offset], &extension_length, message_length - offset);
191 
192                 if (status)
193                 {
194                     return(status);
195                 }
196             }
197             else
198             {
199                 extension_length = (USHORT)((packet_buffer[offset] << 8) + packet_buffer[offset + 1]);
200                 if (extension_length + offset + 2 > message_length)
201                 {
202                     return(NX_SECURE_TLS_INCORRECT_MESSAGE_LENGTH);
203                 }
204             }
205             offset += 2;
206 
207             /* Ignore if not TLS 1.3. */
208             break;
209 #endif
210         case NX_SECURE_TLS_EXTENSION_SUPPORTED_VERSIONS:
211             if (tls_session -> nx_secure_tls_1_3)
212             {
213 
214                 /* Process the TLS 1.3 supported_versions extension. */
215                 status = _nx_secure_tls_proc_serverhello_supported_versions_extension(tls_session, &packet_buffer[offset], &supported_version, &extension_length, message_length - offset);
216 
217                 if (status)
218                 {
219                     return(status);
220                 }
221             }
222             else
223             {
224                 extension_length = (USHORT)((packet_buffer[offset] << 8) + packet_buffer[offset + 1]);
225                 if (extension_length + offset + 2 > message_length)
226                 {
227                     return(NX_SECURE_TLS_INCORRECT_MESSAGE_LENGTH);
228                 }
229             }
230             offset += 2;
231 
232             /* Ignore if not TLS 1.3. */
233             break;
234         case NX_SECURE_TLS_EXTENSION_COOKIE:
235             extension_length = (USHORT)((packet_buffer[offset] << 8) + packet_buffer[offset + 1]);
236             offset += 2;
237 
238             if (extension_length + offset > message_length)
239             {
240                 return(NX_SECURE_TLS_INCORRECT_MESSAGE_LENGTH);
241             }
242 
243             /* Store the pointer of cookie. */
244             /* Note: Cookie data is stored in ServerHello packet buffer. This buffer should not be released
245                or overwrote before Cookie is copied to ClientHello. */
246             if (tls_session -> nx_secure_tls_1_3)
247             {
248                 if (extension_length < 2)
249                 {
250                     return(NX_SECURE_TLS_INCORRECT_MESSAGE_LENGTH);
251                 }
252 
253                 tls_session -> nx_secure_tls_cookie_length = (USHORT)((packet_buffer[offset] << 8) + packet_buffer[offset + 1]);
254                 tls_session -> nx_secure_tls_cookie = &packet_buffer[offset + 2];
255 
256                 if (tls_session -> nx_secure_tls_cookie_length + 2 > extension_length)
257                 {
258                     return(NX_SECURE_TLS_INCORRECT_MESSAGE_LENGTH);
259                 }
260             }
261 
262             break;
263 #endif
264 #ifdef NX_SECURE_ENABLE_ECJPAKE_CIPHERSUITE
265         /* ECJPAKE ciphersuite extensions. */
266         case NX_SECURE_TLS_EXTENSION_EC_POINT_FORMATS:
267             status = _nx_secure_tls_proc_serverhello_ecc_point_formats(tls_session, &packet_buffer[offset], &extension_length, message_length - offset);
268             if (status == NX_SUCCESS)
269             {
270                 ec_point_formats_match = NX_TRUE;
271             }
272             break;
273         case NX_SECURE_TLS_EXTENSION_ECJPAKE_KEY_KP_PAIR:
274             status = _nx_secure_tls_proc_serverhello_ecjpake_key_kp_pair(tls_session, &packet_buffer[offset], &extension_length, message_length - offset);
275             if (status == NX_SUCCESS)
276             {
277                 zkp_verified = NX_TRUE;
278             }
279             break;
280 #else
281         case NX_SECURE_TLS_EXTENSION_EC_GROUPS:
282         case NX_SECURE_TLS_EXTENSION_EC_POINT_FORMATS:
283         case NX_SECURE_TLS_EXTENSION_ECJPAKE_KEY_KP_PAIR:
284 #endif /* NX_SECURE_ENABLE_ECJPAKE_CIPHERSUITE */
285         case NX_SECURE_TLS_EXTENSION_SERVER_NAME_INDICATION:
286         case NX_SECURE_TLS_EXTENSION_MAX_FRAGMENT_LENGTH:
287         case NX_SECURE_TLS_EXTENSION_CLIENT_CERTIFICATE_URL:
288         case NX_SECURE_TLS_EXTENSION_TRUSTED_CA_INDICATION:
289         case NX_SECURE_TLS_EXTENSION_CERTIFICATE_STATUS_REQUEST:
290             /* These extensions require information to be passed to the application. Save off
291                the extension data in our extensions array to pass along in the hello callback. */
292             extension_length = (USHORT)((packet_buffer[offset] << 8) + packet_buffer[offset + 1]);
293             offset += 2;
294 
295             if (extension_length + offset > message_length)
296             {
297                 return(NX_SECURE_TLS_INCORRECT_MESSAGE_LENGTH);
298             }
299 
300             if (*num_extensions < NX_SECURE_TLS_HELLO_EXTENSIONS_MAX)
301             {
302                 extensions[*num_extensions].nx_secure_tls_extension_id = extension_id;
303                 extensions[*num_extensions].nx_secure_tls_extension_data = &packet_buffer[offset];
304                 extensions[*num_extensions].nx_secure_tls_extension_data_length = extension_length;
305 
306                 /* Added another extension to the array. */
307                 *num_extensions = *num_extensions + 1;
308             }
309 
310             break;
311         case NX_SECURE_TLS_EXTENSION_SIGNATURE_ALGORITHMS:
312         case NX_SECURE_TLS_EXTENSION_TRUNCATED_HMAC:
313         default:
314             /* Unknown extension, just ignore - TLS supports multiple extensions and the default
315                behavior is to ignore any extensions that we don't know. Assume the next two
316                octets are the length field so we can continue processing. */
317             extension_length = (USHORT)((packet_buffer[offset] << 8) + packet_buffer[offset + 1]);
318             offset += 2;
319 
320             if (extension_length + offset > message_length)
321             {
322                 return(NX_SECURE_TLS_INCORRECT_MESSAGE_LENGTH);
323             }
324 
325             break;
326         }
327 
328         /* Adjust our offset with the length of the extension we just parsed. */
329         offset += extension_length;
330     }
331 
332 #ifdef NX_SECURE_ENABLE_ECJPAKE_CIPHERSUITE
333     /* Make sure no ECJPAKE extensions are missing.  */
334     if ((tls_session -> nx_secure_tls_session_ciphersuite -> nx_secure_tls_public_auth -> nx_crypto_algorithm == NX_CRYPTO_KEY_EXCHANGE_ECJPAKE) &&
335         (ec_point_formats_match == 0 || zkp_verified == 0))
336     {
337         return(NX_SECURE_TLS_UNSUPPORTED_ECC_FORMAT);
338     }
339 #endif /* NX_SECURE_ENABLE_ECJPAKE_CIPHERSUITE */
340 
341 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
342     if (tls_session -> nx_secure_tls_1_3)
343     {
344         if (supported_version != NX_SECURE_TLS_VERSION_TLS_1_3)
345         {
346 
347             /* Server negotiates a version of TLS prior to TLS 1.3. */
348             if (tls_session -> nx_secure_tls_protocol_version_override == 0)
349             {
350                 tls_session -> nx_secure_tls_1_3 = NX_FALSE;
351 #ifndef NX_SECURE_TLS_DISABLE_SECURE_RENEGOTIATION
352                 tls_session -> nx_secure_tls_renegotation_enabled = NX_TRUE;
353 #endif /* NX_SECURE_TLS_DISABLE_SECURE_RENEGOTIATION */
354             }
355             else
356             {
357 
358                 /* Protocol version is overridden to TLS 1.3. */
359                 return(NX_SECURE_TLS_UNSUPPORTED_TLS_VERSION);
360             }
361         }
362         else
363         {
364             if (tls_session -> nx_secure_tls_protocol_version != NX_SECURE_TLS_VERSION_TLS_1_2)
365             {
366 
367                 /* Server negotiates TLS 1.3 must set the legacy version to TLS 1.2. */
368                 return(NX_SECURE_TLS_UNKNOWN_TLS_VERSION);
369             }
370         }
371     }
372 #endif
373 
374     return(status);
375 #else
376     /* If Client TLS is disabled and we recieve a server key exchange, error! */
377     NX_PARAMETER_NOT_USED(tls_session);
378     NX_PARAMETER_NOT_USED(packet_buffer);
379     NX_PARAMETER_NOT_USED(message_length);
380     NX_PARAMETER_NOT_USED(extensions);
381     NX_PARAMETER_NOT_USED(num_extensions);
382 
383     return(NX_SECURE_TLS_UNEXPECTED_MESSAGE);
384 #endif
385 }
386 
387 
388 #ifndef NX_SECURE_TLS_CLIENT_DISABLED
389 
390 /**************************************************************************/
391 /*                                                                        */
392 /*  FUNCTION                                               RELEASE        */
393 /*                                                                        */
394 /*    _nx_secure_tls_proc_serverhello_ecc_point_formats   PORTABLE C      */
395 /*                                                           6.1          */
396 /*  AUTHOR                                                                */
397 /*                                                                        */
398 /*    Timothy Stapko, Microsoft Corporation                               */
399 /*                                                                        */
400 /*  DESCRIPTION                                                           */
401 /*                                                                        */
402 /*    This function parses the ec_point_formats extension when ECC        */
403 /*    ciphersuites are being used.                                        */
404 /*                                                                        */
405 /*  INPUT                                                                 */
406 /*                                                                        */
407 /*    tls_session                           TLS control block             */
408 /*    packet_buffer                         Outgoing TLS packet buffer    */
409 /*    extension_length                      Length of extension data      */
410 /*    message_length                        Length of message data (bytes)*/
411 /*                                                                        */
412 /*  OUTPUT                                                                */
413 /*                                                                        */
414 /*    status                                Completion status             */
415 /*                                                                        */
416 /*  CALLS                                                                 */
417 /*                                                                        */
418 /*    None                                                                */
419 /*                                                                        */
420 /*  CALLED BY                                                             */
421 /*                                                                        */
422 /*    _nx_secure_tls_process_serverhello_extensions                       */
423 /*                                          Process ServerHello extensions*/
424 /*                                                                        */
425 /*  RELEASE HISTORY                                                       */
426 /*                                                                        */
427 /*    DATE              NAME                      DESCRIPTION             */
428 /*                                                                        */
429 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
430 /*  09-30-2020     Timothy Stapko           Modified comment(s),          */
431 /*                                            resulting in version 6.1    */
432 /*                                                                        */
433 /**************************************************************************/
434 #ifdef NX_SECURE_ENABLE_ECJPAKE_CIPHERSUITE
_nx_secure_tls_proc_serverhello_ecc_point_formats(NX_SECURE_TLS_SESSION * tls_session,UCHAR * packet_buffer,USHORT * extension_length,UINT message_length)435 static UINT _nx_secure_tls_proc_serverhello_ecc_point_formats(NX_SECURE_TLS_SESSION *tls_session,
436                                                               UCHAR *packet_buffer,
437                                                               USHORT *extension_length, UINT message_length)
438 {
439 UINT                                  status;
440 UINT                                  i;
441 UCHAR                                 ec_point_formats_length;
442 UINT                                  offset;
443 
444     *extension_length = (USHORT)((*packet_buffer << 8) + packet_buffer[1] + 2);
445 
446     if (tls_session -> nx_secure_tls_session_ciphersuite == NX_NULL)
447     {
448         return(NX_SECURE_TLS_UNKNOWN_CIPHERSUITE);
449     }
450 
451     /* Skip the length field of this extension. */
452     offset = 2;
453 
454     if (*extension_length > message_length || *extension_length < 3)
455     {
456         return(NX_SECURE_TLS_INCORRECT_MESSAGE_LENGTH);
457     }
458 
459     /* ec_point_formats Extension.  */
460     ec_point_formats_length = packet_buffer[offset];
461     offset += 1;
462 
463     if (offset + ec_point_formats_length != *extension_length)
464     {
465         return(NX_SECURE_TLS_INCORRECT_MESSAGE_LENGTH);
466     }
467 
468     /* Ignore the extension if we are not using ECJPAKE. */
469     if (tls_session -> nx_secure_tls_session_ciphersuite -> nx_secure_tls_public_auth -> nx_crypto_algorithm == NX_CRYPTO_KEY_EXCHANGE_ECJPAKE)
470     {
471         /* Make sure uncompressed (0) format is supported. */
472         status = NX_SECURE_TLS_UNSUPPORTED_CIPHER;
473         for (i = 0; i < ec_point_formats_length; ++i)
474         {
475             if (packet_buffer[offset + i] == 0x0)
476             {
477                 status = NX_SUCCESS;
478                 break;
479             }
480         }
481 
482         /* Check for error. */
483         if (status != NX_SUCCESS)
484         {
485             return(status);
486         }
487     }
488 
489     return(NX_SUCCESS);
490 }
491 #endif
492 
493 
494 /**************************************************************************/
495 /*                                                                        */
496 /*  FUNCTION                                               RELEASE        */
497 /*                                                                        */
498 /*    _nx_secure_tls_proc_serverhello_ecjpake_key_kp_pair PORTABLE C      */
499 /*                                                           6.1          */
500 /*  AUTHOR                                                                */
501 /*                                                                        */
502 /*    Timothy Stapko, Microsoft Corporation                               */
503 /*                                                                        */
504 /*  DESCRIPTION                                                           */
505 /*                                                                        */
506 /*    This function parses the ecjpake_key_kp_pair extension when ECC     */
507 /*    JPAKE ciphersuites are being used.                                  */
508 /*                                                                        */
509 /*  INPUT                                                                 */
510 /*                                                                        */
511 /*    tls_session                           TLS control block             */
512 /*    packet_buffer                         Outgoing TLS packet buffer    */
513 /*    extension_length                      Length of extension data      */
514 /*    message_length                        Length of message data (bytes)*/
515 /*                                                                        */
516 /*  OUTPUT                                                                */
517 /*                                                                        */
518 /*    status                                Completion status             */
519 /*                                                                        */
520 /*  CALLS                                                                 */
521 /*                                                                        */
522 /*    [nx_crypto_operation]                 Crypto operation              */
523 /*                                                                        */
524 /*  CALLED BY                                                             */
525 /*                                                                        */
526 /*    _nx_secure_tls_process_serverhello_extensions                       */
527 /*                                          Process ServerHello extensions*/
528 /*                                                                        */
529 /*  RELEASE HISTORY                                                       */
530 /*                                                                        */
531 /*    DATE              NAME                      DESCRIPTION             */
532 /*                                                                        */
533 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
534 /*  09-30-2020     Timothy Stapko           Modified comment(s),          */
535 /*                                            resulting in version 6.1    */
536 /*                                                                        */
537 /**************************************************************************/
538 #ifdef NX_SECURE_ENABLE_ECJPAKE_CIPHERSUITE
_nx_secure_tls_proc_serverhello_ecjpake_key_kp_pair(NX_SECURE_TLS_SESSION * tls_session,UCHAR * packet_buffer,USHORT * extension_length,UINT message_length)539 static UINT _nx_secure_tls_proc_serverhello_ecjpake_key_kp_pair(NX_SECURE_TLS_SESSION *tls_session,
540                                                                 UCHAR *packet_buffer,
541                                                                 USHORT *extension_length, UINT message_length)
542 {
543 UINT                                  status;
544 NX_CRYPTO_METHOD                     *crypto_method;
545 
546     *extension_length = (USHORT)((*packet_buffer << 8) + packet_buffer[1] + 2);
547 
548     if (*extension_length > message_length || *extension_length <= 2)
549     {
550         return(NX_SECURE_TLS_INCORRECT_MESSAGE_LENGTH);
551     }
552 
553     if (tls_session -> nx_secure_tls_session_ciphersuite == NX_NULL)
554     {
555         return(NX_SECURE_TLS_UNKNOWN_CIPHERSUITE);
556     }
557 
558     /* Ignore the extension if we are not using ECJPAKE. */
559     if (tls_session -> nx_secure_tls_session_ciphersuite -> nx_secure_tls_public_auth -> nx_crypto_algorithm == NX_CRYPTO_KEY_EXCHANGE_ECJPAKE)
560     {
561 
562         crypto_method = (NX_CRYPTO_METHOD*)tls_session -> nx_secure_tls_session_ciphersuite -> nx_secure_tls_public_auth;
563 
564         /* ecjpake_key_kp_pair Extension.  */
565         status = crypto_method -> nx_crypto_operation(NX_CRYPTO_ECJPAKE_SERVER_HELLO_PROCESS,
566                                                       tls_session -> nx_secure_public_auth_handler,
567                                                       crypto_method,
568                                                       NX_NULL, 0,
569                                                       &packet_buffer[2], /* Skip extension length. */
570                                                       (ULONG)(*extension_length - 2),
571                                                       NX_NULL, NX_NULL, 0,
572                                                       tls_session -> nx_secure_public_auth_metadata_area,
573                                                       tls_session -> nx_secure_public_auth_metadata_size,
574                                                       NX_NULL, NX_NULL);
575         if (status)
576         {
577             return(status);
578         }
579     }
580 
581     return(NX_SUCCESS);
582 }
583 #endif
584 
585 /**************************************************************************/
586 /*                                                                        */
587 /*  FUNCTION                                               RELEASE        */
588 /*                                                                        */
589 /*    _nx_secure_tls_proc_serverhello_sec_reneg_extension PORTABLE C      */
590 /*                                                           6.1          */
591 /*  AUTHOR                                                                */
592 /*                                                                        */
593 /*    Timothy Stapko, Microsoft Corporation                               */
594 /*                                                                        */
595 /*  DESCRIPTION                                                           */
596 /*                                                                        */
597 /*    This function parses the Secure Renegotiation Indication extension  */
598 /*    from an incoming ServerHello record.See RFC 5746 for more           */
599 /*    information.                                                        */
600 /*                                                                        */
601 /*  INPUT                                                                 */
602 /*                                                                        */
603 /*    tls_session                           TLS control block             */
604 /*    packet_buffer                         Outgoing TLS packet buffer    */
605 /*    extension_length                      Length of extension data      */
606 /*    message_length                        Length of message data (bytes)*/
607 /*                                                                        */
608 /*  OUTPUT                                                                */
609 /*                                                                        */
610 /*    status                                Completion status             */
611 /*                                                                        */
612 /*  CALLS                                                                 */
613 /*                                                                        */
614 /*    None                                                                */
615 /*                                                                        */
616 /*  CALLED BY                                                             */
617 /*                                                                        */
618 /*    _nx_secure_tls_process_serverhello_extensions                       */
619 /*                                          Process ServerHello extensions*/
620 /*                                                                        */
621 /*  RELEASE HISTORY                                                       */
622 /*                                                                        */
623 /*    DATE              NAME                      DESCRIPTION             */
624 /*                                                                        */
625 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
626 /*  09-30-2020     Timothy Stapko           Modified comment(s),          */
627 /*                                            fixed renegotiation bug,    */
628 /*                                            resulting in version 6.1    */
629 /*                                                                        */
630 /**************************************************************************/
631 #ifndef NX_SECURE_TLS_DISABLE_SECURE_RENEGOTIATION
_nx_secure_tls_proc_serverhello_sec_reneg_extension(NX_SECURE_TLS_SESSION * tls_session,UCHAR * packet_buffer,USHORT * extension_length,UINT message_length)632 static UINT _nx_secure_tls_proc_serverhello_sec_reneg_extension(NX_SECURE_TLS_SESSION *tls_session,
633                                                                 UCHAR *packet_buffer,
634                                                                 USHORT *extension_length, UINT message_length)
635 {
636 ULONG  offset;
637 UCHAR  renegotiated_connection_length;
638 USHORT parsed_length;
639 INT    compare_value;
640 
641     /* Secure Renegotiation Indication Extensions structure (for serverhello):
642      * Initial ServerHello:
643      * |     2      |     2     |        1         |
644      * |  Ext Type  |  Ext Len  |  Reneg Info Len  |
645      * |   0xff01   |   0x0001  |       0x00       |
646      *
647      * Renegotiating ServerHello:
648      * |     2      |     2     |        1         |         12         |         12           |
649      * |  Ext Type  |  Ext Len  |  Reneg Info Len  | client_verify_data |  server_verify_data  |
650      * |   0xff01   |   0x0019  |       0x18       |                    |                      |
651      */
652     /*  From RFC 5746:
653         struct {
654              opaque renegotiated_connection<0..255>;
655          } RenegotiationInfo;
656 
657           The contents of this extension are specified as follows.
658 
659       -  If this is the initial handshake for a connection, then the
660          "renegotiated_connection" field is of zero length in both the
661          ClientHello and the ServerHello.  Thus, the entire encoding of the
662          extension is ff 01 00 01 00.  The first two octets represent the
663          extension type, the third and fourth octets the length of the
664          extension itself, and the final octet the zero length byte for the
665          "renegotiated_connection" field.
666 
667       -  For ClientHellos that are renegotiating, this field contains the
668          "client_verify_data" specified in Section 3.1.
669 
670       -  For ServerHellos that are renegotiating, this field contains the
671          concatenation of client_verify_data and server_verify_data.  For
672          current versions of TLS, this will be a 24-byte value (for SSLv3,
673          it will be a 72-byte value).
674      */
675 
676     /* Get the extension length. */
677     parsed_length = (USHORT)((packet_buffer[0] << 8) + packet_buffer[1]);
678     *extension_length = (USHORT)(2 + parsed_length);
679     offset = 2;
680 
681     if (*extension_length > message_length || *extension_length < 3)
682     {
683         return(NX_SECURE_TLS_INCORRECT_MESSAGE_LENGTH);
684     }
685 
686     /* Get the "renegotiated_connection" field. */
687     renegotiated_connection_length = packet_buffer[offset];
688     offset++;
689 
690     if (offset + renegotiated_connection_length > *extension_length)
691     {
692         return(NX_SECURE_TLS_INCORRECT_MESSAGE_LENGTH);
693     }
694 
695     /* See if the client is attempting to renegotiate an established connection. */
696     if (renegotiated_connection_length)
697     {
698         /* The remote host is attempting a renegotiation - make sure our local session is active and renegotiation is OK. */
699         if (!tls_session -> nx_secure_tls_local_session_active || !tls_session -> nx_secure_tls_remote_session_active)
700         {
701             /* Remote host is attempting a renegotiation but the server is not currently in a session! */
702             return(NX_SECURE_TLS_RENEGOTIATION_EXTENSION_ERROR);
703         }
704 
705         if(!tls_session -> nx_secure_tls_secure_renegotiation)
706         {
707             return(NX_SECURE_TLS_RENEGOTIATION_EXTENSION_ERROR);
708         }
709 
710 
711         /* Check that the received verification data is the expected size. For ServerHello, the size is twice the
712            finished verification hash size because it includes both client and server hashes. */
713         if (renegotiated_connection_length != (2 * NX_SECURE_TLS_FINISHED_HASH_SIZE))
714         {
715             /* Do not have the right amount of data for comparison. */
716             return(NX_SECURE_TLS_RENEGOTIATION_EXTENSION_ERROR);
717         }
718 
719         /* Compare the received verify data to our locally-stored version - start with client (local) verify data. */
720         compare_value = NX_SECURE_MEMCMP(&packet_buffer[offset], tls_session -> nx_secure_tls_local_verify_data, NX_SECURE_TLS_FINISHED_HASH_SIZE);
721 
722         if (compare_value)
723         {
724             /* Session verify data did not match what we expect - error. */
725             return(NX_SECURE_TLS_RENEGOTIATION_EXTENSION_ERROR);
726         }
727 
728         /* Now compare the remote verify data with what we just received. */
729         offset += NX_SECURE_TLS_FINISHED_HASH_SIZE;
730         compare_value = NX_SECURE_MEMCMP(&packet_buffer[offset], tls_session -> nx_secure_tls_remote_verify_data, NX_SECURE_TLS_FINISHED_HASH_SIZE);
731 
732         if (compare_value)
733         {
734             /* Session verify data did not match what we expect - error. */
735             return(NX_SECURE_TLS_RENEGOTIATION_EXTENSION_ERROR);
736         }
737 
738         /* If we get here, the verification data is good! */
739         tls_session -> nx_secure_tls_secure_renegotiation_verified = NX_TRUE;
740     }
741     else
742     {
743         /* Verify that the extension contains only the initial handshake data - this is a new connection. */
744         if ((parsed_length != 1) || (tls_session -> nx_secure_tls_local_session_active))
745         {
746             /* Error - the provided extension length was not expected for an initial handshake. */
747             return(NX_SECURE_TLS_RENEGOTIATION_EXTENSION_ERROR);
748         }
749 
750         /* The remote host supports secure renegotiation. */
751         tls_session -> nx_secure_tls_secure_renegotiation = NX_TRUE;
752     }
753 
754     return(NX_SUCCESS);
755 }
756 #endif
757 
758 
759 /**************************************************************************/
760 /*                                                                        */
761 /*  FUNCTION                                               RELEASE        */
762 /*                                                                        */
763 /*    _nx_secure_tls_proc_serverhello_keyshare_extension  PORTABLE C      */
764 /*                                                           6.2.0        */
765 /*  AUTHOR                                                                */
766 /*                                                                        */
767 /*    Timothy Stapko, Microsoft Corporation                               */
768 /*                                                                        */
769 /*  DESCRIPTION                                                           */
770 /*                                                                        */
771 /*    This function parses the Key Share extension introduced in TLS 1.3. */
772 /*                                                                        */
773 /*  INPUT                                                                 */
774 /*                                                                        */
775 /*    tls_session                           TLS control block             */
776 /*    packet_buffer                         Outgoing TLS packet buffer    */
777 /*    extension_length                      Length of extension data      */
778 /*    message_length                        Length of message data (bytes)*/
779 /*                                                                        */
780 /*  OUTPUT                                                                */
781 /*                                                                        */
782 /*    status                                Completion status             */
783 /*                                                                        */
784 /*  CALLS                                                                 */
785 /*                                                                        */
786 /*    None                                                                */
787 /*                                                                        */
788 /*  CALLED BY                                                             */
789 /*                                                                        */
790 /*    _nx_secure_tls_process_serverhello_extensions                       */
791 /*                                          Process ServerHello extensions*/
792 /*                                                                        */
793 /*  RELEASE HISTORY                                                       */
794 /*                                                                        */
795 /*    DATE              NAME                      DESCRIPTION             */
796 /*                                                                        */
797 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
798 /*  09-30-2020     Timothy Stapko           Modified comment(s), update   */
799 /*                                            ECC find curve method,      */
800 /*                                            resulting in version 6.1    */
801 /*  04-25-2022     Yuxin Zhou               Modified comment(s), removed  */
802 /*                                            public key format checking, */
803 /*                                            resulting in version 6.1.11 */
804 /*  10-31-2022     Yanwu Cai                Modified comment(s),          */
805 /*                                            updated parameters list,    */
806 /*                                            resulting in version 6.2.0  */
807 /*                                                                        */
808 /**************************************************************************/
809 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
810 
811 extern NX_CRYPTO_METHOD crypto_method_ecdhe;
812 
_nx_secure_tls_proc_serverhello_keyshare_extension(NX_SECURE_TLS_SESSION * tls_session,UCHAR * packet_buffer,USHORT * extension_length,UINT message_length)813 static UINT _nx_secure_tls_proc_serverhello_keyshare_extension(NX_SECURE_TLS_SESSION *tls_session,
814                                                                 UCHAR *packet_buffer,
815                                                                 USHORT *extension_length, UINT message_length)
816 {
817 UINT status;
818 UINT i;
819 ULONG  offset;
820 USHORT key_group;
821 USHORT key_length;
822 NX_SECURE_TLS_ECDHE_HANDSHAKE_DATA *ecc_key_data;
823 UCHAR                                *pubkey;
824 UCHAR                                *private_key;
825 UINT                                  private_key_length;
826 NX_CRYPTO_EXTENDED_OUTPUT             extended_output;
827 NX_CRYPTO_METHOD                     *ecdhe_method;
828 const NX_CRYPTO_METHOD               *curve_method;
829 VOID                                 *handler = NX_NULL;
830 NX_SECURE_TLS_ECC *ecc_info;
831 
832     /* Key Share Extension structure (for serverhello):
833      *
834      * ServerHello:
835      * |      2     |     2     |     <key len>       |
836      * |  Key Group |  Key Len  |  Key Exchange value |
837      */
838 
839     offset = 0;
840 
841     /* Extract the extension length. */
842     *extension_length = (USHORT)((packet_buffer[offset] << 8) + packet_buffer[offset + 1]);
843     offset = (USHORT)(offset + 2);
844 
845     if (offset + *extension_length > message_length || *extension_length < 2)
846     {
847         return(NX_SECURE_TLS_INCORRECT_MESSAGE_LENGTH);
848     }
849 
850     /* Get the key group. It must match one we sent in our ClientHello KeyShare extension. */
851     key_group = (USHORT)((packet_buffer[offset] << 8) + packet_buffer[offset + 1]);
852     offset = (USHORT)(offset + 2);
853 
854     /* Get our session ECC data. */
855     ecc_info = &(tls_session -> nx_secure_tls_ecc);
856 
857     /* Check the key group. */
858     key_group = (USHORT)((ULONG)key_group | NX_CRYPTO_EC_MASK);
859 
860 
861     /* Loop through all supported ECC curves in this session. */
862     for (i = 0; i < ecc_info -> nx_secure_tls_ecc_supported_groups_count; i++)
863     {
864         /* Find the matchin group in the keys we generated and saved. */
865         if (key_group != tls_session -> nx_secure_tls_key_material.nx_secure_tls_ecc_key_data[i].nx_secure_tls_ecdhe_named_curve)
866         {
867             continue;
868         }
869 
870         /* Store selected ECDHE key data index. */
871         tls_session -> nx_secure_tls_key_material.nx_secure_tls_ecc_key_data_selected = i;
872 
873         if (tls_session -> nx_secure_tls_client_state == NX_SECURE_TLS_CLIENT_STATE_HELLO_RETRY)
874         {
875 
876             /* A HelloRetryRequest is received. Done here. */
877             return(NX_SUCCESS);
878         }
879 
880         /* Got a matching key/curve combo, get a pointer to the selected key data. */
881         ecc_key_data = tls_session -> nx_secure_tls_key_material.nx_secure_tls_ecc_key_data;
882 
883         if (*extension_length < 4)
884         {
885             return(NX_SECURE_TLS_INCORRECT_MESSAGE_LENGTH);
886         }
887 
888         /* Get the key length. */
889         key_length = (USHORT)((packet_buffer[offset] << 8) + packet_buffer[offset + 1]);
890         if (offset + key_length > *extension_length)
891         {
892             return(NX_SECURE_TLS_INCORRECT_MESSAGE_LENGTH);
893         }
894         offset = (USHORT)(offset + 2);
895 
896         /* Initialize the remote public key in our session. */
897         pubkey = &packet_buffer[offset];
898 
899         /* Get the curve method to initialize the remote public key data. */
900         _nx_secure_tls_find_curve_method(&tls_session -> nx_secure_tls_ecc, key_group, &curve_method, NX_NULL);
901 
902         if (curve_method == NX_NULL)
903         {
904             return(NX_SECURE_TLS_MISSING_CRYPTO_ROUTINE);
905         }
906 
907         /* Get the ECDHE method we are going to use. */
908         ecdhe_method = &crypto_method_ecdhe;
909 
910         if (ecdhe_method -> nx_crypto_operation == NX_NULL )
911         {
912             return(NX_SECURE_TLS_MISSING_CRYPTO_ROUTINE);
913         }
914 
915         /* Initialize the ECDHE method. */
916         if (ecdhe_method -> nx_crypto_init != NX_NULL)
917         {
918             status = ecdhe_method -> nx_crypto_init(ecdhe_method,
919                                                     NX_NULL,
920                                                     0,
921                                                     &handler,
922                                                     tls_session -> nx_secure_public_cipher_metadata_area,
923                                                     tls_session -> nx_secure_public_cipher_metadata_size);
924 
925             if (status != NX_CRYPTO_SUCCESS)
926             {
927                 return(status);
928             }
929         }
930 
931         /* Set the curve we want to use. */
932         status = ecdhe_method -> nx_crypto_operation(NX_CRYPTO_EC_CURVE_SET, handler,
933                                                      ecdhe_method, NX_NULL, 0,
934                                                      (UCHAR *)curve_method, sizeof(NX_CRYPTO_METHOD *), NX_NULL,
935                                                      NX_NULL, 0,
936                                                      tls_session -> nx_secure_public_cipher_metadata_area,
937                                                      tls_session -> nx_secure_public_cipher_metadata_size,
938                                                      NX_NULL, NX_NULL);
939         if (status != NX_CRYPTO_SUCCESS)
940         {
941             return(status);
942         }
943 
944         /* Import the private key to the ECDH context. */
945         private_key = &ecc_key_data[i].nx_secure_tls_ecdhe_private_key[0];
946         private_key_length = ecc_key_data[i].nx_secure_tls_ecdhe_private_key_length;
947 
948         status = ecdhe_method -> nx_crypto_operation(NX_CRYPTO_DH_KEY_PAIR_IMPORT, handler,
949                                                     (NX_CRYPTO_METHOD*)ecdhe_method,
950                                                     private_key, private_key_length << 3,
951                                                     NX_NULL, 0, NX_NULL,
952                                                     NX_NULL,
953                                                     0,
954                                                     tls_session -> nx_secure_public_cipher_metadata_area,
955                                                     tls_session -> nx_secure_public_cipher_metadata_size,
956                                                     NX_NULL, NX_NULL);
957 
958 
959         if (status != NX_CRYPTO_SUCCESS)
960         {
961             return(status);
962         }
963 
964         //tls_session -> nx_secure_tls_key_material.nx_secure_tls_new_key_material_data[0] = (UCHAR)extended_output.nx_crypto_extended_output_actual_size;
965 
966         /* Calculate the final pre_master_secret - the "private key" here is the Pre-Master Secret. */
967         extended_output.nx_crypto_extended_output_data = tls_session -> nx_secure_tls_key_material.nx_secure_tls_pre_master_secret;
968         extended_output.nx_crypto_extended_output_length_in_byte = sizeof(tls_session -> nx_secure_tls_key_material.nx_secure_tls_pre_master_secret);
969         extended_output.nx_crypto_extended_output_actual_size = 0;
970         status = ecdhe_method -> nx_crypto_operation(NX_CRYPTO_DH_CALCULATE, handler,
971                                                      ecdhe_method, NX_NULL, 0,
972                                                      pubkey, key_length, NX_NULL,
973                                                      (UCHAR *)&extended_output,
974                                                      sizeof(extended_output),
975                                                      tls_session -> nx_secure_public_cipher_metadata_area,
976                                                      tls_session -> nx_secure_public_cipher_metadata_size,
977                                                      NX_NULL, NX_NULL);
978         if (status != NX_CRYPTO_SUCCESS)
979         {
980             return(status);
981         }
982 
983         tls_session -> nx_secure_tls_key_material.nx_secure_tls_pre_master_secret_size = extended_output.nx_crypto_extended_output_actual_size;
984 
985         if (ecdhe_method -> nx_crypto_cleanup)
986         {
987             status = ecdhe_method -> nx_crypto_cleanup(tls_session -> nx_secure_public_cipher_metadata_area);
988         }
989 
990         return(status);
991     }
992 
993     /* If we exhaust the list of ECC curves we sent, the server is doing something weird. */
994     return(NX_SECURE_TLS_BAD_SERVERHELLO_KEYSHARE);
995 
996 }
997 
998 /**************************************************************************/
999 /*                                                                        */
1000 /*  FUNCTION                                               RELEASE        */
1001 /*                                                                        */
1002 /*    _nx_secure_tls_proc_serverhello_supported_versions_extension        */
1003 /*                                                        PORTABLE C      */
1004 /*                                                           6.1          */
1005 /*  AUTHOR                                                                */
1006 /*                                                                        */
1007 /*    Timothy Stapko, Microsoft Corporation                               */
1008 /*                                                                        */
1009 /*  DESCRIPTION                                                           */
1010 /*                                                                        */
1011 /*    This function parses the supported versions extension introduced in */
1012 /*    TLS 1.3.                                                            */
1013 /*                                                                        */
1014 /*  INPUT                                                                 */
1015 /*                                                                        */
1016 /*    tls_session                           TLS control block             */
1017 /*    packet_buffer                         Outgoing TLS packet buffer    */
1018 /*    supported_version                     Supported version             */
1019 /*    extension_length                      Length of extension data      */
1020 /*    message_length                        Length of message data (bytes)*/
1021 /*                                                                        */
1022 /*  OUTPUT                                                                */
1023 /*                                                                        */
1024 /*    status                                Completion status             */
1025 /*                                                                        */
1026 /*  CALLS                                                                 */
1027 /*                                                                        */
1028 /*    None                                                                */
1029 /*                                                                        */
1030 /*  CALLED BY                                                             */
1031 /*                                                                        */
1032 /*    _nx_secure_tls_process_serverhello_extensions                       */
1033 /*                                          Process ServerHello extensions*/
1034 /*                                                                        */
1035 /*  RELEASE HISTORY                                                       */
1036 /*                                                                        */
1037 /*    DATE              NAME                      DESCRIPTION             */
1038 /*                                                                        */
1039 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
1040 /*  09-30-2020     Timothy Stapko           Modified comment(s),          */
1041 /*                                            resulting in version 6.1    */
1042 /*                                                                        */
1043 /**************************************************************************/
_nx_secure_tls_proc_serverhello_supported_versions_extension(NX_SECURE_TLS_SESSION * tls_session,UCHAR * packet_buffer,USHORT * supported_version,USHORT * extension_length,UINT message_length)1044 static UINT _nx_secure_tls_proc_serverhello_supported_versions_extension(NX_SECURE_TLS_SESSION *tls_session,
1045                                                                          UCHAR *packet_buffer,
1046                                                                          USHORT *supported_version,
1047                                                                          USHORT *extension_length, UINT message_length)
1048 {
1049 ULONG  offset;
1050 
1051     NX_PARAMETER_NOT_USED(tls_session);
1052 
1053     /* Supported Versions Extension structure (for serverhello):
1054      *
1055      * ServerHello:
1056      * |   2   |     2    |        ...         |
1057      * |  Type |  Length  |  Selected Version  |
1058      */
1059 
1060     /* RFC 8446, section 4.2.1, page 39.
1061      * A server negotiates TLS 1.3 MUST respond with 0x0304 in supported_versions extension.
1062      */
1063 
1064     offset = 0;
1065 
1066     /* Extract the extension length. */
1067     *extension_length = (USHORT)((packet_buffer[offset] << 8) + packet_buffer[offset + 1]);
1068     offset = (USHORT)(offset + 2);
1069 
1070     if (offset + *extension_length > message_length || *extension_length != 2)
1071     {
1072         return(NX_SECURE_TLS_INCORRECT_MESSAGE_LENGTH);
1073     }
1074 
1075     /* Find the selected version 0x0304(TLS 1.3). */
1076     *supported_version = (USHORT)((packet_buffer[offset] << 8) + packet_buffer[offset + 1]);
1077     if (*supported_version == NX_SECURE_TLS_VERSION_TLS_1_3)
1078     {
1079         return(NX_SUCCESS);
1080     }
1081 
1082     return(NX_SECURE_TLS_UNKNOWN_TLS_VERSION);
1083 
1084 }
1085 #endif
1086 
1087 #endif /* NX_SECURE_TLS_CLIENT_DISABLED */
1088