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 
28 /**************************************************************************/
29 /*                                                                        */
30 /*  FUNCTION                                               RELEASE        */
31 /*                                                                        */
32 /*    _nx_secure_tls_handshake_hash_init                  PORTABLE C      */
33 /*                                                           6.1          */
34 /*  AUTHOR                                                                */
35 /*                                                                        */
36 /*    Timothy Stapko, Microsoft Corporation                               */
37 /*                                                                        */
38 /*  DESCRIPTION                                                           */
39 /*                                                                        */
40 /*    This function initializes the hash function states needed for the   */
41 /*    TLS Finished message handshake hash.                                */
42 /*                                                                        */
43 /*  INPUT                                                                 */
44 /*                                                                        */
45 /*    tls_session                           TLS control block             */
46 /*                                                                        */
47 /*  OUTPUT                                                                */
48 /*                                                                        */
49 /*    status                                Completion status             */
50 /*                                                                        */
51 /*  CALLS                                                                 */
52 /*                                                                        */
53 /*    [nx_crypto_operation]                 Hash initialization functions */
54 /*                                                                        */
55 /*  CALLED BY                                                             */
56 /*                                                                        */
57 /*    _nx_secure_dtls_send_clienthello      Send ClientHello              */
58 /*    _nx_secure_dtls_server_handshake      DTLS server state machine     */
59 /*    _nx_secure_tls_send_clienthello       Send ClientHello              */
60 /*    _nx_secure_tls_server_handshake       TLS server state machine      */
61 /*                                                                        */
62 /*  RELEASE HISTORY                                                       */
63 /*                                                                        */
64 /*    DATE              NAME                      DESCRIPTION             */
65 /*                                                                        */
66 /*  05-19-2020     Timothy Stapko           Initial Version 6.0           */
67 /*  09-30-2020     Timothy Stapko           Modified comment(s),          */
68 /*                                            resulting in version 6.1    */
69 /*                                                                        */
70 /**************************************************************************/
_nx_secure_tls_handshake_hash_init(NX_SECURE_TLS_SESSION * tls_session)71 UINT  _nx_secure_tls_handshake_hash_init(NX_SECURE_TLS_SESSION *tls_session)
72 {
73 const NX_CRYPTO_METHOD *method_ptr;
74 UINT              status;
75 VOID             *handler = NX_NULL;
76 VOID             *metadata;
77 UINT              metadata_size;
78 
79 
80     /* We need to hash all of the handshake messages that we receive and send. When sending a ClientHello,
81        we need to initialize the hashes (TLS 1.1 uses both MD5 and SHA-1, TLS 1.2 uses SHA-256). The final
82        hash is generated in the "Finished" message.
83        TLS 1.3 does things a little differently - the handshake hash is the same as that of the chosen
84        ciphersuite, so */
85 
86 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
87     if(tls_session->nx_secure_tls_1_3)
88     {
89         /* Hash handshake record using ciphersuite hash routine. */
90         if (tls_session -> nx_secure_tls_session_ciphersuite == NX_NULL)
91         {
92             /* Set the hash method to the default of SHA-256 if no ciphersuite is available. */
93             method_ptr = tls_session -> nx_secure_tls_crypto_table->nx_secure_tls_handshake_hash_sha256_method;
94 
95         }
96         else
97         {
98             /* The handshake transcript hash in TLS 1.3 uses the hash routine associated with the chosen ciphersuite. */
99             method_ptr = tls_session -> nx_secure_tls_session_ciphersuite -> nx_secure_tls_hash;
100         }
101 
102         /* Generate the "transcript hash" for the point in the handshake where this message falls.
103          * This is needed for TLS 1.3 key generation which uses the hash of all previous handshake
104          * messages at multiple points during the handshake. Instead of saving the entirety of the
105          * handshake messages, just generate a hash when each record is hashed. */
106 
107 
108         /* The handshake transcript hash in TLS 1.3 uses the hash routine associated with the chosen ciphersuite. */
109         metadata = tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_sha256_metadata;
110         metadata_size = tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_sha256_metadata_size;
111 
112         if (method_ptr -> nx_crypto_init)
113         {
114             status = method_ptr -> nx_crypto_init((NX_CRYPTO_METHOD*)method_ptr,
115                                          NX_NULL,
116                                          0,
117                                          &handler,
118                                          metadata,
119                                          metadata_size);
120             tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_sha256_handler = handler;
121 
122             if(status != NX_CRYPTO_SUCCESS)
123             {
124                 return(status);
125             }
126         }
127 
128         if (method_ptr -> nx_crypto_operation != NX_NULL)
129         {
130             status = method_ptr -> nx_crypto_operation(NX_CRYPTO_HASH_INITIALIZE,
131                                               handler,
132                                               (NX_CRYPTO_METHOD*)method_ptr,
133                                               NX_NULL,
134                                               0,
135                                               NX_NULL,
136                                               0,
137                                               NX_NULL,
138                                               NX_NULL,
139                                               0,
140                                               metadata,
141                                               metadata_size,
142                                               NX_NULL,
143                                               NX_NULL);
144         }
145 
146         return(status);
147 
148     }
149 #endif
150 
151 
152 
153     /* Initialize both the handshake "finished" hashes - TLS 1.1 uses both SHA-1 and MD5, TLS 1.2 uses SHA-256 by default.
154        At this point we don't yet know the version we will use, so initialize all of them. */
155     /* Hash is determined by ciphersuite in TLS 1.2. Default is SHA-256. */
156 #if (NX_SECURE_TLS_TLS_1_2_ENABLED)
157     if (tls_session -> nx_secure_tls_supported_versions & (USHORT)(NX_SECURE_TLS_BITFIELD_VERSION_1_2))
158     {
159         method_ptr = tls_session -> nx_secure_tls_crypto_table -> nx_secure_tls_handshake_hash_sha256_method;
160         metadata = tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_sha256_metadata;
161         metadata_size = tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_sha256_metadata_size;
162 
163         if (method_ptr -> nx_crypto_init)
164         {
165             status = method_ptr -> nx_crypto_init((NX_CRYPTO_METHOD*)method_ptr,
166                                          NX_NULL,
167                                          0,
168                                          &handler,
169                                          metadata,
170                                          metadata_size);
171 
172             if(status != NX_CRYPTO_SUCCESS)
173             {
174                 return(status);
175             }
176             tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_sha256_handler = handler;
177         }
178 
179         if (method_ptr -> nx_crypto_operation != NX_NULL)
180         {
181             status = method_ptr -> nx_crypto_operation(NX_CRYPTO_HASH_INITIALIZE,
182                                               handler,
183                                               (NX_CRYPTO_METHOD*)method_ptr,
184                                               NX_NULL,
185                                               0,
186                                               NX_NULL,
187                                               0,
188                                               NX_NULL,
189                                               NX_NULL,
190                                               0,
191                                               metadata,
192                                               metadata_size,
193                                               NX_NULL,
194                                               NX_NULL);
195 
196             if(status != NX_CRYPTO_SUCCESS)
197             {
198                 return(status);
199             }
200         }
201     }
202 #endif
203 
204 #if (NX_SECURE_TLS_TLS_1_0_ENABLED || NX_SECURE_TLS_TLS_1_1_ENABLED)
205     if (tls_session -> nx_secure_tls_supported_versions & (USHORT)(NX_SECURE_TLS_BITFIELD_VERSION_1_0 | NX_SECURE_TLS_BITFIELD_VERSION_1_1))
206     {
207         /* TLS 1.0 and 1.1 use both MD5 and SHA-1. */
208         method_ptr = tls_session -> nx_secure_tls_crypto_table -> nx_secure_tls_handshake_hash_md5_method;
209         metadata = tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_md5_metadata;
210         metadata_size = tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_md5_metadata_size;
211 
212         if (method_ptr -> nx_crypto_init)
213         {
214             status = method_ptr -> nx_crypto_init((NX_CRYPTO_METHOD*)method_ptr,
215                                          NX_NULL,
216                                          0,
217                                          &handler,
218                                          metadata,
219                                          metadata_size);
220 
221             if(status != NX_CRYPTO_SUCCESS)
222             {
223                 return(status);
224             }
225 
226             tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_md5_handler = handler;
227         }
228 
229         if (method_ptr -> nx_crypto_operation != NX_NULL)
230         {
231             status = method_ptr -> nx_crypto_operation(NX_CRYPTO_HASH_INITIALIZE,
232                                               handler,
233                                               (NX_CRYPTO_METHOD*)method_ptr,
234                                               NX_NULL,
235                                               0,
236                                               NX_NULL,
237                                               0,
238                                               NX_NULL,
239                                               NX_NULL,
240                                               0,
241                                               metadata,
242                                               metadata_size,
243                                               NX_NULL,
244                                               NX_NULL);
245 
246             if(status != NX_CRYPTO_SUCCESS)
247             {
248                 return(status);
249             }
250         }
251 
252         method_ptr = tls_session -> nx_secure_tls_crypto_table -> nx_secure_tls_handshake_hash_sha1_method;
253         metadata = tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_sha1_metadata;
254         metadata_size = tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_sha1_metadata_size;
255 
256         if (method_ptr -> nx_crypto_init)
257         {
258             status = method_ptr -> nx_crypto_init((NX_CRYPTO_METHOD*)method_ptr,
259                                          NX_NULL,
260                                          0,
261                                          &handler,
262                                          metadata,
263                                          metadata_size);
264 
265             if(status != NX_CRYPTO_SUCCESS)
266             {
267                 return(status);
268             }
269             tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_sha1_handler = handler;
270         }
271 
272         if (method_ptr -> nx_crypto_operation != NX_NULL)
273         {
274             status = method_ptr -> nx_crypto_operation(NX_CRYPTO_HASH_INITIALIZE,
275                                               handler,
276                                               (NX_CRYPTO_METHOD*)method_ptr,
277                                               NX_NULL,
278                                               0,
279                                               NX_NULL,
280                                               0,
281                                               NX_NULL,
282                                               NX_NULL,
283                                               0,
284                                               metadata,
285                                               metadata_size,
286                                               NX_NULL,
287                                               NX_NULL);
288 
289             if(status != NX_CRYPTO_SUCCESS)
290             {
291                 return(status);
292             }
293         }
294     }
295 #endif
296 
297     return(NX_SUCCESS);
298 }
299 
300