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 #if !defined(NX_SECURE_TLS_DISABLE_SECURE_RENEGOTIATION)
27 static UINT _nx_secure_tls_proc_clienthello_sec_reneg_extension(NX_SECURE_TLS_SESSION *tls_session,
28                                                                 UCHAR *packet_buffer,
29                                                                 UINT extension_length);
30 #endif
31 
32 
33 #if (NX_SECURE_TLS_TLS_1_3_ENABLED) && !defined(NX_SECURE_TLS_SERVER_DISABLED)
34 static UINT _nx_secure_tls_proc_clienthello_keyshare_extension(NX_SECURE_TLS_SESSION *tls_session,
35                                                                 UCHAR *packet_buffer,
36                                                                 USHORT extension_length);
37 static UINT _nx_secure_tls_proc_clienthello_supported_versions_extension(NX_SECURE_TLS_SESSION *tls_session,
38                                                                          UCHAR *packet_buffer,
39                                                                          USHORT *supported_version,
40                                                                          USHORT extension_length);
41 static VOID _nx_secure_tls_proc_clienthello_signature_algorithms_extension(NX_SECURE_TLS_SESSION *tls_session,
42                                                                            const UCHAR *packet_buffer,
43                                                                            USHORT extension_length);
44 
45 #ifdef NX_SECURE_ENABLE_PSK_CIPHERSUITES
46 static UINT _nx_secure_tls_process_clienthello_psk_extension(NX_SECURE_TLS_SESSION *tls_session, const UCHAR *packet_buffer,
47                                                              USHORT extension_length, const UCHAR *client_hello_buffer, UINT client_hello_length);
48 #endif
49 #endif
50 
51 
52 /**************************************************************************/
53 /*                                                                        */
54 /*  FUNCTION                                               RELEASE        */
55 /*                                                                        */
56 /*    _nx_secure_tls_process_clienthello_extensions       PORTABLE C      */
57 /*                                                           6.1.9        */
58 /*  AUTHOR                                                                */
59 /*                                                                        */
60 /*    Timothy Stapko, Microsoft Corporation                               */
61 /*                                                                        */
62 /*  DESCRIPTION                                                           */
63 /*                                                                        */
64 /*    This function processes any extensions included in an incoming      */
65 /*    ClientHello message from a remote host.                             */
66 /*                                                                        */
67 /*  INPUT                                                                 */
68 /*                                                                        */
69 /*    tls_session                           TLS control block             */
70 /*    packet_buffer                         Pointer to message data       */
71 /*    message_length                        Length of message data (bytes)*/
72 /*    extensions                            Extensions for output         */
73 /*    num_extensions                        Number of extensions          */
74 /*                                                                        */
75 /*  OUTPUT                                                                */
76 /*                                                                        */
77 /*    status                                Completion status             */
78 /*                                                                        */
79 /*  CALLS                                                                 */
80 /*                                                                        */
81 /*    _nx_secure_tls_proc_clienthello_sec_reneg_extension                 */
82 /*                                          Process ClientHello           */
83 /*                                            Renegotiation extension     */
84 /*    _nx_secure_tls_proc_clienthello_ec_groups_extension                 */
85 /*                                          Process ClientHello           */
86 /*                                            EC groups extension         */
87 /*    _nx_secure_tls_proc_clienthello_ec_point_formats_extension          */
88 /*                                          Process ClientHello           */
89 /*                                            EC point formats extension  */
90 /*                                                                        */
91 /*  CALLED BY                                                             */
92 /*                                                                        */
93 /*    _nx_secure_tls_process_clienthello    Process ClientHello           */
94 /*                                                                        */
95 /*  RELEASE HISTORY                                                       */
96 /*                                                                        */
97 /*    DATE              NAME                      DESCRIPTION             */
98 /*                                                                        */
99 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
100 /*  09-30-2020     Timothy Stapko           Modified comment(s),          */
101 /*                                            fixed renegotiation bug,    */
102 /*                                            resulting in version 6.1    */
103 /*  10-15-2021     Timothy Stapko           Modified comment(s), added    */
104 /*                                            ability to disable client   */
105 /*                                            initiated renegotiation,    */
106 /*                                            resulting in version 6.1.9  */
107 /*                                                                        */
108 /**************************************************************************/
_nx_secure_tls_process_clienthello_extensions(NX_SECURE_TLS_SESSION * tls_session,UCHAR * packet_buffer,UINT message_length,NX_SECURE_TLS_HELLO_EXTENSION * extensions,UINT * num_extensions,UCHAR * client_hello_buffer,UINT client_hello_length)109 UINT _nx_secure_tls_process_clienthello_extensions(NX_SECURE_TLS_SESSION *tls_session,
110                                                    UCHAR *packet_buffer, UINT message_length,
111                                                    NX_SECURE_TLS_HELLO_EXTENSION *extensions,
112                                                    UINT *num_extensions, UCHAR *client_hello_buffer, UINT client_hello_length)
113 {
114 UINT   status = NX_SUCCESS;
115 UINT   offset;
116 UINT   max_extensions;
117 USHORT extension_id;
118 UINT   extension_length;
119 #if (NX_SECURE_TLS_TLS_1_3_ENABLED) && !defined(NX_SECURE_TLS_SERVER_DISABLED)
120 USHORT supported_version = tls_session -> nx_secure_tls_protocol_version;
121 #endif
122 
123 #if defined(NX_SECURE_TLS_DISABLE_SECURE_RENEGOTIATION) || defined(NX_SECURE_TLS_DISABLE_CLIENT_INITIATED_RENEGOTIATION)
124     NX_PARAMETER_NOT_USED(tls_session);
125 #endif /* NX_SECURE_TLS_DISABLE_SECURE_RENEGOTIATION */
126 
127 #if !(NX_SECURE_TLS_TLS_1_3_ENABLED) || !defined(NX_SECURE_ENABLE_PSK_CIPHERSUITES)
128     NX_PARAMETER_NOT_USED(client_hello_buffer);
129     NX_PARAMETER_NOT_USED(client_hello_length);
130 #endif
131 
132     max_extensions = *num_extensions;
133     offset = 0;
134     *num_extensions = 0;
135 
136     /* Process extensions until we run out. */
137     while (offset < message_length && *num_extensions < max_extensions)
138     {
139 
140         /* Make sure there are at least 4 bytes available so we can read extension_id and
141            extension_length. */
142         if((offset + 4) > message_length)
143         {
144             return(NX_SECURE_TLS_INCORRECT_MESSAGE_LENGTH);
145         }
146 
147         /* See what the extension is. */
148         extension_id = (USHORT)((packet_buffer[offset] << 8) + packet_buffer[offset + 1]);
149         offset += 2;
150 
151         /* Get extension length. */
152         extension_length = (UINT)((packet_buffer[offset] << 8) + packet_buffer[offset + 1]);
153         offset += 2;
154 
155         /* Verify the message_length is at least "extension_length". */
156         if((offset + extension_length) > message_length)
157         {
158             return(NX_SECURE_TLS_INCORRECT_MESSAGE_LENGTH);
159         }
160 
161         /* Parse the extension. */
162         switch (extension_id)
163         {
164 #if !defined(NX_SECURE_TLS_DISABLE_SECURE_RENEGOTIATION)
165         case NX_SECURE_TLS_EXTENSION_SECURE_RENEGOTIATION:
166             status = _nx_secure_tls_proc_clienthello_sec_reneg_extension(tls_session,
167                                                                          &packet_buffer[offset],
168                                                                          extension_length);
169 
170             if (status)
171             {
172                 return(status);
173             }
174             break;
175 #endif /* NX_SECURE_TLS_DISABLE_SECURE_RENEGOTIATION */
176 
177 #if (NX_SECURE_TLS_TLS_1_3_ENABLED) && !defined(NX_SECURE_TLS_SERVER_DISABLED)
178         case NX_SECURE_TLS_EXTENSION_KEY_SHARE:
179             if(tls_session -> nx_secure_tls_1_3)
180             {
181                 /* If TLS 1.3, process the key share extension. */
182                 status = _nx_secure_tls_proc_clienthello_keyshare_extension(tls_session,
183                                                                             &packet_buffer[offset],
184                                                                             (USHORT)extension_length);
185 
186                 if (status)
187                 {
188                     return(status);
189                 }
190             }
191             /* TLS 1.2 and earlier: ignore extension. */
192             break;
193         case NX_SECURE_TLS_EXTENSION_SUPPORTED_VERSIONS:
194             if(tls_session -> nx_secure_tls_1_3)
195             {
196 
197                 /* Process the TLS 1.3 supported_versions extension. */
198                 status = _nx_secure_tls_proc_clienthello_supported_versions_extension(tls_session,
199                                                                                       &packet_buffer[offset],
200                                                                                       &supported_version,
201                                                                                       (USHORT)extension_length);
202 
203                 if (status)
204                 {
205                     return(status);
206                 }
207             }
208 
209             /* Ignore if not TLS 1.3. */
210             break;
211 #ifdef NX_SECURE_ENABLE_PSK_CIPHERSUITES
212         case NX_SECURE_TLS_EXTENSION_PRE_SHARED_KEY:
213             if(tls_session -> nx_secure_tls_1_3)
214             {
215 
216                 /* Process the TLS 1.3 PSK extension. */
217                 status = _nx_secure_tls_process_clienthello_psk_extension(tls_session, &packet_buffer[offset],
218                                                                           (USHORT)extension_length, client_hello_buffer, client_hello_length);
219 
220                 if (status)
221                 {
222                     return(status);
223                 }
224             }
225             break;
226 #endif
227 #endif
228 
229         case NX_SECURE_TLS_EXTENSION_SIGNATURE_ALGORITHMS:
230         case NX_SECURE_TLS_EXTENSION_SERVER_NAME_INDICATION:
231         case NX_SECURE_TLS_EXTENSION_MAX_FRAGMENT_LENGTH:
232         case NX_SECURE_TLS_EXTENSION_CLIENT_CERTIFICATE_URL:
233         case NX_SECURE_TLS_EXTENSION_TRUSTED_CA_INDICATION:
234         case NX_SECURE_TLS_EXTENSION_CERTIFICATE_STATUS_REQUEST:
235         case NX_SECURE_TLS_EXTENSION_EC_GROUPS:
236         case NX_SECURE_TLS_EXTENSION_EC_POINT_FORMATS:
237         case NX_SECURE_TLS_EXTENSION_ECJPAKE_KEY_KP_PAIR:
238             /* These extensions require information to be passed to the application. Save off
239                the extension data in our extensions array to pass along in the hello callback. */
240             extensions[*num_extensions].nx_secure_tls_extension_id = extension_id;
241             extensions[*num_extensions].nx_secure_tls_extension_data = &packet_buffer[offset];
242             extensions[*num_extensions].nx_secure_tls_extension_data_length = (USHORT)extension_length;
243 
244             /* Added another extension to the array. */
245             *num_extensions = *num_extensions + 1;
246 
247             break;
248         case NX_SECURE_TLS_EXTENSION_TRUNCATED_HMAC:
249         default:
250             /* Unknown or unsupported extension, just ignore - TLS supports multiple extensions and the default
251                behavior is to ignore any extensions that we don't know. */
252             break;
253         }
254 
255         /* Adjust our offset with the length of the extension we just parsed. */
256         offset += extension_length;
257     }
258 
259 #if (NX_SECURE_TLS_TLS_1_3_ENABLED) && !defined(NX_SECURE_TLS_SERVER_DISABLED)
260     if((tls_session -> nx_secure_tls_1_3) && (supported_version != NX_SECURE_TLS_VERSION_TLS_1_3))
261     {
262 
263         /* Negotiate a version of TLS prior to TLS 1.3. */
264         if (tls_session -> nx_secure_tls_protocol_version_override == 0)
265         {
266             tls_session -> nx_secure_tls_1_3 = NX_FALSE;
267 #if !defined(NX_SECURE_TLS_DISABLE_SECURE_RENEGOTIATION)
268             tls_session -> nx_secure_tls_renegotation_enabled = NX_TRUE;
269 #endif /* NX_SECURE_TLS_DISABLE_SECURE_RENEGOTIATION */
270             tls_session -> nx_secure_tls_protocol_version = supported_version;
271         }
272         else
273         {
274 
275             /* Protocol version is overridden to TLS 1.3. */
276             return(NX_SECURE_TLS_UNSUPPORTED_TLS_VERSION);
277         }
278     }
279 #endif
280 
281     return(status);
282 }
283 
284 
285 
286 /**************************************************************************/
287 /*                                                                        */
288 /*  FUNCTION                                               RELEASE        */
289 /*                                                                        */
290 /*    _nx_secure_tls_proc_clienthello_sec_reneg_extension PORTABLE C      */
291 /*                                                           6.1.9        */
292 /*  AUTHOR                                                                */
293 /*                                                                        */
294 /*    Timothy Stapko, Microsoft Corporation                               */
295 /*                                                                        */
296 /*  DESCRIPTION                                                           */
297 /*                                                                        */
298 /*    This function parses the Secure Renegotiation Indication extension  */
299 /*    from an incoming ClientHello record.See RFC 5746 for more           */
300 /*    information.                                                        */
301 /*                                                                        */
302 /*  INPUT                                                                 */
303 /*                                                                        */
304 /*    tls_session                           TLS control block             */
305 /*    packet_buffer                         Outgoing TLS packet buffer    */
306 /*    extension_length                      Length of extension data      */
307 /*                                                                        */
308 /*  OUTPUT                                                                */
309 /*                                                                        */
310 /*    status                                Completion status             */
311 /*                                                                        */
312 /*  CALLS                                                                 */
313 /*                                                                        */
314 /*    None                                                                */
315 /*                                                                        */
316 /*  CALLED BY                                                             */
317 /*                                                                        */
318 /*    _nx_secure_tls_process_clienthello_extensions                       */
319 /*                                          Process ClientHello extensions*/
320 /*                                                                        */
321 /*  RELEASE HISTORY                                                       */
322 /*                                                                        */
323 /*    DATE              NAME                      DESCRIPTION             */
324 /*                                                                        */
325 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
326 /*  09-30-2020     Timothy Stapko           Modified comment(s),          */
327 /*                                            fixed renegotiation bug,    */
328 /*                                            resulting in version 6.1    */
329 /*  10-15-2021     Timothy Stapko           Modified comment(s), added    */
330 /*                                            ability to disable client   */
331 /*                                            initiated renegotiation,    */
332 /*                                            resulting in version 6.1.9  */
333 /*                                                                        */
334 /**************************************************************************/
335 #if !defined(NX_SECURE_TLS_DISABLE_SECURE_RENEGOTIATION)
_nx_secure_tls_proc_clienthello_sec_reneg_extension(NX_SECURE_TLS_SESSION * tls_session,UCHAR * packet_buffer,UINT extension_length)336 static UINT _nx_secure_tls_proc_clienthello_sec_reneg_extension(NX_SECURE_TLS_SESSION *tls_session,
337                                                                 UCHAR *packet_buffer,
338                                                                 UINT extension_length)
339 {
340 ULONG  offset = 0;
341 UCHAR  renegotiated_connection_length;
342 INT    compare_value;
343 
344     /* Secure Renegotiation Indication Extensions structure:
345      * Initial ClientHello:
346      * |     2      |     2     |        1         |
347      * |  Ext Type  |  Ext Len  |  Reneg Info Len  |
348      * |   0xff01   |   0x0001  |       0x00       |
349      *
350      * Renegotiating ClientHello:
351      * |     2      |     2     |        1         |         12         |
352      * |  Ext Type  |  Ext Len  |  Reneg Info Len  | client_verify_data |
353      * |   0xff01   |   0x000d  |       0x0c       |                    |
354      */
355     /*  From RFC 5746:
356         struct {
357              opaque renegotiated_connection<0..255>;
358          } RenegotiationInfo;
359 
360           The contents of this extension are specified as follows.
361 
362       -  If this is the initial handshake for a connection, then the
363          "renegotiated_connection" field is of zero length in both the
364          ClientHello and the ServerHello.  Thus, the entire encoding of the
365          extension is ff 01 00 01 00.  The first two octets represent the
366          extension type, the third and fourth octets the length of the
367          extension itself, and the final octet the zero length byte for the
368          "renegotiated_connection" field.
369 
370       -  For ClientHellos that are renegotiating, this field contains the
371          "client_verify_data" specified in Section 3.1.
372 
373       -  For ServerHellos that are renegotiating, this field contains the
374          concatenation of client_verify_data and server_verify_data.  For
375          current versions of TLS, this will be a 24-byte value (for SSLv3,
376          it will be a 72-byte value).
377      */
378 
379     if (extension_length < 1)
380     {
381         return(NX_SECURE_TLS_INCORRECT_MESSAGE_LENGTH);
382     }
383 
384     /* Get the "renegotiated_connection" field. */
385     renegotiated_connection_length = packet_buffer[offset];
386     offset++;
387 
388     if (offset + renegotiated_connection_length > extension_length)
389     {
390         return(NX_SECURE_TLS_INCORRECT_MESSAGE_LENGTH);
391     }
392 
393     /* See if the client is attempting to renegotiate an established connection. */
394     if (renegotiated_connection_length)
395     {
396         /* The remote host is attempting a renegotiation - make sure our local session is active and renegotiation is OK. */
397         if (!tls_session -> nx_secure_tls_local_session_active || !tls_session -> nx_secure_tls_remote_session_active)
398         {
399             /* Remote host is attempting a renegotiation but the server is not currently in a session! */
400             return(NX_SECURE_TLS_RENEGOTIATION_SESSION_INACTIVE);
401         }
402 
403         if(!tls_session -> nx_secure_tls_secure_renegotiation)
404         {
405             return(NX_SECURE_TLS_RENEGOTIATION_FAILURE);
406         }
407 
408         if (renegotiated_connection_length != NX_SECURE_TLS_FINISHED_HASH_SIZE)
409         {
410             /* Do not have the right amount of data for comparison. */
411             return(NX_SECURE_TLS_RENEGOTIATION_EXTENSION_ERROR);
412         }
413 
414         /* Compare the received verify data to our locally-stored version. */
415         compare_value = NX_SECURE_MEMCMP(&packet_buffer[offset], tls_session -> nx_secure_tls_remote_verify_data, NX_SECURE_TLS_FINISHED_HASH_SIZE);
416 
417         if (compare_value)
418         {
419             /* Session verify data did not match what we expect - error. */
420             return(NX_SECURE_TLS_RENEGOTIATION_EXTENSION_ERROR);
421         }
422 
423         tls_session -> nx_secure_tls_secure_renegotiation_verified = NX_TRUE;
424     }
425     else
426     {
427         /* Verify that the extension contains only the initial handshake data - this is a new connection. */
428         if ((extension_length != 1) || (tls_session -> nx_secure_tls_local_session_active))
429         {
430             /* Error - the provided extension length was not expected for an initial handshake. */
431             return(NX_SECURE_TLS_RENEGOTIATION_EXTENSION_ERROR);
432         }
433 
434         /* The remote host supports renegotiation. */
435         tls_session -> nx_secure_tls_secure_renegotiation = NX_TRUE;
436     }
437 
438     return(NX_SUCCESS);
439 }
440 #endif /* NX_SECURE_TLS_DISABLE_SECURE_RENEGOTIATION */
441 
442 /**************************************************************************/
443 /*                                                                        */
444 /*  FUNCTION                                               RELEASE        */
445 /*                                                                        */
446 /*    _nx_secure_tls_proc_clienthello_sec_sa_extension    PORTABLE C      */
447 /*                                                           6.2.1        */
448 /*  AUTHOR                                                                */
449 /*                                                                        */
450 /*    Timothy Stapko, Microsoft Corporation                               */
451 /*                                                                        */
452 /*  DESCRIPTION                                                           */
453 /*                                                                        */
454 /*    This function processes the supported groups extensions included in */
455 /*    an incoming ClientHello message from a remote host.                 */
456 /*                                                                        */
457 /*  INPUT                                                                 */
458 /*                                                                        */
459 /*    tls_session                           TLS control block             */
460 /*    exts                                  Parsed extensions             */
461 /*    num_extensions                        Number of extensions          */
462 /*    selected_curve                        Output selected ECDHE curve   */
463 /*    cert_curve                            Named curve of local cert     */
464 /*    cert_curve_supported                  Output whether curve used by  */
465 /*                                            local cert is supported     */
466 /*    ecdhe_signature_algorithm             Output signature algorithm    */
467 /*                                            for ECDHE key exchange      */
468 /*                                                                        */
469 /*  OUTPUT                                                                */
470 /*                                                                        */
471 /*    status                                Completion status             */
472 /*                                                                        */
473 /*  CALLS                                                                 */
474 /*                                                                        */
475 /*    _nx_secure_tls_find_curve_method      Find named curve used by cert */
476 /*                                                                        */
477 /*  CALLED BY                                                             */
478 /*                                                                        */
479 /*    _nx_secure_tls_process_clienthello    Process ClientHello           */
480 /*                                                                        */
481 /*  RELEASE HISTORY                                                       */
482 /*                                                                        */
483 /*    DATE              NAME                      DESCRIPTION             */
484 /*                                                                        */
485 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
486 /*  09-30-2020     Timothy Stapko           Modified comment(s), added    */
487 /*                                            curve priority logic,       */
488 /*                                            resulting in version 6.1    */
489 /*  10-15-2021     Timothy Stapko           Modified comment(s), fixed    */
490 /*                                            compilation issue with      */
491 /*                                            TLS 1.3 and disabling TLS   */
492 /*                                            server,                     */
493 /*                                            resulting in version 6.1.9  */
494 /*  10-31-2022     Yanwu Cai                Modified comment(s),          */
495 /*                                            updated parameters list,    */
496 /*                                            resulting in version 6.2.0  */
497 /*  03-08-2023     Yanwu Cai                Modified comment(s),          */
498 /*                                            fixed compiler errors when  */
499 /*                                            x509 is disabled,           */
500 /*                                            resulting in version 6.2.1  */
501 /*                                                                        */
502 /**************************************************************************/
503 #if defined(NX_SECURE_ENABLE_ECC_CIPHERSUITE) && !defined(NX_SECURE_DISABLE_X509)
_nx_secure_tls_proc_clienthello_sec_sa_extension(NX_SECURE_TLS_SESSION * tls_session,NX_SECURE_TLS_HELLO_EXTENSION * exts,UINT num_extensions,UINT * selected_curve,USHORT cert_curve,UINT * cert_curve_supported,USHORT * ecdhe_signature_algorithm,NX_SECURE_X509_CERT * cert)504 UINT _nx_secure_tls_proc_clienthello_sec_sa_extension(NX_SECURE_TLS_SESSION *tls_session,
505                                                       NX_SECURE_TLS_HELLO_EXTENSION *exts,
506                                                       UINT num_extensions,
507                                                       UINT *selected_curve, USHORT cert_curve,
508                                                       UINT *cert_curve_supported,
509                                                       USHORT *ecdhe_signature_algorithm,
510                                                       NX_SECURE_X509_CERT *cert)
511 {
512 UINT   status = NX_SUCCESS;
513 UINT   i, j, k;
514 const UCHAR *groups;
515 USHORT group;
516 USHORT groups_len;
517 const NX_CRYPTO_METHOD *curve_method;
518 UINT curve_priority;
519 UINT new_curve_priority = 0;
520 #if (NX_SECURE_TLS_TLS_1_3_ENABLED) && !defined(NX_SECURE_TLS_SERVER_DISABLED)
521 NX_SECURE_TLS_ECC *ecc_info;
522 UINT   signature_algorithm_exist = NX_FALSE;
523 #endif
524 const UCHAR *signature_algorithms;
525 USHORT signature_algorithms_len;
526 USHORT signature_algorithm;
527 USHORT signature_algorithm_id;
528 UCHAR expected_signature = 0;
529 
530 
531     /* Select SHA256 as the signature hash. */
532     *ecdhe_signature_algorithm = NX_SECURE_TLS_SIGNATURE_RSA_SHA256;
533 
534 
535     *cert_curve_supported = NX_FALSE;
536     *selected_curve = 0;
537 
538     if (cert_curve)
539     {
540         status = _nx_secure_tls_find_curve_method(&tls_session -> nx_secure_tls_ecc, cert_curve, &curve_method, NX_NULL);
541         if (status == NX_SUCCESS && curve_method != NX_NULL)
542         {
543             *cert_curve_supported = NX_TRUE;
544         }
545     }
546 
547     if (cert != NX_NULL)
548     {
549         if (cert -> nx_secure_x509_public_algorithm == NX_SECURE_TLS_X509_TYPE_EC)
550         {
551             expected_signature = NX_SECURE_TLS_SIGNATURE_ALGORITHM_ECDSA;
552         }
553         else if (cert -> nx_secure_x509_public_algorithm == NX_SECURE_TLS_X509_TYPE_RSA)
554         {
555             expected_signature = NX_SECURE_TLS_SIGNATURE_ALGORITHM_RSA;
556         }
557 
558 #if (NX_SECURE_TLS_TLS_1_0_ENABLED || NX_SECURE_TLS_TLS_1_1_ENABLED)
559         if (tls_session -> nx_secure_tls_protocol_version == NX_SECURE_TLS_VERSION_TLS_1_0 ||
560             tls_session -> nx_secure_tls_protocol_version == NX_SECURE_TLS_VERSION_TLS_1_1)
561         {
562             *ecdhe_signature_algorithm = (USHORT)((NX_SECURE_TLS_HASH_ALGORITHM_SHA1 << 8) | (expected_signature & 0xFF));
563         }
564 #endif /* NX_SECURE_TLS_TLS_1_0_ENABLED || NX_SECURE_TLS_TLS_1_1_ENABLED */
565     }
566 
567     for (i = 0; i < num_extensions; i++)
568     {
569         switch (exts[i].nx_secure_tls_extension_id)
570         {
571         case NX_SECURE_TLS_EXTENSION_EC_GROUPS:
572             groups = exts[i].nx_secure_tls_extension_data;
573             groups_len = exts[i].nx_secure_tls_extension_data_length;
574 
575             /* Set our start priority to the size of our supported curves list (lowest priority). */
576             curve_priority = tls_session -> nx_secure_tls_ecc.nx_secure_tls_ecc_supported_groups_count;
577 
578             /* Loop through curves sent by client. */
579             for (j = 0; j < groups_len; j += 2)
580             {
581                 group = (USHORT)((groups[j] << 8) + groups[j + 1]);
582 
583                 status = _nx_secure_tls_find_curve_method(&tls_session -> nx_secure_tls_ecc, group, &curve_method, &new_curve_priority);
584 
585                 if ((status == NX_CRYTPO_MISSING_ECC_CURVE) || (new_curve_priority > curve_priority))
586                 {
587 
588                     /* Keep searching list. */
589                     continue;
590                 }
591 
592                 /* Found a higher-priority curve. */
593                 if (status == NX_SUCCESS)
594                 {
595                     /* Found shared named curve. */
596                     *selected_curve = group;
597                     curve_priority = new_curve_priority;
598 
599 #if (NX_SECURE_TLS_TLS_1_3_ENABLED) && !defined(NX_SECURE_TLS_SERVER_DISABLED)
600                     if (tls_session -> nx_secure_tls_1_3 &&
601                         (tls_session -> nx_secure_tls_server_state == NX_SECURE_TLS_SERVER_STATE_SEND_HELLO_RETRY))
602                     {
603 
604                         /* Get our session ECC data. */
605                         ecc_info = &(tls_session -> nx_secure_tls_ecc);
606 
607                         /* Loop through all supported ECC curves in this session. */
608                         for (k = 0; k < ecc_info -> nx_secure_tls_ecc_supported_groups_count; k++)
609                         {
610                             /* Find the matching group in the keys we generated and saved. */
611                             if(group == tls_session -> nx_secure_tls_key_material.nx_secure_tls_ecc_key_data[k].nx_secure_tls_ecdhe_named_curve)
612                             {
613 
614                                 /* Store selected ECDHE key data index. */
615                                 tls_session -> nx_secure_tls_key_material.nx_secure_tls_ecc_key_data_selected = k;
616 
617                             }
618                         }
619                     }
620 #endif
621                 }
622                 else
623                 {
624 
625                     /* status is not NX_CRYTPO_MISSING_ECC_CURVE or NX_SUCCESS, return error. */
626                     return(status);
627                 }
628                 /* Continue searching our supported curves list until we find the highest-priority curve. */
629             }
630 
631             /* Reset status as we do not return NX_CRYTPO_MISSING_ECC_CURVE. */
632             status = NX_SUCCESS;
633             break;
634 
635         case NX_SECURE_TLS_EXTENSION_SIGNATURE_ALGORITHMS:
636             /* This extension is not meaningful for TLS versions prior to 1.2. */
637 #if (NX_SECURE_TLS_TLS_1_3_ENABLED) && !defined(NX_SECURE_TLS_SERVER_DISABLED)
638             if (tls_session -> nx_secure_tls_1_3)
639             {
640                 _nx_secure_tls_proc_clienthello_signature_algorithms_extension(tls_session,
641                                                                                exts[i].nx_secure_tls_extension_data,
642                                                                                exts[i].nx_secure_tls_extension_data_length);
643                 signature_algorithm_exist = NX_TRUE;
644             }
645             else
646 #endif
647 #if (NX_SECURE_TLS_TLS_1_2_ENABLED)
648             if (tls_session -> nx_secure_tls_protocol_version == NX_SECURE_TLS_VERSION_TLS_1_2)
649             {
650 
651                 signature_algorithms = exts[i].nx_secure_tls_extension_data;
652                 signature_algorithms_len = (USHORT)exts[i].nx_secure_tls_extension_data_length;
653 
654                 if (signature_algorithms_len < 2 || (((signature_algorithms[0] << 8) + signature_algorithms[1]) != (signature_algorithms_len - 2)))
655                 {
656                     return(NX_SECURE_TLS_INCORRECT_MESSAGE_LENGTH);
657                 }
658 
659                 /* Loop the signature algorithms in the extension. */
660                 for (j = 2; j < signature_algorithms_len; j += 2)
661                 {
662                     if (signature_algorithms[j + 1] != expected_signature)
663                     {
664                         continue;
665                     }
666 
667                     signature_algorithm = (USHORT)((signature_algorithms[j] << 8) + signature_algorithms[j + 1]);
668 
669                     /* Map signature algorithm to internal ID. */
670                     _nx_secure_tls_get_signature_algorithm_id((UINT)signature_algorithm, &signature_algorithm_id);
671 
672                     if (signature_algorithm_id == NX_SECURE_TLS_X509_TYPE_UNKNOWN)
673                     {
674                         continue;
675                     }
676 
677                     /* Check if this signature algorithm is supported. */
678                     for (k = 0; k < tls_session -> nx_secure_tls_crypto_table -> nx_secure_tls_x509_cipher_table_size; k++)
679                     {
680                         if (signature_algorithm_id == tls_session -> nx_secure_tls_crypto_table -> nx_secure_tls_x509_cipher_table[k].nx_secure_x509_crypto_identifier)
681                         {
682                             *ecdhe_signature_algorithm = signature_algorithm;
683                             break;
684                         }
685                     }
686 
687                     /* Signature algorithm is selected. */
688                     if (*ecdhe_signature_algorithm == signature_algorithm)
689                     {
690                         break;
691                     }
692                 }
693             }
694 #endif
695             break;
696         }
697     }
698 
699 #if (NX_SECURE_TLS_TLS_1_3_ENABLED) && !defined(NX_SECURE_TLS_SERVER_DISABLED)
700     /* RFC8446 4.2.3: If a server is authenticating via a certificate and
701        the client has not sent a "signature_algorithms" extension,
702        then the server MUST abort the handshake with a "missing_extension" alert. */
703     if ((cert != NX_NULL) && (tls_session -> nx_secure_tls_1_3))
704     {
705         if (signature_algorithm_exist == NX_FALSE)
706         {
707             return(NX_SECURE_TLS_MISSING_EXTENSION);
708         }
709 
710         if (tls_session -> nx_secure_tls_signature_algorithm == 0)
711         {
712             return(NX_SECURE_TLS_UNKNOWN_CERT_SIG_ALGORITHM);
713         }
714     }
715 #endif
716 
717     return(status);
718 }
719 #endif /* NX_SECURE_ENABLE_ECC_CIPHERSUITE && !NX_SECURE_DISABLE_X509 */
720 
721 
722 /**************************************************************************/
723 /*                                                                        */
724 /*  FUNCTION                                               RELEASE        */
725 /*                                                                        */
726 /*    _nx_secure_tls_proc_clienthello_keyshare_extension  PORTABLE C      */
727 /*                                                           6.2.0        */
728 /*  AUTHOR                                                                */
729 /*                                                                        */
730 /*    Timothy Stapko, Microsoft Corporation                               */
731 /*                                                                        */
732 /*  DESCRIPTION                                                           */
733 /*                                                                        */
734 /*    This function parses the Key Share extension introduced in TLS 1.3. */
735 /*                                                                        */
736 /*  INPUT                                                                 */
737 /*                                                                        */
738 /*    tls_session                           TLS control block             */
739 /*    packet_buffer                         Outgoing TLS packet buffer    */
740 /*    extension_length                      Length of extension data      */
741 /*                                                                        */
742 /*  OUTPUT                                                                */
743 /*                                                                        */
744 /*    status                                Completion status             */
745 /*                                                                        */
746 /*  CALLS                                                                 */
747 /*                                                                        */
748 /*    None                                                                */
749 /*                                                                        */
750 /*  CALLED BY                                                             */
751 /*                                                                        */
752 /*    _nx_secure_tls_process_serverhello_extensions                       */
753 /*                                          Process ServerHello extensions*/
754 /*                                                                        */
755 /*  RELEASE HISTORY                                                       */
756 /*                                                                        */
757 /*    DATE              NAME                      DESCRIPTION             */
758 /*                                                                        */
759 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
760 /*  09-30-2020     Timothy Stapko           Modified comment(s),          */
761 /*                                            resulting in version 6.1    */
762 /*  10-15-2021     Timothy Stapko           Modified comment(s), fixed    */
763 /*                                            compilation issue with      */
764 /*                                            TLS 1.3 and disabling TLS   */
765 /*                                            server,                     */
766 /*                                            resulting in version 6.1.9  */
767 /*  04-25-2022     Yuxin Zhou               Modified comment(s), removed  */
768 /*                                            public key format checking, */
769 /*                                            resulting in version 6.1.11 */
770 /*  10-31-2022     Yanwu Cai                Modified comment(s),          */
771 /*                                            updated parameters list,    */
772 /*                                            resulting in version 6.2.0  */
773 /*                                                                        */
774 /**************************************************************************/
775 #if (NX_SECURE_TLS_TLS_1_3_ENABLED) && !defined(NX_SECURE_TLS_SERVER_DISABLED)
776 
777 extern NX_CRYPTO_METHOD crypto_method_ecdhe;
778 
_nx_secure_tls_proc_clienthello_keyshare_extension(NX_SECURE_TLS_SESSION * tls_session,UCHAR * packet_buffer,USHORT extension_length)779 static UINT _nx_secure_tls_proc_clienthello_keyshare_extension(NX_SECURE_TLS_SESSION *tls_session,
780                                                                 UCHAR *packet_buffer,
781                                                                 USHORT extension_length)
782 {
783 UINT status;
784 UINT i;
785 USHORT  offset;
786 USHORT key_share_length;
787 USHORT key_group;
788 USHORT key_length;
789 NX_SECURE_TLS_ECDHE_HANDSHAKE_DATA   *ecc_key_data;
790 UCHAR                                *pubkey = NX_NULL;
791 UCHAR                                *private_key;
792 UINT                                  private_key_length;
793 NX_CRYPTO_EXTENDED_OUTPUT             extended_output;
794 NX_CRYPTO_METHOD                     *ecdhe_method;
795 const NX_CRYPTO_METHOD               *curve_method;
796 VOID                                 *handler = NX_NULL;
797 NX_SECURE_TLS_ECC *ecc_info;
798 
799     /* Key Share Extension structure (for clienthello):
800      *
801      * ClientHello KeyShare:
802      *                                   |                 <list length>                      |
803      * |     2      |         2          |  <|       2      |    2    |     <Key len>     |>  |
804      * |  Ext Type  |  Extension length  |  <|  Named Group | Key len | key_exchange data |>  |
805 
806      */
807 
808     if (extension_length == 0)
809     {
810 
811         /* The client_shares may be empty if the client is requesting a HelloRetryRequest. */
812         tls_session -> nx_secure_tls_server_state = NX_SECURE_TLS_SERVER_STATE_SEND_HELLO_RETRY;
813         return(NX_SUCCESS);
814     }
815 
816     offset = 0;
817 
818     /* ecc_key_data will hold the key information from the chosen named curve. */
819     ecc_key_data = NX_NULL;
820 
821     /* Get our session ECC data. */
822     ecc_info = &(tls_session -> nx_secure_tls_ecc);
823 
824     if (extension_length < 2)
825     {
826         return(NX_SECURE_TLS_INCORRECT_MESSAGE_LENGTH);
827     }
828 
829     /* Get the key share length. */
830     key_share_length = (USHORT)((packet_buffer[offset] << 8) + packet_buffer[offset + 1]);
831     offset = (USHORT)(offset + 2);
832 
833     if(offset + key_share_length > extension_length)
834     {
835         return(NX_SECURE_TLS_INCORRECT_MESSAGE_LENGTH);
836     }
837 
838     /* Loop through the list of keys looking for a supported group. */
839     while(offset < extension_length && ecc_key_data == NX_NULL)
840     {
841         if (offset + 4 > extension_length)
842         {
843             return(NX_SECURE_TLS_INCORRECT_MESSAGE_LENGTH);
844         }
845 
846         /* Get the key group.  */
847         key_group = (USHORT)((packet_buffer[offset] << 8) + packet_buffer[offset + 1]);
848         offset = (USHORT)(offset + 2);
849 
850         /* Get the key length. */
851         key_length = (USHORT)((packet_buffer[offset] << 8) + packet_buffer[offset + 1]);
852         offset = (USHORT)(offset + 2);
853 
854         if (offset + key_length > extension_length)
855         {
856             return(NX_SECURE_TLS_INCORRECT_MESSAGE_LENGTH);
857         }
858 
859         /* Check the key group. */
860         key_group = (USHORT)((ULONG)key_group | NX_CRYPTO_EC_MASK);
861 
862         /* Loop through all supported ECC curves in this session - see if we support the current group. */
863         for (i = 0; i < ecc_info -> nx_secure_tls_ecc_supported_groups_count; i++)
864         {
865             /* Find the matching group in the keys we generated and saved. */
866             if(key_group == tls_session -> nx_secure_tls_key_material.nx_secure_tls_ecc_key_data[i].nx_secure_tls_ecdhe_named_curve)
867             {
868                 /* Got a matching key/curve combo, get a pointer to the selected key data. */
869                 ecc_key_data = &tls_session -> nx_secure_tls_key_material.nx_secure_tls_ecc_key_data[i];
870 
871                 /* Extract the remote public key from our packet. */
872                 pubkey = &packet_buffer[offset];
873 
874                 /* Store selected ECDHE key data index. */
875                 tls_session -> nx_secure_tls_key_material.nx_secure_tls_ecc_key_data_selected = i;
876 
877                 break;
878             }
879         }
880 
881         /* Advance past the key data. */
882         offset = (USHORT)(offset + key_length);
883     }
884 
885     /* If we didn't find a matching curve, return error. */
886     if(ecc_key_data == NX_NULL || offset > extension_length)
887     {
888         tls_session -> nx_secure_tls_server_state = NX_SECURE_TLS_SERVER_STATE_SEND_HELLO_RETRY;
889         return(NX_SUCCESS);
890     }
891 
892     /* Get the curve method to initialize the remote public key data. */
893     _nx_secure_tls_find_curve_method(&tls_session -> nx_secure_tls_ecc, key_group, &curve_method, NX_NULL);
894 
895     if (curve_method == NX_NULL)
896     {
897         return(NX_SECURE_TLS_MISSING_CRYPTO_ROUTINE);
898     }
899 
900     /* Get the ECDHE method we are going to use. */
901     ecdhe_method = &crypto_method_ecdhe;
902 
903     if (ecdhe_method -> nx_crypto_operation == NX_NULL )
904     {
905         return(NX_SECURE_TLS_MISSING_CRYPTO_ROUTINE);
906     }
907 
908     /* Initialize the ECDHE method. */
909     if (ecdhe_method -> nx_crypto_init != NX_NULL)
910     {
911         status = ecdhe_method -> nx_crypto_init(ecdhe_method,
912                                                 NX_NULL,
913                                                 0,
914                                                 &handler,
915                                                 tls_session -> nx_secure_public_cipher_metadata_area,
916                                                 tls_session -> nx_secure_public_cipher_metadata_size);
917 
918         if (status != NX_CRYPTO_SUCCESS)
919         {
920             return(status);
921         }
922     }
923 
924     /* Set the curve we want to use. */
925     status = ecdhe_method -> nx_crypto_operation(NX_CRYPTO_EC_CURVE_SET, handler,
926                                                  ecdhe_method, NX_NULL, 0,
927                                                  (UCHAR *)curve_method, sizeof(NX_CRYPTO_METHOD *), NX_NULL,
928                                                  NX_NULL, 0,
929                                                  tls_session -> nx_secure_public_cipher_metadata_area,
930                                                  tls_session -> nx_secure_public_cipher_metadata_size,
931                                                  NX_NULL, NX_NULL);
932     if (status != NX_CRYPTO_SUCCESS)
933     {
934         return(status);
935     }
936 
937     /* Import the private key to the ECDH context. */
938     private_key = &ecc_key_data -> nx_secure_tls_ecdhe_private_key[0];
939     private_key_length = ecc_key_data -> nx_secure_tls_ecdhe_private_key_length;
940 
941     status = ecdhe_method -> nx_crypto_operation(NX_CRYPTO_DH_KEY_PAIR_IMPORT, handler,
942                                                 (NX_CRYPTO_METHOD*)ecdhe_method,
943                                                 private_key, private_key_length << 3,
944                                                 NX_NULL, 0, NX_NULL,
945                                                 NX_NULL,
946                                                 0,
947                                                 tls_session -> nx_secure_public_cipher_metadata_area,
948                                                 tls_session -> nx_secure_public_cipher_metadata_size,
949                                                 NX_NULL, NX_NULL);
950 
951 
952     if (status != NX_CRYPTO_SUCCESS)
953     {
954         return(status);
955     }
956 
957     //tls_session -> nx_secure_tls_key_material.nx_secure_tls_new_key_material_data[0] = (UCHAR)extended_output.nx_crypto_extended_output_actual_size;
958 
959     /* Calculate the final pre_master_secret - the "private key" here is the Pre-Master Secret. */
960     extended_output.nx_crypto_extended_output_data = tls_session -> nx_secure_tls_key_material.nx_secure_tls_pre_master_secret;
961     extended_output.nx_crypto_extended_output_length_in_byte = sizeof(tls_session -> nx_secure_tls_key_material.nx_secure_tls_pre_master_secret);
962     extended_output.nx_crypto_extended_output_actual_size = 0;
963     status = ecdhe_method -> nx_crypto_operation(NX_CRYPTO_DH_CALCULATE, handler,
964                                                  ecdhe_method, NX_NULL, 0,
965                                                  pubkey, key_length, NX_NULL,
966                                                  (UCHAR *)&extended_output,
967                                                  sizeof(extended_output),
968                                                  tls_session -> nx_secure_public_cipher_metadata_area,
969                                                  tls_session -> nx_secure_public_cipher_metadata_size,
970                                                  NX_NULL, NX_NULL);
971     if (status != NX_CRYPTO_SUCCESS)
972     {
973         return(status);
974     }
975 
976     tls_session -> nx_secure_tls_key_material.nx_secure_tls_pre_master_secret_size = extended_output.nx_crypto_extended_output_actual_size;
977 
978     if (ecdhe_method -> nx_crypto_cleanup)
979     {
980         status = ecdhe_method -> nx_crypto_cleanup(tls_session -> nx_secure_public_cipher_metadata_area);
981     }
982 
983     return(status);
984 }
985 
986 /**************************************************************************/
987 /*                                                                        */
988 /*  FUNCTION                                               RELEASE        */
989 /*                                                                        */
990 /*    _nx_secure_tls_proc_clienthello_supported_versions_extension        */
991 /*                                                        PORTABLE C      */
992 /*                                                           6.1          */
993 /*  AUTHOR                                                                */
994 /*                                                                        */
995 /*    Timothy Stapko, Microsoft Corporation                               */
996 /*                                                                        */
997 /*  DESCRIPTION                                                           */
998 /*                                                                        */
999 /*    This function parses the supported versions extension introduced in */
1000 /*    TLS 1.3.                                                            */
1001 /*                                                                        */
1002 /*  INPUT                                                                 */
1003 /*                                                                        */
1004 /*    tls_session                           TLS control block             */
1005 /*    packet_buffer                         Outgoing TLS packet buffer    */
1006 /*    supported_version                     Supported version             */
1007 /*    extension_length                      Length of extension data      */
1008 /*                                                                        */
1009 /*  OUTPUT                                                                */
1010 /*                                                                        */
1011 /*    status                                Completion status             */
1012 /*                                                                        */
1013 /*  CALLS                                                                 */
1014 /*                                                                        */
1015 /*    None                                                                */
1016 /*                                                                        */
1017 /*  CALLED BY                                                             */
1018 /*                                                                        */
1019 /*    _nx_secure_tls_process_clienthello_extensions                       */
1020 /*                                          Process ClientHello extensions*/
1021 /*                                                                        */
1022 /*  RELEASE HISTORY                                                       */
1023 /*                                                                        */
1024 /*    DATE              NAME                      DESCRIPTION             */
1025 /*                                                                        */
1026 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
1027 /*  09-30-2020     Timothy Stapko           Modified comment(s),          */
1028 /*                                            resulting in version 6.1    */
1029 /*                                                                        */
1030 /**************************************************************************/
_nx_secure_tls_proc_clienthello_supported_versions_extension(NX_SECURE_TLS_SESSION * tls_session,UCHAR * packet_buffer,USHORT * supported_version,USHORT extension_length)1031 static UINT _nx_secure_tls_proc_clienthello_supported_versions_extension(NX_SECURE_TLS_SESSION *tls_session,
1032                                                                          UCHAR *packet_buffer,
1033                                                                          USHORT *supported_version,
1034                                                                          USHORT extension_length)
1035 {
1036 UINT i;
1037 ULONG  offset;
1038 
1039     NX_PARAMETER_NOT_USED(tls_session);
1040 
1041     /* Supported Versions Extension structure (for clienthello):
1042      *
1043      * ClientHello:
1044      * |      1       | <list length> |
1045      * |  List Length |  TLS Versions |
1046      */
1047 
1048     offset = 0;
1049 
1050     /* Extract the extension length. */
1051     if ((extension_length) < 1 || (packet_buffer[0] != (extension_length - 1)))
1052     {
1053 
1054         /* Invalid Supported Versions Length. */
1055         return(NX_SECURE_TLS_INCORRECT_MESSAGE_LENGTH);
1056     }
1057 
1058     offset = 1;
1059 
1060     /* Loop through all supported versions in this session. */
1061     for (i = 0; i < (UINT)(extension_length - 1); i += 2)
1062     {
1063 
1064         /* Find the preferred protocol version. */
1065         *supported_version = (USHORT)((packet_buffer[offset] << 8) + packet_buffer[offset + 1]);
1066         if (*supported_version == NX_SECURE_TLS_VERSION_TLS_1_3)
1067         {
1068             return(NX_SUCCESS);
1069         }
1070         else if (_nx_secure_tls_check_protocol_version(tls_session, *supported_version, NX_SECURE_TLS) == NX_SUCCESS)
1071         {
1072             return(NX_SUCCESS);
1073         }
1074         offset = (USHORT)(offset + 2);
1075     }
1076 
1077     return(NX_SECURE_TLS_UNSUPPORTED_TLS_VERSION);
1078 }
1079 
1080 /**************************************************************************/
1081 /*                                                                        */
1082 /*  FUNCTION                                               RELEASE        */
1083 /*                                                                        */
1084 /*    _nx_secure_tls_proc_clienthello_signature_algorithms_extension      */
1085 /*                                                        PORTABLE C      */
1086 /*                                                           6.1.9        */
1087 /*  AUTHOR                                                                */
1088 /*                                                                        */
1089 /*    Timothy Stapko, Microsoft Corporation                               */
1090 /*                                                                        */
1091 /*  DESCRIPTION                                                           */
1092 /*                                                                        */
1093 /*    This function parses the siganture algorithms extension introduced  */
1094 /*    in TLS 1.3.                                                         */
1095 /*                                                                        */
1096 /*  INPUT                                                                 */
1097 /*                                                                        */
1098 /*    tls_session                           TLS control block             */
1099 /*    packet_buffer                         Outgoing TLS packet buffer    */
1100 /*    extension_length                      Length of extension data      */
1101 /*                                                                        */
1102 /*  OUTPUT                                                                */
1103 /*                                                                        */
1104 /*    None                                                                */
1105 /*                                                                        */
1106 /*  CALLS                                                                 */
1107 /*                                                                        */
1108 /*    None                                                                */
1109 /*                                                                        */
1110 /*  CALLED BY                                                             */
1111 /*                                                                        */
1112 /*    _nx_secure_tls_process_clienthello_extensions                       */
1113 /*                                          Process ClientHello extensions*/
1114 /*                                                                        */
1115 /*  RELEASE HISTORY                                                       */
1116 /*                                                                        */
1117 /*    DATE              NAME                      DESCRIPTION             */
1118 /*                                                                        */
1119 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
1120 /*  09-30-2020     Timothy Stapko           Modified comment(s),          */
1121 /*                                            resulting in version 6.1    */
1122 /*  10-15-2021     Timothy Stapko           Modified comment(s), fixed    */
1123 /*                                            compilation issue with      */
1124 /*                                            TLS 1.3 and disabling TLS   */
1125 /*                                            server,                     */
1126 /*                                            resulting in version 6.1.9  */
1127 /*                                                                        */
1128 /**************************************************************************/
_nx_secure_tls_proc_clienthello_signature_algorithms_extension(NX_SECURE_TLS_SESSION * tls_session,const UCHAR * packet_buffer,USHORT extension_length)1129 static VOID _nx_secure_tls_proc_clienthello_signature_algorithms_extension(NX_SECURE_TLS_SESSION *tls_session,
1130                                                                            const UCHAR *packet_buffer,
1131                                                                            USHORT extension_length)
1132 {
1133 UINT i;
1134 USHORT offset;
1135 UINT status = 0;
1136 UINT expected_sign_alg = 0;
1137 UINT sign_alg = 0;
1138 NX_SECURE_X509_CERT *local_certificate = NX_NULL;
1139 
1140 
1141     /* Signature Algorithm Extension structure (for clienthello):
1142      *
1143      * ClientHello:
1144      * |      2       |      <list length>      |
1145      * |  List Length |  Signature Algorithems  |
1146      */
1147 
1148     tls_session -> nx_secure_tls_signature_algorithm = 0;
1149     offset = 0;
1150 
1151     /* Extract the extension length. */
1152     if ((extension_length < 2) || (((packet_buffer[0] << 8) + packet_buffer[1]) != (extension_length - 2)))
1153     {
1154 
1155         /* Invalid Supported Versions Length. */
1156         return;
1157     }
1158 
1159     offset = 2;
1160 
1161     /* Get the local certificate. */
1162     if (tls_session -> nx_secure_tls_credentials.nx_secure_tls_active_certificate != NX_NULL)
1163     {
1164         local_certificate = tls_session -> nx_secure_tls_credentials.nx_secure_tls_active_certificate;
1165     }
1166     else
1167     {
1168         /* Get reference to local device certificate. NX_NULL is passed for name to get default entry. */
1169         status = _nx_secure_x509_local_device_certificate_get(&tls_session -> nx_secure_tls_credentials.nx_secure_tls_certificate_store,
1170                                                                 NX_NULL, &local_certificate);
1171         if (status != NX_SUCCESS)
1172         {
1173             local_certificate = NX_NULL;
1174         }
1175     }
1176 
1177     if (local_certificate != NX_NULL)
1178     {
1179         if (local_certificate -> nx_secure_x509_public_algorithm == NX_SECURE_TLS_X509_TYPE_RSA)
1180         {
1181             return;
1182         }
1183 #ifdef NX_SECURE_ENABLE_ECC_CIPHERSUITE
1184         else if (local_certificate -> nx_secure_x509_public_algorithm == NX_SECURE_TLS_X509_TYPE_EC)
1185         {
1186 
1187             switch (local_certificate -> nx_secure_x509_private_key.ec_private_key.nx_secure_ec_named_curve)
1188             {
1189             case NX_CRYPTO_EC_SECP256R1:
1190                 expected_sign_alg = NX_SECURE_TLS_SIGNATURE_ECDSA_SHA256;
1191                 break;
1192             case NX_CRYPTO_EC_SECP384R1:
1193                 expected_sign_alg = NX_SECURE_TLS_SIGNATURE_ECDSA_SHA384;
1194                 break;
1195             case NX_CRYPTO_EC_SECP521R1:
1196                 expected_sign_alg = NX_SECURE_TLS_SIGNATURE_ECDSA_SHA512;
1197                 break;
1198             default:
1199                 return;
1200             }
1201         }
1202 #endif /* NX_SECURE_ENABLE_ECC_CIPHERSUITE */
1203     }
1204 
1205     /* Loop through all supported versions in this session. */
1206     for (i = 0; i < (UINT)(extension_length - 2); i += 2)
1207     {
1208 
1209         /* Find the expected signature algorithm. */
1210         sign_alg = (UINT)((packet_buffer[offset] << 8) + packet_buffer[offset + 1]);
1211 
1212         if (sign_alg == expected_sign_alg)
1213         {
1214             break;
1215         }
1216 
1217         offset = (USHORT)(offset + 2);
1218     }
1219 
1220     /* Make sure we are using the right signature algorithm! */
1221     if (sign_alg != expected_sign_alg)
1222     {
1223         return;
1224     }
1225 
1226     tls_session -> nx_secure_tls_signature_algorithm = sign_alg;
1227 }
1228 #endif /* NX_SECURE_TLS_TLS_1_3_ENABLED */
1229 
1230 /**************************************************************************/
1231 /*                                                                        */
1232 /*  FUNCTION                                               RELEASE        */
1233 /*                                                                        */
1234 /*    _nx_secure_tls_get_signature_algorithm_id           PORTABLE C      */
1235 /*                                                           6.1          */
1236 /*  AUTHOR                                                                */
1237 /*                                                                        */
1238 /*    Timothy Stapko, Microsoft Corporation                               */
1239 /*                                                                        */
1240 /*  DESCRIPTION                                                           */
1241 /*                                                                        */
1242 /*    Get internal x509 ID of signature algorithm.                        */
1243 /*                                                                        */
1244 /*  INPUT                                                                 */
1245 /*                                                                        */
1246 /*    signature_algorithm                   Signature algorithm           */
1247 /*    signature_algorithm_id                Internal ID                   */
1248 /*                                                                        */
1249 /*  OUTPUT                                                                */
1250 /*                                                                        */
1251 /*    None                                                                */
1252 /*                                                                        */
1253 /*  CALLS                                                                 */
1254 /*                                                                        */
1255 /*                                                                        */
1256 /*  CALLED BY                                                             */
1257 /*                                                                        */
1258 /*                                                                        */
1259 /*                                                                        */
1260 /*  RELEASE HISTORY                                                       */
1261 /*                                                                        */
1262 /*    DATE              NAME                      DESCRIPTION             */
1263 /*                                                                        */
1264 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
1265 /*  09-30-2020     Timothy Stapko           Modified comment(s),          */
1266 /*                                            resulting in version 6.1    */
1267 /*                                                                        */
1268 /**************************************************************************/
_nx_secure_tls_get_signature_algorithm_id(UINT signature_algorithm,USHORT * signature_algorithm_id)1269 VOID _nx_secure_tls_get_signature_algorithm_id(UINT signature_algorithm, USHORT *signature_algorithm_id)
1270 {
1271 
1272     *signature_algorithm_id = NX_SECURE_TLS_X509_TYPE_UNKNOWN;
1273 
1274     switch (signature_algorithm)
1275     {
1276     case NX_SECURE_TLS_SIGNATURE_RSA_MD5:
1277         *signature_algorithm_id = NX_SECURE_TLS_X509_TYPE_RSA_MD5;
1278         break;
1279     case NX_SECURE_TLS_SIGNATURE_RSA_SHA1:
1280         *signature_algorithm_id = NX_SECURE_TLS_X509_TYPE_RSA_SHA_1;
1281         break;
1282     case NX_SECURE_TLS_SIGNATURE_RSA_SHA256:
1283         *signature_algorithm_id = NX_SECURE_TLS_X509_TYPE_RSA_SHA_256;
1284         break;
1285     case NX_SECURE_TLS_SIGNATURE_RSA_SHA384:
1286         *signature_algorithm_id = NX_SECURE_TLS_X509_TYPE_RSA_SHA_384;
1287         break;
1288     case NX_SECURE_TLS_SIGNATURE_RSA_SHA512:
1289         *signature_algorithm_id = NX_SECURE_TLS_X509_TYPE_RSA_SHA_512;
1290         break;
1291     case NX_SECURE_TLS_SIGNATURE_ECDSA_SHA1:
1292         *signature_algorithm_id = NX_SECURE_TLS_X509_TYPE_ECDSA_SHA_1;
1293         break;
1294     case NX_SECURE_TLS_SIGNATURE_ECDSA_SHA224:
1295         *signature_algorithm_id = NX_SECURE_TLS_X509_TYPE_ECDSA_SHA_224;
1296         break;
1297     case NX_SECURE_TLS_SIGNATURE_ECDSA_SHA256:
1298         *signature_algorithm_id = NX_SECURE_TLS_X509_TYPE_ECDSA_SHA_256;
1299         break;
1300     case NX_SECURE_TLS_SIGNATURE_ECDSA_SHA384:
1301         *signature_algorithm_id = NX_SECURE_TLS_X509_TYPE_ECDSA_SHA_384;
1302         break;
1303     case NX_SECURE_TLS_SIGNATURE_ECDSA_SHA512:
1304         *signature_algorithm_id = NX_SECURE_TLS_X509_TYPE_ECDSA_SHA_512;
1305         break;
1306     default:
1307         return;
1308     }
1309 }
1310 
1311 
1312 /**************************************************************************/
1313 /*                                                                        */
1314 /*  FUNCTION                                               RELEASE        */
1315 /*                                                                        */
1316 /*    _nx_secure_tls_process_clienthello_psk_extension    PORTABLE C      */
1317 /*                                                           6.1.8        */
1318 /*  AUTHOR                                                                */
1319 /*                                                                        */
1320 /*    Timothy Stapko, Microsoft Corporation                               */
1321 /*                                                                        */
1322 /*  DESCRIPTION                                                           */
1323 /*                                                                        */
1324 /*    Process an incoming TLS 1.3 PSK extension from a TLS Client.        */
1325 /*                                                                        */
1326 /*  INPUT                                                                 */
1327 /*                                                                        */
1328 /*    tls_session                           TLS control block             */
1329 /*    packet_buffer                         Incoming packet data          */
1330 /*    extension_length                      Length of PSK extension       */
1331 /*                                                                        */
1332 /*  OUTPUT                                                                */
1333 /*                                                                        */
1334 /*    None                                                                */
1335 /*                                                                        */
1336 /*  CALLS                                                                 */
1337 /*                                                                        */
1338 /*                                                                        */
1339 /*  CALLED BY                                                             */
1340 /*                                                                        */
1341 /*                                                                        */
1342 /*                                                                        */
1343 /*  RELEASE HISTORY                                                       */
1344 /*                                                                        */
1345 /*    DATE              NAME                      DESCRIPTION             */
1346 /*                                                                        */
1347 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
1348 /*  09-30-2020     Timothy Stapko           Modified comment(s),          */
1349 /*                                            verified memcpy use cases,  */
1350 /*                                            resulting in version 6.1    */
1351 /*  08-02-2021     Timothy Stapko           Modified comment(s), added    */
1352 /*                                            hash clone and cleanup,     */
1353 /*                                            resulting in version 6.1.8  */
1354 /*                                                                        */
1355 /**************************************************************************/
1356 #if (NX_SECURE_TLS_TLS_1_3_ENABLED) && defined(NX_SECURE_ENABLE_PSK_CIPHERSUITES)
_nx_secure_tls_process_clienthello_psk_extension(NX_SECURE_TLS_SESSION * tls_session,const UCHAR * packet_buffer,USHORT extension_length,const UCHAR * client_hello_buffer,UINT client_hello_length)1357 static UINT _nx_secure_tls_process_clienthello_psk_extension(NX_SECURE_TLS_SESSION *tls_session, const UCHAR *packet_buffer,
1358                                                       USHORT extension_length, const UCHAR *client_hello_buffer, UINT client_hello_length)
1359 {
1360 UINT list_length;
1361 UCHAR                                *psk_data = NX_NULL;
1362 UINT                                  psk_length;
1363 UCHAR   binder_len;
1364 UINT psk_index;
1365 UINT binder_index;
1366 UINT psk_store_index = 0;
1367 ULONG  offset;
1368 UINT   id_len;
1369 const UCHAR  *id;
1370 const UCHAR  *binder;
1371 INT   binder_total;
1372 UINT   status;
1373 UINT   age;
1374 UINT psk_found = NX_FALSE;
1375 UINT partial_hello_length;
1376 
1377 NX_SECURE_TLS_PSK_STORE *psk_store;
1378 
1379 
1380     /* PSK Extension structure (From TLS 1.3 RFC 8446):
1381           struct {
1382               opaque identity<1..2^16-1>;
1383               uint32 obfuscated_ticket_age;
1384           } PskIdentity;
1385 
1386           opaque PskBinderEntry<32..255>;
1387 
1388           struct {
1389               PskIdentity identities<7..2^16-1>;
1390               PskBinderEntry binders<33..2^16-1>;
1391           } OfferedPsks;
1392 
1393           struct {
1394               select (Handshake.msg_type) {
1395                   case client_hello: OfferedPsks;
1396                   case server_hello: uint16 selected_identity;
1397               };
1398           } PreSharedKeyExtension;
1399 
1400        identity:  A label for a key.  For instance, a ticket (as defined in
1401           Appendix B.3.4) or a label for a pre-shared key established
1402           externally.
1403 
1404        obfuscated_ticket_age:  An obfuscated version of the age of the key.
1405           Section 4.2.11.1 describes how to form this value for identities
1406           established via the NewSessionTicket message.  For identities
1407           established externally, an obfuscated_ticket_age of 0 SHOULD be
1408           used, and servers MUST ignore the value.
1409 
1410        identities:  A list of the identities that the client is willing to
1411           negotiate with the server.  If sent alongside the "early_data"
1412           extension (see Section 4.2.10), the first identity is the one used
1413           for 0-RTT data.
1414 
1415        binders:  A series of HMAC values, one for each value in the
1416           identities list and in the same order, computed as described
1417           below.
1418 
1419        selected_identity:  The server's chosen identity expressed as a
1420           (0-based) index into the identities in the client's list.
1421 
1422 
1423       ClientHello PSK extension layout:
1424       |       2      |      <ID list len>        |      2      | <binders len>   |
1425       |  ID list len | <|<ID len> | ID | age |>  | binders len | <len> | binder  |
1426     */
1427 
1428 
1429     if (tls_session == NX_NULL)
1430     {
1431         return(NX_PTR_ERROR);
1432     }
1433 
1434     offset = 0;
1435 
1436     if (extension_length < 2)
1437     {
1438         return(NX_SECURE_TLS_INCORRECT_MESSAGE_LENGTH);
1439     }
1440 
1441     /* Get the length of the ID list. (Extension id and length already removed by caller). */
1442     list_length = (USHORT)((packet_buffer[offset] << 8) + packet_buffer[offset + 1]);
1443     offset += 2;
1444 
1445     /* Make sure the length is reasonable. */
1446     if(list_length > extension_length)
1447     {
1448         return(NX_SECURE_TLS_INCORRECT_MESSAGE_LENGTH);
1449     }
1450 
1451     /* Get our PSK store for easy access. */
1452     psk_store = tls_session -> nx_secure_tls_credentials.nx_secure_tls_psk_store;
1453     binder_total = 0;
1454     psk_index = 0;
1455 
1456     /* Loop through all IDs. */
1457     while(list_length > 0)
1458     {
1459 
1460         if (list_length < 2)
1461         {
1462             return(NX_SECURE_TLS_INCORRECT_MESSAGE_LENGTH);
1463         }
1464 
1465         /* Extract ID length. */
1466         id_len = (USHORT)((packet_buffer[offset] << 8) + packet_buffer[offset + 1]);
1467         offset += 2;
1468 
1469         if(offset + id_len > extension_length || list_length < 2 + id_len + 4)
1470         {
1471             return(NX_SECURE_TLS_INCORRECT_MESSAGE_LENGTH);
1472         }
1473 
1474         /* Reference to ID data. */
1475         id = &packet_buffer[offset];
1476         offset += id_len;
1477 
1478         /* Extract the age field. */
1479         age = (UINT)((packet_buffer[offset]     << 24) + (packet_buffer[offset + 1] << 16) +
1480                      (packet_buffer[offset + 2] <<  8) +  packet_buffer[offset + 3]);
1481         offset += 4;
1482 
1483         /* Only support external PSKs (no session resumption). */
1484         if(age != 0)
1485         {
1486             return(NX_SECURE_TLS_BAD_CLIENTHELLO_PSK_EXTENSION);
1487         }
1488 
1489         /* Size of entry = 2 bytes id_len + <id_len> + 4 bytes age field. */
1490         list_length -= (2 + id_len + 4);
1491 
1492         /* Check the ID list against our PSK store. */
1493         status = _nx_secure_tls_psk_identity_find(tls_session, &psk_data, &psk_length, (UCHAR*)id, id_len, &psk_store_index);
1494 
1495         /* No match? Continue. */
1496         if(status == NX_SECURE_TLS_NO_MATCHING_PSK)
1497         {
1498             /* Advance our selected PSK index. */
1499             psk_index++;
1500 
1501             continue;
1502         }
1503         else if(status != NX_SUCCESS)
1504         {
1505             return(status);
1506         }
1507 
1508         /* At this point, we have a match - use this PSK if the age and binder check out.
1509          * Add the remaining list length to the offset to reach the binder list. */
1510         psk_found = NX_TRUE;
1511         offset += list_length;
1512         break;
1513     }
1514 
1515     /* If we didn't find a match, return the error. */
1516     if(!psk_found)
1517     {
1518         return(NX_SECURE_TLS_NO_MATCHING_PSK);
1519     }
1520 
1521     /* Now we can verify the age. */
1522 
1523     if (extension_length < offset + 2)
1524     {
1525         return(NX_SECURE_TLS_INCORRECT_MESSAGE_LENGTH);
1526     }
1527 
1528     /* Extract the total binder list length. */
1529     binder_total = (USHORT)((packet_buffer[offset] << 8) + packet_buffer[offset + 1]);
1530     offset += 2;
1531 
1532     /* Make sure the length is reasonable. */
1533     if((UINT)binder_total + offset > extension_length)
1534     {
1535         return(NX_SECURE_TLS_INCORRECT_MESSAGE_LENGTH);
1536     }
1537 
1538     /* We need to subtract the binders from the ClientHello for our binder generation
1539        since the hash for the binder is generated from a partial ClientHello before
1540        the binders are generated. Include 2 bytes for the length field. */
1541     partial_hello_length = client_hello_length - ((UINT)binder_total + 2);
1542 
1543     binder = NX_NULL;
1544     binder_index = 0;
1545 
1546     /* Loop through the binders to get the binder for our selected PSK. */
1547     while(binder_total > 0)
1548     {
1549         /* Extract binder length. */
1550         binder_len = packet_buffer[offset];
1551         offset++;
1552 
1553         if (1 + binder_len > binder_total)
1554         {
1555             return(NX_SECURE_TLS_INCORRECT_MESSAGE_LENGTH);
1556         }
1557 
1558         /* Subtract the binder length and field from the total. */
1559         binder_total--;
1560         binder_total -= binder_len;
1561 
1562         /* Check our current binder index against the selected PSK index. */
1563         if(binder_index == psk_index)
1564         {
1565             /* Extract binder and exit loop. */
1566             binder = &packet_buffer[offset];
1567             break;
1568         }
1569 
1570         /* Advance the binder index. */
1571         binder_index++;
1572     }
1573 
1574     if(binder == NX_NULL)
1575     {
1576         /* Binder is missing! */
1577         return(NX_SECURE_TLS_BAD_CLIENTHELLO_PSK_EXTENSION);
1578     }
1579 
1580     /* Check binder against locally-generated version. */
1581     /* If nx_secure_tls_psk_data_size is zero, it means this is ClientHello1, need to initialize the handshake hash.
1582        If not, it means this is ClientHello2, need to save the metadata(ClientHello1 and HelloRetryRequest) to sratch buffer. */
1583     if (tls_session -> nx_secure_tls_credentials.nx_secure_tls_client_psk.nx_secure_tls_psk_data_size == 0)
1584     {
1585 
1586         /* Initialize the handshake hash to hash the ClientHello up to now. */
1587         _nx_secure_tls_handshake_hash_init(tls_session);
1588     }
1589     else
1590     {
1591 
1592         /* Save the handshake hash state. */
1593         NX_SECURE_HASH_METADATA_CLONE(tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_scratch,
1594                                       tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_sha256_metadata,
1595                                       tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_sha256_metadata_size); /* Use case of memcpy is verified. */
1596     }
1597 
1598     /* Hash the ClientHello, adding the TLS record header. */
1599     UCHAR header[] = { 0x01, 0x00, 0x00, 0x00 };
1600     header[2] = (UCHAR)((client_hello_length) >> 8);
1601     header[3] = (UCHAR)((client_hello_length) & 0xFF);
1602     _nx_secure_tls_handshake_hash_update(tls_session, header, sizeof(header));
1603     _nx_secure_tls_handshake_hash_update(tls_session, (UCHAR*)client_hello_buffer, partial_hello_length);
1604 
1605     /* Save the transcript hash for the ClientHello, which is used in generating the PSK binders. */
1606     status = _nx_secure_tls_1_3_transcript_hash_save(tls_session, NX_SECURE_TLS_TRANSCRIPT_IDX_CLIENTHELLO, NX_FALSE);
1607     if (status != NX_SUCCESS)
1608     {
1609 
1610         if (tls_session -> nx_secure_tls_credentials.nx_secure_tls_client_psk.nx_secure_tls_psk_data_size)
1611         {
1612             NX_SECURE_HASH_CLONE_CLEANUP(tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_scratch,
1613                                          tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_sha256_metadata_size);
1614         }
1615 
1616         return(status);
1617     }
1618 
1619     /* Restore the original metadata(ClientHello1 and HelloRetryRequest) from scratch buffer. */
1620     if (tls_session -> nx_secure_tls_credentials.nx_secure_tls_client_psk.nx_secure_tls_psk_data_size)
1621     {
1622 
1623         NX_SECURE_HASH_CLONE_CLEANUP(tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_sha256_metadata,
1624                                      tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_sha256_metadata_size);
1625 
1626         NX_SECURE_HASH_METADATA_CLONE(tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_sha256_metadata,
1627                                       tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_scratch,
1628                                       tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_sha256_metadata_size); /* Use case of memcpy is verified. */
1629 
1630         NX_SECURE_HASH_CLONE_CLEANUP(tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_scratch,
1631                                      tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_sha256_metadata_size);
1632     }
1633 
1634     /* Generate the binder for our selected PSK. */
1635     _nx_secure_tls_psk_binder_generate(tls_session, &psk_store[psk_store_index]);
1636 
1637     /* Compare the generated binder to the received binder, using our generated length to avoid overflow
1638        from incoming length problems. */
1639     status = (UINT)NX_SECURE_MEMCMP(binder, psk_store[psk_store_index].nx_secure_tls_psk_binder, psk_store[psk_store_index].nx_secure_tls_psk_binder_size);
1640 
1641     /* Make sure the generated binder matches the one sent by the client. */
1642     if((status != 0) || (binder_len != psk_store[psk_store_index].nx_secure_tls_psk_binder_size))
1643     {
1644         return(NX_SECURE_TLS_PSK_BINDER_MISMATCH);
1645     }
1646 
1647     /* The PSK is too big to save in our internal buffer. */
1648     if(psk_length > NX_SECURE_TLS_MAX_PSK_SIZE)
1649     {
1650         return(NX_SECURE_TLS_NO_MORE_PSK_SPACE);
1651     }
1652 
1653     /* Make sure the Client PSK is initialized for later key generation. */
1654     NX_SECURE_MEMCPY(tls_session -> nx_secure_tls_credentials.nx_secure_tls_client_psk.nx_secure_tls_psk_data, psk_data, psk_length); /* Use case of memcpy is verified. */
1655     tls_session -> nx_secure_tls_credentials.nx_secure_tls_client_psk.nx_secure_tls_psk_data_size = psk_length;
1656 
1657     return(NX_SUCCESS);
1658 }
1659 #endif
1660 
1661 
1662 
1663