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