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 #ifndef NX_SECURE_DISABLE_X509
29 static VOID _nx_secure_tls_get_signature_algorithm(NX_SECURE_TLS_SESSION *tls_session,
30                                                    NX_SECURE_X509_CRYPTO *crypto_method,
31                                                    USHORT *signature_algorithm);
32 
33 static UINT _nx_secure_tls_send_clienthello_sig_extension(NX_SECURE_TLS_SESSION *tls_session,
34                                                           UCHAR *packet_buffer, ULONG *packet_offset,
35                                                           USHORT *extension_length,
36                                                           ULONG available_size);
37 #endif
38 #ifndef NX_SECURE_TLS_SNI_EXTENSION_DISABLED
39 static UINT _nx_secure_tls_send_clienthello_sni_extension(NX_SECURE_TLS_SESSION *tls_session,
40                                                           UCHAR *packet_buffer, ULONG *packet_offset,
41                                                           USHORT *extension_length,
42                                                           ULONG available_size);
43 #endif
44 #ifdef NX_SECURE_ENABLE_ECC_CIPHERSUITE
45 static UINT _nx_secure_tls_send_clienthello_sec_spf_extensions(NX_SECURE_TLS_SESSION *tls_session,
46                                                                UCHAR *packet_buffer, ULONG *packet_offset,
47                                                                USHORT *extension_length,
48                                                                ULONG available_size);
49 #endif
50 
51 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
52 static UINT _nx_secure_tls_send_clienthello_supported_versions_extension(NX_SECURE_TLS_SESSION *tls_session,
53                                                           UCHAR *packet_buffer, ULONG *packet_offset,
54                                                           USHORT *extension_length,
55                                                           ULONG available_size);
56 
57 static UINT _nx_secure_tls_send_clienthello_key_share_extension(NX_SECURE_TLS_SESSION *tls_session,
58                                                                 UCHAR *packet_buffer, ULONG *packet_offset,
59                                                                 USHORT *extension_length,
60                                                                 ULONG available_size);
61 
62 static UINT _nx_secure_tls_send_clienthello_psk_kem_extension(NX_SECURE_TLS_SESSION *tls_session,
63                                                               UCHAR *packet_buffer, ULONG *packet_length,
64                                                               USHORT *extension_length);
65 
66 /* Note: PSK extension generation is called directly, so not static. */
67 UINT _nx_secure_tls_send_clienthello_psk_extension(NX_SECURE_TLS_SESSION *tls_session,
68                                                           UCHAR *packet_buffer, ULONG *packet_length,
69                                                           ULONG extension_length_offset, ULONG total_extensions_length,
70                                                           ULONG *extension_length,
71                                                           ULONG available_size);
72 #endif
73 
74 #ifndef NX_SECURE_TLS_DISABLE_SECURE_RENEGOTIATION
75 static UINT _nx_secure_tls_send_clienthello_sec_reneg_extension(NX_SECURE_TLS_SESSION *tls_session,
76                                                                 UCHAR *packet_buffer,
77                                                                 ULONG *packet_offset,
78                                                                 USHORT *extension_length,
79                                                                 ULONG available_size);
80 #endif
81 
82 
83 /**************************************************************************/
84 /*                                                                        */
85 /*  FUNCTION                                               RELEASE        */
86 /*                                                                        */
87 /*    _nx_secure_tls_send_clienthello_extensions          PORTABLE C      */
88 /*                                                           6.2.1        */
89 /*  AUTHOR                                                                */
90 /*                                                                        */
91 /*    Timothy Stapko, Microsoft Corporation                               */
92 /*                                                                        */
93 /*  DESCRIPTION                                                           */
94 /*                                                                        */
95 /*    This function populates an NX_PACKET with ClientHello extensions,   */
96 /*    which provide additional information to the remote host for the     */
97 /*    initial handshake negotiations.                                     */
98 /*                                                                        */
99 /*  INPUT                                                                 */
100 /*                                                                        */
101 /*    tls_session                           TLS control block             */
102 /*    packet_buffer                         Outgoing TLS packet           */
103 /*    packet_offset                         Offset into packet buffer     */
104 /*    extensions_length                     Return total extension length */
105 /*    available_size                        Available size of buffer      */
106 /*                                                                        */
107 /*  OUTPUT                                                                */
108 /*                                                                        */
109 /*    status                                Completion status             */
110 /*                                                                        */
111 /*  CALLS                                                                 */
112 /*                                                                        */
113 /*    _nx_secure_tls_send_clienthello_sec_reneg_extension                 */
114 /*                                          Send ClientHello Renegotiation*/
115 /*                                            extension                   */
116 /*    _nx_secure_tls_send_clienthello_sig_extension                       */
117 /*                                          Send ClientHello Signature    */
118 /*                                            extension                   */
119 /*    _nx_secure_tls_send_clienthello_sni_extension                       */
120 /*                                          Send ClientHello SNI extension*/
121 /*    _nx_secure_tls_send_clienthello_ec_extension                        */
122 /*                                          Send ClientHello EC extension */
123 /*                                                                        */
124 /*  CALLED BY                                                             */
125 /*                                                                        */
126 /*    _nx_secure_tls_send_clienthello       Send TLS ClientHello          */
127 /*                                                                        */
128 /*  RELEASE HISTORY                                                       */
129 /*                                                                        */
130 /*    DATE              NAME                      DESCRIPTION             */
131 /*                                                                        */
132 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
133 /*  09-30-2020     Timothy Stapko           Modified comment(s),          */
134 /*                                            verified memcpy use cases,  */
135 /*                                            fixed renegotiation bug,    */
136 /*                                            resulting in version 6.1    */
137 /*  04-25-2022     Yajun Xia                Modified comment(s),          */
138 /*                                            added exception case,       */
139 /*                                            resulting in version 6.1.11 */
140 /*  03-08-2023     Yanwu Cai                Modified comment(s),          */
141 /*                                            fixed compiler errors when  */
142 /*                                            x509 is disabled,           */
143 /*                                            resulting in version 6.2.1  */
144 /*                                                                        */
145 /**************************************************************************/
_nx_secure_tls_send_clienthello_extensions(NX_SECURE_TLS_SESSION * tls_session,UCHAR * packet_buffer,ULONG * packet_offset,ULONG * extensions_length,ULONG available_size)146 UINT _nx_secure_tls_send_clienthello_extensions(NX_SECURE_TLS_SESSION *tls_session,
147                                                 UCHAR *packet_buffer, ULONG *packet_offset,
148                                                 ULONG *extensions_length, ULONG available_size)
149 {
150 ULONG  length = *packet_offset;
151 USHORT extension_length = 0, total_extensions_length;
152 UINT   status;
153 
154     total_extensions_length = 0;
155 
156 
157 #ifdef NX_SECURE_ENABLE_ECC_CIPHERSUITE
158     status = _nx_secure_tls_send_clienthello_sec_spf_extensions(tls_session,
159                                                                 packet_buffer,
160                                                                 &length,
161                                                                 &extension_length,
162                                                                 available_size);
163     if (status != NX_SUCCESS)
164     {
165         return(status);
166     }
167     total_extensions_length = (USHORT)(total_extensions_length + extension_length);
168 #endif
169 
170 #ifndef NX_SECURE_TLS_DISABLE_SECURE_RENEGOTIATION
171     /* We have to add renegotiation extensions in both initial sessions and renegotiating sessions. */
172     if (tls_session -> nx_secure_tls_renegotation_enabled == NX_TRUE)
173     {
174         status = _nx_secure_tls_send_clienthello_sec_reneg_extension(tls_session, packet_buffer, &length, &extension_length, available_size);
175         if(status != NX_SUCCESS)
176         {
177             return(status);
178         }
179         total_extensions_length = (USHORT)(total_extensions_length + extension_length);
180     }
181 #endif
182 
183 /* We can't do TLS 1.3 without ECC. */
184 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
185     if(tls_session->nx_secure_tls_1_3)
186     {
187         /* Send supported TLS versions extensions (for TLS 1.3). */
188         status = _nx_secure_tls_send_clienthello_supported_versions_extension(tls_session, packet_buffer, &length, &extension_length, available_size);
189         if(status != NX_SUCCESS)
190         {
191             return(status);
192         }
193         total_extensions_length = (USHORT)(total_extensions_length + extension_length);
194 
195         /* Send KeyShare extension (for TLS 1.3). */
196         _nx_secure_tls_send_clienthello_key_share_extension(tls_session, packet_buffer, &length, &extension_length, available_size);
197         if(status != NX_SUCCESS)
198         {
199             return(status);
200         }
201         total_extensions_length = (USHORT)(total_extensions_length + extension_length);
202 
203         /* Including a "cookie" extension if one was provided in the HelloRetryRequest. */
204         if ((tls_session -> nx_secure_tls_client_state == NX_SECURE_TLS_CLIENT_STATE_HELLO_RETRY) &&
205             (tls_session -> nx_secure_tls_cookie_length != 0))
206         {
207 
208             /* Add Extension Type. */
209             packet_buffer[length] = (UCHAR)((NX_SECURE_TLS_EXTENSION_COOKIE) >> 8);
210             packet_buffer[length + 1] = (UCHAR)(NX_SECURE_TLS_EXTENSION_COOKIE);
211             length += 2;
212 
213             /* Add Extension Length. */
214             extension_length = (USHORT)(tls_session -> nx_secure_tls_cookie_length + 2);
215             packet_buffer[length] = (UCHAR)(extension_length >> 8);
216             packet_buffer[length + 1] = (UCHAR)(extension_length);
217             length += 2;
218 
219             /* Add Cookie Length. */
220             packet_buffer[length] = (UCHAR)(tls_session -> nx_secure_tls_cookie_length >> 8);
221             packet_buffer[length + 1] = (UCHAR)(tls_session -> nx_secure_tls_cookie_length);
222             length += 2;
223 
224             /* Add Cookie. */
225             NX_SECURE_MEMCPY(&packet_buffer[length], tls_session -> nx_secure_tls_cookie, tls_session -> nx_secure_tls_cookie_length); /* Use case of memcpy is verified. */
226             length += (tls_session -> nx_secure_tls_cookie_length);
227 
228             /* Update total extensions length and reset the stored cookie length. */
229             total_extensions_length = (USHORT)(total_extensions_length + extension_length + 4);
230             tls_session -> nx_secure_tls_cookie_length = 0;
231         }
232     }
233 #endif
234 
235 #ifndef NX_SECURE_DISABLE_X509
236 
237     /* RFC 5246 7.4.1.4.1 Signature Algorithm:
238        Note: this extension is not meaningful for TLS versions prior to 1.2.
239        Clients MUST NOT offer it if they are offering prior versions. */
240     if (tls_session -> nx_secure_tls_protocol_version == NX_SECURE_TLS_VERSION_TLS_1_2)
241     {
242 
243         /* Send the available signature algorithms extension. */
244         status = _nx_secure_tls_send_clienthello_sig_extension(tls_session, packet_buffer, &length, &extension_length, available_size);
245         if (status != NX_SUCCESS)
246         {
247             return(status);
248         }
249         total_extensions_length = (USHORT)(total_extensions_length + extension_length);
250     }
251 #endif
252 
253 #ifndef NX_SECURE_TLS_SNI_EXTENSION_DISABLED
254     /* Send the server name indication extension. */
255     status = _nx_secure_tls_send_clienthello_sni_extension(tls_session, packet_buffer, &length, &extension_length, available_size);
256     if(status != NX_SUCCESS)
257     {
258         return(status);
259     }
260     total_extensions_length = (USHORT)(total_extensions_length + extension_length);
261 #endif
262 
263 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
264     if(tls_session->nx_secure_tls_1_3 && tls_session->nx_secure_tls_credentials.nx_secure_tls_psk_count > 0)
265     {
266         status = _nx_secure_tls_send_clienthello_psk_kem_extension(tls_session, packet_buffer, &length, &extension_length);
267         if (status != NX_SUCCESS)
268         {
269             return(status);
270         }
271         total_extensions_length = (USHORT)(total_extensions_length + extension_length);
272     }
273 #endif
274 
275     *extensions_length = total_extensions_length;
276     *packet_offset = length;
277 
278 
279     return(NX_SUCCESS);
280 }
281 
282 
283 
284 /**************************************************************************/
285 /*                                                                        */
286 /*  FUNCTION                                               RELEASE        */
287 /*                                                                        */
288 /*    _nx_secure_tls_send_clienthello_sig_extension       PORTABLE C      */
289 /*                                                           6.1.11       */
290 /*  AUTHOR                                                                */
291 /*                                                                        */
292 /*    Timothy Stapko, Microsoft Corporation                               */
293 /*                                                                        */
294 /*  DESCRIPTION                                                           */
295 /*                                                                        */
296 /*    This function adds the Signature Algorithms extension to an         */
297 /*    outgoing ClientHello record. See RFC 5246 section 7.4.1.4.1.        */
298 /*                                                                        */
299 /*  INPUT                                                                 */
300 /*                                                                        */
301 /*    tls_session                           TLS control block             */
302 /*    packet_buffer                         Outgoing TLS packet buffer    */
303 /*    packet_offset                         Offset into packet buffer     */
304 /*    extension_length                      Return length of data         */
305 /*    available_size                        Available size of buffer      */
306 /*                                                                        */
307 /*  OUTPUT                                                                */
308 /*                                                                        */
309 /*    status                                Completion status             */
310 /*                                                                        */
311 /*  CALLS                                                                 */
312 /*                                                                        */
313 /*    None                                                                */
314 /*                                                                        */
315 /*  CALLED BY                                                             */
316 /*                                                                        */
317 /*    _nx_secure_tls_send_clienthello_extensions                          */
318 /*                                          Send TLS ClientHello extension*/
319 /*                                                                        */
320 /*  RELEASE HISTORY                                                       */
321 /*                                                                        */
322 /*    DATE              NAME                      DESCRIPTION             */
323 /*                                                                        */
324 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
325 /*  09-30-2020     Timothy Stapko           Modified comment(s),          */
326 /*                                            resulting in version 6.1    */
327 /*  04-25-2022     Yuxin Zhou               Modified comment(s),          */
328 /*                                            removed unused code,        */
329 /*                                            resulting in version 6.1.11 */
330 /*                                                                        */
331 /**************************************************************************/
332 #ifndef NX_SECURE_DISABLE_X509
_nx_secure_tls_send_clienthello_sig_extension(NX_SECURE_TLS_SESSION * tls_session,UCHAR * packet_buffer,ULONG * packet_offset,USHORT * extension_length,ULONG available_size)333 static UINT _nx_secure_tls_send_clienthello_sig_extension(NX_SECURE_TLS_SESSION *tls_session,
334                                                           UCHAR *packet_buffer, ULONG *packet_offset,
335                                                           USHORT *extension_length,
336                                                           ULONG available_size)
337 {
338 ULONG  offset, ext_pos;
339 USHORT ext_len, sig_len, sighash_len, ext;
340 UINT i;
341 USHORT signature_algorithm;
342 NX_SECURE_X509_CRYPTO *cipher_table;
343 
344     /* Signature Extensions structure:
345      * |     2     |     2   |       2      | <SigHash Len> |
346      * |  Ext Type | Sig Len |  SigHash Len | SigHash Algos |
347      *
348      * Each algorithm pair has a hash ID and a public key operation ID represented
349      * by a single octet. Therefore each entry in the list is 2 bytes long.
350      */
351 
352     if (available_size < (*packet_offset + 6u +
353                           (ULONG)(tls_session -> nx_secure_tls_crypto_table -> nx_secure_tls_x509_cipher_table_size << 1)))
354     {
355 
356         /* Packet buffer too small. */
357         return(NX_SECURE_TLS_PACKET_BUFFER_TOO_SMALL);
358     }
359 
360     /* Start with our passed-in packet offset. */
361     offset = *packet_offset;
362 
363     ext_pos = offset;
364     offset += 6;
365 
366     ext_len = sighash_len = 0;
367 
368     cipher_table = tls_session -> nx_secure_tls_crypto_table -> nx_secure_tls_x509_cipher_table;
369 
370     /* Loop the x509 cipher table to add signature algorithms. */
371     for (i = 0; i < tls_session -> nx_secure_tls_crypto_table -> nx_secure_tls_x509_cipher_table_size; i++)
372     {
373 
374         /* Map crypto method to signature algorithm. */
375         _nx_secure_tls_get_signature_algorithm(tls_session, &cipher_table[i], &signature_algorithm);
376         if (signature_algorithm == 0)
377         {
378             continue;
379         }
380 
381         packet_buffer[offset] = (UCHAR)((signature_algorithm & 0xFF00) >> 8);
382         packet_buffer[offset + 1] = (UCHAR)(signature_algorithm & 0x00FF);
383 
384         offset += 2;
385         sighash_len = (USHORT)(sighash_len + 2);
386     }
387 
388     ext = NX_SECURE_TLS_EXTENSION_SIGNATURE_ALGORITHMS;  /* Signature algorithms */
389     ext_len = (USHORT)(ext_len + 2);
390 
391     sig_len = 2;
392     ext_len = (USHORT)(ext_len + 2);
393 
394     sig_len = (USHORT)(sig_len + sighash_len);
395     ext_len = (USHORT)(ext_len + sig_len);
396 
397     packet_buffer[ext_pos] = (UCHAR)((ext & 0xFF00) >> 8);
398     packet_buffer[ext_pos + 1] = (UCHAR)(ext & 0x00FF);
399     ext_pos += 2;
400 
401     packet_buffer[ext_pos] = (UCHAR)((sig_len & 0xFF00) >> 8);
402     packet_buffer[ext_pos + 1] = (UCHAR)(sig_len & 0x00FF);
403     ext_pos += 2;
404 
405     packet_buffer[ext_pos] = (UCHAR)((sighash_len & 0xFF00) >> 8);
406     packet_buffer[ext_pos + 1] = (UCHAR)(sighash_len & 0x00FF);
407 
408     /* Return our updated packet offset. */
409     *extension_length = ext_len;
410     *packet_offset = offset;
411 
412     return(NX_SUCCESS);
413 }
414 
_nx_secure_tls_get_signature_algorithm(NX_SECURE_TLS_SESSION * tls_session,NX_SECURE_X509_CRYPTO * crypto_method,USHORT * signature_algorithm)415 VOID _nx_secure_tls_get_signature_algorithm(NX_SECURE_TLS_SESSION *tls_session,
416                                             NX_SECURE_X509_CRYPTO *crypto_method,
417                                             USHORT *signature_algorithm)
418 {
419 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
420 UINT j;
421 #endif /* (NX_SECURE_TLS_TLS_1_3_ENABLED) */
422 USHORT named_curve = 0;
423 UCHAR hash_algo = 0;
424 UCHAR sig_algo = 0;
425 
426     *signature_algorithm = 0;
427 
428     switch (crypto_method -> nx_secure_x509_public_cipher_method -> nx_crypto_algorithm)
429     {
430     case NX_CRYPTO_KEY_EXCHANGE_RSA:
431         sig_algo = NX_SECURE_TLS_SIGNATURE_ALGORITHM_RSA;
432         break;
433     case NX_CRYPTO_DIGITAL_SIGNATURE_DSA:
434         sig_algo = NX_SECURE_TLS_SIGNATURE_ALGORITHM_DSA;
435         break;
436     case NX_CRYPTO_DIGITAL_SIGNATURE_ECDSA:
437         sig_algo = NX_SECURE_TLS_SIGNATURE_ALGORITHM_ECDSA;
438         break;
439     default:
440         return;
441     }
442 
443     switch (crypto_method -> nx_secure_x509_hash_method -> nx_crypto_algorithm)
444     {
445     case NX_CRYPTO_HASH_MD5:
446         hash_algo = NX_SECURE_TLS_HASH_ALGORITHM_MD5;
447         break;
448     case NX_CRYPTO_HASH_SHA1:
449         hash_algo = NX_SECURE_TLS_HASH_ALGORITHM_SHA1;
450         break;
451     case NX_CRYPTO_HASH_SHA224:
452         hash_algo = NX_SECURE_TLS_HASH_ALGORITHM_SHA224;
453         break;
454     case NX_CRYPTO_HASH_SHA256:
455         hash_algo = NX_SECURE_TLS_HASH_ALGORITHM_SHA256;
456         named_curve = (USHORT)NX_CRYPTO_EC_SECP256R1;
457         break;
458     case NX_CRYPTO_HASH_SHA384:
459         hash_algo = NX_SECURE_TLS_HASH_ALGORITHM_SHA384;
460         named_curve = (USHORT)NX_CRYPTO_EC_SECP384R1;
461         break;
462     case NX_CRYPTO_HASH_SHA512:
463         hash_algo = NX_SECURE_TLS_HASH_ALGORITHM_SHA512;
464         named_curve = (USHORT)NX_CRYPTO_EC_SECP521R1;
465         break;
466     default:
467         return;
468     }
469 
470 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
471     /* TLS 1.3 deprecates MD5, and SHA-1 is obsolete. Remove them from the signing list. */
472     if(tls_session -> nx_secure_tls_1_3)
473     {
474         if((hash_algo == NX_SECURE_TLS_HASH_ALGORITHM_MD5) || (hash_algo == NX_SECURE_TLS_HASH_ALGORITHM_SHA1))
475         {
476             *signature_algorithm = 0;
477             return;
478         }
479     }
480 
481     /* In TLS 1.3, the signing curve is constrained.  */
482     if (tls_session -> nx_secure_tls_1_3 &&
483         (named_curve != 0) &&
484         (sig_algo == NX_SECURE_TLS_SIGNATURE_ALGORITHM_ECDSA))
485     {
486         for (j = 0; j < tls_session->nx_secure_tls_ecc.nx_secure_tls_ecc_supported_groups_count; j++)
487         {
488             if (named_curve == tls_session->nx_secure_tls_ecc.nx_secure_tls_ecc_supported_groups[j])
489             {
490                 *signature_algorithm = (USHORT)((hash_algo << 8) + sig_algo);
491                 return;
492             }
493         }
494     }
495     else
496 #else
497     NX_PARAMETER_NOT_USED(named_curve);
498     NX_PARAMETER_NOT_USED(tls_session);
499 #endif
500     {
501         *signature_algorithm = (USHORT)((hash_algo << 8) + sig_algo);
502     }
503 }
504 #endif
505 
506 
507 /**************************************************************************/
508 /*                                                                        */
509 /*  FUNCTION                                               RELEASE        */
510 /*                                                                        */
511 /*    _nx_secure_tls_send_clienthello_supported_versions_extension        */
512 /*                                                        PORTABLE C      */
513 /*                                                           6.2.1        */
514 /*  AUTHOR                                                                */
515 /*                                                                        */
516 /*    Timothy Stapko, Microsoft Corporation                               */
517 /*                                                                        */
518 /*  DESCRIPTION                                                           */
519 /*                                                                        */
520 /*    This function adds the Supported Versions extension, added in TLS   */
521 /*    v1.3.                                                               */
522 /*                                                                        */
523 /*  INPUT                                                                 */
524 /*                                                                        */
525 /*    tls_session                           TLS control block             */
526 /*    packet_buffer                         Outgoing TLS packet buffer    */
527 /*    packet_offset                         Offset into packet buffer     */
528 /*    extension_length                      Return length of data         */
529 /*    available_size                        Available size of buffer      */
530 /*                                                                        */
531 /*  OUTPUT                                                                */
532 /*                                                                        */
533 /*    status                                Completion status             */
534 /*                                                                        */
535 /*  CALLS                                                                 */
536 /*                                                                        */
537 /*    None                                                                */
538 /*                                                                        */
539 /*  CALLED BY                                                             */
540 /*                                                                        */
541 /*    _nx_secure_tls_send_clienthello_extensions                          */
542 /*                                          Send TLS ClientHello extension*/
543 /*                                                                        */
544 /*  RELEASE HISTORY                                                       */
545 /*                                                                        */
546 /*    DATE              NAME                      DESCRIPTION             */
547 /*                                                                        */
548 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
549 /*  09-30-2020     Timothy Stapko           Modified comment(s),          */
550 /*                                            resulting in version 6.1    */
551 /*  03-08-2023     Tiejun Zhou              Modified comment(s),          */
552 /*                                            fixed compiler warnings,    */
553 /*                                            resulting in version 6.2.1  */
554 /*                                                                        */
555 /**************************************************************************/
556 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
557 /* We need to access the supported versions table located in nx_secure_tls_check_protocol_version.c. */
558 extern const NX_SECURE_VERSIONS_LIST nx_secure_supported_versions_list[];
_nx_secure_tls_send_clienthello_supported_versions_extension(NX_SECURE_TLS_SESSION * tls_session,UCHAR * packet_buffer,ULONG * packet_offset,USHORT * extension_length,ULONG available_size)559 static UINT _nx_secure_tls_send_clienthello_supported_versions_extension(NX_SECURE_TLS_SESSION *tls_session,
560                                                           UCHAR *packet_buffer, ULONG *packet_offset,
561                                                           USHORT *extension_length, ULONG available_size)
562 {
563 ULONG  offset;
564 USHORT ext;
565 UINT   data_length;
566 UINT   id = NX_SECURE_TLS;
567 #ifndef NX_SECURE_TLS_DISABLE_PROTOCOL_VERSION_DOWNGRADE
568 USHORT protocol_version;
569 INT    i;
570 #endif /* NX_SECURE_TLS_DISABLE_PROTOCOL_VERSION_DOWNGRADE */
571 
572     /* Supported Versions Extension structure:
573      * |     2      |         2          |      1       | <list length> |
574      * |  Ext Type  |  Extension length  |  List Length |  TLS Versions |
575      */
576     NX_PARAMETER_NOT_USED(tls_session);
577 
578     if (available_size < (*packet_offset + 7u +
579                           (nx_secure_supported_versions_list[id].nx_secure_versions_list_count << 1)))
580     {
581 
582         /* Packet buffer too small. */
583         return(NX_SECURE_TLS_PACKET_BUFFER_TOO_SMALL);
584     }
585 
586     /* Start with our passed-in packet offset. */
587     offset = *packet_offset;
588 
589     /* The extension identifier. */
590     ext = NX_SECURE_TLS_EXTENSION_SUPPORTED_VERSIONS;
591 
592     /* Put the extension ID into the packet. */
593     packet_buffer[offset] = (UCHAR)((ext & 0xFF00) >> 8);
594     packet_buffer[offset + 1] = (UCHAR)(ext & 0x00FF);
595     offset += 2;
596 
597     /* Fill in the supported versions first. */
598     offset += 3;
599     data_length = 0;
600 
601     /* Add TLS 1.3 (0x0304) which is not in legacy supported versions list. */
602     packet_buffer[offset] = (UCHAR)NX_SECURE_TLS_VERSION_MAJOR_3;
603     packet_buffer[offset + 1] = (UCHAR)NX_SECURE_TLS_VERSION_MINOR_1_3;
604     data_length += 2;
605     offset += 2;
606 
607 #ifndef NX_SECURE_TLS_DISABLE_PROTOCOL_VERSION_DOWNGRADE
608     /* Loop through the supported versions to see if the passed-in version is one that is enabled. */
609     for (i = (INT)(nx_secure_supported_versions_list[id].nx_secure_versions_list_count - 1); i >= 0; --i)
610     {
611 
612         /* See if it is supported. */
613         if (nx_secure_supported_versions_list[id].nx_secure_versions_list[i].nx_secure_tls_is_supported)
614         {
615 
616             /* Set the version value. */
617             protocol_version = nx_secure_supported_versions_list[id].nx_secure_versions_list[i].nx_secure_tls_protocol_version;
618             packet_buffer[offset] = (UCHAR)((protocol_version & 0xFF00) >> 8);
619             packet_buffer[offset + 1] = (UCHAR)(protocol_version & 0x00FF);
620             data_length += 2;
621             offset += 2;
622         }
623         else
624         {
625             break;
626         }
627     }
628 #endif /* NX_SECURE_TLS_DISABLE_PROTOCOL_VERSION_DOWNGRADE */
629 
630     /* Fill in list length and extension length. */
631     packet_buffer[*packet_offset + 4] = (UCHAR)(data_length & 0xFF);
632 
633     data_length++;
634     packet_buffer[*packet_offset + 2] = (UCHAR)((data_length & 0xFF00) >> 8);
635     packet_buffer[*packet_offset + 3] = (UCHAR)(data_length & 0x00FF);
636 
637     /* Return the amount of data we wrote. */
638     *extension_length = (USHORT)(offset - *packet_offset);
639 
640     /* Return our updated packet offset. */
641     *packet_offset = offset;
642 
643 
644     return(NX_SUCCESS);
645 }
646 #endif
647 
648 /**************************************************************************/
649 /*                                                                        */
650 /*  FUNCTION                                               RELEASE        */
651 /*                                                                        */
652 /*    _nx_secure_tls_send_clienthello_key_share_extension PORTABLE C      */
653 /*                                                           6.1          */
654 /*  AUTHOR                                                                */
655 /*                                                                        */
656 /*    Timothy Stapko, Microsoft Corporation                               */
657 /*                                                                        */
658 /*  DESCRIPTION                                                           */
659 /*                                                                        */
660 /*    This function adds the Key Share extension, added in TLS            */
661 /*    v1.3.                                                               */
662 /*                                                                        */
663 /*  INPUT                                                                 */
664 /*                                                                        */
665 /*    tls_session                           TLS control block             */
666 /*    packet_buffer                         Outgoing TLS packet buffer    */
667 /*    packet_offset                         Offset into packet buffer     */
668 /*    extension_length                      Return length of data         */
669 /*    available_size                        Available size of buffer      */
670 /*                                                                        */
671 /*  OUTPUT                                                                */
672 /*                                                                        */
673 /*    status                                Completion status             */
674 /*                                                                        */
675 /*  CALLS                                                                 */
676 /*                                                                        */
677 /*    None                                                                */
678 /*                                                                        */
679 /*  CALLED BY                                                             */
680 /*                                                                        */
681 /*    _nx_secure_tls_send_clienthello_extensions                          */
682 /*                                          Send TLS ClientHello extension*/
683 /*                                                                        */
684 /*  RELEASE HISTORY                                                       */
685 /*                                                                        */
686 /*    DATE              NAME                      DESCRIPTION             */
687 /*                                                                        */
688 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
689 /*  09-30-2020     Timothy Stapko           Modified comment(s),          */
690 /*                                            verified memcpy use cases,  */
691 /*                                            resulting in version 6.1    */
692 /*                                                                        */
693 /**************************************************************************/
694 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
_nx_secure_tls_send_clienthello_key_share_extension(NX_SECURE_TLS_SESSION * tls_session,UCHAR * packet_buffer,ULONG * packet_offset,USHORT * extension_length,ULONG available_size)695 static UINT _nx_secure_tls_send_clienthello_key_share_extension(NX_SECURE_TLS_SESSION *tls_session,
696                                                                 UCHAR *packet_buffer, ULONG *packet_offset,
697                                                                 USHORT *extension_length, ULONG available_size)
698 {
699 ULONG  offset;
700 ULONG  length_offset;
701 USHORT ext;
702 UINT   entry_index;
703 UINT   entry_length;
704 UINT   key_length;
705 UINT   data_length;
706 NX_SECURE_TLS_ECDHE_HANDSHAKE_DATA   *ecdhe_data;
707 USHORT named_curve;
708 
709     /* Key Share Extension structure (From TLS 1.3 RFC Draft #28):
710      *  struct {
711      *     NamedGroup group;
712      *     opaque key_exchange<1..2^16-1>;
713      *  } KeyShareEntry;
714      *
715      *  struct {
716      *     KeyShareEntry client_shares<0..2^16-1>;
717      *  } KeyShareClientHello;
718      *
719      *  Diffie-Hellman [DH] parameters for both clients and servers are
720      *  encoded in the opaque key_exchange field of a KeyShareEntry in a
721      *  KeyShare structure.  The opaque value contains the Diffie-Hellman
722      *  public value (Y = g^X mod p) for the specified group (see [RFC7919]
723      *  for group definitions) encoded as a big-endian integer and padded to
724      *  the left with zeros to the size of p in bytes.
725      *
726      *  ECDHE structure for key_exchange (For secp256r1, secp384r1 and secp521r1)
727      *  struct {
728      *     uint8 legacy_form = 4;
729      *     opaque X[coordinate_length];
730      *     opaque Y[coordinate_length];
731      *  } UncompressedPointRepresentation;
732      *
733      *   X and Y respectively are the binary representations of the x and y
734      *   values in network byte order.  There are no internal length markers,
735      *   so each number representation occupies as many octets as implied by
736      *   the curve parameters.  For P-256 this means that each of X and Y use
737      *   32 octets, padded on the left by zeros if necessary.  For P-384 they
738      *   take 48 octets each, and for P-521 they take 66 octets each.
739      *
740      *  The X,Y point is the public key (Q) which is generated using the following:
741      *  -  The public key to put into the KeyShareEntry.key_exchange
742      *     structure is the result of applying the ECDH scalar multiplication
743      *     function to the secret key of appropriate length (into scalar
744      *     input) and the standard public basepoint (into u-coordinate point
745      *     input).
746      *
747      *  -  The ECDH shared secret is the result of applying the ECDH scalar
748      *     multiplication function to the secret key (into scalar input) and
749      *     the peer's public key (into u-coordinate point input).  The output
750      *     is used raw, with no processing.
751      *
752      *  NamedGroup examples: secp256r1(0x0017), secp384r1(0x0018), secp521r1(0x0019)
753      *                                   |                 <list length>                      |
754      * |     2      |         2          |  <|       2      |    2    |     <Key len>     |>  |
755      * |  Ext Type  |  Extension length  |  <|  Named Group | Key len | key_exchange data |>  |
756      */
757 
758     if (tls_session == NX_NULL)
759     {
760         return(NX_PTR_ERROR);
761     }
762 
763     if (tls_session -> nx_secure_tls_client_state == NX_SECURE_TLS_CLIENT_STATE_HELLO_RETRY)
764     {
765         entry_index = tls_session -> nx_secure_tls_key_material.nx_secure_tls_ecc_key_data_selected;
766     }
767     else
768     {
769 
770         /* Select default entry is based on the actual curves we support. */
771         entry_index = 0;
772     }
773 
774     /* Get the ECDHE structure for our key data. */
775     ecdhe_data = &tls_session -> nx_secure_tls_key_material.nx_secure_tls_ecc_key_data[entry_index];
776 
777     /* Get the curve for the key we are sending. */
778     named_curve = (USHORT)ecdhe_data->nx_secure_tls_ecdhe_named_curve;
779 
780     /* Key length will differ for each curve. For p256, 32 octets per coordinate, plus the "legacy_form" byte. */
781     key_length = ecdhe_data->nx_secure_tls_ecdhe_public_key_length;
782 
783     if (available_size < (*packet_offset + 10u + key_length))
784     {
785 
786         /* Packet buffer too small. */
787         return(NX_SECURE_TLS_PACKET_BUFFER_TOO_SMALL);
788     }
789 
790     /* Start with our passed-in packet offset. */
791     offset = *packet_offset;
792 
793     /* The extension identifier. */
794     ext = NX_SECURE_TLS_EXTENSION_KEY_SHARE;
795 
796     /* Put the extension ID into the packet. */
797     packet_buffer[offset] = (UCHAR)((ext & 0xFF00) >> 8);
798     packet_buffer[offset + 1] = (UCHAR)(ext & 0x00FF);
799     offset += 2;
800 
801     /* Add Total Length (2 bytes) and List length (2 bytes) to packet after we
802        fill in the key data. */
803     length_offset = offset;
804     data_length = 0;
805     offset += 4;
806 
807     /* Entry is named group(2) + key len(2) + key data(key len). */
808     entry_length = 2 + 2 + key_length;
809 
810     /* Set the named group. */
811     packet_buffer[offset] = (UCHAR)((named_curve & 0xFF00) >> 8);;
812     packet_buffer[offset + 1] = (UCHAR)(named_curve & 0x00FF);
813     offset += 2;
814 
815     /* Set the key length. */
816     packet_buffer[offset] = (UCHAR)((key_length & 0xFF00) >> 8);;
817     packet_buffer[offset + 1] = (UCHAR)(key_length & 0x00FF);
818     offset += 2;
819 
820     /* Set the key data from our already-generated ECC keys. */
821     NX_SECURE_MEMCPY(&packet_buffer[offset], &tls_session -> nx_secure_tls_key_material.nx_secure_tls_ecc_key_data[entry_index].nx_secure_tls_ecdhe_public_key[0], key_length); /* Use case of memcpy is verified. */
822     offset += (key_length);
823 
824     /* Get the length of the entire extension. */
825     data_length = data_length + (UINT)(entry_length);
826 
827     /* Go back and set the total extension length. */
828     data_length = data_length + 2;
829     packet_buffer[length_offset] = (UCHAR)((data_length & 0xFF00) >> 8);
830     packet_buffer[length_offset + 1] = (UCHAR)(data_length & 0x00FF);
831     length_offset += 2;
832     data_length = data_length - 2;
833 
834     /* Finally, put the list length into the packet. */
835     packet_buffer[length_offset] = (UCHAR)((data_length & 0xFF00) >> 8);
836     packet_buffer[length_offset + 1] = (UCHAR)(data_length & 0x00FF);
837 
838     /* Return the amount of data we wrote. */
839     *extension_length = (USHORT)(offset - *packet_offset);
840 
841     /* Return our updated packet offset. */
842     *packet_offset = offset;
843 
844 
845     return(NX_SUCCESS);
846 }
847 #endif
848 
849 
850 
851 /**************************************************************************/
852 /*                                                                        */
853 /*  FUNCTION                                               RELEASE        */
854 /*                                                                        */
855 /*    _nx_secure_tls_send_clienthello_psk_extension       PORTABLE C      */
856 /*                                                           6.1.8        */
857 /*  AUTHOR                                                                */
858 /*                                                                        */
859 /*    Timothy Stapko, Microsoft Corporation                               */
860 /*                                                                        */
861 /*  DESCRIPTION                                                           */
862 /*                                                                        */
863 /*    This function adds the pre_shared_key extension, added in TLS       */
864 /*    v1.3.                                                               */
865 /*                                                                        */
866 /*  INPUT                                                                 */
867 /*                                                                        */
868 /*    tls_session                           TLS control block             */
869 /*    packet_buffer                         Outgoing TLS packet buffer    */
870 /*    packet_length                         Length of data in packet      */
871 /*    extension_length                      Return length of data         */
872 /*    available_size                        Available size of buffer      */
873 /*                                                                        */
874 /*  OUTPUT                                                                */
875 /*                                                                        */
876 /*    status                                Completion status             */
877 /*                                                                        */
878 /*  CALLS                                                                 */
879 /*                                                                        */
880 /*    None                                                                */
881 /*                                                                        */
882 /*  CALLED BY                                                             */
883 /*                                                                        */
884 /*    _nx_secure_tls_send_clienthello_extensions                          */
885 /*                                          Send TLS ClientHello extension*/
886 /*                                                                        */
887 /*  RELEASE HISTORY                                                       */
888 /*                                                                        */
889 /*    DATE              NAME                      DESCRIPTION             */
890 /*                                                                        */
891 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
892 /*  09-30-2020     Timothy Stapko           Modified comment(s),          */
893 /*                                            verified memcpy use cases,  */
894 /*                                            resulting in version 6.1    */
895 /*  08-02-2021     Timothy Stapko           Modified comment(s), added    */
896 /*                                            hash clone and cleanup,     */
897 /*                                            resulting in version 6.1.8  */
898 /*                                                                        */
899 /**************************************************************************/
900 
901 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
_nx_secure_tls_send_clienthello_psk_extension(NX_SECURE_TLS_SESSION * tls_session,UCHAR * packet_buffer,ULONG * packet_length,ULONG extension_length_offset,ULONG total_extensions_length,ULONG * extension_length,ULONG available_size)902 UINT _nx_secure_tls_send_clienthello_psk_extension(NX_SECURE_TLS_SESSION *tls_session,
903                                                    UCHAR *packet_buffer, ULONG *packet_length,
904                                                    ULONG extension_length_offset, ULONG total_extensions_length,
905                                                    ULONG *extension_length, ULONG available_size)
906 {
907 ULONG  offset;
908 ULONG  length_offset;
909 USHORT ext;
910 UINT   i;
911 UINT   num_ids;
912 UINT   data_length;
913 UINT   ids_total;
914 UINT   id_len;
915 UINT   age;
916 UCHAR  *id;
917 UINT   binder_len = 0;
918 UCHAR  *binder;
919 UINT   num_binders;
920 UINT   binder_offset;
921 UINT   binder_total;
922 UINT   status;
923 UINT   partial_client_hello_len;
924 NX_SECURE_TLS_PSK_STORE *psk_store;
925 
926 
927     /* Key Share Extension structure (From TLS 1.3 RFC 8446):
928           struct {
929               opaque identity<1..2^16-1>;
930               uint32 obfuscated_ticket_age;
931           } PskIdentity;
932 
933           opaque PskBinderEntry<32..255>;
934 
935           struct {
936               PskIdentity identities<7..2^16-1>;
937               PskBinderEntry binders<33..2^16-1>;
938           } OfferedPsks;
939 
940           struct {
941               select (Handshake.msg_type) {
942                   case client_hello: OfferedPsks;
943                   case server_hello: uint16 selected_identity;
944               };
945           } PreSharedKeyExtension;
946 
947        identity:  A label for a key.  For instance, a ticket (as defined in
948           Appendix B.3.4) or a label for a pre-shared key established
949           externally.
950 
951        obfuscated_ticket_age:  An obfuscated version of the age of the key.
952           Section 4.2.11.1 describes how to form this value for identities
953           established via the NewSessionTicket message.  For identities
954           established externally, an obfuscated_ticket_age of 0 SHOULD be
955           used, and servers MUST ignore the value.
956 
957        identities:  A list of the identities that the client is willing to
958           negotiate with the server.  If sent alongside the "early_data"
959           extension (see Section 4.2.10), the first identity is the one used
960           for 0-RTT data.
961 
962        binders:  A series of HMAC values, one for each value in the
963           identities list and in the same order, computed as described
964           below.
965 
966        selected_identity:  The server's chosen identity expressed as a
967           (0-based) index into the identities in the client's list.
968 
969 
970       ClientHello extension layout:
971       |     2      |         2          |       2      |      <ID list len>        |      2      | <binders len>   |
972       |  Ext Type  |  Extension length  |  ID list len | <|<ID len> | ID | age |>  | binders len | <len> | binder  |
973     */
974     NX_PARAMETER_NOT_USED(tls_session);
975 
976     /* Start with our passed-in packet offset. */
977     offset = *packet_length;
978 
979     /* The extension identifier. */
980     ext = NX_SECURE_TLS_EXTENSION_PRE_SHARED_KEY;
981 
982     if (tls_session == NX_NULL)
983     {
984         return(NX_PTR_ERROR);
985     }
986 
987     if (available_size < (offset + 6u))
988     {
989 
990         /* Packet buffer too small. */
991         return(NX_SECURE_TLS_PACKET_BUFFER_TOO_SMALL);
992     }
993 
994     /* Put the extension ID into the packet. */
995     packet_buffer[offset] = (UCHAR)((ext & 0xFF00) >> 8);
996     packet_buffer[offset + 1] = (UCHAR)(ext & 0x00FF);
997     offset += 2;
998 
999     /* Add Total Length (2 bytes) and List length (2 bytes) to packet after we
1000        fill in the key data. */
1001     length_offset = offset;
1002     data_length = 4;
1003     offset += 4;
1004 
1005     /* Get our PSK store for easy access. */
1006     psk_store = tls_session->nx_secure_tls_credentials.nx_secure_tls_psk_store;
1007     num_ids = tls_session->nx_secure_tls_credentials.nx_secure_tls_psk_count;
1008     ids_total = 0;
1009     binder_total = 0;
1010 
1011     /* Loop through all IDs. */
1012     for(i = 0; i < num_ids; ++i)
1013     {
1014         /* Setup the ID list. */
1015         id_len = psk_store[i].nx_secure_tls_psk_id_size;
1016         id = psk_store[i].nx_secure_tls_psk_id;
1017 
1018         if (available_size < (offset + 6u + id_len))
1019         {
1020 
1021             /* Packet buffer too small. */
1022             return(NX_SECURE_TLS_PACKET_BUFFER_TOO_SMALL);
1023         }
1024 
1025         packet_buffer[offset] = (UCHAR)((id_len & 0xFF00) >> 8);;
1026         packet_buffer[offset + 1] = (UCHAR)(id_len & 0x00FF);
1027         offset += 2;
1028 
1029         /* Put the ID data into our packet. */
1030         NX_SECURE_MEMCPY(&packet_buffer[offset], id, id_len); /* Use case of memcpy is verified. */
1031         offset += (UINT)(id_len);
1032 
1033         /* Set the obfuscated PSK age. */
1034         age = 0;
1035         packet_buffer[offset]     = (UCHAR)((age & 0xFF000000) >> 24);
1036         packet_buffer[offset + 1] = (UCHAR)((age & 0x00FF0000) >> 16);
1037         packet_buffer[offset + 2] = (UCHAR)((age & 0x0000FF00) >> 8);
1038         packet_buffer[offset + 3] = (UCHAR) (age & 0x000000FF);
1039         offset += 4;
1040 
1041         /* Update the length with the ID length (id_len), length field (2), and age field (4). */
1042         ids_total = ids_total + (UINT)(id_len + 2 + 4);
1043 
1044         /* Caclulate the length of the binder list - binder for each PSK + the length field. */
1045         binder_total += (UINT)(1 + binder_len);
1046     }
1047 
1048     /* Put the list length into the packet - the list length is the 16-bit field following the total length field (16-bits). */
1049     packet_buffer[length_offset + 2] = (UCHAR)((ids_total & 0xFF00) >> 8);
1050     packet_buffer[length_offset + 3] = (UCHAR)(ids_total & 0x00FF);
1051     data_length += ids_total;
1052 
1053 
1054     /* Get the length of the ClientHello to this point, plus the length field that comes next. */
1055     partial_client_hello_len = (UINT)(*packet_length) + data_length + 2;
1056 
1057     /* Update the total length of the extension with the anticipated size of the binders - this is used in generating
1058        the binder hashes. */
1059 //    printf(">>>Binder list length: %d\n", binder_total);
1060     binder_total = 33;
1061     data_length += binder_total;
1062 
1063     /* Extension length. */
1064     packet_buffer[length_offset] =     (UCHAR)((data_length & 0xFF00) >> 8);
1065     packet_buffer[length_offset + 1] = (UCHAR)(data_length & 0x00FF);
1066 
1067     /* IMPORTANT: We also need to update the total extensions length field using the passed-in parameters.
1068        Failure to to so will invalidate the transcript hash we do next. */
1069     total_extensions_length += data_length + 4;
1070     packet_buffer[extension_length_offset] =      (UCHAR)((total_extensions_length & 0xFF00) >> 8);
1071     packet_buffer[extension_length_offset + 1] =  (UCHAR)(total_extensions_length & 0x00FF);
1072 
1073 
1074     /* Now calculate the binders for this session. The binder is an HMAC hash of the entire ClientHello
1075      * up to and including the pre_shared_key extension with the IDs added above but NOT the binders.
1076      * The Length fields for the extension, however, are set to a value that matches the complete extension
1077      * with assumed correct binder lengths.
1078      *
1079      * Binders are calculated using the following (ClientHello1 is the first ClientHello,
1080      * and "Truncate" removes the binder data which is being generated):
1081      *    Transcript-Hash(Truncate(ClientHello1))
1082      *
1083      * Each PSK is associated with a single Hash algorithm.  For PSKs
1084      * established via the ticket mechanism (Section 4.6.1), this is the KDF
1085      * Hash algorithm on the connection where the ticket was established.
1086      * For externally established PSKs, the Hash algorithm MUST be set when
1087      * the PSK is established or default to SHA-256 if no such algorithm is
1088      * defined.  The server MUST ensure that it selects a compatible PSK
1089      * (if any) and cipher suite.
1090      */
1091 
1092     /* If nx_secure_tls_client_state is IDLE, it means this is ClientHello1, need to initialize the handshake hash.
1093        If not, it means this is ClientHello2, need to save the metadata(ClientHello1 and HelloRetryRequest) to sratch buffer. */
1094     if (tls_session -> nx_secure_tls_client_state == NX_SECURE_TLS_CLIENT_STATE_IDLE)
1095     {
1096 
1097         /* Initialize the handshake hash to hash the ClientHello up to now. */
1098         _nx_secure_tls_handshake_hash_init(tls_session);
1099     }
1100     else
1101     {
1102 
1103         /* Save the handshake hash state. */
1104         NX_SECURE_HASH_METADATA_CLONE(tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_scratch,
1105                                       tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_sha256_metadata,
1106                                       tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_sha256_metadata_size); /* Use case of memcpy is verified. */
1107     }
1108 
1109     /* Hash the ClientHello up to its current point. */
1110     /* The Transcript hash needs to include the handshake record header which means we need to calculate the full length
1111        of the expected ClientHello (with expected binder list length) and fill in the header appropriately. */
1112     UCHAR header[] = { 0x01, 0x00, 0x01, 0x30 };
1113     header[2] = (UCHAR)((partial_client_hello_len + binder_total + 2) >> 8);
1114     header[3] = (UCHAR)((partial_client_hello_len + binder_total + 2) & 0xFF);
1115     _nx_secure_tls_handshake_hash_update(tls_session, header, sizeof(header));
1116     _nx_secure_tls_handshake_hash_update(tls_session, packet_buffer, partial_client_hello_len);
1117 
1118     /* Save the transcript hash for the ClientHello, which is used in generating the PSK binders. */
1119     status = _nx_secure_tls_1_3_transcript_hash_save(tls_session, NX_SECURE_TLS_TRANSCRIPT_IDX_CLIENTHELLO, NX_FALSE);
1120     if (status != NX_SUCCESS)
1121     {
1122 
1123         if (tls_session -> nx_secure_tls_client_state != NX_SECURE_TLS_CLIENT_STATE_IDLE)
1124         {
1125             NX_SECURE_HASH_CLONE_CLEANUP(tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_scratch,
1126                                          tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_sha256_metadata_size);
1127         }
1128 
1129         return(status);
1130     }
1131 
1132     /* Restore the original metadata(ClientHello1 and HelloRetryRequest) from scratch buffer. */
1133     if (tls_session -> nx_secure_tls_client_state != NX_SECURE_TLS_CLIENT_STATE_IDLE)
1134     {
1135         NX_SECURE_HASH_CLONE_CLEANUP(tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_sha256_metadata,
1136                                      tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_sha256_metadata_size);
1137 
1138         NX_SECURE_HASH_METADATA_CLONE(tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_sha256_metadata,
1139                                       tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_scratch,
1140                                       tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_sha256_metadata_size); /* Use case of memcpy is verified. */
1141 
1142         NX_SECURE_HASH_CLONE_CLEANUP(tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_scratch,
1143                                      tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_sha256_metadata_size);
1144     }
1145 
1146     /* Loop through all IDs and set the binders accordingly. */
1147     for(i = 0; i < num_ids; ++i)
1148     {
1149         _nx_secure_tls_psk_binder_generate(tls_session, &psk_store[i]);
1150     }
1151 
1152     if (available_size < (offset + 2u))
1153     {
1154 
1155         /* Packet buffer too small. */
1156         return(NX_SECURE_TLS_PACKET_BUFFER_TOO_SMALL);
1157     }
1158 
1159     /* Now add in the PSK binders. Skip the list length and fill in after. */
1160     binder_offset = offset;
1161     offset += 2;
1162     binder_total = 0;
1163 
1164     num_binders = num_ids;
1165     for(i = 0; i < num_binders; ++i)
1166     {
1167         binder_len = psk_store[i].nx_secure_tls_psk_binder_size;
1168         binder = psk_store[i].nx_secure_tls_psk_binder;
1169 
1170         if (available_size < (offset + 1u + binder_len))
1171         {
1172 
1173             /* Packet buffer too small. */
1174             return(NX_SECURE_TLS_PACKET_BUFFER_TOO_SMALL);
1175         }
1176 
1177         /* Add in the length of the binder. */
1178         packet_buffer[offset] = (UCHAR)(binder_len);
1179         offset += (UINT)(1);
1180 
1181         /* Put the binder data into the packet. */
1182         NX_SECURE_MEMCPY(&packet_buffer[offset], binder, binder_len); /* Use case of memcpy is verified. */
1183         offset += (UINT)(binder_len);
1184 
1185         /* Update our total with the binder length (binder_len) and length field(1). */
1186         binder_total += (UINT)(1 + binder_len);
1187     }
1188 
1189     /* Binder list length - this was set above, but overwrite it here. */
1190     packet_buffer[binder_offset] = (UCHAR)((binder_total & 0xFF00) >> 8);;
1191     packet_buffer[binder_offset + 1] = (UCHAR)(binder_total & 0x00FF);
1192 
1193     /* Go back and set the total extension length. */
1194     packet_buffer[length_offset] = (UCHAR)((data_length & 0xFF00) >> 8);
1195     packet_buffer[length_offset + 1] = (UCHAR)(data_length & 0x00FF);
1196 
1197     /* Return the amount of data we wrote. */
1198     *extension_length = (USHORT)(offset - *packet_length);
1199 
1200     /* Return our updated packet offset. */
1201     *packet_length = offset;
1202 
1203     return(NX_SUCCESS);
1204 }
1205 #endif
1206 
1207 
1208 /**************************************************************************/
1209 /*                                                                        */
1210 /*  FUNCTION                                               RELEASE        */
1211 /*                                                                        */
1212 /*    _nx_secure_tls_send_clienthello_psk_kem_extension   PORTABLE C      */
1213 /*                                                           6.1          */
1214 /*  AUTHOR                                                                */
1215 /*                                                                        */
1216 /*    Timothy Stapko, Microsoft Corporation                               */
1217 /*                                                                        */
1218 /*  DESCRIPTION                                                           */
1219 /*                                                                        */
1220 /*    This function adds the psk_key_exchange_mode extension, added in TLS*/
1221 /*    v1.3.                                                               */
1222 /*                                                                        */
1223 /*  INPUT                                                                 */
1224 /*                                                                        */
1225 /*    tls_session                           TLS control block             */
1226 /*    packet_buffer                         Outgoing TLS packet buffer    */
1227 /*    packet_length                         Length of data in packet      */
1228 /*    extension_length                      Return length of data         */
1229 /*                                                                        */
1230 /*  OUTPUT                                                                */
1231 /*                                                                        */
1232 /*    status                                Completion status             */
1233 /*                                                                        */
1234 /*  CALLS                                                                 */
1235 /*                                                                        */
1236 /*    None                                                                */
1237 /*                                                                        */
1238 /*  CALLED BY                                                             */
1239 /*                                                                        */
1240 /*    _nx_secure_tls_send_clienthello_extensions                          */
1241 /*                                          Send TLS ClientHello extension*/
1242 /*                                                                        */
1243 /*  RELEASE HISTORY                                                       */
1244 /*                                                                        */
1245 /*    DATE              NAME                      DESCRIPTION             */
1246 /*                                                                        */
1247 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
1248 /*  09-30-2020     Timothy Stapko           Modified comment(s),          */
1249 /*                                            resulting in version 6.1    */
1250 /*                                                                        */
1251 /**************************************************************************/
1252 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
_nx_secure_tls_send_clienthello_psk_kem_extension(NX_SECURE_TLS_SESSION * tls_session,UCHAR * packet_buffer,ULONG * packet_length,USHORT * extension_length)1253 static UINT _nx_secure_tls_send_clienthello_psk_kem_extension(NX_SECURE_TLS_SESSION *tls_session,
1254                                                               UCHAR *packet_buffer, ULONG *packet_length,
1255                                                               USHORT *extension_length)
1256 {
1257 ULONG offset;
1258 USHORT length;
1259 
1260     /* PSK Key Exchange Modes Extension structure (From TLS 1.3 RFC 8446):
1261           enum { psk_ke(0), psk_dhe_ke(1), (255) } PskKeyExchangeMode;
1262 
1263           struct {
1264               PskKeyExchangeMode ke_modes<1..255>;
1265           } PskKeyExchangeModes;
1266 
1267        psk_ke: PSK-only key establishment. In this mode, the server
1268           MUST NOT supply a "key_share" value.
1269 
1270        psk_dhe_ke: PSK with (EC)DHE key establishment. In this mode, the
1271           client and server MUST supply "key_share" values as described in
1272           Section 4.2.8.
1273 
1274       ClientHello extension layout:
1275       |     2      |         2          |                 1               | <PSK Key Exchange Modes list len> |
1276       |  Ext Type  |  Extension length  | PSK Key Exchange Modes list len |    PSK Key Exchange Modes list    |
1277     */
1278 
1279     NX_PARAMETER_NOT_USED(tls_session);
1280 
1281     offset = *packet_length;
1282 
1283     /* Add extension type.  */
1284     packet_buffer[offset] = (UCHAR)((NX_SECURE_TLS_EXTENSION_PSK_KEY_EXCHANGE_MODES) >> 8);
1285     packet_buffer[offset + 1] = (UCHAR)(NX_SECURE_TLS_EXTENSION_PSK_KEY_EXCHANGE_MODES);
1286     offset += 2;
1287 
1288     /* Add extension length.  */
1289     length = 3;
1290     packet_buffer[offset] = (UCHAR)(length >> 8);
1291     packet_buffer[offset + 1] = (UCHAR)(length);
1292     offset += 2;
1293 
1294     /* Add PSK Key Exchange Modes Length.  */
1295     packet_buffer[offset++] = 2;
1296 
1297     /* Add PSK Key Exchange Mode.  */
1298     /* psk_ke : 0, psk_dhe_ke : 1.  */
1299     packet_buffer[offset++] = 1;
1300     packet_buffer[offset++] = 0;
1301 
1302     /* Return the amount of data we wrote. */
1303     *extension_length = (USHORT)(offset - *packet_length);
1304 
1305     /* Return our updated packet offset. */
1306     *packet_length = offset;
1307 
1308     return(NX_SUCCESS);
1309 }
1310 #endif
1311 
1312 
1313 /**************************************************************************/
1314 /*                                                                        */
1315 /*  FUNCTION                                               RELEASE        */
1316 /*                                                                        */
1317 /*    _nx_secure_tls_send_clienthello_sni_extension       PORTABLE C      */
1318 /*                                                           6.1          */
1319 /*  AUTHOR                                                                */
1320 /*                                                                        */
1321 /*    Timothy Stapko, Microsoft Corporation                               */
1322 /*                                                                        */
1323 /*  DESCRIPTION                                                           */
1324 /*                                                                        */
1325 /*    This function adds the Server Name Indication extension to an       */
1326 /*    outgoing ClientHello record if a server name has been set by the    */
1327 /*    application.                                                        */
1328 /*                                                                        */
1329 /*  INPUT                                                                 */
1330 /*                                                                        */
1331 /*    tls_session                           TLS control block             */
1332 /*    packet_buffer                         Outgoing TLS packet buffer    */
1333 /*    packet_offset                         Offset into packet buffer     */
1334 /*    extension_length                      Return length of data         */
1335 /*    available_size                        Available size of buffer      */
1336 /*                                                                        */
1337 /*  OUTPUT                                                                */
1338 /*                                                                        */
1339 /*    status                                Completion status             */
1340 /*                                                                        */
1341 /*  CALLS                                                                 */
1342 /*                                                                        */
1343 /*    None                                                                */
1344 /*                                                                        */
1345 /*  CALLED BY                                                             */
1346 /*                                                                        */
1347 /*    _nx_secure_tls_send_clienthello_extensions                          */
1348 /*                                          Send TLS ClientHello extension*/
1349 /*                                                                        */
1350 /*  RELEASE HISTORY                                                       */
1351 /*                                                                        */
1352 /*    DATE              NAME                      DESCRIPTION             */
1353 /*                                                                        */
1354 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
1355 /*  09-30-2020     Timothy Stapko           Modified comment(s),          */
1356 /*                                            verified memcpy use cases,  */
1357 /*                                            resulting in version 6.1    */
1358 /*                                                                        */
1359 /**************************************************************************/
1360 #ifndef NX_SECURE_TLS_SNI_EXTENSION_DISABLED
_nx_secure_tls_send_clienthello_sni_extension(NX_SECURE_TLS_SESSION * tls_session,UCHAR * packet_buffer,ULONG * packet_offset,USHORT * extension_length,ULONG available_size)1361 static UINT _nx_secure_tls_send_clienthello_sni_extension(NX_SECURE_TLS_SESSION *tls_session,
1362                                                           UCHAR *packet_buffer, ULONG *packet_offset,
1363                                                           USHORT *extension_length, ULONG available_size)
1364 {
1365 ULONG  offset;
1366 USHORT ext;
1367 UINT   data_length;
1368 
1369     /* Server Name Indication Extension structure:
1370      * |     2      |      2        |      1     |     2       |   <name length>   |
1371      * |  Ext Type  |  list length  |  name type | name length |  Host name string |
1372      */
1373     /*  From RFC 6066:
1374 
1375           struct {
1376               NameType name_type;
1377               select (name_type) {
1378                   case host_name: HostName;
1379               } name;
1380           } ServerName;
1381 
1382           enum {
1383               host_name(0), (255)
1384           } NameType;
1385 
1386           opaque HostName<1..2^16-1>;
1387 
1388           struct {
1389               ServerName server_name_list<1..2^16-1>
1390           } ServerNameList;
1391 
1392           The contents of this extension are specified as follows.
1393 
1394       -   The ServerNameList MUST NOT contain more than one name of the same
1395           name_type.
1396 
1397       -   Currently, the only server names supported are DNS hostnames.
1398      */
1399 
1400     /* If there is no SNI server name, just return. */
1401     if (tls_session -> nx_secure_tls_sni_extension_server_name == NX_NULL)
1402     {
1403         *extension_length = 0;
1404         return(NX_SUCCESS);
1405     }
1406 
1407     /* Start with our passed-in packet offset. */
1408     offset = *packet_offset;
1409 
1410     if (available_size < (offset + 9u + tls_session -> nx_secure_tls_sni_extension_server_name -> nx_secure_x509_dns_name_length))
1411     {
1412 
1413         /* Packet buffer too small. */
1414         return(NX_SECURE_TLS_PACKET_BUFFER_TOO_SMALL);
1415     }
1416 
1417     /* The extension identifier. */
1418     ext = NX_SECURE_TLS_EXTENSION_SERVER_NAME_INDICATION;
1419 
1420     /* Put the extension ID into the packet. */
1421     packet_buffer[offset] = (UCHAR)((ext & 0xFF00) >> 8);
1422     packet_buffer[offset + 1] = (UCHAR)(ext & 0x00FF);
1423     offset += 2;
1424 
1425     /* Get the length of the entire extension. In this case it is a single name entry. Add 2 for the list length, plus 1 for
1426        the name_type field and 2 for the name length field (name type and length would be duplicated for all entries). */
1427     data_length = (UINT)(tls_session -> nx_secure_tls_sni_extension_server_name -> nx_secure_x509_dns_name_length + 5);
1428 
1429     /* Set the total extension length. */
1430     packet_buffer[offset] = (UCHAR)((data_length & 0xFF00) >> 8);
1431     packet_buffer[offset + 1] = (UCHAR)(data_length & 0x00FF);
1432     offset += 2;
1433     data_length -= 2; /* Remove list length. */
1434 
1435     /* Set the name list length. */
1436     packet_buffer[offset] = (UCHAR)((data_length & 0xFF00) >> 8);
1437     packet_buffer[offset + 1] = (UCHAR)(data_length & 0x00FF);
1438     offset += 2;
1439     data_length -= 3; /* Remove name type and name length. */
1440 
1441     /* Set the name type. */
1442     packet_buffer[offset] = NX_SECURE_TLS_SNI_NAME_TYPE_DNS;
1443     offset++;
1444 
1445     /* Set the name length. */
1446     packet_buffer[offset] = (UCHAR)((data_length & 0xFF00) >> 8);
1447     packet_buffer[offset + 1] = (UCHAR)(data_length & 0x00FF);
1448     offset += 2;
1449 
1450     /* Write the name into the packet. */
1451     NX_SECURE_MEMCPY(&packet_buffer[offset], tls_session -> nx_secure_tls_sni_extension_server_name -> nx_secure_x509_dns_name, data_length); /* Use case of memcpy is verified. lgtm[cpp/banned-api-usage-required-any] */
1452     offset += data_length;
1453 
1454     /* Return the amount of data we wrote. */
1455     *extension_length = (USHORT)(offset - *packet_offset);
1456 
1457     /* Return our updated packet offset. */
1458     *packet_offset = offset;
1459 
1460 
1461     return(NX_SUCCESS);
1462 }
1463 #endif
1464 
1465 /**************************************************************************/
1466 /*                                                                        */
1467 /*  FUNCTION                                               RELEASE        */
1468 /*                                                                        */
1469 /*    _nx_secure_tls_send_clienthello_sec_reneg_extension PORTABLE C      */
1470 /*                                                           6.1          */
1471 /*  AUTHOR                                                                */
1472 /*                                                                        */
1473 /*    Timothy Stapko, Microsoft Corporation                               */
1474 /*                                                                        */
1475 /*  DESCRIPTION                                                           */
1476 /*                                                                        */
1477 /*    This function adds the Secure Renegotiation Indication extension    */
1478 /*    to an outgoing ClientHello record if the ClientHello is part of a   */
1479 /*    renegotiation handshake (the extension should be empty for the      */
1480 /*    initial handshake. See RFC 5746 for more information.               */
1481 /*                                                                        */
1482 /*  INPUT                                                                 */
1483 /*                                                                        */
1484 /*    tls_session                           TLS control block             */
1485 /*    packet_buffer                         Outgoing TLS packet buffer    */
1486 /*    packet_offset                         Offset into packet buffer     */
1487 /*    extension_length                      Return length of data         */
1488 /*    available_size                        Available size of buffer      */
1489 /*                                                                        */
1490 /*  OUTPUT                                                                */
1491 /*                                                                        */
1492 /*    status                                Completion status             */
1493 /*                                                                        */
1494 /*  CALLS                                                                 */
1495 /*                                                                        */
1496 /*    None                                                                */
1497 /*                                                                        */
1498 /*  CALLED BY                                                             */
1499 /*                                                                        */
1500 /*    _nx_secure_tls_send_clienthello_extensions                          */
1501 /*                                          Send TLS ClientHello extension*/
1502 /*                                                                        */
1503 /*  RELEASE HISTORY                                                       */
1504 /*                                                                        */
1505 /*    DATE              NAME                      DESCRIPTION             */
1506 /*                                                                        */
1507 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
1508 /*  09-30-2020     Timothy Stapko           Modified comment(s),          */
1509 /*                                            verified memcpy use cases,  */
1510 /*                                            fixed renegotiation bug,    */
1511 /*                                            resulting in version 6.1    */
1512 /*                                                                        */
1513 /**************************************************************************/
1514 #ifndef NX_SECURE_TLS_DISABLE_SECURE_RENEGOTIATION
_nx_secure_tls_send_clienthello_sec_reneg_extension(NX_SECURE_TLS_SESSION * tls_session,UCHAR * packet_buffer,ULONG * packet_offset,USHORT * extension_length,ULONG available_size)1515 static UINT _nx_secure_tls_send_clienthello_sec_reneg_extension(NX_SECURE_TLS_SESSION *tls_session,
1516                                                                 UCHAR *packet_buffer,
1517                                                                 ULONG *packet_offset,
1518                                                                 USHORT *extension_length,
1519                                                                 ULONG available_size)
1520 {
1521 ULONG  offset;
1522 USHORT ext;
1523 UINT   data_length;
1524 
1525     /* Secure Renegotiation Indication Extensions structure:
1526      * |     2      |           12        |
1527      * |  Ext Type  |  client_verify_data |
1528      */
1529     /*  From RFC 5746:
1530         struct {
1531              opaque renegotiated_connection<0..255>;
1532          } RenegotiationInfo;
1533 
1534           The contents of this extension are specified as follows.
1535 
1536       -  If this is the initial handshake for a connection, then the
1537          "renegotiated_connection" field is of zero length in both the
1538          ClientHello and the ServerHello.  Thus, the entire encoding of the
1539          extension is ff 01 00 01 00.  The first two octets represent the
1540          extension type, the third and fourth octets the length of the
1541          extension itself, and the final octet the zero length byte for the
1542          "renegotiated_connection" field.
1543 
1544       -  For ClientHellos that are renegotiating, this field contains the
1545          "client_verify_data" specified in Section 3.1.
1546 
1547       -  For ServerHellos that are renegotiating, this field contains the
1548          concatenation of client_verify_data and server_verify_data.  For
1549          current versions of TLS, this will be a 24-byte value (for SSLv3,
1550          it will be a 72-byte value).
1551      */
1552 
1553 #ifdef NX_SECURE_TLS_USE_SCSV_CIPHPERSUITE
1554     /* If we are using the SCSV ciphersuite for TLS 1.0 compatibility
1555        and the session is not yet active (first handshake, not a renegotiation),
1556        then don't send the empty extension below, just return with no
1557        offset adjustments. */
1558     if (!tls_session -> nx_secure_tls_local_session_active)
1559     {
1560         *extension_length = 0;
1561         return(NX_SUCCESS);
1562     }
1563 #endif
1564 
1565 
1566     /* Start with our passed-in packet offset. */
1567     offset = *packet_offset;
1568 
1569     if (available_size < (offset + 2u))
1570     {
1571 
1572         /* Packet buffer too small. */
1573         return(NX_SECURE_TLS_PACKET_BUFFER_TOO_SMALL);
1574     }
1575 
1576     /* The extension identifier. */
1577     ext = NX_SECURE_TLS_EXTENSION_SECURE_RENEGOTIATION;
1578 
1579     /* Put the extension ID into the packet. */
1580     packet_buffer[offset] = (UCHAR)((ext & 0xFF00) >> 8);
1581     packet_buffer[offset + 1] = (UCHAR)(ext & 0x00FF);
1582     offset += 2;
1583 
1584     if (!tls_session -> nx_secure_tls_local_session_active)
1585     {
1586         /* The extension has zero data because this is an initial handshake. Send
1587            the encoded extension as documented in the RFC. */
1588 
1589         if (available_size < (offset + 3u))
1590         {
1591 
1592             /* Packet buffer too small. */
1593             return(NX_SECURE_TLS_PACKET_BUFFER_TOO_SMALL);
1594         }
1595 
1596         /* Fill in the length of current extension. */
1597         packet_buffer[offset] = 0x00;
1598         packet_buffer[offset + 1] = 0x01;
1599 
1600         /* Fill in the length of renegotiated connection field. */
1601         packet_buffer[offset + 2] = 0x00;
1602 
1603         offset += 3;
1604     }
1605     else
1606     {
1607         /* Fill in the length of current extension. */
1608         if (available_size < (offset + 3u + NX_SECURE_TLS_FINISHED_HASH_SIZE))
1609         {
1610 
1611             /* Packet buffer too small. */
1612             return(NX_SECURE_TLS_PACKET_BUFFER_TOO_SMALL);
1613         }
1614 
1615         data_length = NX_SECURE_TLS_FINISHED_HASH_SIZE + 1;
1616         packet_buffer[offset] = (UCHAR)((data_length & 0xFF00) >> 8);
1617         packet_buffer[offset + 1] = (UCHAR)(data_length & 0x00FF);
1618         offset += 2;
1619 
1620         /* The extension actually has a second length field of 1 byte that needs to be populated. */
1621         /* Fill in the length of renegotiated connection field. */
1622         packet_buffer[offset] = (UCHAR)(NX_SECURE_TLS_FINISHED_HASH_SIZE & 0x00FF);
1623         offset++;
1624 
1625         /* Copy the verify data into the packet. */
1626         NX_SECURE_MEMCPY(&packet_buffer[offset], tls_session -> nx_secure_tls_local_verify_data, NX_SECURE_TLS_FINISHED_HASH_SIZE); /* Use case of memcpy is verified. lgtm[cpp/banned-api-usage-required-any] */
1627         offset += NX_SECURE_TLS_FINISHED_HASH_SIZE;
1628     }
1629 
1630     /* Return the amount of data we wrote. */
1631     *extension_length = (USHORT)(offset - *packet_offset);
1632 
1633     /* Return our updated packet offset. */
1634     *packet_offset = offset;
1635 
1636 
1637     return(NX_SUCCESS);
1638 }
1639 #endif
1640 
1641 /**************************************************************************/
1642 /*                                                                        */
1643 /*  FUNCTION                                               RELEASE        */
1644 /*                                                                        */
1645 /*    _nx_secure_tls_send_clienthello_sec_spf_extensions  PORTABLE C      */
1646 /*                                                           6.1          */
1647 /*  AUTHOR                                                                */
1648 /*                                                                        */
1649 /*    Timothy Stapko, Microsoft Corporation                               */
1650 /*                                                                        */
1651 /*  DESCRIPTION                                                           */
1652 /*                                                                        */
1653 /*    This function adds the Supported Elliptic Curves extension and the  */
1654 /*    Supported Point Formats extension to an outgoing ClientHello        */
1655 /*    record. See RFC 4492 section 5.1.                                   */
1656 /*                                                                        */
1657 /*  INPUT                                                                 */
1658 /*                                                                        */
1659 /*    tls_session                           TLS control block             */
1660 /*    packet_buffer                         Outgoing TLS packet buffer    */
1661 /*    packet_offset                         Offset into packet buffer     */
1662 /*    extension_length                      Return length of data         */
1663 /*    available_size                        Available size of buffer      */
1664 /*                                                                        */
1665 /*  OUTPUT                                                                */
1666 /*                                                                        */
1667 /*    status                                Completion status             */
1668 /*                                                                        */
1669 /*  CALLS                                                                 */
1670 /*                                                                        */
1671 /*    None                                                                */
1672 /*                                                                        */
1673 /*  CALLED BY                                                             */
1674 /*                                                                        */
1675 /*    _nx_secure_tls_send_clienthello_extensions                          */
1676 /*                                          Send TLS ClientHello extension*/
1677 /*                                                                        */
1678 /*  RELEASE HISTORY                                                       */
1679 /*                                                                        */
1680 /*    DATE              NAME                      DESCRIPTION             */
1681 /*                                                                        */
1682 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
1683 /*  09-30-2020     Timothy Stapko           Modified comment(s),          */
1684 /*                                            resulting in version 6.1    */
1685 /*                                                                        */
1686 /**************************************************************************/
1687 #ifdef NX_SECURE_ENABLE_ECC_CIPHERSUITE
_nx_secure_tls_send_clienthello_sec_spf_extensions(NX_SECURE_TLS_SESSION * tls_session,UCHAR * packet_buffer,ULONG * packet_offset,USHORT * extension_length,ULONG available_size)1688 static UINT _nx_secure_tls_send_clienthello_sec_spf_extensions(NX_SECURE_TLS_SESSION *tls_session,
1689                                                                UCHAR *packet_buffer, ULONG *packet_offset,
1690                                                                USHORT *extension_length, ULONG available_size)
1691 {
1692 ULONG  offset;
1693 USHORT ext_len, list_len, ext, i;
1694 NX_SECURE_TLS_ECC *ecc_info;
1695 
1696     ecc_info = &(tls_session -> nx_secure_tls_ecc);
1697 
1698     if (ecc_info -> nx_secure_tls_ecc_supported_groups_count == 0)
1699     {
1700         *extension_length = 0;
1701         return(NX_SUCCESS);
1702     }
1703 
1704     /* Start with our passed-in packet offset. */
1705     offset = *packet_offset;
1706 
1707     if (available_size < (offset + 12u + (ULONG)(ecc_info -> nx_secure_tls_ecc_supported_groups_count << 1)))
1708     {
1709 
1710         /* Packet buffer too small. */
1711         return(NX_SECURE_TLS_PACKET_BUFFER_TOO_SMALL);
1712     }
1713 
1714     /* Supported Elliptic Curves Extension. */
1715     ext = NX_SECURE_TLS_EXTENSION_EC_GROUPS;  /* Supported Groups */
1716     list_len = (USHORT)(ecc_info -> nx_secure_tls_ecc_supported_groups_count * sizeof(USHORT));
1717     ext_len = (USHORT)(list_len + 2);
1718 
1719     packet_buffer[offset] = (UCHAR)((ext & 0xFF00) >> 8);
1720     packet_buffer[offset + 1] = (UCHAR)(ext & 0x00FF);
1721     offset += 2;
1722 
1723     packet_buffer[offset] = (UCHAR)((ext_len & 0xFF00) >> 8);
1724     packet_buffer[offset + 1] = (UCHAR)(ext_len & 0x00FF);
1725     offset += 2;
1726 
1727     packet_buffer[offset] = (UCHAR)((list_len & 0xFF00) >> 8);
1728     packet_buffer[offset + 1] = (UCHAR)(list_len & 0x00FF);
1729     offset += 2;
1730 
1731     for (i = 0; i < ecc_info -> nx_secure_tls_ecc_supported_groups_count; i++)
1732     {
1733         packet_buffer[offset] = (UCHAR)((ecc_info -> nx_secure_tls_ecc_supported_groups[i] & 0xFF00) >> 8);
1734         packet_buffer[offset + 1] = (UCHAR)(ecc_info -> nx_secure_tls_ecc_supported_groups[i] & 0x00FF);
1735         offset += 2;
1736     }
1737 
1738     /* ec_point_formats Extension.  */
1739     ext = NX_SECURE_TLS_EXTENSION_EC_POINT_FORMATS;
1740     ext_len = 2; /* ec_point_formats Length: 2.  */
1741 
1742     packet_buffer[offset] = (UCHAR)((ext & 0xFF00) >> 8);
1743     packet_buffer[offset + 1] = (UCHAR)(ext & 0x00FF);
1744     offset += 2;
1745 
1746     packet_buffer[offset] = (UCHAR)((ext_len & 0xFF00) >> 8);
1747     packet_buffer[offset + 1] = (UCHAR)(ext_len & 0x00FF);
1748     offset += 2;
1749 
1750     packet_buffer[offset] = 1;
1751     offset += 1;
1752 
1753     packet_buffer[offset] = 0;
1754     offset += 1;
1755 
1756     /* Return our updated packet offset. */
1757     *extension_length = (USHORT)(offset - *packet_offset);
1758     *packet_offset = offset;
1759 
1760     return(NX_SUCCESS);
1761 }
1762 #endif /* NX_SECURE_ENABLE_ECC_CIPHERSUITE */
1763 #endif /* NX_SECURE_TLS_CLIENT_DISABLED */
1764 
1765