1 /***************************************************************************
2  * Copyright (c) 2024 Microsoft Corporation
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the MIT License which is available at
6  * https://opensource.org/licenses/MIT.
7  *
8  * SPDX-License-Identifier: MIT
9  **************************************************************************/
10 
11 
12 /**************************************************************************/
13 /**************************************************************************/
14 /**                                                                       */
15 /** NetX Secure Component                                                 */
16 /**                                                                       */
17 /**    Transport Layer Security (TLS)                                     */
18 /**                                                                       */
19 /**************************************************************************/
20 /**************************************************************************/
21 
22 #define NX_SECURE_SOURCE_CODE
23 
24 #include "nx_secure_tls.h"
25 
26 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
27 const UCHAR _nx_secure_tls_hello_retry_request_random[32] =
28 {
29     0xCF, 0x21, 0xAD, 0x74, 0xE5, 0x9A, 0x61, 0x11, 0xBE, 0x1D, 0x8C, 0x02, 0x1E, 0x65, 0xB8, 0x91,
30     0xC2, 0xA2, 0x11, 0x16, 0x7A, 0xBB, 0x8C, 0x5E, 0x07, 0x9E, 0x09, 0xE2, 0xC8, 0xA8, 0x33, 0x9C
31 };
32 
33 const UCHAR _nx_secure_tls_1_2_random[8] =
34 {
35     0x44, 0x4F, 0x57, 0x4E, 0x47, 0x52, 0x44, 0x01
36 };
37 
38 const UCHAR _nx_secure_tls_1_1_random[8] =
39 {
40     0x44, 0x4F, 0x57, 0x4E, 0x47, 0x52, 0x44, 0x00
41 };
42 #endif
43 
44 /**************************************************************************/
45 /*                                                                        */
46 /*  FUNCTION                                               RELEASE        */
47 /*                                                                        */
48 /*    _nx_secure_tls_send_serverhello                     PORTABLE C      */
49 /*                                                           6.1.9        */
50 /*  AUTHOR                                                                */
51 /*                                                                        */
52 /*    Timothy Stapko, Microsoft Corporation                               */
53 /*                                                                        */
54 /*  DESCRIPTION                                                           */
55 /*                                                                        */
56 /*    This function generates a ServerHello message, which is used to     */
57 /*    respond to an incoming ClientHello message and provide the remote   */
58 /*    TLS Client with the chosen ciphersuite and key generation data.     */
59 /*                                                                        */
60 /*  INPUT                                                                 */
61 /*                                                                        */
62 /*    tls_session                           TLS control block             */
63 /*    send_packet                           Packet used to send message   */
64 /*                                                                        */
65 /*  OUTPUT                                                                */
66 /*                                                                        */
67 /*    status                                Completion status             */
68 /*                                                                        */
69 /*  CALLS                                                                 */
70 /*                                                                        */
71 /*    _nx_secure_tls_send_serverhello_extensions                          */
72 /*                                          Send TLS ServerHello extension*/
73 /*                                                                        */
74 /*  CALLED BY                                                             */
75 /*                                                                        */
76 /*    _nx_secure_tls_server_handshake       TLS server state machine      */
77 /*                                                                        */
78 /*  RELEASE HISTORY                                                       */
79 /*                                                                        */
80 /*    DATE              NAME                      DESCRIPTION             */
81 /*                                                                        */
82 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
83 /*  09-30-2020     Timothy Stapko           Modified comment(s), improved */
84 /*                                            buffer length verification, */
85 /*                                            verified memcpy use cases,  */
86 /*                                            resulting in version 6.1    */
87 /*  10-15-2021     Timothy Stapko           Modified comment(s), fixed    */
88 /*                                            compilation issue with      */
89 /*                                            TLS 1.3 and disabling TLS   */
90 /*                                            server,                     */
91 /*                                            resulting in version 6.1.9  */
92 /*                                                                        */
93 /**************************************************************************/
_nx_secure_tls_send_serverhello(NX_SECURE_TLS_SESSION * tls_session,NX_PACKET * send_packet)94 UINT _nx_secure_tls_send_serverhello(NX_SECURE_TLS_SESSION *tls_session, NX_PACKET *send_packet)
95 {
96 #ifndef NX_SECURE_TLS_SERVER_DISABLED
97 ULONG  length;
98 UINT   gmt_time;
99 UINT   random_value;
100 UINT   i;
101 USHORT ciphersuite;
102 UCHAR *packet_buffer;
103 USHORT protocol_version;
104 UINT   status;
105 
106 
107     /* Build up the ServerHello message.
108      * Structure:
109      * |     2       |          4 + 28          |    1       |   <SID len>  |      2      |      1      |    2     | <Ext. Len> |
110      * | TLS version |  Random (time + random)  | SID length |  Session ID  | Ciphersuite | Compression | Ext. Len | Extensions |
111      */
112 
113     if ((6u + sizeof(tls_session -> nx_secure_tls_key_material.nx_secure_tls_server_random)) >
114         ((ULONG)(send_packet -> nx_packet_data_end) - (ULONG)(send_packet -> nx_packet_append_ptr)))
115 
116     {
117 
118         /* Packet buffer is too small to hold random. */
119         return(NX_SECURE_TLS_PACKET_BUFFER_TOO_SMALL);
120     }
121 
122     packet_buffer = send_packet -> nx_packet_append_ptr;
123 
124     /* Use our length as an index into the buffer. */
125     length = 0;
126 
127     /* First two bytes of the hello following the header are the TLS major and minor version numbers. */
128     protocol_version = tls_session -> nx_secure_tls_protocol_version;
129 
130     packet_buffer[length]     = (UCHAR)((protocol_version & 0xFF00) >> 8);
131     packet_buffer[length + 1] = (UCHAR)(protocol_version & 0x00FF);
132     length += 2;
133 
134     /* Set the Server random data, used in key generation. First 4 bytes is GMT time. */
135     gmt_time = 0;
136     if (tls_session -> nx_secure_tls_session_time_function != NX_NULL)
137     {
138         gmt_time = tls_session -> nx_secure_tls_session_time_function();
139     }
140     NX_CHANGE_ULONG_ENDIAN(gmt_time);
141 
142     NX_SECURE_MEMCPY(tls_session -> nx_secure_tls_key_material.nx_secure_tls_server_random, (UCHAR *)&gmt_time, sizeof(gmt_time)); /* Use case of memcpy is verified. lgtm[cpp/banned-api-usage-required-any] */
143 
144 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
145     if (tls_session -> nx_secure_tls_server_state == NX_SECURE_TLS_SERVER_STATE_SEND_HELLO_RETRY)
146     {
147         NX_SECURE_MEMCPY(tls_session -> nx_secure_tls_key_material.nx_secure_tls_server_random,
148                          _nx_secure_tls_hello_retry_request_random,
149                          sizeof(_nx_secure_tls_hello_retry_request_random)); /* Use case of memcpy is verified. */
150     }
151     else if (!(tls_session -> nx_secure_tls_1_3) && !(tls_session -> nx_secure_tls_protocol_version_override))
152     {
153         /* Next 20 bytes is random data. */
154         for (i = 4; i <= 20; i += (UINT)sizeof(random_value))
155         {
156             random_value = (UINT)NX_RAND();
157             tls_session -> nx_secure_tls_key_material.nx_secure_tls_server_random[i]     = (UCHAR)(random_value);
158             tls_session -> nx_secure_tls_key_material.nx_secure_tls_server_random[i + 1] = (UCHAR)(random_value >> 8);
159             tls_session -> nx_secure_tls_key_material.nx_secure_tls_server_random[i + 2] = (UCHAR)(random_value >> 16);
160             tls_session -> nx_secure_tls_key_material.nx_secure_tls_server_random[i + 3] = (UCHAR)(random_value >> 24);
161         }
162 
163         /* RFC 8446 4.1.3:
164            TLS 1.3 servers which negotiate TLS 1.2 or below in response to a ClientHello
165            MUST set the last 8 bytes of their Random value specially in their ServerHello. */
166         if (tls_session -> nx_secure_tls_protocol_version == NX_SECURE_TLS_VERSION_TLS_1_2)
167         {
168             NX_SECURE_MEMCPY(&(tls_session -> nx_secure_tls_key_material.nx_secure_tls_server_random[24]),
169                              _nx_secure_tls_1_2_random,
170                              sizeof(_nx_secure_tls_1_2_random)); /* Use case of memcpy is verified. */
171         }
172         else
173         {
174             NX_SECURE_MEMCPY(&(tls_session -> nx_secure_tls_key_material.nx_secure_tls_server_random[24]),
175                              _nx_secure_tls_1_1_random,
176                              sizeof(_nx_secure_tls_1_1_random)); /* Use case of memcpy is verified. */
177         }
178     }
179     else
180 #endif
181     {
182 
183         /* Next 28 bytes is random data. */
184         for (i = 4; i <= 28; i += (UINT)sizeof(random_value))
185         {
186             random_value = (UINT)NX_RAND();
187             tls_session -> nx_secure_tls_key_material.nx_secure_tls_server_random[i]     = (UCHAR)(random_value);
188             tls_session -> nx_secure_tls_key_material.nx_secure_tls_server_random[i + 1] = (UCHAR)(random_value >> 8);
189             tls_session -> nx_secure_tls_key_material.nx_secure_tls_server_random[i + 2] = (UCHAR)(random_value >> 16);
190             tls_session -> nx_secure_tls_key_material.nx_secure_tls_server_random[i + 3] = (UCHAR)(random_value >> 24);
191         }
192     }
193 
194     /* Copy the random data into the packet. */
195     NX_SECURE_MEMCPY(&packet_buffer[length], tls_session -> nx_secure_tls_key_material.nx_secure_tls_server_random, /* lgtm[cpp/banned-api-usage-required-any] */
196                      sizeof(tls_session -> nx_secure_tls_key_material.nx_secure_tls_server_random)); /* Use case of memcpy is verified. */
197     length += sizeof(tls_session -> nx_secure_tls_key_material.nx_secure_tls_server_random);
198 
199     /* Session ID length is one byte. Session ID data follows if we ever implement session resumption. */
200 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
201     if(tls_session->nx_secure_tls_1_3)
202     {
203         /* TLS 1.3 doesn't use the session ID, but the Server must echo the server ID provided in the ClientHello
204            back to the client or the client will abort the handshake (RFC 8446, Section 4.1.3). */
205 
206         packet_buffer[length] = tls_session->nx_secure_tls_session_id_length;
207         length++;
208 
209         if ((length + tls_session->nx_secure_tls_session_id_length + 3) >
210             ((ULONG)(send_packet -> nx_packet_data_end) - (ULONG)(send_packet -> nx_packet_append_ptr)))
211         {
212 
213             /* Packet buffer is too small to hold random. */
214             return(NX_SECURE_TLS_PACKET_BUFFER_TOO_SMALL);
215         }
216 
217         NX_SECURE_MEMCPY(&packet_buffer[length], tls_session -> nx_secure_tls_session_id, tls_session->nx_secure_tls_session_id_length); /* Use case of memcpy is verified. */
218         length += tls_session->nx_secure_tls_session_id_length;
219     }
220     else
221 #endif
222     {
223         packet_buffer[length] = 0;
224         length++;
225     }
226     /* Finally, our chosen ciphersuite - this is selected when we receive the Client Hello. */
227     ciphersuite = tls_session -> nx_secure_tls_session_ciphersuite -> nx_secure_tls_ciphersuite;
228     packet_buffer[length]     = (UCHAR)(ciphersuite >> 8);
229     packet_buffer[length + 1] = (UCHAR)ciphersuite;
230     length += 2;
231 
232     /* Compression method - for now this is NULL. */
233     packet_buffer[length] = 0x0;
234     length++;
235 
236     /* ============ TLS ServerHello extensions. ============= */
237     status = _nx_secure_tls_send_serverhello_extensions(tls_session, packet_buffer, &length,
238                                                         ((ULONG)(send_packet -> nx_packet_data_end) -
239                                                          (ULONG)packet_buffer));
240 
241     if (status)
242     {
243         return(status);
244     }
245 
246     /* Finally, we have a complete length and can put it into the buffer. Before that,
247        save off and return the number of bytes we wrote and need to send. */
248     send_packet -> nx_packet_append_ptr = send_packet -> nx_packet_append_ptr + length;
249     send_packet -> nx_packet_length = send_packet -> nx_packet_length + length;
250 
251     return(status);
252 #else
253 
254     NX_PARAMETER_NOT_USED(send_packet);
255 
256     /* If TLS Server is disabled and we have processed a ClientKeyExchange, something is wrong... */
257     tls_session -> nx_secure_tls_client_state = NX_SECURE_TLS_CLIENT_STATE_ERROR;
258 
259     /* Server is disabled, we shouldn't be sending a ServerHello - error! */
260     return(NX_SECURE_TLS_INVALID_STATE);
261 #endif
262 
263 }
264 
265