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