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