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