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 #ifdef NX_SECURE_ENABLE_DTLS
27 #include "nx_secure_dtls.h"
28 #endif /* NX_SECURE_ENABLE_DTLS */
29 
30 /**************************************************************************/
31 /*                                                                        */
32 /*  FUNCTION                                               RELEASE        */
33 /*                                                                        */
34 /*    _nx_secure_tls_handshake_hash_update                PORTABLE C      */
35 /*                                                           6.1.9        */
36 /*  AUTHOR                                                                */
37 /*                                                                        */
38 /*    Timothy Stapko, Microsoft Corporation                               */
39 /*                                                                        */
40 /*  DESCRIPTION                                                           */
41 /*                                                                        */
42 /*    This function updates the hash function states with handshake       */
43 /*    messages, both generated by this host and received from a remote    */
44 /*    host. This is needed for the TLS Finished message handshake hash.   */
45 /*                                                                        */
46 /*  INPUT                                                                 */
47 /*                                                                        */
48 /*    tls_session                           TLS control block             */
49 /*    data                                  Data to be hashed             */
50 /*    length                                Data length                   */
51 /*                                                                        */
52 /*  OUTPUT                                                                */
53 /*                                                                        */
54 /*    status                                Completion status             */
55 /*                                                                        */
56 /*  CALLS                                                                 */
57 /*                                                                        */
58 /*    [nx_crypto_operation]                 Hash update functions         */
59 /*                                                                        */
60 /*  CALLED BY                                                             */
61 /*                                                                        */
62 /*    _nx_secure_dtls_send_clienthello      Send ClientHello              */
63 /*    _nx_secure_dtls_send_handshake_record Send DTLS handshake record    */
64 /*    _nx_secure_dtls_server_handshake      DTLS server state machine     */
65 /*    _nx_secure_tls_send_clienthello       Send ClientHello              */
66 /*    _nx_secure_tls_send_handshake_record  Send TLS handshake record     */
67 /*    _nx_secure_tls_server_handshake       TLS server state machine      */
68 /*                                                                        */
69 /*  RELEASE HISTORY                                                       */
70 /*                                                                        */
71 /*    DATE              NAME                      DESCRIPTION             */
72 /*                                                                        */
73 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
74 /*  09-30-2020     Timothy Stapko           Modified comment(s),          */
75 /*                                            resulting in version 6.1    */
76 /*  10-15-2021     Timothy Stapko           Modified comment(s), fixed    */
77 /*                                            compilation issue with      */
78 /*                                            TLS 1.3 and disabling TLS   */
79 /*                                            server,                     */
80 /*                                            resulting in version 6.1.9  */
81 /*                                                                        */
82 /**************************************************************************/
_nx_secure_tls_handshake_hash_update(NX_SECURE_TLS_SESSION * tls_session,UCHAR * data,UINT length)83 UINT  _nx_secure_tls_handshake_hash_update(NX_SECURE_TLS_SESSION *tls_session, UCHAR *data,
84                                            UINT length)
85 {
86 UINT                    status = NX_NOT_SUCCESSFUL;
87 const NX_CRYPTO_METHOD *method_ptr;
88 
89 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
90 UINT                    hash_length;
91 USHORT                  hello_retry_process = 0;
92 #endif
93 
94 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
95     if(tls_session->nx_secure_tls_1_3)
96     {
97         /* Hash handshake record using ciphersuite hash routine. */
98         if (tls_session -> nx_secure_tls_session_ciphersuite == NX_NULL)
99         {
100             /* Set the hash method to the default of SHA-256 if no ciphersuite is available. */
101             method_ptr = tls_session -> nx_secure_tls_crypto_table->nx_secure_tls_handshake_hash_sha256_method;
102 
103         }
104         else
105         {
106             /* The handshake transcript hash in TLS 1.3 uses the hash routine associated with the chosen ciphersuite. */
107             method_ptr = tls_session -> nx_secure_tls_session_ciphersuite -> nx_secure_tls_hash;
108         }
109 
110         /* Generate the "transcript hash" for the point in the handshake where this message falls.
111          * This is needed for TLS 1.3 key generation which uses the hash of all previous handshake
112          * messages at multiple points during the handshake. Instead of saving the entirety of the
113          * handshake messages, just generate a hash when each record is hashed. */
114         if (method_ptr -> nx_crypto_operation != NX_NULL)
115         {
116             status = method_ptr -> nx_crypto_operation(NX_CRYPTO_HASH_UPDATE,
117                                                        tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_sha256_handler,
118                                                        (NX_CRYPTO_METHOD*)method_ptr,
119                                                        NX_NULL,
120                                                        0,
121                                                        data,
122                                                        length,
123                                                        NX_NULL,
124                                                        NX_NULL,
125                                                        0,
126                                                        tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_sha256_metadata,
127                                                        tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_sha256_metadata_size,
128                                                        NX_NULL,
129                                                        NX_NULL);
130 
131             /* See if we have recieved or are sending a hello retry message - we need to process the hash differently. */
132 #ifndef NX_SECURE_TLS_SERVER_DISABLED
133             if (tls_session -> nx_secure_tls_socket_type == NX_SECURE_TLS_SESSION_TYPE_SERVER)
134             {
135                 hello_retry_process = (tls_session -> nx_secure_tls_server_state == NX_SECURE_TLS_SERVER_STATE_SEND_HELLO_RETRY);
136             }
137 #endif
138 #ifndef NX_SECURE_TLS_CLIENT_DISABLED
139             if (tls_session -> nx_secure_tls_socket_type == NX_SECURE_TLS_SESSION_TYPE_CLIENT)
140             {
141                 hello_retry_process = (tls_session -> nx_secure_tls_client_state == NX_SECURE_TLS_CLIENT_STATE_HELLO_RETRY);
142             }
143 #endif
144 
145            /* Modify message buffer - replace message with hash used for HelloRetryRequest processing. */
146             if ((status == NX_SUCCESS) &&
147                 (hello_retry_process) &&
148                 (data[0] == NX_SECURE_TLS_CLIENT_HELLO) &&
149                 (length > NX_SECURE_TLS_HANDSHAKE_HEADER_SIZE))
150             {
151 
152                 /* ClientHello1 is replaced with "message_hash || 00 00 Hash.length || Hash(ClientHello1)"*/
153                 status = method_ptr -> nx_crypto_operation(NX_CRYPTO_HASH_CALCULATE,
154                                                            tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_sha256_handler,
155                                                            (NX_CRYPTO_METHOD*)method_ptr,
156                                                            NX_NULL,
157                                                            0,
158                                                            NX_NULL,
159                                                            0,
160                                                            NX_NULL,
161                                                            data + 4, /* Reuse input buffer since the input will not be used anymore. */
162                                                            NX_SECURE_TLS_MAX_HASH_SIZE,
163                                                            tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_sha256_metadata,
164                                                            tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_sha256_metadata_size,
165                                                            NX_NULL,
166                                                            NX_NULL);
167 
168                 /* Initialize handshake HASH again. */
169                 if (status == NX_SUCCESS)
170                 {
171                     status = _nx_secure_tls_handshake_hash_init(tls_session);
172                 }
173 
174                 if (status == NX_SUCCESS)
175                 {
176                     hash_length = method_ptr -> nx_crypto_ICV_size_in_bits >> 3;
177                     data[0] = NX_SECURE_TLS_MESSAGE_HASH & 0xFF;
178                     data[1] = 0;
179                     data[2] = 0;
180                     data[3] = hash_length & 0xFF;
181 
182                     status = method_ptr -> nx_crypto_operation(NX_CRYPTO_HASH_UPDATE,
183                                                                tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_sha256_handler,
184                                                                (NX_CRYPTO_METHOD*)method_ptr,
185                                                                NX_NULL,
186                                                                0,
187                                                                data,
188                                                                hash_length + 4,
189                                                                NX_NULL,
190                                                                NX_NULL,
191                                                                0,
192                                                                tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_sha256_metadata,
193                                                                tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_sha256_metadata_size,
194                                                                NX_NULL,
195                                                                NX_NULL);
196                 }
197             }
198         }
199 
200         return(status);
201 
202 
203     }
204 #endif
205 
206     /* Hash this handshake message. We do not hash HelloRequest messages, but since only the server will send them,
207        we do not worry about them here because these are only messages received from the client at this point.
208        Hashes include the handshake layer header but not the record layer header. */
209 #if (NX_SECURE_TLS_TLS_1_2_ENABLED)
210 #ifdef NX_SECURE_ENABLE_DTLS
211     if (tls_session -> nx_secure_tls_protocol_version == NX_SECURE_TLS_VERSION_TLS_1_2 ||
212         tls_session -> nx_secure_tls_protocol_version == NX_SECURE_DTLS_VERSION_1_2)
213 #else
214     if (tls_session -> nx_secure_tls_protocol_version == NX_SECURE_TLS_VERSION_TLS_1_2)
215 #endif /* NX_SECURE_ENABLE_DTLS */
216     {
217         /* Hash is determined by ciphersuite in TLS 1.2. Default is SHA-256. */
218         method_ptr = tls_session -> nx_secure_tls_crypto_table -> nx_secure_tls_handshake_hash_sha256_method;
219         if (method_ptr -> nx_crypto_operation != NX_NULL)
220         {
221             status = method_ptr -> nx_crypto_operation(NX_CRYPTO_HASH_UPDATE,
222                                                        tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_sha256_handler,
223                                                        (NX_CRYPTO_METHOD*)method_ptr,
224                                                        NX_NULL,
225                                                        0,
226                                                        data,
227                                                        length,
228                                                        NX_NULL,
229                                                        NX_NULL,
230                                                        0,
231                                                        tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_sha256_metadata,
232                                                        tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_sha256_metadata_size,
233                                                        NX_NULL,
234                                                        NX_NULL);
235 
236             if (status != NX_CRYPTO_SUCCESS)
237             {
238                 return(status);
239             }
240         }
241     }
242 #endif
243 
244 #if (NX_SECURE_TLS_TLS_1_0_ENABLED || NX_SECURE_TLS_TLS_1_1_ENABLED)
245 #ifdef NX_SECURE_ENABLE_DTLS
246     if (tls_session -> nx_secure_tls_protocol_version == NX_SECURE_TLS_VERSION_TLS_1_0 ||
247         tls_session -> nx_secure_tls_protocol_version == NX_SECURE_TLS_VERSION_TLS_1_1 ||
248         tls_session -> nx_secure_tls_protocol_version == NX_SECURE_DTLS_VERSION_1_0)
249 #else
250     if (tls_session -> nx_secure_tls_protocol_version == NX_SECURE_TLS_VERSION_TLS_1_0 ||
251         tls_session -> nx_secure_tls_protocol_version == NX_SECURE_TLS_VERSION_TLS_1_1)
252 #endif /* NX_SECURE_ENABLE_DTLS */
253     {
254         /* TLS 1.0 and 1.1 use both MD5 and SHA-1. */
255         method_ptr = tls_session -> nx_secure_tls_crypto_table -> nx_secure_tls_handshake_hash_md5_method;
256         if (method_ptr -> nx_crypto_operation != NX_NULL)
257         {
258             status = method_ptr -> nx_crypto_operation(NX_CRYPTO_HASH_UPDATE,
259                                                        tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_md5_handler,
260                                                        (NX_CRYPTO_METHOD*)method_ptr,
261                                                        NX_NULL,
262                                                        0,
263                                                        data,
264                                                        length,
265                                                        NX_NULL,
266                                                        NX_NULL,
267                                                        0,
268                                                        tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_md5_metadata,
269                                                        tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_md5_metadata_size,
270                                                        NX_NULL,
271                                                        NX_NULL);
272 
273             if (status != NX_CRYPTO_SUCCESS)
274             {
275                 return(status);
276             }
277         }
278 
279         method_ptr = tls_session -> nx_secure_tls_crypto_table -> nx_secure_tls_handshake_hash_sha1_method;
280         if (method_ptr -> nx_crypto_operation != NX_NULL)
281         {
282             status = method_ptr -> nx_crypto_operation(NX_CRYPTO_HASH_UPDATE,
283                                                        tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_sha1_handler,
284                                                        (NX_CRYPTO_METHOD*)method_ptr,
285                                                        NX_NULL,
286                                                        0,
287                                                        data,
288                                                        length,
289                                                        NX_NULL,
290                                                        NX_NULL,
291                                                        0,
292                                                        tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_sha1_metadata,
293                                                        tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_sha1_metadata_size,
294                                                        NX_NULL,
295                                                        NX_NULL);
296 
297             if (status != NX_CRYPTO_SUCCESS)
298             {
299                 return(status);
300             }
301         }
302     }
303 #endif
304 
305     return(status);
306 }
307 
308