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_DISABLE_SECURE_RENEGOTIATION
27 static UINT _nx_secure_tls_send_serverhello_sec_reneg_extension(NX_SECURE_TLS_SESSION *tls_session,
28                                                                 UCHAR *packet_buffer,
29                                                                 ULONG *packet_offset,
30                                                                 USHORT *extension_length,
31                                                                 ULONG available_size);
32 #endif
33 
34 #if (NX_SECURE_TLS_TLS_1_3_ENABLED) && !defined(NX_SECURE_TLS_SERVER_DISABLED)
35 static UINT _nx_secure_tls_send_serverhello_supported_versions_extension(NX_SECURE_TLS_SESSION *tls_session,
36                                                           UCHAR *packet_buffer, ULONG *packet_offset,
37                                                           USHORT *extension_length,
38                                                           ULONG available_size);
39 
40 static UINT _nx_secure_tls_send_serverhello_key_share_extension(NX_SECURE_TLS_SESSION *tls_session,
41                                                                 UCHAR *packet_buffer, ULONG *packet_offset,
42                                                                 USHORT *extension_length,
43                                                                 ULONG available_size);
44 
45 #ifdef NX_SECURE_ENABLE_PSK_CIPHERSUITES
46 static UINT _nx_secure_tls_send_serverhello_psk_extension(NX_SECURE_TLS_SESSION *tls_session,
47                                                    UCHAR *packet_buffer, ULONG *packet_length,
48                                                    USHORT *extension_length, ULONG available_size);
49 #endif
50 
51 #endif
52 
53 /**************************************************************************/
54 /*                                                                        */
55 /*  FUNCTION                                               RELEASE        */
56 /*                                                                        */
57 /*    _nx_secure_tls_send_serverhello_extensions          PORTABLE C      */
58 /*                                                           6.2.1        */
59 /*  AUTHOR                                                                */
60 /*                                                                        */
61 /*    Timothy Stapko, Microsoft Corporation                               */
62 /*                                                                        */
63 /*  DESCRIPTION                                                           */
64 /*                                                                        */
65 /*    This function generates a ServerHello extensions.                   */
66 /*                                                                        */
67 /*  INPUT                                                                 */
68 /*                                                                        */
69 /*    tls_session                           TLS control block             */
70 /*    packet_buffer                         Outgoing TLS packet buffer    */
71 /*    packet_offset                         Offset into packet buffer     */
72 /*    available_size                        Available size of buffer      */
73 /*                                                                        */
74 /*  OUTPUT                                                                */
75 /*                                                                        */
76 /*    status                                Completion status             */
77 /*                                                                        */
78 /*  CALLS                                                                 */
79 /*                                                                        */
80 /*    _nx_secure_tls_send_serverhello_sec_reneg_extension                 */
81 /*                                          Send ServerHello Renegotiation*/
82 /*                                            extension                   */
83 /*    _nx_secure_tls_send_serverhello_ec_extension                        */
84 /*                                          Send ClientHello EC extension */
85 /*                                                                        */
86 /*  CALLED BY                                                             */
87 /*                                                                        */
88 /*    _nx_secure_tls_send_serverhello       Send TLS ServerHello          */
89 /*                                                                        */
90 /*  RELEASE HISTORY                                                       */
91 /*                                                                        */
92 /*    DATE              NAME                      DESCRIPTION             */
93 /*                                                                        */
94 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
95 /*  09-30-2020     Timothy Stapko           Modified comment(s),          */
96 /*                                            fixed renegotiation bug,    */
97 /*                                            resulting in version 6.1    */
98 /*  04-25-2022     Yuxin Zhou               Modified comment(s),          */
99 /*                                            removed unused code,        */
100 /*                                            resulting in version 6.1.11 */
101 /*  03-08-2023     Tiejun Zhou              Modified comment(s),          */
102 /*                                            fixed compiler warnings,    */
103 /*                                            resulting in version 6.2.1  */
104 /*                                                                        */
105 /**************************************************************************/
_nx_secure_tls_send_serverhello_extensions(NX_SECURE_TLS_SESSION * tls_session,UCHAR * packet_buffer,ULONG * packet_offset,ULONG available_size)106 UINT _nx_secure_tls_send_serverhello_extensions(NX_SECURE_TLS_SESSION *tls_session,
107                                                 UCHAR *packet_buffer, ULONG *packet_offset,
108                                                 ULONG available_size)
109 {
110 ULONG  length = *packet_offset;
111 UCHAR *extension_offset;
112 #if !defined(NX_SECURE_TLS_DISABLE_SECURE_RENEGOTIATION) || ((NX_SECURE_TLS_TLS_1_3_ENABLED) && !defined(NX_SECURE_TLS_SERVER_DISABLED))
113 USHORT extension_length = 0;
114 #endif /* !defined(NX_SECURE_TLS_DISABLE_SECURE_RENEGOTIATION) || (NX_SECURE_TLS_TLS_1_3_ENABLED)  */
115 USHORT total_extensions_length;
116 UINT   status = NX_SUCCESS;
117 
118 #if defined(NX_SECURE_TLS_DISABLE_SECURE_RENEGOTIATION) || (!NX_SECURE_TLS_TLS_1_3_ENABLED)
119     NX_PARAMETER_NOT_USED(tls_session);
120 #endif /* defined(NX_SECURE_TLS_DISABLE_SECURE_RENEGOTIATION) || (!NX_SECURE_TLS_TLS_1_3_ENABLED) */
121 
122     if (available_size < (*packet_offset + 2u))
123     {
124 
125         /* Packet buffer too small. */
126         return(NX_SECURE_TLS_PACKET_BUFFER_TOO_SMALL);
127     }
128 
129     /* Save an offset to the beginning of the extensions so we can fill in the length
130        once all the extensions are added. */
131     extension_offset = &packet_buffer[length];
132 
133     /* The extensions length field is two bytes. */
134     length += 2;
135     total_extensions_length = 0;
136 
137 #ifndef NX_SECURE_TLS_DISABLE_SECURE_RENEGOTIATION
138 #if (NX_SECURE_TLS_TLS_1_3_ENABLED) && !defined(NX_SECURE_TLS_SERVER_DISABLED)
139     /* Renegotiation is deprecated in TLS 1.3 so don't send extension. */
140     if(!tls_session->nx_secure_tls_1_3)
141 #endif
142     {
143         /* We have to add renegotiation extensions in both initial sessions and renegotiating sessions. */
144         status = _nx_secure_tls_send_serverhello_sec_reneg_extension(tls_session, packet_buffer, &length,
145                                                             &extension_length, available_size);
146         total_extensions_length = (USHORT)(total_extensions_length + extension_length);
147 
148         if(status != NX_SUCCESS)
149         {
150             return(status);
151         }
152     }
153 #endif /* NX_SECURE_TLS_DISABLE_SECURE_RENEGOTIATION */
154 
155 
156 #if (NX_SECURE_TLS_TLS_1_3_ENABLED) && !defined(NX_SECURE_TLS_SERVER_DISABLED)
157     if(tls_session->nx_secure_tls_1_3)
158     {
159 
160         /* MUST send the supported versions extension in all TLS 1.3 ServerHellos. */
161         status = _nx_secure_tls_send_serverhello_supported_versions_extension(tls_session, packet_buffer, &length,
162                                                                               &extension_length, available_size);
163         total_extensions_length = (USHORT)(total_extensions_length + extension_length);
164 
165         if(status != NX_SUCCESS)
166         {
167             return(status);
168         }
169 
170         /* MUST send the key share extension in all TLS 1.3 ServerHellos. */
171         status = _nx_secure_tls_send_serverhello_key_share_extension(tls_session, packet_buffer, &length,
172                                                                      &extension_length, available_size);
173 
174         total_extensions_length = (USHORT)(total_extensions_length + extension_length);
175         if(status != NX_SUCCESS)
176         {
177             return(status);
178         }
179 
180 #ifdef NX_SECURE_ENABLE_PSK_CIPHERSUITES
181         if ((tls_session -> nx_secure_tls_server_state != NX_SECURE_TLS_SERVER_STATE_SEND_HELLO_RETRY) &&
182             (tls_session->nx_secure_tls_credentials.nx_secure_tls_client_psk.nx_secure_tls_psk_data_size))
183         {
184 
185             /* Send the PSK extension for PSK key exchange modes. */
186             status = _nx_secure_tls_send_serverhello_psk_extension(tls_session, packet_buffer, &length,
187                                                                    &extension_length, available_size);
188 
189             total_extensions_length = (USHORT)(total_extensions_length + extension_length);
190             if (status != NX_SUCCESS)
191             {
192                 return(status);
193             }
194         }
195 #endif
196     }
197 #endif
198 
199 
200 
201     /* Make sure we actually wrote some extension data. If none, back up the packet pointer and length. */
202     if (total_extensions_length == 0)
203     {
204         /* No extensions written, back up our pointer and length. */
205         length -= 2;
206     }
207     else
208     {
209         /* Put the extensions length into the packet at our original offset and add
210            the total to our packet length. */
211         extension_offset[0] = (UCHAR)((total_extensions_length & 0xFF00) >> 8);
212         extension_offset[1] = (UCHAR)(total_extensions_length & 0x00FF);
213     }
214 
215     *packet_offset = length;
216 
217     return(status);
218 }
219 
220 
221 /**************************************************************************/
222 /*                                                                        */
223 /*  FUNCTION                                               RELEASE        */
224 /*                                                                        */
225 /*    _nx_secure_tls_send_serverhello_sec_reneg_extension PORTABLE C      */
226 /*                                                           6.1          */
227 /*  AUTHOR                                                                */
228 /*                                                                        */
229 /*    Timothy Stapko, Microsoft Corporation                               */
230 /*                                                                        */
231 /*  DESCRIPTION                                                           */
232 /*                                                                        */
233 /*    This function adds the Secure Renegotiation Indication extension    */
234 /*    to an outgoing ServerHello record if the ServerHello is part of a   */
235 /*    renegotiation handshake. See RFC 5746 for more information.         */
236 /*                                                                        */
237 /*  INPUT                                                                 */
238 /*                                                                        */
239 /*    tls_session                           TLS control block             */
240 /*    packet_buffer                         Outgoing TLS packet buffer    */
241 /*    packet_offset                         Offset into packet buffer     */
242 /*    extension_length                      Return length of data         */
243 /*    available_size                        Available size of buffer      */
244 /*                                                                        */
245 /*  OUTPUT                                                                */
246 /*                                                                        */
247 /*    status                                Completion status             */
248 /*                                                                        */
249 /*  CALLS                                                                 */
250 /*                                                                        */
251 /*    None                                                                */
252 /*                                                                        */
253 /*  CALLED BY                                                             */
254 /*                                                                        */
255 /*    _nx_secure_tls_send_serverhello_extensions                          */
256 /*                                          Send TLS ServerHello extension*/
257 /*                                                                        */
258 /*  RELEASE HISTORY                                                       */
259 /*                                                                        */
260 /*    DATE              NAME                      DESCRIPTION             */
261 /*                                                                        */
262 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
263 /*  09-30-2020     Timothy Stapko           Modified comment(s), improved */
264 /*                                            buffer length verification, */
265 /*                                            verified memcpy use cases,  */
266 /*                                            fixed renegotiation bug,    */
267 /*                                            resulting in version 6.1    */
268 /*                                                                        */
269 /**************************************************************************/
270 #ifndef NX_SECURE_TLS_DISABLE_SECURE_RENEGOTIATION
_nx_secure_tls_send_serverhello_sec_reneg_extension(NX_SECURE_TLS_SESSION * tls_session,UCHAR * packet_buffer,ULONG * packet_offset,USHORT * extension_length,ULONG available_size)271 static UINT _nx_secure_tls_send_serverhello_sec_reneg_extension(NX_SECURE_TLS_SESSION *tls_session,
272                                                                 UCHAR *packet_buffer,
273                                                                 ULONG *packet_offset,
274                                                                 USHORT *extension_length,
275                                                                 ULONG available_size)
276 {
277 ULONG  offset;
278 USHORT ext;
279 UINT   data_length;
280 
281     /* Secure Renegotiation Indication Extensions structure (for serverhello):
282      * |     2      |           12        |         12           |
283      * |  Ext Type  |  client_verify_data |  server_verify_data  |
284      */
285     /*  From RFC 5746:
286         struct {
287              opaque renegotiated_connection<0..255>;
288          } RenegotiationInfo;
289 
290           The contents of this extension are specified as follows.
291 
292       -  If this is the initial handshake for a connection, then the
293          "renegotiated_connection" field is of zero length in both the
294          ClientHello and the ServerHello.  Thus, the entire encoding of the
295          extension is ff 01 00 01 00.  The first two octets represent the
296          extension type, the third and fourth octets the length of the
297          extension itself, and the final octet the zero length byte for the
298          "renegotiated_connection" field.
299 
300       -  For ClientHellos that are renegotiating, this field contains the
301          "client_verify_data" specified in Section 3.1.
302 
303       -  For ServerHellos that are renegotiating, this field contains the
304          concatenation of client_verify_data and server_verify_data.  For
305          current versions of TLS, this will be a 24-byte value (for SSLv3,
306          it will be a 72-byte value).
307      */
308 
309     /* Start with our passed-in packet offset. */
310     offset = *packet_offset;
311 
312     if (available_size < (offset + 2u))
313     {
314 
315         /* Packet buffer too small. */
316         return(NX_SECURE_TLS_PACKET_BUFFER_TOO_SMALL);
317     }
318 
319     /* The extension identifier. */
320     ext = NX_SECURE_TLS_EXTENSION_SECURE_RENEGOTIATION;
321 
322     /* Put the extension ID into the packet. */
323     packet_buffer[offset] = (UCHAR)((ext & 0xFF00) >> 8);
324     packet_buffer[offset + 1] = (UCHAR)(ext & 0x00FF);
325     offset += 2;
326 
327     /* See if this is the initial handshake or not. */
328     if (!tls_session -> nx_secure_tls_local_session_active)
329     {
330         /* The extension has zero data because this is an initial handshake. Send
331            the encoded extension as documented in the RFC. */
332 
333         if (available_size < (offset + 3u))
334         {
335 
336             /* Packet buffer too small. */
337             return(NX_SECURE_TLS_PACKET_BUFFER_TOO_SMALL);
338         }
339 
340         /* Fill in the length of current extension. */
341         packet_buffer[offset] = 0x00;
342         packet_buffer[offset + 1] = 0x01;
343 
344         /* Fill in the length of renegotiated connection field. */
345         packet_buffer[offset + 2] = 0x00;
346 
347         offset += 3;
348     }
349     else
350     {
351         /* Fill in the length of current extension. */
352         if (available_size < (offset + 3u + 2 * NX_SECURE_TLS_FINISHED_HASH_SIZE))
353         {
354 
355             /* Packet buffer too small. */
356             return(NX_SECURE_TLS_PACKET_BUFFER_TOO_SMALL);
357         }
358 
359         data_length = (NX_SECURE_TLS_FINISHED_HASH_SIZE * 2) + 1;
360         packet_buffer[offset] = (UCHAR)((data_length & 0xFF00) >> 8);
361         packet_buffer[offset + 1] = (UCHAR)(data_length & 0x00FF);
362         offset += 2;
363 
364         /* The extension actually has a second length field of 1 byte that needs to be populated. */
365         /* Fill in the length of renegotiated connection field. */
366         packet_buffer[offset] = (UCHAR)((NX_SECURE_TLS_FINISHED_HASH_SIZE * 2) & 0x00FF);
367         offset++;
368 
369         /* Copy the verify data into the packet. */
370         NX_SECURE_MEMCPY(&packet_buffer[offset], tls_session -> nx_secure_tls_remote_verify_data, NX_SECURE_TLS_FINISHED_HASH_SIZE); /* Use case of memcpy is verified. lgtm[cpp/banned-api-usage-required-any] */
371         offset += NX_SECURE_TLS_FINISHED_HASH_SIZE;
372         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] */
373         offset += NX_SECURE_TLS_FINISHED_HASH_SIZE;
374     }
375 
376     /* Return the amount of data we wrote. */
377     *extension_length = (USHORT)(offset - *packet_offset);
378 
379     /* Return our updated packet offset. */
380     *packet_offset = offset;
381 
382 
383     return(NX_SUCCESS);
384 }
385 #endif
386 
387 
388 /**************************************************************************/
389 /*                                                                        */
390 /*  FUNCTION                                               RELEASE        */
391 /*                                                                        */
392 /*    _nx_secure_tls_send_clienthello_supported_versions_extension        */
393 /*                                                        PORTABLE C      */
394 /*                                                           6.1          */
395 /*  AUTHOR                                                                */
396 /*                                                                        */
397 /*    Timothy Stapko, Microsoft Corporation                               */
398 /*                                                                        */
399 /*  DESCRIPTION                                                           */
400 /*                                                                        */
401 /*    This function adds the Supported Versions extension, added in TLS   */
402 /*    v1.3.                                                               */
403 /*                                                                        */
404 /*  INPUT                                                                 */
405 /*                                                                        */
406 /*    tls_session                           TLS control block             */
407 /*    packet_buffer                         Outgoing TLS packet buffer    */
408 /*    packet_offset                         Offset into packet buffer     */
409 /*    extension_length                      Return length of data         */
410 /*    available_size                        Available size of buffer      */
411 /*                                                                        */
412 /*  OUTPUT                                                                */
413 /*                                                                        */
414 /*    status                                Completion status             */
415 /*                                                                        */
416 /*  CALLS                                                                 */
417 /*                                                                        */
418 /*    None                                                                */
419 /*                                                                        */
420 /*  CALLED BY                                                             */
421 /*                                                                        */
422 /*    _nx_secure_tls_send_clienthello_extensions                          */
423 /*                                          Send TLS ClientHello extension*/
424 /*                                                                        */
425 /*  RELEASE HISTORY                                                       */
426 /*                                                                        */
427 /*    DATE              NAME                      DESCRIPTION             */
428 /*                                                                        */
429 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
430 /*  09-30-2020     Timothy Stapko           Modified comment(s),          */
431 /*                                            resulting in version 6.1    */
432 /*                                                                        */
433 /**************************************************************************/
434 #if (NX_SECURE_TLS_TLS_1_3_ENABLED) && !defined(NX_SECURE_TLS_SERVER_DISABLED)
_nx_secure_tls_send_serverhello_supported_versions_extension(NX_SECURE_TLS_SESSION * tls_session,UCHAR * packet_buffer,ULONG * packet_offset,USHORT * extension_length,ULONG available_size)435 static UINT _nx_secure_tls_send_serverhello_supported_versions_extension(NX_SECURE_TLS_SESSION *tls_session,
436                                                           UCHAR *packet_buffer, ULONG *packet_offset,
437                                                           USHORT *extension_length, ULONG available_size)
438 {
439 ULONG  offset;
440 USHORT ext;
441 UINT   data_length;
442 
443 
444     /* Supported Versions Extension structure:
445      * |     2      |         2          |           2           |
446      * |  Ext Type  |  Extension length  | Selected TLS Versions |
447      */
448     NX_PARAMETER_NOT_USED(tls_session);
449 
450     /* Start with our passed-in packet offset. */
451     offset = *packet_offset;
452 
453     if (available_size < (offset + 6u))
454     {
455 
456         /* Packet buffer too small. */
457         return(NX_SECURE_TLS_PACKET_BUFFER_TOO_SMALL);
458     }
459 
460     /* The extension identifier. */
461     ext = NX_SECURE_TLS_EXTENSION_SUPPORTED_VERSIONS;
462 
463     /* Put the extension ID into the packet. */
464     packet_buffer[offset] = (UCHAR)((ext & 0xFF00) >> 8);
465     packet_buffer[offset + 1] = (UCHAR)(ext & 0x00FF);
466     offset += 2;
467 
468     data_length = (UINT)(2);
469 
470     /* Set the total extension length. */
471     packet_buffer[offset] = (UCHAR)((data_length & 0xFF00) >> 8);
472     packet_buffer[offset + 1] = (UCHAR)(data_length & 0x00FF);
473     offset += 2;
474 
475 
476     /* Set the version value. */
477     packet_buffer[offset] = 0x03;  //(UCHAR)((NX_SECURE_TLS_VERSION_TLS_1_3 & 0xFF00) >> 8);
478     packet_buffer[offset + 1] = 0x04; //(UCHAR)(NX_SECURE_TLS_VERSION_TLS_1_3 & 0x00FF);
479     offset += 2;
480 
481     /* Return the amount of data we wrote. */
482     *extension_length = (USHORT)(offset - *packet_offset);
483 
484     /* Return our updated packet offset. */
485     *packet_offset = offset;
486 
487 
488     return(NX_SUCCESS);
489 }
490 #endif
491 
492 /**************************************************************************/
493 /*                                                                        */
494 /*  FUNCTION                                               RELEASE        */
495 /*                                                                        */
496 /*    _nx_secure_tls_send_serverhello_key_share_extension PORTABLE C      */
497 /*                                                           6.1.9        */
498 /*  AUTHOR                                                                */
499 /*                                                                        */
500 /*    Timothy Stapko, Microsoft Corporation                               */
501 /*                                                                        */
502 /*  DESCRIPTION                                                           */
503 /*                                                                        */
504 /*    This function adds the Key Share extension, added in TLS            */
505 /*    v1.3.                                                               */
506 /*                                                                        */
507 /*  INPUT                                                                 */
508 /*                                                                        */
509 /*    tls_session                           TLS control block             */
510 /*    packet_buffer                         Outgoing TLS packet buffer    */
511 /*    packet_offset                         Offset into packet buffer     */
512 /*    extension_length                      Return length of data         */
513 /*    available_size                        Available size of buffer      */
514 /*                                                                        */
515 /*  OUTPUT                                                                */
516 /*                                                                        */
517 /*    status                                Completion status             */
518 /*                                                                        */
519 /*  CALLS                                                                 */
520 /*                                                                        */
521 /*    None                                                                */
522 /*                                                                        */
523 /*  CALLED BY                                                             */
524 /*                                                                        */
525 /*    _nx_secure_tls_send_clienthello_extensions                          */
526 /*                                          Send TLS ClientHello extension*/
527 /*                                                                        */
528 /*  RELEASE HISTORY                                                       */
529 /*                                                                        */
530 /*    DATE              NAME                      DESCRIPTION             */
531 /*                                                                        */
532 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
533 /*  09-30-2020     Timothy Stapko           Modified comment(s),          */
534 /*                                            verified memcpy use cases,  */
535 /*                                            resulting in version 6.1    */
536 /*  10-15-2021     Timothy Stapko           Modified comment(s), fixed    */
537 /*                                            compilation issue with      */
538 /*                                            TLS 1.3 and disabling TLS   */
539 /*                                            server,                     */
540 /*                                            resulting in version 6.1.9  */
541 /*                                                                        */
542 /**************************************************************************/
543 #if (NX_SECURE_TLS_TLS_1_3_ENABLED) && !defined(NX_SECURE_TLS_SERVER_DISABLED)
_nx_secure_tls_send_serverhello_key_share_extension(NX_SECURE_TLS_SESSION * tls_session,UCHAR * packet_buffer,ULONG * packet_offset,USHORT * extension_length,ULONG available_size)544 static UINT _nx_secure_tls_send_serverhello_key_share_extension(NX_SECURE_TLS_SESSION *tls_session,
545                                                                 UCHAR *packet_buffer, ULONG *packet_offset,
546                                                                 USHORT *extension_length,
547                                                                 ULONG available_size)
548 {
549 #ifndef NX_SECURE_TLS_SERVER_DISABLED
550 ULONG  offset;
551 ULONG  length_offset;
552 USHORT ext;
553 UINT   i;
554 UINT   entry_length;
555 UINT   key_length;
556 UINT   data_length;
557 NX_SECURE_TLS_ECDHE_HANDSHAKE_DATA   *ecdhe_data;
558 USHORT named_curve;
559 
560     /* Key Share Extension structure (From TLS 1.3 RFC 8446):
561      *  struct {
562      *     NamedGroup group;
563      *     opaque key_exchange<1..2^16-1>;
564      *  } KeyShareEntry;
565      *
566      *  In a ServerHello message, the "extension_data" field of this
567      *  extension contains a KeyShareServerHello value:
568      *
569      *     struct {
570      *         KeyShareEntry server_share;
571      *     } KeyShareServerHello;
572      *
573      *  server_share:  A single KeyShareEntry value that is in the same group
574      *     as one of the client's shares.
575      *
576      *  If using (EC)DHE key establishment, servers offer exactly one
577      *  KeyShareEntry in the ServerHello.  This value MUST be in the same
578      *  group as the KeyShareEntry value offered by the client that the
579      *  server has selected for the negotiated key exchange.  Servers
580      *  MUST NOT send a KeyShareEntry for any group not indicated in the
581      *  client's "supported_groups" extension and MUST NOT send a
582      *  KeyShareEntry when using the "psk_ke" PskKeyExchangeMode.  If using
583      *  (EC)DHE key establishment and a HelloRetryRequest containing a
584      *  "key_share" extension was received by the client, the client MUST
585      *  verify that the selected NamedGroup in the ServerHello is the same as
586      *  that in the HelloRetryRequest.  If this check fails, the client MUST
587      *  abort the handshake with an "illegal_parameter" alert.
588      *
589      *  Diffie-Hellman [DH] parameters for both clients and servers are
590      *  encoded in the opaque key_exchange field of a KeyShareEntry in a
591      *  KeyShare structure.  The opaque value contains the Diffie-Hellman
592      *  public value (Y = g^X mod p) for the specified group (see [RFC7919]
593      *  for group definitions) encoded as a big-endian integer and padded to
594      *  the left with zeros to the size of p in bytes.
595      *
596      *  ECDHE structure for key_exchange (For secp256r1, secp384r1 and secp521r1)
597      *  struct {
598      *     uint8 legacy_form = 4;
599      *     opaque X[coordinate_length];
600      *     opaque Y[coordinate_length];
601      *  } UncompressedPointRepresentation;
602      *
603      *   X and Y respectively are the binary representations of the x and y
604      *   values in network byte order.  There are no internal length markers,
605      *   so each number representation occupies as many octets as implied by
606      *   the curve parameters.  For P-256 this means that each of X and Y use
607      *   32 octets, padded on the left by zeros if necessary.  For P-384 they
608      *   take 48 octets each, and for P-521 they take 66 octets each.
609      *
610      *  The X,Y point is the public key (Q) which is generated using the following:
611      *  -  The public key to put into the KeyShareEntry.key_exchange
612      *     structure is the result of applying the ECDH scalar multiplication
613      *     function to the secret key of appropriate length (into scalar
614      *     input) and the standard public basepoint (into u-coordinate point
615      *     input).
616      *
617      *  -  The ECDH shared secret is the result of applying the ECDH scalar
618      *     multiplication function to the secret key (into scalar input) and
619      *     the peer's public key (into u-coordinate point input).  The output
620      *     is used raw, with no processing.
621      *
622      *  NamedGroup examples: secp256r1(0x0017), secp384r1(0x0018), secp521r1(0x0019)
623      * |     2      |         2          |       2      |    2    |    <key_len>      |
624      * |  Ext Type  |  Extension length  |  Named Group | key_len | key_exchange data |
625      */
626 
627     /* Start with our passed-in packet offset. */
628     offset = *packet_offset;
629 
630     if (available_size < (offset + 2u))
631     {
632 
633         /* Packet buffer too small. */
634         return(NX_SECURE_TLS_PACKET_BUFFER_TOO_SMALL);
635     }
636 
637     /* The extension identifier. */
638     ext = NX_SECURE_TLS_EXTENSION_KEY_SHARE;
639 
640     if (tls_session == NX_NULL)
641     {
642         return(NX_PTR_ERROR);
643     }
644 
645     /* Put the extension ID into the packet. */
646     packet_buffer[offset] = (UCHAR)((ext & 0xFF00) >> 8);
647     packet_buffer[offset + 1] = (UCHAR)(ext & 0x00FF);
648     offset += 2;
649 
650     i = tls_session -> nx_secure_tls_key_material.nx_secure_tls_ecc_key_data_selected;
651     ecdhe_data = &(tls_session -> nx_secure_tls_key_material.nx_secure_tls_ecc_key_data[i]);
652     named_curve = (USHORT)(ecdhe_data -> nx_secure_tls_ecdhe_named_curve);
653     if (tls_session -> nx_secure_tls_server_state == NX_SECURE_TLS_SERVER_STATE_SEND_HELLO_RETRY)
654     {
655 
656         if (available_size < (offset + 4u))
657         {
658 
659             /* Packet buffer too small. */
660             return(NX_SECURE_TLS_PACKET_BUFFER_TOO_SMALL);
661         }
662 
663         /* Put the fixed length into the packet. */
664         packet_buffer[offset] = 0;
665         packet_buffer[offset + 1] = 2;
666         offset += 2;
667 
668         /* Put the selected group into the packet. */
669         packet_buffer[offset] = (UCHAR)((named_curve & 0xFF00) >> 8);;
670         packet_buffer[offset + 1] = (UCHAR)(named_curve & 0x00FF);
671         offset += 2;
672 
673         /* Return the amount of data we wrote. */
674         *extension_length = (USHORT)(offset - *packet_offset);
675 
676         /* Return our updated packet offset. */
677         *packet_offset = offset;
678 
679         return(NX_SUCCESS);
680     }
681 
682     /* Add Total Length (2 bytes) to packet after we fill in the key data. */
683     length_offset = offset;
684     data_length = 0;
685     offset += 2;
686 
687     /* Key length will differ for each curve. For p256, 32 octets per coordinate, plus the "legacy_form" byte. */
688     key_length = ecdhe_data->nx_secure_tls_ecdhe_public_key_length;
689 
690     /* Entry is named group(2) + key len(2) + key data(key len). */
691     entry_length = 2 + 2 + key_length;
692 
693     if (available_size < (offset + 4u + key_length))
694     {
695 
696         /* Packet buffer too small. */
697         return(NX_SECURE_TLS_PACKET_BUFFER_TOO_SMALL);
698     }
699 
700     /* Set the named group. */
701     packet_buffer[offset] = (UCHAR)((named_curve & 0xFF00) >> 8);;
702     packet_buffer[offset + 1] = (UCHAR)(named_curve & 0x00FF);
703     offset += 2;
704 
705     /* Set the key length. */
706     packet_buffer[offset] = (UCHAR)((key_length & 0xFF00) >> 8);;
707     packet_buffer[offset + 1] = (UCHAR)(key_length & 0x00FF);
708     offset += 2;
709 
710     /* Set the key data from our already-generated ECC keys. */
711     NX_SECURE_MEMCPY(&packet_buffer[offset], &ecdhe_data->nx_secure_tls_ecdhe_public_key[0], key_length); /* Use case of memcpy is verified. */
712     offset += (key_length);
713 
714     /* Get the length of the entire extension. */
715     data_length = data_length + (UINT)(entry_length);
716 
717     /* Go back and set the total extension length. */
718     packet_buffer[length_offset] = (UCHAR)((data_length & 0xFF00) >> 8);
719     packet_buffer[length_offset + 1] = (UCHAR)(data_length & 0x00FF);
720 
721     /* Return the amount of data we wrote. */
722     *extension_length = (USHORT)(offset - *packet_offset);
723 
724     /* Return our updated packet offset. */
725     *packet_offset = offset;
726 
727 
728     return(NX_SUCCESS);
729 #else
730     /* Server is disabled, we shouldn't be processing a ClientHello - error! */
731     return(NX_SECURE_TLS_INVALID_STATE);
732 #endif
733 }
734 #endif
735 
736 /**************************************************************************/
737 /*                                                                        */
738 /*  FUNCTION                                               RELEASE        */
739 /*                                                                        */
740 /*    _nx_secure_tls_send_serverhello_psk_extension       PORTABLE C      */
741 /*                                                           6.1          */
742 /*  AUTHOR                                                                */
743 /*                                                                        */
744 /*    Timothy Stapko, Microsoft Corporation                               */
745 /*                                                                        */
746 /*  DESCRIPTION                                                           */
747 /*                                                                        */
748 /*    This function adds the pre_shared_key extension, added in TLS       */
749 /*    v1.3.                                                               */
750 /*                                                                        */
751 /*  INPUT                                                                 */
752 /*                                                                        */
753 /*    tls_session                           TLS control block             */
754 /*    packet_buffer                         Outgoing TLS packet buffer    */
755 /*    packet_length                         Length of data in packet      */
756 /*    extension_length                      Return length of data         */
757 /*    available_size                        Available size of buffer      */
758 /*                                                                        */
759 /*  OUTPUT                                                                */
760 /*                                                                        */
761 /*    status                                Completion status             */
762 /*                                                                        */
763 /*  CALLS                                                                 */
764 /*                                                                        */
765 /*    None                                                                */
766 /*                                                                        */
767 /*  CALLED BY                                                             */
768 /*                                                                        */
769 /*    _nx_secure_tls_send_serverhello_extensions                          */
770 /*                                          Send TLS ServerHello extension*/
771 /*                                                                        */
772 /*  RELEASE HISTORY                                                       */
773 /*                                                                        */
774 /*    DATE              NAME                      DESCRIPTION             */
775 /*                                                                        */
776 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
777 /*  09-30-2020     Timothy Stapko           Modified comment(s),          */
778 /*                                            resulting in version 6.1    */
779 /*                                                                        */
780 /**************************************************************************/
781 
782 #if (NX_SECURE_TLS_TLS_1_3_ENABLED) && defined (NX_SECURE_ENABLE_PSK_CIPHERSUITES) && !defined(NX_SECURE_TLS_SERVER_DISABLED)
_nx_secure_tls_send_serverhello_psk_extension(NX_SECURE_TLS_SESSION * tls_session,UCHAR * packet_buffer,ULONG * packet_length,USHORT * extension_length,ULONG available_size)783 static UINT _nx_secure_tls_send_serverhello_psk_extension(NX_SECURE_TLS_SESSION *tls_session,
784                                                    UCHAR *packet_buffer, ULONG *packet_length,
785                                                    USHORT *extension_length, ULONG available_size)
786 {
787 ULONG  offset;
788 USHORT ext;
789 
790     /* Key Share Extension structure (From TLS 1.3 RFC 8446):
791           struct {
792               opaque identity<1..2^16-1>;
793               uint32 obfuscated_ticket_age;
794           } PskIdentity;
795 
796           opaque PskBinderEntry<32..255>;
797 
798           struct {
799               PskIdentity identities<7..2^16-1>;
800               PskBinderEntry binders<33..2^16-1>;
801           } OfferedPsks;
802 
803           struct {
804               select (Handshake.msg_type) {
805                   case client_hello: OfferedPsks;
806                   case server_hello: uint16 selected_identity;
807               };
808           } PreSharedKeyExtension;
809 
810        identity:  A label for a key.  For instance, a ticket (as defined in
811           Appendix B.3.4) or a label for a pre-shared key established
812           externally.
813 
814        obfuscated_ticket_age:  An obfuscated version of the age of the key.
815           Section 4.2.11.1 describes how to form this value for identities
816           established via the NewSessionTicket message.  For identities
817           established externally, an obfuscated_ticket_age of 0 SHOULD be
818           used, and servers MUST ignore the value.
819 
820        identities:  A list of the identities that the client is willing to
821           negotiate with the server.  If sent alongside the "early_data"
822           extension (see Section 4.2.10), the first identity is the one used
823           for 0-RTT data.
824 
825        binders:  A series of HMAC values, one for each value in the
826           identities list and in the same order, computed as described
827           below.
828 
829        selected_identity:  The server's chosen identity expressed as a
830           (0-based) index into the identities in the client's list.
831 
832 
833       ServerHello extension layout:
834       |     2      |         2          |       2      |
835       |  Ext Type  |  Extension length  |  Selected ID |
836     */
837     NX_PARAMETER_NOT_USED(tls_session);
838 
839     /* Start with our passed-in packet offset. */
840     offset = *packet_length;
841 
842     /* The extension identifier. */
843     ext = NX_SECURE_TLS_EXTENSION_PRE_SHARED_KEY;
844 
845     if (tls_session == NX_NULL)
846     {
847         return(NX_PTR_ERROR);
848     }
849 
850     if (available_size < (offset + 6u))
851     {
852 
853         /* Packet buffer too small. */
854         return(NX_SECURE_TLS_PACKET_BUFFER_TOO_SMALL);
855     }
856 
857     /* Put the extension ID into the packet. */
858     packet_buffer[offset] = (UCHAR)((ext & 0xFF00) >> 8);
859     packet_buffer[offset + 1] = (UCHAR)(ext & 0x00FF);
860     offset += 2;
861 
862     /* The total extension length - only the uint16 of the selected identity field. */
863     packet_buffer[offset] = (UCHAR)(0);
864     packet_buffer[offset + 1] = (UCHAR)(2);
865     offset += 2;
866 
867     /* The selected_identity index into the ClientHello PSK list. */
868     packet_buffer[offset] = (UCHAR)(0);
869     packet_buffer[offset + 1] = (UCHAR)(0);
870     offset += 2;
871 
872 
873     /* Return the amount of data we wrote. */
874     *extension_length = (USHORT)(offset - *packet_length);
875 
876     /* Return our updated packet offset. */
877     *packet_length = offset;
878 
879     return(NX_SUCCESS);
880 }
881 #endif
882 
883 
884