1 /***************************************************************************
2 * Copyright (c) 2024 Microsoft Corporation
3 *
4 * This program and the accompanying materials are made available under the
5 * terms of the MIT License which is available at
6 * https://opensource.org/licenses/MIT.
7 *
8 * SPDX-License-Identifier: MIT
9 **************************************************************************/
10
11
12 /**************************************************************************/
13 /**************************************************************************/
14 /** */
15 /** NetX Secure Component */
16 /** */
17 /** Transport Layer Security (TLS) */
18 /** */
19 /**************************************************************************/
20 /**************************************************************************/
21
22 #define NX_SECURE_SOURCE_CODE
23
24 #include "nx_secure_tls.h"
25
26 /**************************************************************************/
27 /* */
28 /* FUNCTION RELEASE */
29 /* */
30 /* _nx_secure_tls_session_create_ext PORTABLE C */
31 /* 6.2.1 */
32 /* AUTHOR */
33 /* */
34 /* Timothy Stapko, Microsoft Corporation */
35 /* */
36 /* DESCRIPTION */
37 /* */
38 /* This function is the new-style API for creating a new TLS session. */
39 /* Like the original function, it initializes a TLS session control */
40 /* block for later use in establishing a secure TLS session over a TCP */
41 /* socket or other lower-level networking protocol. The difference is */
42 /* that this function takes an un-ordered array of cryptographic */
43 /* methods and a mapping table from ciphersuites to algorithm */
44 /* identifiers so the mapping of crypto methods to ciphersuites can be */
45 /* done automatically, rather than needing to link in all possible */
46 /* cipher routines in a single table. */
47 /* */
48 /* To calculate the necessary metadata size, the API */
49 /* nx_secure_tls_metadata_size_calculate may be used. */
50 /* */
51 /* INPUT */
52 /* */
53 /* session_ptr TLS session control block */
54 /* crypto_array crypto methods to use */
55 /* cipher_map Mapping table for ciphersuites*/
56 /* metadata_buffer Encryption metadata area */
57 /* metadata_size Encryption metadata size */
58 /* */
59 /* OUTPUT */
60 /* */
61 /* status Completion status */
62 /* */
63 /* CALLS */
64 /* */
65 /* _nx_secure_tls_session_reset Clear out the session */
66 /* tx_mutex_get Get protection mutex */
67 /* tx_mutex_put Put protection mutex */
68 /* */
69 /* CALLED BY */
70 /* */
71 /* Application Code */
72 /* */
73 /* RELEASE HISTORY */
74 /* */
75 /* DATE NAME DESCRIPTION */
76 /* */
77 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
78 /* 09-30-2020 Timothy Stapko Modified comment(s), and */
79 /* fixed race condition for */
80 /* multithread transmission, */
81 /* added ECC initialization, */
82 /* fixed renegotiation bug, */
83 /* resulting in version 6.1 */
84 /* 01-31-2022 Timothy Stapko Modified comment(s), and */
85 /* added null pointer checking,*/
86 /* resulting in version 6.1.10 */
87 /* 04-25-2022 Yuxin Zhou Modified comment(s), and */
88 /* added null pointer checking,*/
89 /* removed unused code, */
90 /* resulting in version 6.1.11 */
91 /* 10-31-2022 Yanwu Cai Modified comment(s), and added*/
92 /* custom secret generation, */
93 /* resulting in version 6.2.0 */
94 /* 03-08-2023 Yanwu Cai Modified comment(s), */
95 /* fixed compiler errors when */
96 /* x509 is disabled, */
97 /* resulting in version 6.2.1 */
98 /* */
99 /**************************************************************************/
100
_find_cipher(UINT cipher_id,UINT cipher_role_id,UINT key_size,const NX_CRYPTO_METHOD ** crypto_array,UINT array_size,const NX_CRYPTO_METHOD ** crypto_method)101 static UINT _find_cipher(UINT cipher_id, UINT cipher_role_id, UINT key_size, const NX_CRYPTO_METHOD **crypto_array, UINT array_size, const NX_CRYPTO_METHOD **crypto_method)
102 {
103 UINT i;
104
105 for(i = 0; i < array_size; ++i)
106 {
107 if(crypto_array[i]->nx_crypto_algorithm == cipher_id)
108 {
109 if (cipher_role_id == NX_CRYPTO_ROLE_SYMMETRIC &&
110 crypto_array[i] -> nx_crypto_key_size_in_bits != key_size << 3)
111 {
112 continue;
113 }
114
115 *crypto_method = crypto_array[i];
116 return(NX_SUCCESS);
117 }
118 }
119
120 *crypto_method = NX_NULL;
121 return(NX_SECURE_TLS_UNSUPPORTED_CIPHER);
122 }
123
124
125
_map_tls_ciphersuites(NX_SECURE_TLS_SESSION * tls_session,const NX_CRYPTO_METHOD ** crypto_array,UINT crypto_array_size,const NX_CRYPTO_CIPHERSUITE ** cipher_map,UINT cipher_map_size,UINT * metadata_size)126 static UINT _map_tls_ciphersuites(NX_SECURE_TLS_SESSION *tls_session,
127 const NX_CRYPTO_METHOD **crypto_array, UINT crypto_array_size,
128 const NX_CRYPTO_CIPHERSUITE **cipher_map, UINT cipher_map_size, UINT *metadata_size)
129 {
130 NX_CRYPTO_ROLE_ENTRY current_cipher;
131 const NX_CRYPTO_METHOD *cipher_method;
132 NX_SECURE_TLS_CIPHERSUITE_INFO *cipher_entry;
133 NX_SECURE_TLS_CRYPTO * crypto_table;
134 UINT cipher_id;
135 UINT suite;
136 UINT cipher_counter;
137 UINT remaining_size;
138 UCHAR crypto_found;
139 UINT status;
140
141 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
142 UINT ecdhe_found;
143 UINT dhe_found;
144 UINT rsa_found;
145 UINT dsa_found;
146 UINT ecdsa_found;
147 #endif
148
149 /* Bitmasks for marking found ciphers. */
150 const UCHAR sig_found = 0x1;
151 const UCHAR key_ex_found = 0x2;
152 const UCHAR symm_found = 0x4;
153 const UCHAR hash_found = 0x8;
154 const UCHAR prf_found = 0x10;
155 const UCHAR all_found = sig_found | key_ex_found | symm_found | hash_found | prf_found;
156
157 /* Pointer to our lookup table. */
158 crypto_table = tls_session->nx_secure_tls_crypto_table;
159
160 /* Get a pointer to our entry. */
161 cipher_entry = crypto_table->nx_secure_tls_ciphersuite_lookup_table;
162
163 /* For bookkeeping, keep track of remaining metadata space. */
164 remaining_size = *metadata_size;
165
166 /* TLS version-specific cipher mapping. */
167 #if (NX_SECURE_TLS_TLS_1_0_ENABLED || NX_SECURE_TLS_TLS_1_1_ENABLED)
168 /* TLS 1.0, 1.1 both need SHA-1 AND MD5. If both are present, we support those versions, otherwise
169 * we don't support either. */
170
171 /* Find MD5. If not found, cipher_method is set to NX_NULL so all good either way. */
172 status = _find_cipher(NX_CRYPTO_HASH_MD5, NX_CRYPTO_ROLE_RAW_HASH, 0, crypto_array, crypto_array_size, &cipher_method);
173 crypto_table->nx_secure_tls_handshake_hash_md5_method = cipher_method;
174 if(status != NX_SUCCESS)
175 {
176 /* TLS 1.0, 1.1 NOT supported! */
177 tls_session->nx_secure_tls_supported_versions = (tls_session->nx_secure_tls_supported_versions & (USHORT)(~(NX_SECURE_TLS_BITFIELD_VERSION_1_0)));
178 tls_session->nx_secure_tls_supported_versions = (tls_session->nx_secure_tls_supported_versions & (USHORT)(~(NX_SECURE_TLS_BITFIELD_VERSION_1_1)));
179 }
180
181 /* Find SHA-1 and assign (if not found, pointer is set to NX_NULL). */
182 status = _find_cipher(NX_CRYPTO_HASH_SHA1, NX_CRYPTO_ROLE_RAW_HASH, 0, crypto_array, crypto_array_size, &cipher_method);
183 crypto_table->nx_secure_tls_handshake_hash_sha1_method = cipher_method;
184
185 if(status != NX_SUCCESS)
186 {
187 /* TLS 1.0, 1.1 NOT supported! */
188 tls_session->nx_secure_tls_supported_versions = (tls_session->nx_secure_tls_supported_versions & (USHORT)(~(NX_SECURE_TLS_BITFIELD_VERSION_1_0)));
189 tls_session->nx_secure_tls_supported_versions = (tls_session->nx_secure_tls_supported_versions & (USHORT)(~(NX_SECURE_TLS_BITFIELD_VERSION_1_1)));
190 }
191
192 /* Find TLS PRF (for TLS 1.0 and 1.1) and assign (if not found, pointer is set to NX_NULL). */
193 status = _find_cipher(NX_CRYPTO_PRF_HMAC_SHA1, NX_CRYPTO_ROLE_PRF, 0, crypto_array, crypto_array_size, &cipher_method);
194 crypto_table->nx_secure_tls_prf_1_method = cipher_method;
195
196 if(status != NX_SUCCESS)
197 {
198 /* TLS 1.0, 1.1 NOT supported! */
199 tls_session->nx_secure_tls_supported_versions = (tls_session->nx_secure_tls_supported_versions & (USHORT)(~(NX_SECURE_TLS_BITFIELD_VERSION_1_0)));
200 tls_session->nx_secure_tls_supported_versions = (tls_session->nx_secure_tls_supported_versions & (USHORT)(~(NX_SECURE_TLS_BITFIELD_VERSION_1_1)));
201 }
202
203 #endif
204
205 /* TLS 1.2 - the default PRF uses SHA-256 so make sure we have at least that routine. */
206 #if (NX_SECURE_TLS_TLS_1_2_ENABLED)
207 status = _find_cipher(NX_CRYPTO_HASH_SHA256, NX_CRYPTO_ROLE_RAW_HASH, 0, crypto_array, crypto_array_size, &cipher_method);
208 crypto_table->nx_secure_tls_handshake_hash_sha256_method = cipher_method;
209
210 if(status != NX_SUCCESS)
211 {
212 /* Version 1.2 NOT supported! */
213 tls_session->nx_secure_tls_supported_versions = (tls_session->nx_secure_tls_supported_versions & (USHORT)(~(NX_SECURE_TLS_BITFIELD_VERSION_1_2)));
214 }
215
216 /* Find TLS PRF (for TLS 1.0 and 1.1) and assign (if not found, pointer is set to NX_NULL). */
217 status = _find_cipher(NX_CRYPTO_PRF_HMAC_SHA2_256, NX_CRYPTO_ROLE_PRF, 0, crypto_array, crypto_array_size, &cipher_method);
218 crypto_table->nx_secure_tls_prf_sha256_method = cipher_method;
219
220 if(status != NX_SUCCESS)
221 {
222 /* TLS 1.0, 1.1 NOT supported! */
223 tls_session->nx_secure_tls_supported_versions = (tls_session->nx_secure_tls_supported_versions & (USHORT)(~(NX_SECURE_TLS_BITFIELD_VERSION_1_0)));
224 tls_session->nx_secure_tls_supported_versions = (tls_session->nx_secure_tls_supported_versions & (USHORT)(~(NX_SECURE_TLS_BITFIELD_VERSION_1_1)));
225 }
226
227 #endif
228
229 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
230 /* TLS 1.3. */
231 /* TLS 1.3 supports only ECDHE and DHE key exchanges. */
232 ecdhe_found = _find_cipher(NX_CRYPTO_KEY_EXCHANGE_ECDHE, NX_CRYPTO_ROLE_KEY_EXCHANGE, 0, crypto_array, crypto_array_size, &cipher_method);
233 crypto_table->nx_secure_tls_ecdhe_method = cipher_method;
234 dhe_found = _find_cipher(NX_CRYPTO_KEY_EXCHANGE_DHE, NX_CRYPTO_ROLE_KEY_EXCHANGE, 0, crypto_array, crypto_array_size, &cipher_method);
235 if(!(ecdhe_found || dhe_found))
236 {
237 /* TLS 1.3 NOT supported! */
238 tls_session->nx_secure_tls_supported_versions = (tls_session->nx_secure_tls_supported_versions & (USHORT)(~(NX_SECURE_TLS_BITFIELD_VERSION_1_3)));
239 }
240
241 /* TLS 1.3 needs at least one signature authentication routine. */
242 rsa_found = _find_cipher(NX_CRYPTO_DIGITAL_SIGNATURE_RSA, NX_CRYPTO_ROLE_SIGNATURE_CRYPTO, 0, crypto_array, crypto_array_size, &cipher_method);
243 dsa_found = _find_cipher(NX_CRYPTO_DIGITAL_SIGNATURE_DSA, NX_CRYPTO_ROLE_SIGNATURE_CRYPTO, 0, crypto_array, crypto_array_size, &cipher_method);
244 ecdsa_found = _find_cipher(NX_CRYPTO_DIGITAL_SIGNATURE_ECDSA, NX_CRYPTO_ROLE_SIGNATURE_CRYPTO, 0, crypto_array, crypto_array_size, &cipher_method);
245
246 if(!((rsa_found == NX_SUCCESS) || (dsa_found == NX_SUCCESS) || (ecdsa_found == NX_SUCCESS)))
247 {
248 /* TLS 1.3 is NOTsupported!. */
249 tls_session->nx_secure_tls_supported_versions = (tls_session->nx_secure_tls_supported_versions & (USHORT)(~(NX_SECURE_TLS_BITFIELD_VERSION_1_3)));
250 }
251
252 /* TLS 1.3 needs HKDF and HMAC methods. */
253 status = _find_cipher(NX_CRYPTO_HASH_HMAC, NX_CRYPTO_ROLE_HMAC, 0, crypto_array, crypto_array_size, &cipher_method);
254 crypto_table->nx_secure_tls_hmac_method = cipher_method;
255 if(status != NX_SUCCESS)
256 {
257 /* TLS 1.3 is NOTsupported!. */
258 tls_session->nx_secure_tls_supported_versions = (tls_session->nx_secure_tls_supported_versions & (USHORT)(~(NX_SECURE_TLS_BITFIELD_VERSION_1_3)));
259 }
260
261 status = _find_cipher(NX_CRYPTO_HKDF_METHOD, NX_CRYPTO_ROLE_PRF, 0, crypto_array, crypto_array_size, &cipher_method);
262 crypto_table->nx_secure_tls_hkdf_method = cipher_method;
263 if(status != NX_SUCCESS)
264 {
265 /* TLS 1.3 is NOTsupported!. */
266 tls_session->nx_secure_tls_supported_versions = (tls_session->nx_secure_tls_supported_versions & (USHORT)(~(NX_SECURE_TLS_BITFIELD_VERSION_1_3)));
267 }
268 #endif
269
270
271 /* Loop through cipher map, check each ciphersuite. */
272 for(suite = 0; suite < cipher_map_size; ++suite)
273 {
274 /* Search the crypto array for each cipher in this ciphersuite map. */
275 cipher_entry->nx_secure_tls_ciphersuite = cipher_map[suite]->nx_crypto_ciphersuite_id;
276
277 /* Handle TLS mapping. */
278 if(cipher_map[suite]->nx_crypto_internal_id == NX_SECURE_APPLICATION_TLS)
279 {
280 /* Start with no crypto methods found. */
281 crypto_found = 0;
282
283 /* Loop through the ciphers in this ciphersuite and map to a cipher method in the cipher array. */
284 for(cipher_counter = 0; cipher_counter < NX_CRYPTO_MAX_CIPHER_ROLES; ++cipher_counter)
285 {
286 /* Get the current entry and role. */
287 current_cipher = cipher_map[suite]->nx_crypto_ciphers[cipher_counter];
288 cipher_id = current_cipher.nx_crypto_role_cipher_id;
289
290 /* Check for end of expected ciphers. */
291 if(current_cipher.nx_crypto_role_id == NX_CRYPTO_ROLE_NONE)
292 {
293 /* Reached the end of the list - ciphersuite is good if we found the
294 expected ciphers. */
295 if(crypto_found != all_found)
296 {
297 break;
298 }
299
300 /* The ciphersuite is fully supported given the input
301 crypto method array. Add it to the table by advancing the pointer
302 as a ciphersuite we can use. */
303 cipher_entry = &cipher_entry[1];
304 crypto_table->nx_secure_tls_ciphersuite_lookup_table_size++;
305
306 /* If there is not enough space, return error. */
307 if(remaining_size < sizeof(NX_SECURE_TLS_CIPHERSUITE_INFO))
308 {
309 return(NX_SECURE_TLS_INSUFFICIENT_METADATA_SPACE);
310 }
311
312 /* Update our bookkeeping. */
313 remaining_size -= sizeof(NX_SECURE_TLS_CIPHERSUITE_INFO);
314
315 /* Exit the search loop. */
316 break;
317 }
318
319 /* Cipher is not "None" so we need to see if it is available. */
320 status = _find_cipher(cipher_id, current_cipher.nx_crypto_role_id, cipher_map[suite] -> nx_crypto_symmetric_key_size, crypto_array, crypto_array_size, &cipher_method);
321 if(status != NX_SUCCESS)
322 {
323 /* Did not find a cipher, break out of search. */
324 break;
325 }
326
327 /* Put the cipher method into the ciphersuite info structure. */
328 switch(current_cipher.nx_crypto_role_id)
329 {
330 case NX_CRYPTO_ROLE_KEY_EXCHANGE:
331 cipher_entry->nx_secure_tls_public_cipher = cipher_method;
332 crypto_found |= key_ex_found;
333 break;
334 case NX_CRYPTO_ROLE_SIGNATURE_CRYPTO:
335 cipher_entry->nx_secure_tls_public_auth = cipher_method;
336 crypto_found |= sig_found;
337 break;
338 case NX_CRYPTO_ROLE_MAC_HASH:
339 cipher_entry->nx_secure_tls_hash = cipher_method;
340 cipher_entry->nx_secure_tls_hash_size = (USHORT)(cipher_method->nx_crypto_ICV_size_in_bits >> 3);
341 crypto_found |= hash_found;
342 break;
343 case NX_CRYPTO_ROLE_SYMMETRIC:
344 cipher_entry->nx_secure_tls_session_cipher = cipher_method;
345 cipher_entry->nx_secure_tls_session_key_size = (UCHAR)cipher_map[suite]->nx_crypto_symmetric_key_size;
346 cipher_entry->nx_secure_tls_iv_size = (UCHAR)(cipher_method->nx_crypto_IV_size_in_bits >> 3);
347 crypto_found |= symm_found;
348 break;
349 case NX_CRYPTO_ROLE_PRF:
350 cipher_entry->nx_secure_tls_prf = cipher_method;
351 crypto_found |= prf_found;
352 break;
353 default:
354 /* Cipher role not supported by TLS. Ignore. */
355 break;
356 }
357 }
358 }
359 }
360
361 /* Return the used metadata size. */
362 *metadata_size = (*metadata_size - remaining_size);
363
364 return(NX_SUCCESS);
365 }
366
367
368 #ifndef NX_SECURE_DISABLE_X509
_map_x509_ciphersuites(NX_SECURE_TLS_SESSION * tls_session,const NX_CRYPTO_METHOD ** crypto_array,UINT crypto_array_size,const NX_CRYPTO_CIPHERSUITE ** cipher_map,UINT cipher_map_size,UINT * metadata_size)369 static UINT _map_x509_ciphersuites(NX_SECURE_TLS_SESSION *tls_session,
370 const NX_CRYPTO_METHOD **crypto_array, UINT crypto_array_size,
371 const NX_CRYPTO_CIPHERSUITE **cipher_map, UINT cipher_map_size, UINT *metadata_size)
372 {
373 NX_CRYPTO_ROLE_ENTRY current_cipher;
374 const NX_CRYPTO_METHOD *cipher_method;
375 NX_SECURE_X509_CRYPTO *cert_crypto;
376 NX_SECURE_TLS_CRYPTO *crypto_table;
377 UINT cipher_id;
378 UINT suite;
379 UINT cipher_counter;
380 UINT status;
381 UINT remaining_size;
382 UCHAR crypto_found;
383
384 /* Constants for marking ciphers as found. */
385 const UCHAR pub_key_found = 0x1;
386 const UCHAR hash_found = 0x2;
387 const UCHAR all_found = pub_key_found | hash_found;
388
389 /* Get a pointer to our entry. */
390 crypto_table = tls_session->nx_secure_tls_crypto_table;
391 cert_crypto = crypto_table->nx_secure_tls_x509_cipher_table;
392
393 /* For bookkeeping, keep track of remaining metadata space. */
394 remaining_size = *metadata_size;
395
396 /* Loop through cipher map, check each ciphersuite. */
397 for(suite = 0; suite < cipher_map_size; ++suite)
398 {
399 /* Search the crypto array for each cipher in this ciphersuite map. */
400 cert_crypto->nx_secure_x509_crypto_identifier = cipher_map[suite]->nx_crypto_ciphersuite_id;
401
402 /* Handle X.509 mapping. */
403 if(cipher_map[suite]->nx_crypto_internal_id == NX_SECURE_APPLICATION_X509)
404 {
405 crypto_found = 0;
406
407 /* Loop through the ciphers in this ciphersuite and map to a cipher method in the cipher array. */
408 for(cipher_counter = 0; cipher_counter < NX_CRYPTO_MAX_CIPHER_ROLES; ++cipher_counter)
409 {
410 /* Get the current entry and role. */
411 current_cipher = cipher_map[suite]->nx_crypto_ciphers[cipher_counter];
412 cipher_id = current_cipher.nx_crypto_role_cipher_id;
413
414 if(current_cipher.nx_crypto_role_id == NX_CRYPTO_ROLE_NONE)
415 {
416 /* Reached the end of the list - ciphersuite is good if all ciphers present. */
417 if(crypto_found != all_found)
418 {
419 break;
420 }
421
422 /* Advance to the next entry in the table. */
423 cert_crypto = &cert_crypto[1];
424 crypto_table->nx_secure_tls_x509_cipher_table_size++;
425
426 /* If there is not enough space, return error. */
427 if(remaining_size < sizeof(NX_SECURE_X509_CRYPTO))
428 {
429 return(NX_SECURE_TLS_INSUFFICIENT_METADATA_SPACE);
430 }
431
432 /* Update our bookkeeping. */
433 remaining_size -= sizeof(NX_SECURE_X509_CRYPTO);
434
435 /* Break out of the search loop. */
436 break;
437 }
438
439 /* Cipher is not "none" so see if it's available. */
440 status = _find_cipher(cipher_id, current_cipher.nx_crypto_role_id, 0, crypto_array, crypto_array_size, &cipher_method);
441 if(status != NX_SUCCESS)
442 {
443 /* Did not find a cipher, break out of search. */
444 break;
445 }
446
447 /* Put the cipher method into the ciphersuite info structure. */
448 switch(current_cipher.nx_crypto_role_id)
449 {
450 case NX_CRYPTO_ROLE_SIGNATURE_CRYPTO:
451 cert_crypto->nx_secure_x509_public_cipher_method = cipher_method;
452 crypto_found |= pub_key_found;
453 break;
454 case NX_CRYPTO_ROLE_SIGNATURE_HASH:
455 cert_crypto->nx_secure_x509_hash_method = cipher_method;
456 crypto_found |= hash_found;
457 break;
458 default:
459 /* Cipher role not supported by X.509. Ignore. */
460 break;
461 }
462 }
463 }
464 }
465
466 /* Return the used metadata size. */
467 *metadata_size = (*metadata_size - remaining_size);
468
469 return(NX_SUCCESS);
470 }
471 #endif
472
473
_nx_secure_tls_session_create_ext(NX_SECURE_TLS_SESSION * tls_session,const NX_CRYPTO_METHOD ** crypto_array,UINT crypto_array_size,const NX_CRYPTO_CIPHERSUITE ** cipher_map,UINT cipher_map_size,VOID * metadata_buffer,ULONG metadata_size)474 UINT _nx_secure_tls_session_create_ext(NX_SECURE_TLS_SESSION *tls_session,
475 const NX_CRYPTO_METHOD **crypto_array, UINT crypto_array_size,
476 const NX_CRYPTO_CIPHERSUITE **cipher_map, UINT cipher_map_size,
477 VOID *metadata_buffer,
478 ULONG metadata_size)
479 {
480 NX_SECURE_TLS_SESSION *tail_ptr;
481 UINT i;
482 UINT cipher_table_bytes;
483 UINT status;
484
485 UINT max_public_cipher_metadata_size = 0;
486 UINT max_public_auth_metadata_size = 0;
487 UINT max_session_cipher_metadata_size = 0;
488 UINT max_hash_mac_metadata_size = 0;
489 UINT max_tls_prf_metadata_size = 0;
490 UINT max_handshake_hash_metadata_size = 0;
491 UINT max_handshake_hash_scratch_size = 0;
492 ULONG max_total_metadata_size;
493 ULONG offset;
494 CHAR *metadata_area;
495
496 NX_SECURE_TLS_CRYPTO * crypto_table;
497
498 NX_SECURE_TLS_CIPHERSUITE_INFO *ciphersuite_table;
499 USHORT ciphersuite_table_size;
500 #ifndef NX_SECURE_DISABLE_X509
501 NX_SECURE_X509_CRYPTO *cert_crypto;
502 USHORT cert_crypto_size;
503 #endif
504
505 #ifdef NX_SECURE_ENABLE_ECC_CIPHERSUITE
506 NX_CRYPTO_METHOD **curve_crypto_list = NX_NULL;
507 USHORT *supported_groups = NX_NULL;
508 USHORT ecc_curves_count = 0;
509 UINT supported_groups_bytes;
510 #endif
511
512 #if (NX_SECURE_TLS_TLS_1_0_ENABLED || NX_SECURE_TLS_TLS_1_1_ENABLED)
513 const NX_CRYPTO_METHOD *crypto_method_md5;
514 const NX_CRYPTO_METHOD *crypto_method_sha1;
515 ULONG metadata_size_md5 = 0;
516 ULONG metadata_size_sha1 = 0;
517 #endif
518
519 #if (NX_SECURE_TLS_TLS_1_2_ENABLED)
520 const NX_CRYPTO_METHOD *crypto_method_sha256;
521 ULONG metadata_size_sha256 = 0;
522 #endif
523
524 /* Get a working pointer to the metadata buffer. */
525 metadata_area = (CHAR*)metadata_buffer;
526
527 /* Check and adjust metadata for four byte alignment. */
528 if (((ULONG)metadata_area) & 0x3)
529 {
530 if (metadata_size < 4 - (((ULONG)metadata_area) & 0x3))
531 {
532 return(NX_SECURE_TLS_INSUFFICIENT_METADATA_SPACE);
533 }
534
535 metadata_size -= 4 - (((ULONG)metadata_area) & 0x3);
536 metadata_area += 4 - (((ULONG)metadata_area) & 0x3);
537 }
538
539 if((crypto_array == NX_NULL) || (cipher_map == NX_NULL))
540 {
541
542 /* Coming from the old-style API. Don't allocate crypto table. */
543 crypto_table = tls_session->nx_secure_tls_crypto_table;
544
545 if (crypto_table == NX_NULL)
546 {
547 return(NX_PTR_ERROR);
548 }
549
550 /* Start by assuming all versions are enabled, remove versions without the appropriate ciphers. */
551 tls_session->nx_secure_tls_supported_versions = NX_SECURE_TLS_BITFIELD_VERSIONS_ALL;
552 }
553 else
554 {
555 NX_SECURE_MEMSET(tls_session, 0, sizeof(NX_SECURE_TLS_SESSION));
556
557 /* Start by assuming all versions are enabled, remove versions without the appropriate ciphers. */
558 tls_session->nx_secure_tls_supported_versions = NX_SECURE_TLS_BITFIELD_VERSIONS_ALL;
559
560 /* Make sure we can allocate our crypto table. */
561 if(metadata_size < sizeof(NX_SECURE_TLS_CRYPTO))
562 {
563 return(NX_SECURE_TLS_INSUFFICIENT_METADATA_SPACE);
564 }
565
566 /* Carve out space for our dynamic crypto table. */
567 tls_session->nx_secure_tls_crypto_table = (NX_SECURE_TLS_CRYPTO *)(&metadata_area[0]);
568
569 /* Advance the metadata buffer pointer. */
570 metadata_area += sizeof(NX_SECURE_TLS_CRYPTO);
571 metadata_size -= sizeof(NX_SECURE_TLS_CRYPTO);
572
573 /* Get a working pointer to our newly-allocated crypto table. */
574 crypto_table = tls_session->nx_secure_tls_crypto_table;
575
576 /* Allocate space for our ciphersuite lookup table prior to mapping crypto methods. */
577 crypto_table->nx_secure_tls_ciphersuite_lookup_table = (NX_SECURE_TLS_CIPHERSUITE_INFO*)(&metadata_area[0]);
578 crypto_table->nx_secure_tls_ciphersuite_lookup_table_size = 0;
579
580 /* Map crypto methods to TLS ciphersuites. */
581 cipher_table_bytes = metadata_size;
582 status = _map_tls_ciphersuites(tls_session, crypto_array, crypto_array_size, cipher_map, cipher_map_size, &cipher_table_bytes);
583
584 if(status != NX_SUCCESS)
585 {
586 return(status);
587 }
588
589 /* Update metadata pointers. */
590 metadata_area += cipher_table_bytes;
591 metadata_size -= cipher_table_bytes;
592 cipher_table_bytes = metadata_size;
593
594 #ifndef NX_SECURE_DISABLE_X509
595
596 /* Carve out space for our dynamic X.509 ciphersuite table. */
597 crypto_table->nx_secure_tls_x509_cipher_table = (NX_SECURE_X509_CRYPTO*)(&metadata_area[0]);
598 crypto_table->nx_secure_tls_x509_cipher_table_size = 0;
599
600 /* Map crypto methods to X.509 ciphersuites. */
601 status = _map_x509_ciphersuites(tls_session, crypto_array, crypto_array_size, cipher_map, cipher_map_size, &cipher_table_bytes);
602
603 if(status != NX_SUCCESS)
604 {
605 return(status);
606 }
607
608
609 /* Advance the metadata area past the end of the crypto table. */
610 metadata_area += cipher_table_bytes;
611 metadata_size -= cipher_table_bytes;
612 #endif
613
614 #ifdef NX_SECURE_ENABLE_ECC_CIPHERSUITE
615 curve_crypto_list = (NX_CRYPTO_METHOD **)(&metadata_area[0]);
616
617 /* Find ECC curves in the crypto array. */
618 for (i = 0; i < crypto_array_size; i++)
619 {
620 if ((crypto_array[i] -> nx_crypto_algorithm & 0xFFFF0000) == NX_CRYPTO_EC_MASK)
621 {
622 if (metadata_size < sizeof(NX_CRYPTO_METHOD *))
623 {
624 return(NX_SECURE_TLS_INSUFFICIENT_METADATA_SPACE);
625 }
626 curve_crypto_list[ecc_curves_count] = (NX_CRYPTO_METHOD *)crypto_array[i];
627 ecc_curves_count++;
628 metadata_size -= sizeof(NX_CRYPTO_METHOD *);
629 }
630 }
631
632 if (ecc_curves_count > 0)
633 {
634 metadata_area += ecc_curves_count * sizeof(NX_CRYPTO_METHOD *);
635 supported_groups = (USHORT *)(&metadata_area[0]);
636
637 supported_groups_bytes = ecc_curves_count * sizeof(USHORT);
638
639 /* Align length to 4 bytes. */
640 if (supported_groups_bytes & 0x3)
641 {
642 supported_groups_bytes += 4 - (supported_groups_bytes & 0x3);
643 }
644
645 if (metadata_size < supported_groups_bytes)
646 {
647 return(NX_SECURE_TLS_INSUFFICIENT_METADATA_SPACE);
648 }
649
650 metadata_area += supported_groups_bytes;
651 metadata_size -= supported_groups_bytes;
652
653 for (i = 0; i < ecc_curves_count; i++)
654 {
655 supported_groups[i] = (USHORT)(curve_crypto_list[i] -> nx_crypto_algorithm & 0xFFFF);
656 }
657
658 _nx_secure_tls_ecc_initialize(tls_session, supported_groups, ecc_curves_count, (const NX_CRYPTO_METHOD **)curve_crypto_list);
659 }
660 #endif
661
662 }
663
664 /* Get working pointers to our crypto methods. */
665 ciphersuite_table = crypto_table -> nx_secure_tls_ciphersuite_lookup_table;
666 ciphersuite_table_size = crypto_table -> nx_secure_tls_ciphersuite_lookup_table_size;
667
668 #if (NX_SECURE_TLS_TLS_1_0_ENABLED || NX_SECURE_TLS_TLS_1_1_ENABLED)
669 crypto_method_md5 = crypto_table -> nx_secure_tls_handshake_hash_md5_method;
670 crypto_method_sha1 = crypto_table -> nx_secure_tls_handshake_hash_sha1_method;
671
672 if (crypto_method_md5 != NX_NULL)
673 {
674 metadata_size_md5 = crypto_method_md5 -> nx_crypto_metadata_area_size;
675
676 /* Align metadata size to four bytes. */
677 if (metadata_size_md5 & 0x3)
678 {
679 metadata_size_md5 += 4 - (metadata_size_md5 & 0x3);
680 }
681 }
682
683 if (crypto_method_sha1 != NX_NULL)
684 {
685 metadata_size_sha1 = crypto_method_sha1 -> nx_crypto_metadata_area_size;
686
687 if (metadata_size_sha1 & 0x3)
688 {
689 metadata_size_sha1 += 4 - (metadata_size_sha1 & 0x3);
690 }
691 }
692 #endif
693 #if (NX_SECURE_TLS_TLS_1_2_ENABLED)
694 crypto_method_sha256 = crypto_table -> nx_secure_tls_handshake_hash_sha256_method;
695 if (crypto_method_sha256 != NX_NULL)
696 {
697 metadata_size_sha256 = crypto_method_sha256 -> nx_crypto_metadata_area_size;
698
699 if (metadata_size_sha256 & 0x3)
700 {
701 metadata_size_sha256 += 4 - (metadata_size_sha256 & 0x3);
702 }
703 }
704 #endif
705 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
706 tls_session -> nx_secure_tls_1_3_supported = NX_FALSE;
707 #endif
708
709 /* Loop through the ciphersuite table and find the largest metadata for each type of cipher. */
710 for (i = 0; i < ciphersuite_table_size; ++i)
711 {
712 if (max_public_cipher_metadata_size < ciphersuite_table[i].nx_secure_tls_public_cipher -> nx_crypto_metadata_area_size)
713 {
714 max_public_cipher_metadata_size = ciphersuite_table[i].nx_secure_tls_public_cipher -> nx_crypto_metadata_area_size;
715 }
716
717 if (max_public_auth_metadata_size < ciphersuite_table[i].nx_secure_tls_public_auth -> nx_crypto_metadata_area_size)
718 {
719 max_public_auth_metadata_size = ciphersuite_table[i].nx_secure_tls_public_auth -> nx_crypto_metadata_area_size;
720 }
721
722 if (max_session_cipher_metadata_size < ciphersuite_table[i].nx_secure_tls_session_cipher -> nx_crypto_metadata_area_size)
723 {
724 max_session_cipher_metadata_size = ciphersuite_table[i].nx_secure_tls_session_cipher -> nx_crypto_metadata_area_size;
725 }
726
727 if (max_tls_prf_metadata_size < ciphersuite_table[i].nx_secure_tls_prf -> nx_crypto_metadata_area_size)
728 {
729 max_tls_prf_metadata_size = ciphersuite_table[i].nx_secure_tls_prf -> nx_crypto_metadata_area_size;
730 }
731
732 if (max_hash_mac_metadata_size < ciphersuite_table[i].nx_secure_tls_hash -> nx_crypto_metadata_area_size)
733 {
734 max_hash_mac_metadata_size = ciphersuite_table[i].nx_secure_tls_hash -> nx_crypto_metadata_area_size;
735 }
736
737 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
738 if ((ciphersuite_table[i].nx_secure_tls_ciphersuite >> 8) == 0x13)
739 {
740
741 /* Enable TLS 1.3 only if the ciphersuite required by RFC 8446 is provided. */
742 tls_session->nx_secure_tls_1_3_supported = NX_TRUE;
743 }
744 #endif
745 }
746
747 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
748 tls_session -> nx_secure_tls_1_3 = tls_session -> nx_secure_tls_1_3_supported;
749 #endif
750
751 #ifndef NX_SECURE_DISABLE_X509
752 cert_crypto = crypto_table->nx_secure_tls_x509_cipher_table;
753 cert_crypto_size = crypto_table->nx_secure_tls_x509_cipher_table_size;
754
755 /* Loop through the certificate cipher table as well. */
756 for (i = 0; i < cert_crypto_size; ++i)
757 {
758 if (max_public_auth_metadata_size < cert_crypto[i].nx_secure_x509_public_cipher_method -> nx_crypto_metadata_area_size)
759 {
760 max_public_auth_metadata_size = cert_crypto[i].nx_secure_x509_public_cipher_method -> nx_crypto_metadata_area_size;
761 }
762
763 if (max_hash_mac_metadata_size < cert_crypto[i].nx_secure_x509_hash_method -> nx_crypto_metadata_area_size)
764 {
765 max_hash_mac_metadata_size = cert_crypto[i].nx_secure_x509_hash_method -> nx_crypto_metadata_area_size;
766 }
767
768 if (max_handshake_hash_scratch_size < cert_crypto[i].nx_secure_x509_hash_method -> nx_crypto_metadata_area_size)
769 {
770 max_handshake_hash_scratch_size = cert_crypto[i].nx_secure_x509_hash_method -> nx_crypto_metadata_area_size;
771 }
772 }
773 #endif
774
775 /* We also need metadata space for the TLS handshake hash, so add that into the total.
776 We need some scratch space to copy the handshake hash metadata during final hash generation
777 so figure out the largest metadata between SHA-1+MD5 (TLSv1.0, 1.1) and SHA256 (TLSv1.2). */
778 #if (NX_SECURE_TLS_TLS_1_0_ENABLED || NX_SECURE_TLS_TLS_1_1_ENABLED)
779 if (tls_session -> nx_secure_tls_supported_versions & (USHORT)(NX_SECURE_TLS_BITFIELD_VERSION_1_0 | NX_SECURE_TLS_BITFIELD_VERSION_1_1))
780 {
781 max_handshake_hash_metadata_size += (metadata_size_md5 + metadata_size_sha1);
782 if (max_handshake_hash_scratch_size < metadata_size_md5 + metadata_size_sha1)
783 {
784 max_handshake_hash_scratch_size = metadata_size_md5 + metadata_size_sha1;
785 }
786
787 if (crypto_table -> nx_secure_tls_prf_1_method != NX_NULL)
788 {
789 if (max_tls_prf_metadata_size < crypto_table -> nx_secure_tls_prf_1_method -> nx_crypto_metadata_area_size)
790 {
791 max_tls_prf_metadata_size = crypto_table -> nx_secure_tls_prf_1_method -> nx_crypto_metadata_area_size;
792 }
793 }
794 }
795 #endif
796 #if (NX_SECURE_TLS_TLS_1_2_ENABLED)
797 max_handshake_hash_metadata_size += metadata_size_sha256;
798
799 /* See if the scratch size from above is bigger. */
800 if (max_handshake_hash_scratch_size < metadata_size_sha256)
801 {
802 max_handshake_hash_scratch_size = metadata_size_sha256;
803 }
804
805 if ((crypto_table -> nx_secure_tls_prf_sha256_method != NX_NULL) &&
806 (max_tls_prf_metadata_size < crypto_table -> nx_secure_tls_prf_sha256_method -> nx_crypto_metadata_area_size))
807 {
808 max_tls_prf_metadata_size = crypto_table -> nx_secure_tls_prf_sha256_method -> nx_crypto_metadata_area_size;
809 }
810 #endif
811
812 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
813 if (crypto_table -> nx_secure_tls_hmac_method != NX_NULL)
814 {
815 max_handshake_hash_scratch_size += crypto_table -> nx_secure_tls_hmac_method -> nx_crypto_metadata_area_size;
816 }
817
818 if (crypto_table -> nx_secure_tls_hkdf_method != NX_NULL)
819 {
820 if (max_tls_prf_metadata_size < crypto_table -> nx_secure_tls_hkdf_method -> nx_crypto_metadata_area_size)
821 {
822 max_tls_prf_metadata_size = crypto_table -> nx_secure_tls_hkdf_method -> nx_crypto_metadata_area_size;
823 }
824 }
825 #endif
826
827 /* The public cipher and authentication should never be used simultaneously, so it should be OK
828 to share their metadata areas. */
829 if (max_public_cipher_metadata_size < max_public_auth_metadata_size)
830 {
831 max_public_cipher_metadata_size = max_public_auth_metadata_size;
832 }
833
834 /* Check and adjust every metadata sizes for four byte alignment. */
835 if (max_public_cipher_metadata_size & 0x3)
836 {
837 max_public_cipher_metadata_size += 4 - (max_public_cipher_metadata_size & 0x3);
838 }
839 if (max_session_cipher_metadata_size & 0x3)
840 {
841 max_session_cipher_metadata_size += 4 - (max_session_cipher_metadata_size & 0x3);
842 }
843 if (max_hash_mac_metadata_size & 0x3)
844 {
845 max_hash_mac_metadata_size += 4 - (max_hash_mac_metadata_size & 0x3);
846 }
847 if (max_tls_prf_metadata_size & 0x3)
848 {
849 max_tls_prf_metadata_size += 4 - (max_tls_prf_metadata_size & 0x3);
850 }
851 if (max_handshake_hash_scratch_size & 0x3)
852 {
853 max_handshake_hash_scratch_size += 4 - (max_handshake_hash_scratch_size & 0x3);
854 }
855
856 /* The Total metadata size needed is the sum of all the maximums calculated above.
857 We need to keep track of two separate session cipher states, one for the server and one for the client,
858 so account for that extra space. */
859 max_total_metadata_size = max_public_cipher_metadata_size +
860 (2 * max_session_cipher_metadata_size) +
861 max_hash_mac_metadata_size +
862 max_tls_prf_metadata_size +
863 max_handshake_hash_metadata_size +
864 max_handshake_hash_scratch_size;
865
866 /* Check if the caller provided enough metadata space. */
867 if (max_total_metadata_size > metadata_size)
868 {
869 return(NX_INVALID_PARAMETERS);
870 }
871
872 /* Get the protection. */
873 tx_mutex_get(&_nx_secure_tls_protection, TX_WAIT_FOREVER);
874
875 #ifndef NX_SECURE_DISABLE_X509
876
877 /* Clear out the X509 certificate stores when we create a new TLS Session. */
878 tls_session -> nx_secure_tls_credentials.nx_secure_tls_certificate_store.nx_secure_x509_remote_certificates = NX_NULL;
879 tls_session -> nx_secure_tls_credentials.nx_secure_tls_certificate_store.nx_secure_x509_local_certificates = NX_NULL;
880 tls_session -> nx_secure_tls_credentials.nx_secure_tls_certificate_store.nx_secure_x509_trusted_certificates = NX_NULL;
881 tls_session -> nx_secure_tls_credentials.nx_secure_tls_active_certificate = NX_NULL;
882 #endif
883
884 /* Release the protection. */
885 tx_mutex_put(&_nx_secure_tls_protection);
886
887 /* Initialize/reset all the other TLS state. */
888 _nx_secure_tls_session_reset(tls_session);
889
890 /* Get the protection. */
891 tx_mutex_get(&_nx_secure_tls_protection, TX_WAIT_FOREVER);
892
893 /* Now allocate cipher metadata space from our calculated numbers above. */
894 offset = 0;
895
896 /* Handshake hash metadata. */
897 #if (NX_SECURE_TLS_TLS_1_0_ENABLED || NX_SECURE_TLS_TLS_1_1_ENABLED)
898 if (tls_session -> nx_secure_tls_supported_versions & (USHORT)(NX_SECURE_TLS_BITFIELD_VERSION_1_0 | NX_SECURE_TLS_BITFIELD_VERSION_1_1))
899 {
900 tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_md5_metadata = &metadata_area[offset];
901 tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_md5_metadata_size = metadata_size_md5;
902 offset += metadata_size_md5;
903
904 tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_sha1_metadata = &metadata_area[offset];
905 tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_sha1_metadata_size = metadata_size_sha1;
906 offset += metadata_size_sha1;
907 }
908 #endif
909
910 #if NX_SECURE_TLS_TLS_1_2_ENABLED
911 tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_sha256_metadata = &metadata_area[offset];
912 tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_sha256_metadata_size = metadata_size_sha256;
913 offset += metadata_size_sha256;
914 #endif
915
916 tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_scratch = &metadata_area[offset];
917 tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_scratch_size = max_handshake_hash_scratch_size;
918 offset += max_handshake_hash_scratch_size;
919
920 /* Client and server session cipher metadata. */
921 tls_session -> nx_secure_session_cipher_metadata_size = max_session_cipher_metadata_size;
922
923 tls_session -> nx_secure_session_cipher_metadata_area_client = &metadata_area[offset];
924 offset += max_session_cipher_metadata_size;
925
926 tls_session -> nx_secure_session_cipher_metadata_area_server = &metadata_area[offset];
927 offset += max_session_cipher_metadata_size;
928
929 /* Public cipher metadata. */
930 tls_session -> nx_secure_public_cipher_metadata_area = &metadata_area[offset];
931 tls_session -> nx_secure_public_cipher_metadata_size = max_public_cipher_metadata_size;
932 offset += max_public_cipher_metadata_size;
933
934 /* Public authentication metadata. For now it shares space with the public cipher. */
935 tls_session -> nx_secure_public_auth_metadata_area = tls_session -> nx_secure_public_cipher_metadata_area;
936 tls_session -> nx_secure_public_auth_metadata_size = max_public_cipher_metadata_size;
937
938 /* Hash MAC metadata. */
939 tls_session -> nx_secure_hash_mac_metadata_area = &metadata_area[offset];
940 tls_session -> nx_secure_hash_mac_metadata_size = max_hash_mac_metadata_size;
941 offset += max_hash_mac_metadata_size;
942
943 /* TLS PRF metadata. */
944 tls_session -> nx_secure_tls_prf_metadata_area = &metadata_area[offset];
945 tls_session -> nx_secure_tls_prf_metadata_size = max_tls_prf_metadata_size;
946
947 /* Place the new TLS control block on the list of created TLS. */
948 if (_nx_secure_tls_created_ptr)
949 {
950
951 /* Pickup tail pointer. */
952 tail_ptr = _nx_secure_tls_created_ptr -> nx_secure_tls_created_previous;
953
954 /* Place the new TLS control block in the list. */
955 _nx_secure_tls_created_ptr -> nx_secure_tls_created_previous = tls_session;
956 tail_ptr -> nx_secure_tls_created_next = tls_session;
957
958 /* Setup this TLS's created links. */
959 tls_session -> nx_secure_tls_created_previous = tail_ptr;
960 tls_session -> nx_secure_tls_created_next = _nx_secure_tls_created_ptr;
961 }
962 else
963 {
964
965 /* The created TLS list is empty. Add TLS control block to empty list. */
966 _nx_secure_tls_created_ptr = tls_session;
967 tls_session -> nx_secure_tls_created_previous = tls_session;
968 tls_session -> nx_secure_tls_created_next = tls_session;
969 }
970 _nx_secure_tls_created_count++;
971
972 #ifndef NX_SECURE_TLS_DISABLE_SECURE_RENEGOTIATION
973 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
974 /* Flag to indicate when a session renegotiation is enabled. Enabled by default. */
975 if (tls_session -> nx_secure_tls_1_3)
976 {
977 tls_session -> nx_secure_tls_renegotation_enabled = NX_FALSE;
978 }
979 else
980 #endif
981 {
982 tls_session -> nx_secure_tls_renegotation_enabled = NX_TRUE;
983 }
984 #endif /* NX_SECURE_TLS_DISABLE_SECURE_RENEGOTIATION */
985
986 /* Set the secret generation functions to the default implementation. */
987 tls_session -> nx_secure_generate_premaster_secret = _nx_secure_generate_premaster_secret;
988 tls_session -> nx_secure_generate_master_secret = _nx_secure_generate_master_secret;
989 tls_session -> nx_secure_generate_session_keys = _nx_secure_generate_session_keys;
990 tls_session -> nx_secure_session_keys_set = _nx_secure_session_keys_set;
991 #ifndef NX_SECURE_TLS_CLIENT_DISABLED
992 tls_session -> nx_secure_process_server_key_exchange = _nx_secure_process_server_key_exchange;
993 tls_session -> nx_secure_generate_client_key_exchange = _nx_secure_generate_client_key_exchange;
994 #endif
995 #ifndef NX_SECURE_TLS_SERVER_DISABLED
996 tls_session -> nx_secure_process_client_key_exchange = _nx_secure_process_client_key_exchange;
997 tls_session -> nx_secure_generate_server_key_exchange = _nx_secure_generate_server_key_exchange;
998 #endif
999 tls_session -> nx_secure_verify_mac = _nx_secure_verify_mac;
1000 tls_session -> nx_secure_remote_certificate_verify = _nx_secure_remote_certificate_verify;
1001 tls_session -> nx_secure_trusted_certificate_add = _nx_secure_trusted_certificate_add;
1002
1003 #ifdef NX_SECURE_CUSTOM_SECRET_GENERATION
1004
1005 /* Customized secret generation functions can be set by the user in nx_secure_custom_secret_generation_init. */
1006 status = nx_secure_custom_secret_generation_init(tls_session);
1007 if (status != NX_SUCCESS)
1008 {
1009 return(status);
1010 }
1011 #endif
1012
1013 /* Set ID to check initialization status. */
1014 tls_session -> nx_secure_tls_id = NX_SECURE_TLS_ID;
1015
1016 /* Create the mutex used for TLS session while transmitting packets. */
1017 tx_mutex_create(&(tls_session -> nx_secure_tls_session_transmit_mutex), "TLS transmit mutex", TX_NO_INHERIT);
1018
1019 /* Release the protection. */
1020 tx_mutex_put(&_nx_secure_tls_protection);
1021
1022 return(NX_SUCCESS);
1023 }
1024
1025