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 #ifndef NX_SECURE_TLS_CLIENT_DISABLED
27
28 #ifndef NX_SECURE_DISABLE_X509
29 static VOID _nx_secure_tls_get_signature_algorithm(NX_SECURE_TLS_SESSION *tls_session,
30 NX_SECURE_X509_CRYPTO *crypto_method,
31 USHORT *signature_algorithm);
32
33 static UINT _nx_secure_tls_send_clienthello_sig_extension(NX_SECURE_TLS_SESSION *tls_session,
34 UCHAR *packet_buffer, ULONG *packet_offset,
35 USHORT *extension_length,
36 ULONG available_size);
37 #endif
38 #ifndef NX_SECURE_TLS_SNI_EXTENSION_DISABLED
39 static UINT _nx_secure_tls_send_clienthello_sni_extension(NX_SECURE_TLS_SESSION *tls_session,
40 UCHAR *packet_buffer, ULONG *packet_offset,
41 USHORT *extension_length,
42 ULONG available_size);
43 #endif
44 #ifdef NX_SECURE_ENABLE_ECC_CIPHERSUITE
45 static UINT _nx_secure_tls_send_clienthello_sec_spf_extensions(NX_SECURE_TLS_SESSION *tls_session,
46 UCHAR *packet_buffer, ULONG *packet_offset,
47 USHORT *extension_length,
48 ULONG available_size);
49 #endif
50
51 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
52 static UINT _nx_secure_tls_send_clienthello_supported_versions_extension(NX_SECURE_TLS_SESSION *tls_session,
53 UCHAR *packet_buffer, ULONG *packet_offset,
54 USHORT *extension_length,
55 ULONG available_size);
56
57 static UINT _nx_secure_tls_send_clienthello_key_share_extension(NX_SECURE_TLS_SESSION *tls_session,
58 UCHAR *packet_buffer, ULONG *packet_offset,
59 USHORT *extension_length,
60 ULONG available_size);
61
62 static UINT _nx_secure_tls_send_clienthello_psk_kem_extension(NX_SECURE_TLS_SESSION *tls_session,
63 UCHAR *packet_buffer, ULONG *packet_length,
64 USHORT *extension_length);
65
66 /* Note: PSK extension generation is called directly, so not static. */
67 UINT _nx_secure_tls_send_clienthello_psk_extension(NX_SECURE_TLS_SESSION *tls_session,
68 UCHAR *packet_buffer, ULONG *packet_length,
69 ULONG extension_length_offset, ULONG total_extensions_length,
70 ULONG *extension_length,
71 ULONG available_size);
72 #endif
73
74 #ifndef NX_SECURE_TLS_DISABLE_SECURE_RENEGOTIATION
75 static UINT _nx_secure_tls_send_clienthello_sec_reneg_extension(NX_SECURE_TLS_SESSION *tls_session,
76 UCHAR *packet_buffer,
77 ULONG *packet_offset,
78 USHORT *extension_length,
79 ULONG available_size);
80 #endif
81
82
83 /**************************************************************************/
84 /* */
85 /* FUNCTION RELEASE */
86 /* */
87 /* _nx_secure_tls_send_clienthello_extensions PORTABLE C */
88 /* 6.2.1 */
89 /* AUTHOR */
90 /* */
91 /* Timothy Stapko, Microsoft Corporation */
92 /* */
93 /* DESCRIPTION */
94 /* */
95 /* This function populates an NX_PACKET with ClientHello extensions, */
96 /* which provide additional information to the remote host for the */
97 /* initial handshake negotiations. */
98 /* */
99 /* INPUT */
100 /* */
101 /* tls_session TLS control block */
102 /* packet_buffer Outgoing TLS packet */
103 /* packet_offset Offset into packet buffer */
104 /* extensions_length Return total extension length */
105 /* available_size Available size of buffer */
106 /* */
107 /* OUTPUT */
108 /* */
109 /* status Completion status */
110 /* */
111 /* CALLS */
112 /* */
113 /* _nx_secure_tls_send_clienthello_sec_reneg_extension */
114 /* Send ClientHello Renegotiation*/
115 /* extension */
116 /* _nx_secure_tls_send_clienthello_sig_extension */
117 /* Send ClientHello Signature */
118 /* extension */
119 /* _nx_secure_tls_send_clienthello_sni_extension */
120 /* Send ClientHello SNI extension*/
121 /* _nx_secure_tls_send_clienthello_ec_extension */
122 /* Send ClientHello EC extension */
123 /* */
124 /* CALLED BY */
125 /* */
126 /* _nx_secure_tls_send_clienthello Send TLS ClientHello */
127 /* */
128 /* RELEASE HISTORY */
129 /* */
130 /* DATE NAME DESCRIPTION */
131 /* */
132 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
133 /* 09-30-2020 Timothy Stapko Modified comment(s), */
134 /* verified memcpy use cases, */
135 /* fixed renegotiation bug, */
136 /* resulting in version 6.1 */
137 /* 04-25-2022 Yajun Xia Modified comment(s), */
138 /* added exception case, */
139 /* resulting in version 6.1.11 */
140 /* 03-08-2023 Yanwu Cai Modified comment(s), */
141 /* fixed compiler errors when */
142 /* x509 is disabled, */
143 /* resulting in version 6.2.1 */
144 /* */
145 /**************************************************************************/
_nx_secure_tls_send_clienthello_extensions(NX_SECURE_TLS_SESSION * tls_session,UCHAR * packet_buffer,ULONG * packet_offset,ULONG * extensions_length,ULONG available_size)146 UINT _nx_secure_tls_send_clienthello_extensions(NX_SECURE_TLS_SESSION *tls_session,
147 UCHAR *packet_buffer, ULONG *packet_offset,
148 ULONG *extensions_length, ULONG available_size)
149 {
150 ULONG length = *packet_offset;
151 USHORT extension_length = 0, total_extensions_length;
152 UINT status;
153
154 total_extensions_length = 0;
155
156
157 #ifdef NX_SECURE_ENABLE_ECC_CIPHERSUITE
158 status = _nx_secure_tls_send_clienthello_sec_spf_extensions(tls_session,
159 packet_buffer,
160 &length,
161 &extension_length,
162 available_size);
163 if (status != NX_SUCCESS)
164 {
165 return(status);
166 }
167 total_extensions_length = (USHORT)(total_extensions_length + extension_length);
168 #endif
169
170 #ifndef NX_SECURE_TLS_DISABLE_SECURE_RENEGOTIATION
171 /* We have to add renegotiation extensions in both initial sessions and renegotiating sessions. */
172 if (tls_session -> nx_secure_tls_renegotation_enabled == NX_TRUE)
173 {
174 status = _nx_secure_tls_send_clienthello_sec_reneg_extension(tls_session, packet_buffer, &length, &extension_length, available_size);
175 if(status != NX_SUCCESS)
176 {
177 return(status);
178 }
179 total_extensions_length = (USHORT)(total_extensions_length + extension_length);
180 }
181 #endif
182
183 /* We can't do TLS 1.3 without ECC. */
184 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
185 if(tls_session->nx_secure_tls_1_3)
186 {
187 /* Send supported TLS versions extensions (for TLS 1.3). */
188 status = _nx_secure_tls_send_clienthello_supported_versions_extension(tls_session, packet_buffer, &length, &extension_length, available_size);
189 if(status != NX_SUCCESS)
190 {
191 return(status);
192 }
193 total_extensions_length = (USHORT)(total_extensions_length + extension_length);
194
195 /* Send KeyShare extension (for TLS 1.3). */
196 _nx_secure_tls_send_clienthello_key_share_extension(tls_session, packet_buffer, &length, &extension_length, available_size);
197 if(status != NX_SUCCESS)
198 {
199 return(status);
200 }
201 total_extensions_length = (USHORT)(total_extensions_length + extension_length);
202
203 /* Including a "cookie" extension if one was provided in the HelloRetryRequest. */
204 if ((tls_session -> nx_secure_tls_client_state == NX_SECURE_TLS_CLIENT_STATE_HELLO_RETRY) &&
205 (tls_session -> nx_secure_tls_cookie_length != 0))
206 {
207
208 /* Add Extension Type. */
209 packet_buffer[length] = (UCHAR)((NX_SECURE_TLS_EXTENSION_COOKIE) >> 8);
210 packet_buffer[length + 1] = (UCHAR)(NX_SECURE_TLS_EXTENSION_COOKIE);
211 length += 2;
212
213 /* Add Extension Length. */
214 extension_length = (USHORT)(tls_session -> nx_secure_tls_cookie_length + 2);
215 packet_buffer[length] = (UCHAR)(extension_length >> 8);
216 packet_buffer[length + 1] = (UCHAR)(extension_length);
217 length += 2;
218
219 /* Add Cookie Length. */
220 packet_buffer[length] = (UCHAR)(tls_session -> nx_secure_tls_cookie_length >> 8);
221 packet_buffer[length + 1] = (UCHAR)(tls_session -> nx_secure_tls_cookie_length);
222 length += 2;
223
224 /* Add Cookie. */
225 NX_SECURE_MEMCPY(&packet_buffer[length], tls_session -> nx_secure_tls_cookie, tls_session -> nx_secure_tls_cookie_length); /* Use case of memcpy is verified. */
226 length += (tls_session -> nx_secure_tls_cookie_length);
227
228 /* Update total extensions length and reset the stored cookie length. */
229 total_extensions_length = (USHORT)(total_extensions_length + extension_length + 4);
230 tls_session -> nx_secure_tls_cookie_length = 0;
231 }
232 }
233 #endif
234
235 #ifndef NX_SECURE_DISABLE_X509
236
237 /* RFC 5246 7.4.1.4.1 Signature Algorithm:
238 Note: this extension is not meaningful for TLS versions prior to 1.2.
239 Clients MUST NOT offer it if they are offering prior versions. */
240 if (tls_session -> nx_secure_tls_protocol_version == NX_SECURE_TLS_VERSION_TLS_1_2)
241 {
242
243 /* Send the available signature algorithms extension. */
244 status = _nx_secure_tls_send_clienthello_sig_extension(tls_session, packet_buffer, &length, &extension_length, available_size);
245 if (status != NX_SUCCESS)
246 {
247 return(status);
248 }
249 total_extensions_length = (USHORT)(total_extensions_length + extension_length);
250 }
251 #endif
252
253 #ifndef NX_SECURE_TLS_SNI_EXTENSION_DISABLED
254 /* Send the server name indication extension. */
255 status = _nx_secure_tls_send_clienthello_sni_extension(tls_session, packet_buffer, &length, &extension_length, available_size);
256 if(status != NX_SUCCESS)
257 {
258 return(status);
259 }
260 total_extensions_length = (USHORT)(total_extensions_length + extension_length);
261 #endif
262
263 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
264 if(tls_session->nx_secure_tls_1_3 && tls_session->nx_secure_tls_credentials.nx_secure_tls_psk_count > 0)
265 {
266 status = _nx_secure_tls_send_clienthello_psk_kem_extension(tls_session, packet_buffer, &length, &extension_length);
267 if (status != NX_SUCCESS)
268 {
269 return(status);
270 }
271 total_extensions_length = (USHORT)(total_extensions_length + extension_length);
272 }
273 #endif
274
275 *extensions_length = total_extensions_length;
276 *packet_offset = length;
277
278
279 return(NX_SUCCESS);
280 }
281
282
283
284 /**************************************************************************/
285 /* */
286 /* FUNCTION RELEASE */
287 /* */
288 /* _nx_secure_tls_send_clienthello_sig_extension PORTABLE C */
289 /* 6.1.11 */
290 /* AUTHOR */
291 /* */
292 /* Timothy Stapko, Microsoft Corporation */
293 /* */
294 /* DESCRIPTION */
295 /* */
296 /* This function adds the Signature Algorithms extension to an */
297 /* outgoing ClientHello record. See RFC 5246 section 7.4.1.4.1. */
298 /* */
299 /* INPUT */
300 /* */
301 /* tls_session TLS control block */
302 /* packet_buffer Outgoing TLS packet buffer */
303 /* packet_offset Offset into packet buffer */
304 /* extension_length Return length of data */
305 /* available_size Available size of buffer */
306 /* */
307 /* OUTPUT */
308 /* */
309 /* status Completion status */
310 /* */
311 /* CALLS */
312 /* */
313 /* None */
314 /* */
315 /* CALLED BY */
316 /* */
317 /* _nx_secure_tls_send_clienthello_extensions */
318 /* Send TLS ClientHello extension*/
319 /* */
320 /* RELEASE HISTORY */
321 /* */
322 /* DATE NAME DESCRIPTION */
323 /* */
324 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
325 /* 09-30-2020 Timothy Stapko Modified comment(s), */
326 /* resulting in version 6.1 */
327 /* 04-25-2022 Yuxin Zhou Modified comment(s), */
328 /* removed unused code, */
329 /* resulting in version 6.1.11 */
330 /* */
331 /**************************************************************************/
332 #ifndef NX_SECURE_DISABLE_X509
_nx_secure_tls_send_clienthello_sig_extension(NX_SECURE_TLS_SESSION * tls_session,UCHAR * packet_buffer,ULONG * packet_offset,USHORT * extension_length,ULONG available_size)333 static UINT _nx_secure_tls_send_clienthello_sig_extension(NX_SECURE_TLS_SESSION *tls_session,
334 UCHAR *packet_buffer, ULONG *packet_offset,
335 USHORT *extension_length,
336 ULONG available_size)
337 {
338 ULONG offset, ext_pos;
339 USHORT ext_len, sig_len, sighash_len, ext;
340 UINT i;
341 USHORT signature_algorithm;
342 NX_SECURE_X509_CRYPTO *cipher_table;
343
344 /* Signature Extensions structure:
345 * | 2 | 2 | 2 | <SigHash Len> |
346 * | Ext Type | Sig Len | SigHash Len | SigHash Algos |
347 *
348 * Each algorithm pair has a hash ID and a public key operation ID represented
349 * by a single octet. Therefore each entry in the list is 2 bytes long.
350 */
351
352 if (available_size < (*packet_offset + 6u +
353 (ULONG)(tls_session -> nx_secure_tls_crypto_table -> nx_secure_tls_x509_cipher_table_size << 1)))
354 {
355
356 /* Packet buffer too small. */
357 return(NX_SECURE_TLS_PACKET_BUFFER_TOO_SMALL);
358 }
359
360 /* Start with our passed-in packet offset. */
361 offset = *packet_offset;
362
363 ext_pos = offset;
364 offset += 6;
365
366 ext_len = sighash_len = 0;
367
368 cipher_table = tls_session -> nx_secure_tls_crypto_table -> nx_secure_tls_x509_cipher_table;
369
370 /* Loop the x509 cipher table to add signature algorithms. */
371 for (i = 0; i < tls_session -> nx_secure_tls_crypto_table -> nx_secure_tls_x509_cipher_table_size; i++)
372 {
373
374 /* Map crypto method to signature algorithm. */
375 _nx_secure_tls_get_signature_algorithm(tls_session, &cipher_table[i], &signature_algorithm);
376 if (signature_algorithm == 0)
377 {
378 continue;
379 }
380
381 packet_buffer[offset] = (UCHAR)((signature_algorithm & 0xFF00) >> 8);
382 packet_buffer[offset + 1] = (UCHAR)(signature_algorithm & 0x00FF);
383
384 offset += 2;
385 sighash_len = (USHORT)(sighash_len + 2);
386 }
387
388 ext = NX_SECURE_TLS_EXTENSION_SIGNATURE_ALGORITHMS; /* Signature algorithms */
389 ext_len = (USHORT)(ext_len + 2);
390
391 sig_len = 2;
392 ext_len = (USHORT)(ext_len + 2);
393
394 sig_len = (USHORT)(sig_len + sighash_len);
395 ext_len = (USHORT)(ext_len + sig_len);
396
397 packet_buffer[ext_pos] = (UCHAR)((ext & 0xFF00) >> 8);
398 packet_buffer[ext_pos + 1] = (UCHAR)(ext & 0x00FF);
399 ext_pos += 2;
400
401 packet_buffer[ext_pos] = (UCHAR)((sig_len & 0xFF00) >> 8);
402 packet_buffer[ext_pos + 1] = (UCHAR)(sig_len & 0x00FF);
403 ext_pos += 2;
404
405 packet_buffer[ext_pos] = (UCHAR)((sighash_len & 0xFF00) >> 8);
406 packet_buffer[ext_pos + 1] = (UCHAR)(sighash_len & 0x00FF);
407
408 /* Return our updated packet offset. */
409 *extension_length = ext_len;
410 *packet_offset = offset;
411
412 return(NX_SUCCESS);
413 }
414
_nx_secure_tls_get_signature_algorithm(NX_SECURE_TLS_SESSION * tls_session,NX_SECURE_X509_CRYPTO * crypto_method,USHORT * signature_algorithm)415 VOID _nx_secure_tls_get_signature_algorithm(NX_SECURE_TLS_SESSION *tls_session,
416 NX_SECURE_X509_CRYPTO *crypto_method,
417 USHORT *signature_algorithm)
418 {
419 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
420 UINT j;
421 #endif /* (NX_SECURE_TLS_TLS_1_3_ENABLED) */
422 USHORT named_curve = 0;
423 UCHAR hash_algo = 0;
424 UCHAR sig_algo = 0;
425
426 *signature_algorithm = 0;
427
428 switch (crypto_method -> nx_secure_x509_public_cipher_method -> nx_crypto_algorithm)
429 {
430 case NX_CRYPTO_KEY_EXCHANGE_RSA:
431 sig_algo = NX_SECURE_TLS_SIGNATURE_ALGORITHM_RSA;
432 break;
433 case NX_CRYPTO_DIGITAL_SIGNATURE_DSA:
434 sig_algo = NX_SECURE_TLS_SIGNATURE_ALGORITHM_DSA;
435 break;
436 case NX_CRYPTO_DIGITAL_SIGNATURE_ECDSA:
437 sig_algo = NX_SECURE_TLS_SIGNATURE_ALGORITHM_ECDSA;
438 break;
439 default:
440 return;
441 }
442
443 switch (crypto_method -> nx_secure_x509_hash_method -> nx_crypto_algorithm)
444 {
445 case NX_CRYPTO_HASH_MD5:
446 hash_algo = NX_SECURE_TLS_HASH_ALGORITHM_MD5;
447 break;
448 case NX_CRYPTO_HASH_SHA1:
449 hash_algo = NX_SECURE_TLS_HASH_ALGORITHM_SHA1;
450 break;
451 case NX_CRYPTO_HASH_SHA224:
452 hash_algo = NX_SECURE_TLS_HASH_ALGORITHM_SHA224;
453 break;
454 case NX_CRYPTO_HASH_SHA256:
455 hash_algo = NX_SECURE_TLS_HASH_ALGORITHM_SHA256;
456 named_curve = (USHORT)NX_CRYPTO_EC_SECP256R1;
457 break;
458 case NX_CRYPTO_HASH_SHA384:
459 hash_algo = NX_SECURE_TLS_HASH_ALGORITHM_SHA384;
460 named_curve = (USHORT)NX_CRYPTO_EC_SECP384R1;
461 break;
462 case NX_CRYPTO_HASH_SHA512:
463 hash_algo = NX_SECURE_TLS_HASH_ALGORITHM_SHA512;
464 named_curve = (USHORT)NX_CRYPTO_EC_SECP521R1;
465 break;
466 default:
467 return;
468 }
469
470 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
471 /* TLS 1.3 deprecates MD5, and SHA-1 is obsolete. Remove them from the signing list. */
472 if(tls_session -> nx_secure_tls_1_3)
473 {
474 if((hash_algo == NX_SECURE_TLS_HASH_ALGORITHM_MD5) || (hash_algo == NX_SECURE_TLS_HASH_ALGORITHM_SHA1))
475 {
476 *signature_algorithm = 0;
477 return;
478 }
479 }
480
481 /* In TLS 1.3, the signing curve is constrained. */
482 if (tls_session -> nx_secure_tls_1_3 &&
483 (named_curve != 0) &&
484 (sig_algo == NX_SECURE_TLS_SIGNATURE_ALGORITHM_ECDSA))
485 {
486 for (j = 0; j < tls_session->nx_secure_tls_ecc.nx_secure_tls_ecc_supported_groups_count; j++)
487 {
488 if (named_curve == tls_session->nx_secure_tls_ecc.nx_secure_tls_ecc_supported_groups[j])
489 {
490 *signature_algorithm = (USHORT)((hash_algo << 8) + sig_algo);
491 return;
492 }
493 }
494 }
495 else
496 #else
497 NX_PARAMETER_NOT_USED(named_curve);
498 NX_PARAMETER_NOT_USED(tls_session);
499 #endif
500 {
501 *signature_algorithm = (USHORT)((hash_algo << 8) + sig_algo);
502 }
503 }
504 #endif
505
506
507 /**************************************************************************/
508 /* */
509 /* FUNCTION RELEASE */
510 /* */
511 /* _nx_secure_tls_send_clienthello_supported_versions_extension */
512 /* PORTABLE C */
513 /* 6.2.1 */
514 /* AUTHOR */
515 /* */
516 /* Timothy Stapko, Microsoft Corporation */
517 /* */
518 /* DESCRIPTION */
519 /* */
520 /* This function adds the Supported Versions extension, added in TLS */
521 /* v1.3. */
522 /* */
523 /* INPUT */
524 /* */
525 /* tls_session TLS control block */
526 /* packet_buffer Outgoing TLS packet buffer */
527 /* packet_offset Offset into packet buffer */
528 /* extension_length Return length of data */
529 /* available_size Available size of buffer */
530 /* */
531 /* OUTPUT */
532 /* */
533 /* status Completion status */
534 /* */
535 /* CALLS */
536 /* */
537 /* None */
538 /* */
539 /* CALLED BY */
540 /* */
541 /* _nx_secure_tls_send_clienthello_extensions */
542 /* Send TLS ClientHello extension*/
543 /* */
544 /* RELEASE HISTORY */
545 /* */
546 /* DATE NAME DESCRIPTION */
547 /* */
548 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
549 /* 09-30-2020 Timothy Stapko Modified comment(s), */
550 /* resulting in version 6.1 */
551 /* 03-08-2023 Tiejun Zhou Modified comment(s), */
552 /* fixed compiler warnings, */
553 /* resulting in version 6.2.1 */
554 /* */
555 /**************************************************************************/
556 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
557 /* We need to access the supported versions table located in nx_secure_tls_check_protocol_version.c. */
558 extern const NX_SECURE_VERSIONS_LIST nx_secure_supported_versions_list[];
_nx_secure_tls_send_clienthello_supported_versions_extension(NX_SECURE_TLS_SESSION * tls_session,UCHAR * packet_buffer,ULONG * packet_offset,USHORT * extension_length,ULONG available_size)559 static UINT _nx_secure_tls_send_clienthello_supported_versions_extension(NX_SECURE_TLS_SESSION *tls_session,
560 UCHAR *packet_buffer, ULONG *packet_offset,
561 USHORT *extension_length, ULONG available_size)
562 {
563 ULONG offset;
564 USHORT ext;
565 UINT data_length;
566 UINT id = NX_SECURE_TLS;
567 #ifndef NX_SECURE_TLS_DISABLE_PROTOCOL_VERSION_DOWNGRADE
568 USHORT protocol_version;
569 INT i;
570 #endif /* NX_SECURE_TLS_DISABLE_PROTOCOL_VERSION_DOWNGRADE */
571
572 /* Supported Versions Extension structure:
573 * | 2 | 2 | 1 | <list length> |
574 * | Ext Type | Extension length | List Length | TLS Versions |
575 */
576 NX_PARAMETER_NOT_USED(tls_session);
577
578 if (available_size < (*packet_offset + 7u +
579 (nx_secure_supported_versions_list[id].nx_secure_versions_list_count << 1)))
580 {
581
582 /* Packet buffer too small. */
583 return(NX_SECURE_TLS_PACKET_BUFFER_TOO_SMALL);
584 }
585
586 /* Start with our passed-in packet offset. */
587 offset = *packet_offset;
588
589 /* The extension identifier. */
590 ext = NX_SECURE_TLS_EXTENSION_SUPPORTED_VERSIONS;
591
592 /* Put the extension ID into the packet. */
593 packet_buffer[offset] = (UCHAR)((ext & 0xFF00) >> 8);
594 packet_buffer[offset + 1] = (UCHAR)(ext & 0x00FF);
595 offset += 2;
596
597 /* Fill in the supported versions first. */
598 offset += 3;
599 data_length = 0;
600
601 /* Add TLS 1.3 (0x0304) which is not in legacy supported versions list. */
602 packet_buffer[offset] = (UCHAR)NX_SECURE_TLS_VERSION_MAJOR_3;
603 packet_buffer[offset + 1] = (UCHAR)NX_SECURE_TLS_VERSION_MINOR_1_3;
604 data_length += 2;
605 offset += 2;
606
607 #ifndef NX_SECURE_TLS_DISABLE_PROTOCOL_VERSION_DOWNGRADE
608 /* Loop through the supported versions to see if the passed-in version is one that is enabled. */
609 for (i = (INT)(nx_secure_supported_versions_list[id].nx_secure_versions_list_count - 1); i >= 0; --i)
610 {
611
612 /* See if it is supported. */
613 if (nx_secure_supported_versions_list[id].nx_secure_versions_list[i].nx_secure_tls_is_supported)
614 {
615
616 /* Set the version value. */
617 protocol_version = nx_secure_supported_versions_list[id].nx_secure_versions_list[i].nx_secure_tls_protocol_version;
618 packet_buffer[offset] = (UCHAR)((protocol_version & 0xFF00) >> 8);
619 packet_buffer[offset + 1] = (UCHAR)(protocol_version & 0x00FF);
620 data_length += 2;
621 offset += 2;
622 }
623 else
624 {
625 break;
626 }
627 }
628 #endif /* NX_SECURE_TLS_DISABLE_PROTOCOL_VERSION_DOWNGRADE */
629
630 /* Fill in list length and extension length. */
631 packet_buffer[*packet_offset + 4] = (UCHAR)(data_length & 0xFF);
632
633 data_length++;
634 packet_buffer[*packet_offset + 2] = (UCHAR)((data_length & 0xFF00) >> 8);
635 packet_buffer[*packet_offset + 3] = (UCHAR)(data_length & 0x00FF);
636
637 /* Return the amount of data we wrote. */
638 *extension_length = (USHORT)(offset - *packet_offset);
639
640 /* Return our updated packet offset. */
641 *packet_offset = offset;
642
643
644 return(NX_SUCCESS);
645 }
646 #endif
647
648 /**************************************************************************/
649 /* */
650 /* FUNCTION RELEASE */
651 /* */
652 /* _nx_secure_tls_send_clienthello_key_share_extension PORTABLE C */
653 /* 6.1 */
654 /* AUTHOR */
655 /* */
656 /* Timothy Stapko, Microsoft Corporation */
657 /* */
658 /* DESCRIPTION */
659 /* */
660 /* This function adds the Key Share extension, added in TLS */
661 /* v1.3. */
662 /* */
663 /* INPUT */
664 /* */
665 /* tls_session TLS control block */
666 /* packet_buffer Outgoing TLS packet buffer */
667 /* packet_offset Offset into packet buffer */
668 /* extension_length Return length of data */
669 /* available_size Available size of buffer */
670 /* */
671 /* OUTPUT */
672 /* */
673 /* status Completion status */
674 /* */
675 /* CALLS */
676 /* */
677 /* None */
678 /* */
679 /* CALLED BY */
680 /* */
681 /* _nx_secure_tls_send_clienthello_extensions */
682 /* Send TLS ClientHello extension*/
683 /* */
684 /* RELEASE HISTORY */
685 /* */
686 /* DATE NAME DESCRIPTION */
687 /* */
688 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
689 /* 09-30-2020 Timothy Stapko Modified comment(s), */
690 /* verified memcpy use cases, */
691 /* resulting in version 6.1 */
692 /* */
693 /**************************************************************************/
694 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
_nx_secure_tls_send_clienthello_key_share_extension(NX_SECURE_TLS_SESSION * tls_session,UCHAR * packet_buffer,ULONG * packet_offset,USHORT * extension_length,ULONG available_size)695 static UINT _nx_secure_tls_send_clienthello_key_share_extension(NX_SECURE_TLS_SESSION *tls_session,
696 UCHAR *packet_buffer, ULONG *packet_offset,
697 USHORT *extension_length, ULONG available_size)
698 {
699 ULONG offset;
700 ULONG length_offset;
701 USHORT ext;
702 UINT entry_index;
703 UINT entry_length;
704 UINT key_length;
705 UINT data_length;
706 NX_SECURE_TLS_ECDHE_HANDSHAKE_DATA *ecdhe_data;
707 USHORT named_curve;
708
709 /* Key Share Extension structure (From TLS 1.3 RFC Draft #28):
710 * struct {
711 * NamedGroup group;
712 * opaque key_exchange<1..2^16-1>;
713 * } KeyShareEntry;
714 *
715 * struct {
716 * KeyShareEntry client_shares<0..2^16-1>;
717 * } KeyShareClientHello;
718 *
719 * Diffie-Hellman [DH] parameters for both clients and servers are
720 * encoded in the opaque key_exchange field of a KeyShareEntry in a
721 * KeyShare structure. The opaque value contains the Diffie-Hellman
722 * public value (Y = g^X mod p) for the specified group (see [RFC7919]
723 * for group definitions) encoded as a big-endian integer and padded to
724 * the left with zeros to the size of p in bytes.
725 *
726 * ECDHE structure for key_exchange (For secp256r1, secp384r1 and secp521r1)
727 * struct {
728 * uint8 legacy_form = 4;
729 * opaque X[coordinate_length];
730 * opaque Y[coordinate_length];
731 * } UncompressedPointRepresentation;
732 *
733 * X and Y respectively are the binary representations of the x and y
734 * values in network byte order. There are no internal length markers,
735 * so each number representation occupies as many octets as implied by
736 * the curve parameters. For P-256 this means that each of X and Y use
737 * 32 octets, padded on the left by zeros if necessary. For P-384 they
738 * take 48 octets each, and for P-521 they take 66 octets each.
739 *
740 * The X,Y point is the public key (Q) which is generated using the following:
741 * - The public key to put into the KeyShareEntry.key_exchange
742 * structure is the result of applying the ECDH scalar multiplication
743 * function to the secret key of appropriate length (into scalar
744 * input) and the standard public basepoint (into u-coordinate point
745 * input).
746 *
747 * - The ECDH shared secret is the result of applying the ECDH scalar
748 * multiplication function to the secret key (into scalar input) and
749 * the peer's public key (into u-coordinate point input). The output
750 * is used raw, with no processing.
751 *
752 * NamedGroup examples: secp256r1(0x0017), secp384r1(0x0018), secp521r1(0x0019)
753 * | <list length> |
754 * | 2 | 2 | <| 2 | 2 | <Key len> |> |
755 * | Ext Type | Extension length | <| Named Group | Key len | key_exchange data |> |
756 */
757
758 if (tls_session == NX_NULL)
759 {
760 return(NX_PTR_ERROR);
761 }
762
763 if (tls_session -> nx_secure_tls_client_state == NX_SECURE_TLS_CLIENT_STATE_HELLO_RETRY)
764 {
765 entry_index = tls_session -> nx_secure_tls_key_material.nx_secure_tls_ecc_key_data_selected;
766 }
767 else
768 {
769
770 /* Select default entry is based on the actual curves we support. */
771 entry_index = 0;
772 }
773
774 /* Get the ECDHE structure for our key data. */
775 ecdhe_data = &tls_session -> nx_secure_tls_key_material.nx_secure_tls_ecc_key_data[entry_index];
776
777 /* Get the curve for the key we are sending. */
778 named_curve = (USHORT)ecdhe_data->nx_secure_tls_ecdhe_named_curve;
779
780 /* Key length will differ for each curve. For p256, 32 octets per coordinate, plus the "legacy_form" byte. */
781 key_length = ecdhe_data->nx_secure_tls_ecdhe_public_key_length;
782
783 if (available_size < (*packet_offset + 10u + key_length))
784 {
785
786 /* Packet buffer too small. */
787 return(NX_SECURE_TLS_PACKET_BUFFER_TOO_SMALL);
788 }
789
790 /* Start with our passed-in packet offset. */
791 offset = *packet_offset;
792
793 /* The extension identifier. */
794 ext = NX_SECURE_TLS_EXTENSION_KEY_SHARE;
795
796 /* Put the extension ID into the packet. */
797 packet_buffer[offset] = (UCHAR)((ext & 0xFF00) >> 8);
798 packet_buffer[offset + 1] = (UCHAR)(ext & 0x00FF);
799 offset += 2;
800
801 /* Add Total Length (2 bytes) and List length (2 bytes) to packet after we
802 fill in the key data. */
803 length_offset = offset;
804 data_length = 0;
805 offset += 4;
806
807 /* Entry is named group(2) + key len(2) + key data(key len). */
808 entry_length = 2 + 2 + key_length;
809
810 /* Set the named group. */
811 packet_buffer[offset] = (UCHAR)((named_curve & 0xFF00) >> 8);;
812 packet_buffer[offset + 1] = (UCHAR)(named_curve & 0x00FF);
813 offset += 2;
814
815 /* Set the key length. */
816 packet_buffer[offset] = (UCHAR)((key_length & 0xFF00) >> 8);;
817 packet_buffer[offset + 1] = (UCHAR)(key_length & 0x00FF);
818 offset += 2;
819
820 /* Set the key data from our already-generated ECC keys. */
821 NX_SECURE_MEMCPY(&packet_buffer[offset], &tls_session -> nx_secure_tls_key_material.nx_secure_tls_ecc_key_data[entry_index].nx_secure_tls_ecdhe_public_key[0], key_length); /* Use case of memcpy is verified. */
822 offset += (key_length);
823
824 /* Get the length of the entire extension. */
825 data_length = data_length + (UINT)(entry_length);
826
827 /* Go back and set the total extension length. */
828 data_length = data_length + 2;
829 packet_buffer[length_offset] = (UCHAR)((data_length & 0xFF00) >> 8);
830 packet_buffer[length_offset + 1] = (UCHAR)(data_length & 0x00FF);
831 length_offset += 2;
832 data_length = data_length - 2;
833
834 /* Finally, put the list length into the packet. */
835 packet_buffer[length_offset] = (UCHAR)((data_length & 0xFF00) >> 8);
836 packet_buffer[length_offset + 1] = (UCHAR)(data_length & 0x00FF);
837
838 /* Return the amount of data we wrote. */
839 *extension_length = (USHORT)(offset - *packet_offset);
840
841 /* Return our updated packet offset. */
842 *packet_offset = offset;
843
844
845 return(NX_SUCCESS);
846 }
847 #endif
848
849
850
851 /**************************************************************************/
852 /* */
853 /* FUNCTION RELEASE */
854 /* */
855 /* _nx_secure_tls_send_clienthello_psk_extension PORTABLE C */
856 /* 6.1.8 */
857 /* AUTHOR */
858 /* */
859 /* Timothy Stapko, Microsoft Corporation */
860 /* */
861 /* DESCRIPTION */
862 /* */
863 /* This function adds the pre_shared_key extension, added in TLS */
864 /* v1.3. */
865 /* */
866 /* INPUT */
867 /* */
868 /* tls_session TLS control block */
869 /* packet_buffer Outgoing TLS packet buffer */
870 /* packet_length Length of data in packet */
871 /* extension_length Return length of data */
872 /* available_size Available size of buffer */
873 /* */
874 /* OUTPUT */
875 /* */
876 /* status Completion status */
877 /* */
878 /* CALLS */
879 /* */
880 /* None */
881 /* */
882 /* CALLED BY */
883 /* */
884 /* _nx_secure_tls_send_clienthello_extensions */
885 /* Send TLS ClientHello extension*/
886 /* */
887 /* RELEASE HISTORY */
888 /* */
889 /* DATE NAME DESCRIPTION */
890 /* */
891 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
892 /* 09-30-2020 Timothy Stapko Modified comment(s), */
893 /* verified memcpy use cases, */
894 /* resulting in version 6.1 */
895 /* 08-02-2021 Timothy Stapko Modified comment(s), added */
896 /* hash clone and cleanup, */
897 /* resulting in version 6.1.8 */
898 /* */
899 /**************************************************************************/
900
901 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
_nx_secure_tls_send_clienthello_psk_extension(NX_SECURE_TLS_SESSION * tls_session,UCHAR * packet_buffer,ULONG * packet_length,ULONG extension_length_offset,ULONG total_extensions_length,ULONG * extension_length,ULONG available_size)902 UINT _nx_secure_tls_send_clienthello_psk_extension(NX_SECURE_TLS_SESSION *tls_session,
903 UCHAR *packet_buffer, ULONG *packet_length,
904 ULONG extension_length_offset, ULONG total_extensions_length,
905 ULONG *extension_length, ULONG available_size)
906 {
907 ULONG offset;
908 ULONG length_offset;
909 USHORT ext;
910 UINT i;
911 UINT num_ids;
912 UINT data_length;
913 UINT ids_total;
914 UINT id_len;
915 UINT age;
916 UCHAR *id;
917 UINT binder_len = 0;
918 UCHAR *binder;
919 UINT num_binders;
920 UINT binder_offset;
921 UINT binder_total;
922 UINT status;
923 UINT partial_client_hello_len;
924 NX_SECURE_TLS_PSK_STORE *psk_store;
925
926
927 /* Key Share Extension structure (From TLS 1.3 RFC 8446):
928 struct {
929 opaque identity<1..2^16-1>;
930 uint32 obfuscated_ticket_age;
931 } PskIdentity;
932
933 opaque PskBinderEntry<32..255>;
934
935 struct {
936 PskIdentity identities<7..2^16-1>;
937 PskBinderEntry binders<33..2^16-1>;
938 } OfferedPsks;
939
940 struct {
941 select (Handshake.msg_type) {
942 case client_hello: OfferedPsks;
943 case server_hello: uint16 selected_identity;
944 };
945 } PreSharedKeyExtension;
946
947 identity: A label for a key. For instance, a ticket (as defined in
948 Appendix B.3.4) or a label for a pre-shared key established
949 externally.
950
951 obfuscated_ticket_age: An obfuscated version of the age of the key.
952 Section 4.2.11.1 describes how to form this value for identities
953 established via the NewSessionTicket message. For identities
954 established externally, an obfuscated_ticket_age of 0 SHOULD be
955 used, and servers MUST ignore the value.
956
957 identities: A list of the identities that the client is willing to
958 negotiate with the server. If sent alongside the "early_data"
959 extension (see Section 4.2.10), the first identity is the one used
960 for 0-RTT data.
961
962 binders: A series of HMAC values, one for each value in the
963 identities list and in the same order, computed as described
964 below.
965
966 selected_identity: The server's chosen identity expressed as a
967 (0-based) index into the identities in the client's list.
968
969
970 ClientHello extension layout:
971 | 2 | 2 | 2 | <ID list len> | 2 | <binders len> |
972 | Ext Type | Extension length | ID list len | <|<ID len> | ID | age |> | binders len | <len> | binder |
973 */
974 NX_PARAMETER_NOT_USED(tls_session);
975
976 /* Start with our passed-in packet offset. */
977 offset = *packet_length;
978
979 /* The extension identifier. */
980 ext = NX_SECURE_TLS_EXTENSION_PRE_SHARED_KEY;
981
982 if (tls_session == NX_NULL)
983 {
984 return(NX_PTR_ERROR);
985 }
986
987 if (available_size < (offset + 6u))
988 {
989
990 /* Packet buffer too small. */
991 return(NX_SECURE_TLS_PACKET_BUFFER_TOO_SMALL);
992 }
993
994 /* Put the extension ID into the packet. */
995 packet_buffer[offset] = (UCHAR)((ext & 0xFF00) >> 8);
996 packet_buffer[offset + 1] = (UCHAR)(ext & 0x00FF);
997 offset += 2;
998
999 /* Add Total Length (2 bytes) and List length (2 bytes) to packet after we
1000 fill in the key data. */
1001 length_offset = offset;
1002 data_length = 4;
1003 offset += 4;
1004
1005 /* Get our PSK store for easy access. */
1006 psk_store = tls_session->nx_secure_tls_credentials.nx_secure_tls_psk_store;
1007 num_ids = tls_session->nx_secure_tls_credentials.nx_secure_tls_psk_count;
1008 ids_total = 0;
1009 binder_total = 0;
1010
1011 /* Loop through all IDs. */
1012 for(i = 0; i < num_ids; ++i)
1013 {
1014 /* Setup the ID list. */
1015 id_len = psk_store[i].nx_secure_tls_psk_id_size;
1016 id = psk_store[i].nx_secure_tls_psk_id;
1017
1018 if (available_size < (offset + 6u + id_len))
1019 {
1020
1021 /* Packet buffer too small. */
1022 return(NX_SECURE_TLS_PACKET_BUFFER_TOO_SMALL);
1023 }
1024
1025 packet_buffer[offset] = (UCHAR)((id_len & 0xFF00) >> 8);;
1026 packet_buffer[offset + 1] = (UCHAR)(id_len & 0x00FF);
1027 offset += 2;
1028
1029 /* Put the ID data into our packet. */
1030 NX_SECURE_MEMCPY(&packet_buffer[offset], id, id_len); /* Use case of memcpy is verified. */
1031 offset += (UINT)(id_len);
1032
1033 /* Set the obfuscated PSK age. */
1034 age = 0;
1035 packet_buffer[offset] = (UCHAR)((age & 0xFF000000) >> 24);
1036 packet_buffer[offset + 1] = (UCHAR)((age & 0x00FF0000) >> 16);
1037 packet_buffer[offset + 2] = (UCHAR)((age & 0x0000FF00) >> 8);
1038 packet_buffer[offset + 3] = (UCHAR) (age & 0x000000FF);
1039 offset += 4;
1040
1041 /* Update the length with the ID length (id_len), length field (2), and age field (4). */
1042 ids_total = ids_total + (UINT)(id_len + 2 + 4);
1043
1044 /* Caclulate the length of the binder list - binder for each PSK + the length field. */
1045 binder_total += (UINT)(1 + binder_len);
1046 }
1047
1048 /* Put the list length into the packet - the list length is the 16-bit field following the total length field (16-bits). */
1049 packet_buffer[length_offset + 2] = (UCHAR)((ids_total & 0xFF00) >> 8);
1050 packet_buffer[length_offset + 3] = (UCHAR)(ids_total & 0x00FF);
1051 data_length += ids_total;
1052
1053
1054 /* Get the length of the ClientHello to this point, plus the length field that comes next. */
1055 partial_client_hello_len = (UINT)(*packet_length) + data_length + 2;
1056
1057 /* Update the total length of the extension with the anticipated size of the binders - this is used in generating
1058 the binder hashes. */
1059 // printf(">>>Binder list length: %d\n", binder_total);
1060 binder_total = 33;
1061 data_length += binder_total;
1062
1063 /* Extension length. */
1064 packet_buffer[length_offset] = (UCHAR)((data_length & 0xFF00) >> 8);
1065 packet_buffer[length_offset + 1] = (UCHAR)(data_length & 0x00FF);
1066
1067 /* IMPORTANT: We also need to update the total extensions length field using the passed-in parameters.
1068 Failure to to so will invalidate the transcript hash we do next. */
1069 total_extensions_length += data_length + 4;
1070 packet_buffer[extension_length_offset] = (UCHAR)((total_extensions_length & 0xFF00) >> 8);
1071 packet_buffer[extension_length_offset + 1] = (UCHAR)(total_extensions_length & 0x00FF);
1072
1073
1074 /* Now calculate the binders for this session. The binder is an HMAC hash of the entire ClientHello
1075 * up to and including the pre_shared_key extension with the IDs added above but NOT the binders.
1076 * The Length fields for the extension, however, are set to a value that matches the complete extension
1077 * with assumed correct binder lengths.
1078 *
1079 * Binders are calculated using the following (ClientHello1 is the first ClientHello,
1080 * and "Truncate" removes the binder data which is being generated):
1081 * Transcript-Hash(Truncate(ClientHello1))
1082 *
1083 * Each PSK is associated with a single Hash algorithm. For PSKs
1084 * established via the ticket mechanism (Section 4.6.1), this is the KDF
1085 * Hash algorithm on the connection where the ticket was established.
1086 * For externally established PSKs, the Hash algorithm MUST be set when
1087 * the PSK is established or default to SHA-256 if no such algorithm is
1088 * defined. The server MUST ensure that it selects a compatible PSK
1089 * (if any) and cipher suite.
1090 */
1091
1092 /* If nx_secure_tls_client_state is IDLE, it means this is ClientHello1, need to initialize the handshake hash.
1093 If not, it means this is ClientHello2, need to save the metadata(ClientHello1 and HelloRetryRequest) to sratch buffer. */
1094 if (tls_session -> nx_secure_tls_client_state == NX_SECURE_TLS_CLIENT_STATE_IDLE)
1095 {
1096
1097 /* Initialize the handshake hash to hash the ClientHello up to now. */
1098 _nx_secure_tls_handshake_hash_init(tls_session);
1099 }
1100 else
1101 {
1102
1103 /* Save the handshake hash state. */
1104 NX_SECURE_HASH_METADATA_CLONE(tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_scratch,
1105 tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_sha256_metadata,
1106 tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_sha256_metadata_size); /* Use case of memcpy is verified. */
1107 }
1108
1109 /* Hash the ClientHello up to its current point. */
1110 /* The Transcript hash needs to include the handshake record header which means we need to calculate the full length
1111 of the expected ClientHello (with expected binder list length) and fill in the header appropriately. */
1112 UCHAR header[] = { 0x01, 0x00, 0x01, 0x30 };
1113 header[2] = (UCHAR)((partial_client_hello_len + binder_total + 2) >> 8);
1114 header[3] = (UCHAR)((partial_client_hello_len + binder_total + 2) & 0xFF);
1115 _nx_secure_tls_handshake_hash_update(tls_session, header, sizeof(header));
1116 _nx_secure_tls_handshake_hash_update(tls_session, packet_buffer, partial_client_hello_len);
1117
1118 /* Save the transcript hash for the ClientHello, which is used in generating the PSK binders. */
1119 status = _nx_secure_tls_1_3_transcript_hash_save(tls_session, NX_SECURE_TLS_TRANSCRIPT_IDX_CLIENTHELLO, NX_FALSE);
1120 if (status != NX_SUCCESS)
1121 {
1122
1123 if (tls_session -> nx_secure_tls_client_state != NX_SECURE_TLS_CLIENT_STATE_IDLE)
1124 {
1125 NX_SECURE_HASH_CLONE_CLEANUP(tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_scratch,
1126 tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_sha256_metadata_size);
1127 }
1128
1129 return(status);
1130 }
1131
1132 /* Restore the original metadata(ClientHello1 and HelloRetryRequest) from scratch buffer. */
1133 if (tls_session -> nx_secure_tls_client_state != NX_SECURE_TLS_CLIENT_STATE_IDLE)
1134 {
1135 NX_SECURE_HASH_CLONE_CLEANUP(tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_sha256_metadata,
1136 tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_sha256_metadata_size);
1137
1138 NX_SECURE_HASH_METADATA_CLONE(tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_sha256_metadata,
1139 tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_scratch,
1140 tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_sha256_metadata_size); /* Use case of memcpy is verified. */
1141
1142 NX_SECURE_HASH_CLONE_CLEANUP(tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_scratch,
1143 tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_sha256_metadata_size);
1144 }
1145
1146 /* Loop through all IDs and set the binders accordingly. */
1147 for(i = 0; i < num_ids; ++i)
1148 {
1149 _nx_secure_tls_psk_binder_generate(tls_session, &psk_store[i]);
1150 }
1151
1152 if (available_size < (offset + 2u))
1153 {
1154
1155 /* Packet buffer too small. */
1156 return(NX_SECURE_TLS_PACKET_BUFFER_TOO_SMALL);
1157 }
1158
1159 /* Now add in the PSK binders. Skip the list length and fill in after. */
1160 binder_offset = offset;
1161 offset += 2;
1162 binder_total = 0;
1163
1164 num_binders = num_ids;
1165 for(i = 0; i < num_binders; ++i)
1166 {
1167 binder_len = psk_store[i].nx_secure_tls_psk_binder_size;
1168 binder = psk_store[i].nx_secure_tls_psk_binder;
1169
1170 if (available_size < (offset + 1u + binder_len))
1171 {
1172
1173 /* Packet buffer too small. */
1174 return(NX_SECURE_TLS_PACKET_BUFFER_TOO_SMALL);
1175 }
1176
1177 /* Add in the length of the binder. */
1178 packet_buffer[offset] = (UCHAR)(binder_len);
1179 offset += (UINT)(1);
1180
1181 /* Put the binder data into the packet. */
1182 NX_SECURE_MEMCPY(&packet_buffer[offset], binder, binder_len); /* Use case of memcpy is verified. */
1183 offset += (UINT)(binder_len);
1184
1185 /* Update our total with the binder length (binder_len) and length field(1). */
1186 binder_total += (UINT)(1 + binder_len);
1187 }
1188
1189 /* Binder list length - this was set above, but overwrite it here. */
1190 packet_buffer[binder_offset] = (UCHAR)((binder_total & 0xFF00) >> 8);;
1191 packet_buffer[binder_offset + 1] = (UCHAR)(binder_total & 0x00FF);
1192
1193 /* Go back and set the total extension length. */
1194 packet_buffer[length_offset] = (UCHAR)((data_length & 0xFF00) >> 8);
1195 packet_buffer[length_offset + 1] = (UCHAR)(data_length & 0x00FF);
1196
1197 /* Return the amount of data we wrote. */
1198 *extension_length = (USHORT)(offset - *packet_length);
1199
1200 /* Return our updated packet offset. */
1201 *packet_length = offset;
1202
1203 return(NX_SUCCESS);
1204 }
1205 #endif
1206
1207
1208 /**************************************************************************/
1209 /* */
1210 /* FUNCTION RELEASE */
1211 /* */
1212 /* _nx_secure_tls_send_clienthello_psk_kem_extension PORTABLE C */
1213 /* 6.1 */
1214 /* AUTHOR */
1215 /* */
1216 /* Timothy Stapko, Microsoft Corporation */
1217 /* */
1218 /* DESCRIPTION */
1219 /* */
1220 /* This function adds the psk_key_exchange_mode extension, added in TLS*/
1221 /* v1.3. */
1222 /* */
1223 /* INPUT */
1224 /* */
1225 /* tls_session TLS control block */
1226 /* packet_buffer Outgoing TLS packet buffer */
1227 /* packet_length Length of data in packet */
1228 /* extension_length Return length of data */
1229 /* */
1230 /* OUTPUT */
1231 /* */
1232 /* status Completion status */
1233 /* */
1234 /* CALLS */
1235 /* */
1236 /* None */
1237 /* */
1238 /* CALLED BY */
1239 /* */
1240 /* _nx_secure_tls_send_clienthello_extensions */
1241 /* Send TLS ClientHello extension*/
1242 /* */
1243 /* RELEASE HISTORY */
1244 /* */
1245 /* DATE NAME DESCRIPTION */
1246 /* */
1247 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
1248 /* 09-30-2020 Timothy Stapko Modified comment(s), */
1249 /* resulting in version 6.1 */
1250 /* */
1251 /**************************************************************************/
1252 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
_nx_secure_tls_send_clienthello_psk_kem_extension(NX_SECURE_TLS_SESSION * tls_session,UCHAR * packet_buffer,ULONG * packet_length,USHORT * extension_length)1253 static UINT _nx_secure_tls_send_clienthello_psk_kem_extension(NX_SECURE_TLS_SESSION *tls_session,
1254 UCHAR *packet_buffer, ULONG *packet_length,
1255 USHORT *extension_length)
1256 {
1257 ULONG offset;
1258 USHORT length;
1259
1260 /* PSK Key Exchange Modes Extension structure (From TLS 1.3 RFC 8446):
1261 enum { psk_ke(0), psk_dhe_ke(1), (255) } PskKeyExchangeMode;
1262
1263 struct {
1264 PskKeyExchangeMode ke_modes<1..255>;
1265 } PskKeyExchangeModes;
1266
1267 psk_ke: PSK-only key establishment. In this mode, the server
1268 MUST NOT supply a "key_share" value.
1269
1270 psk_dhe_ke: PSK with (EC)DHE key establishment. In this mode, the
1271 client and server MUST supply "key_share" values as described in
1272 Section 4.2.8.
1273
1274 ClientHello extension layout:
1275 | 2 | 2 | 1 | <PSK Key Exchange Modes list len> |
1276 | Ext Type | Extension length | PSK Key Exchange Modes list len | PSK Key Exchange Modes list |
1277 */
1278
1279 NX_PARAMETER_NOT_USED(tls_session);
1280
1281 offset = *packet_length;
1282
1283 /* Add extension type. */
1284 packet_buffer[offset] = (UCHAR)((NX_SECURE_TLS_EXTENSION_PSK_KEY_EXCHANGE_MODES) >> 8);
1285 packet_buffer[offset + 1] = (UCHAR)(NX_SECURE_TLS_EXTENSION_PSK_KEY_EXCHANGE_MODES);
1286 offset += 2;
1287
1288 /* Add extension length. */
1289 length = 3;
1290 packet_buffer[offset] = (UCHAR)(length >> 8);
1291 packet_buffer[offset + 1] = (UCHAR)(length);
1292 offset += 2;
1293
1294 /* Add PSK Key Exchange Modes Length. */
1295 packet_buffer[offset++] = 2;
1296
1297 /* Add PSK Key Exchange Mode. */
1298 /* psk_ke : 0, psk_dhe_ke : 1. */
1299 packet_buffer[offset++] = 1;
1300 packet_buffer[offset++] = 0;
1301
1302 /* Return the amount of data we wrote. */
1303 *extension_length = (USHORT)(offset - *packet_length);
1304
1305 /* Return our updated packet offset. */
1306 *packet_length = offset;
1307
1308 return(NX_SUCCESS);
1309 }
1310 #endif
1311
1312
1313 /**************************************************************************/
1314 /* */
1315 /* FUNCTION RELEASE */
1316 /* */
1317 /* _nx_secure_tls_send_clienthello_sni_extension PORTABLE C */
1318 /* 6.1 */
1319 /* AUTHOR */
1320 /* */
1321 /* Timothy Stapko, Microsoft Corporation */
1322 /* */
1323 /* DESCRIPTION */
1324 /* */
1325 /* This function adds the Server Name Indication extension to an */
1326 /* outgoing ClientHello record if a server name has been set by the */
1327 /* application. */
1328 /* */
1329 /* INPUT */
1330 /* */
1331 /* tls_session TLS control block */
1332 /* packet_buffer Outgoing TLS packet buffer */
1333 /* packet_offset Offset into packet buffer */
1334 /* extension_length Return length of data */
1335 /* available_size Available size of buffer */
1336 /* */
1337 /* OUTPUT */
1338 /* */
1339 /* status Completion status */
1340 /* */
1341 /* CALLS */
1342 /* */
1343 /* None */
1344 /* */
1345 /* CALLED BY */
1346 /* */
1347 /* _nx_secure_tls_send_clienthello_extensions */
1348 /* Send TLS ClientHello extension*/
1349 /* */
1350 /* RELEASE HISTORY */
1351 /* */
1352 /* DATE NAME DESCRIPTION */
1353 /* */
1354 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
1355 /* 09-30-2020 Timothy Stapko Modified comment(s), */
1356 /* verified memcpy use cases, */
1357 /* resulting in version 6.1 */
1358 /* */
1359 /**************************************************************************/
1360 #ifndef NX_SECURE_TLS_SNI_EXTENSION_DISABLED
_nx_secure_tls_send_clienthello_sni_extension(NX_SECURE_TLS_SESSION * tls_session,UCHAR * packet_buffer,ULONG * packet_offset,USHORT * extension_length,ULONG available_size)1361 static UINT _nx_secure_tls_send_clienthello_sni_extension(NX_SECURE_TLS_SESSION *tls_session,
1362 UCHAR *packet_buffer, ULONG *packet_offset,
1363 USHORT *extension_length, ULONG available_size)
1364 {
1365 ULONG offset;
1366 USHORT ext;
1367 UINT data_length;
1368
1369 /* Server Name Indication Extension structure:
1370 * | 2 | 2 | 1 | 2 | <name length> |
1371 * | Ext Type | list length | name type | name length | Host name string |
1372 */
1373 /* From RFC 6066:
1374
1375 struct {
1376 NameType name_type;
1377 select (name_type) {
1378 case host_name: HostName;
1379 } name;
1380 } ServerName;
1381
1382 enum {
1383 host_name(0), (255)
1384 } NameType;
1385
1386 opaque HostName<1..2^16-1>;
1387
1388 struct {
1389 ServerName server_name_list<1..2^16-1>
1390 } ServerNameList;
1391
1392 The contents of this extension are specified as follows.
1393
1394 - The ServerNameList MUST NOT contain more than one name of the same
1395 name_type.
1396
1397 - Currently, the only server names supported are DNS hostnames.
1398 */
1399
1400 /* If there is no SNI server name, just return. */
1401 if (tls_session -> nx_secure_tls_sni_extension_server_name == NX_NULL)
1402 {
1403 *extension_length = 0;
1404 return(NX_SUCCESS);
1405 }
1406
1407 /* Start with our passed-in packet offset. */
1408 offset = *packet_offset;
1409
1410 if (available_size < (offset + 9u + tls_session -> nx_secure_tls_sni_extension_server_name -> nx_secure_x509_dns_name_length))
1411 {
1412
1413 /* Packet buffer too small. */
1414 return(NX_SECURE_TLS_PACKET_BUFFER_TOO_SMALL);
1415 }
1416
1417 /* The extension identifier. */
1418 ext = NX_SECURE_TLS_EXTENSION_SERVER_NAME_INDICATION;
1419
1420 /* Put the extension ID into the packet. */
1421 packet_buffer[offset] = (UCHAR)((ext & 0xFF00) >> 8);
1422 packet_buffer[offset + 1] = (UCHAR)(ext & 0x00FF);
1423 offset += 2;
1424
1425 /* Get the length of the entire extension. In this case it is a single name entry. Add 2 for the list length, plus 1 for
1426 the name_type field and 2 for the name length field (name type and length would be duplicated for all entries). */
1427 data_length = (UINT)(tls_session -> nx_secure_tls_sni_extension_server_name -> nx_secure_x509_dns_name_length + 5);
1428
1429 /* Set the total extension length. */
1430 packet_buffer[offset] = (UCHAR)((data_length & 0xFF00) >> 8);
1431 packet_buffer[offset + 1] = (UCHAR)(data_length & 0x00FF);
1432 offset += 2;
1433 data_length -= 2; /* Remove list length. */
1434
1435 /* Set the name list length. */
1436 packet_buffer[offset] = (UCHAR)((data_length & 0xFF00) >> 8);
1437 packet_buffer[offset + 1] = (UCHAR)(data_length & 0x00FF);
1438 offset += 2;
1439 data_length -= 3; /* Remove name type and name length. */
1440
1441 /* Set the name type. */
1442 packet_buffer[offset] = NX_SECURE_TLS_SNI_NAME_TYPE_DNS;
1443 offset++;
1444
1445 /* Set the name length. */
1446 packet_buffer[offset] = (UCHAR)((data_length & 0xFF00) >> 8);
1447 packet_buffer[offset + 1] = (UCHAR)(data_length & 0x00FF);
1448 offset += 2;
1449
1450 /* Write the name into the packet. */
1451 NX_SECURE_MEMCPY(&packet_buffer[offset], tls_session -> nx_secure_tls_sni_extension_server_name -> nx_secure_x509_dns_name, data_length); /* Use case of memcpy is verified. lgtm[cpp/banned-api-usage-required-any] */
1452 offset += data_length;
1453
1454 /* Return the amount of data we wrote. */
1455 *extension_length = (USHORT)(offset - *packet_offset);
1456
1457 /* Return our updated packet offset. */
1458 *packet_offset = offset;
1459
1460
1461 return(NX_SUCCESS);
1462 }
1463 #endif
1464
1465 /**************************************************************************/
1466 /* */
1467 /* FUNCTION RELEASE */
1468 /* */
1469 /* _nx_secure_tls_send_clienthello_sec_reneg_extension PORTABLE C */
1470 /* 6.1 */
1471 /* AUTHOR */
1472 /* */
1473 /* Timothy Stapko, Microsoft Corporation */
1474 /* */
1475 /* DESCRIPTION */
1476 /* */
1477 /* This function adds the Secure Renegotiation Indication extension */
1478 /* to an outgoing ClientHello record if the ClientHello is part of a */
1479 /* renegotiation handshake (the extension should be empty for the */
1480 /* initial handshake. See RFC 5746 for more information. */
1481 /* */
1482 /* INPUT */
1483 /* */
1484 /* tls_session TLS control block */
1485 /* packet_buffer Outgoing TLS packet buffer */
1486 /* packet_offset Offset into packet buffer */
1487 /* extension_length Return length of data */
1488 /* available_size Available size of buffer */
1489 /* */
1490 /* OUTPUT */
1491 /* */
1492 /* status Completion status */
1493 /* */
1494 /* CALLS */
1495 /* */
1496 /* None */
1497 /* */
1498 /* CALLED BY */
1499 /* */
1500 /* _nx_secure_tls_send_clienthello_extensions */
1501 /* Send TLS ClientHello extension*/
1502 /* */
1503 /* RELEASE HISTORY */
1504 /* */
1505 /* DATE NAME DESCRIPTION */
1506 /* */
1507 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
1508 /* 09-30-2020 Timothy Stapko Modified comment(s), */
1509 /* verified memcpy use cases, */
1510 /* fixed renegotiation bug, */
1511 /* resulting in version 6.1 */
1512 /* */
1513 /**************************************************************************/
1514 #ifndef NX_SECURE_TLS_DISABLE_SECURE_RENEGOTIATION
_nx_secure_tls_send_clienthello_sec_reneg_extension(NX_SECURE_TLS_SESSION * tls_session,UCHAR * packet_buffer,ULONG * packet_offset,USHORT * extension_length,ULONG available_size)1515 static UINT _nx_secure_tls_send_clienthello_sec_reneg_extension(NX_SECURE_TLS_SESSION *tls_session,
1516 UCHAR *packet_buffer,
1517 ULONG *packet_offset,
1518 USHORT *extension_length,
1519 ULONG available_size)
1520 {
1521 ULONG offset;
1522 USHORT ext;
1523 UINT data_length;
1524
1525 /* Secure Renegotiation Indication Extensions structure:
1526 * | 2 | 12 |
1527 * | Ext Type | client_verify_data |
1528 */
1529 /* From RFC 5746:
1530 struct {
1531 opaque renegotiated_connection<0..255>;
1532 } RenegotiationInfo;
1533
1534 The contents of this extension are specified as follows.
1535
1536 - If this is the initial handshake for a connection, then the
1537 "renegotiated_connection" field is of zero length in both the
1538 ClientHello and the ServerHello. Thus, the entire encoding of the
1539 extension is ff 01 00 01 00. The first two octets represent the
1540 extension type, the third and fourth octets the length of the
1541 extension itself, and the final octet the zero length byte for the
1542 "renegotiated_connection" field.
1543
1544 - For ClientHellos that are renegotiating, this field contains the
1545 "client_verify_data" specified in Section 3.1.
1546
1547 - For ServerHellos that are renegotiating, this field contains the
1548 concatenation of client_verify_data and server_verify_data. For
1549 current versions of TLS, this will be a 24-byte value (for SSLv3,
1550 it will be a 72-byte value).
1551 */
1552
1553 #ifdef NX_SECURE_TLS_USE_SCSV_CIPHPERSUITE
1554 /* If we are using the SCSV ciphersuite for TLS 1.0 compatibility
1555 and the session is not yet active (first handshake, not a renegotiation),
1556 then don't send the empty extension below, just return with no
1557 offset adjustments. */
1558 if (!tls_session -> nx_secure_tls_local_session_active)
1559 {
1560 *extension_length = 0;
1561 return(NX_SUCCESS);
1562 }
1563 #endif
1564
1565
1566 /* Start with our passed-in packet offset. */
1567 offset = *packet_offset;
1568
1569 if (available_size < (offset + 2u))
1570 {
1571
1572 /* Packet buffer too small. */
1573 return(NX_SECURE_TLS_PACKET_BUFFER_TOO_SMALL);
1574 }
1575
1576 /* The extension identifier. */
1577 ext = NX_SECURE_TLS_EXTENSION_SECURE_RENEGOTIATION;
1578
1579 /* Put the extension ID into the packet. */
1580 packet_buffer[offset] = (UCHAR)((ext & 0xFF00) >> 8);
1581 packet_buffer[offset + 1] = (UCHAR)(ext & 0x00FF);
1582 offset += 2;
1583
1584 if (!tls_session -> nx_secure_tls_local_session_active)
1585 {
1586 /* The extension has zero data because this is an initial handshake. Send
1587 the encoded extension as documented in the RFC. */
1588
1589 if (available_size < (offset + 3u))
1590 {
1591
1592 /* Packet buffer too small. */
1593 return(NX_SECURE_TLS_PACKET_BUFFER_TOO_SMALL);
1594 }
1595
1596 /* Fill in the length of current extension. */
1597 packet_buffer[offset] = 0x00;
1598 packet_buffer[offset + 1] = 0x01;
1599
1600 /* Fill in the length of renegotiated connection field. */
1601 packet_buffer[offset + 2] = 0x00;
1602
1603 offset += 3;
1604 }
1605 else
1606 {
1607 /* Fill in the length of current extension. */
1608 if (available_size < (offset + 3u + NX_SECURE_TLS_FINISHED_HASH_SIZE))
1609 {
1610
1611 /* Packet buffer too small. */
1612 return(NX_SECURE_TLS_PACKET_BUFFER_TOO_SMALL);
1613 }
1614
1615 data_length = NX_SECURE_TLS_FINISHED_HASH_SIZE + 1;
1616 packet_buffer[offset] = (UCHAR)((data_length & 0xFF00) >> 8);
1617 packet_buffer[offset + 1] = (UCHAR)(data_length & 0x00FF);
1618 offset += 2;
1619
1620 /* The extension actually has a second length field of 1 byte that needs to be populated. */
1621 /* Fill in the length of renegotiated connection field. */
1622 packet_buffer[offset] = (UCHAR)(NX_SECURE_TLS_FINISHED_HASH_SIZE & 0x00FF);
1623 offset++;
1624
1625 /* Copy the verify data into the packet. */
1626 NX_SECURE_MEMCPY(&packet_buffer[offset], tls_session -> nx_secure_tls_local_verify_data, NX_SECURE_TLS_FINISHED_HASH_SIZE); /* Use case of memcpy is verified. lgtm[cpp/banned-api-usage-required-any] */
1627 offset += NX_SECURE_TLS_FINISHED_HASH_SIZE;
1628 }
1629
1630 /* Return the amount of data we wrote. */
1631 *extension_length = (USHORT)(offset - *packet_offset);
1632
1633 /* Return our updated packet offset. */
1634 *packet_offset = offset;
1635
1636
1637 return(NX_SUCCESS);
1638 }
1639 #endif
1640
1641 /**************************************************************************/
1642 /* */
1643 /* FUNCTION RELEASE */
1644 /* */
1645 /* _nx_secure_tls_send_clienthello_sec_spf_extensions PORTABLE C */
1646 /* 6.1 */
1647 /* AUTHOR */
1648 /* */
1649 /* Timothy Stapko, Microsoft Corporation */
1650 /* */
1651 /* DESCRIPTION */
1652 /* */
1653 /* This function adds the Supported Elliptic Curves extension and the */
1654 /* Supported Point Formats extension to an outgoing ClientHello */
1655 /* record. See RFC 4492 section 5.1. */
1656 /* */
1657 /* INPUT */
1658 /* */
1659 /* tls_session TLS control block */
1660 /* packet_buffer Outgoing TLS packet buffer */
1661 /* packet_offset Offset into packet buffer */
1662 /* extension_length Return length of data */
1663 /* available_size Available size of buffer */
1664 /* */
1665 /* OUTPUT */
1666 /* */
1667 /* status Completion status */
1668 /* */
1669 /* CALLS */
1670 /* */
1671 /* None */
1672 /* */
1673 /* CALLED BY */
1674 /* */
1675 /* _nx_secure_tls_send_clienthello_extensions */
1676 /* Send TLS ClientHello extension*/
1677 /* */
1678 /* RELEASE HISTORY */
1679 /* */
1680 /* DATE NAME DESCRIPTION */
1681 /* */
1682 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
1683 /* 09-30-2020 Timothy Stapko Modified comment(s), */
1684 /* resulting in version 6.1 */
1685 /* */
1686 /**************************************************************************/
1687 #ifdef NX_SECURE_ENABLE_ECC_CIPHERSUITE
_nx_secure_tls_send_clienthello_sec_spf_extensions(NX_SECURE_TLS_SESSION * tls_session,UCHAR * packet_buffer,ULONG * packet_offset,USHORT * extension_length,ULONG available_size)1688 static UINT _nx_secure_tls_send_clienthello_sec_spf_extensions(NX_SECURE_TLS_SESSION *tls_session,
1689 UCHAR *packet_buffer, ULONG *packet_offset,
1690 USHORT *extension_length, ULONG available_size)
1691 {
1692 ULONG offset;
1693 USHORT ext_len, list_len, ext, i;
1694 NX_SECURE_TLS_ECC *ecc_info;
1695
1696 ecc_info = &(tls_session -> nx_secure_tls_ecc);
1697
1698 if (ecc_info -> nx_secure_tls_ecc_supported_groups_count == 0)
1699 {
1700 *extension_length = 0;
1701 return(NX_SUCCESS);
1702 }
1703
1704 /* Start with our passed-in packet offset. */
1705 offset = *packet_offset;
1706
1707 if (available_size < (offset + 12u + (ULONG)(ecc_info -> nx_secure_tls_ecc_supported_groups_count << 1)))
1708 {
1709
1710 /* Packet buffer too small. */
1711 return(NX_SECURE_TLS_PACKET_BUFFER_TOO_SMALL);
1712 }
1713
1714 /* Supported Elliptic Curves Extension. */
1715 ext = NX_SECURE_TLS_EXTENSION_EC_GROUPS; /* Supported Groups */
1716 list_len = (USHORT)(ecc_info -> nx_secure_tls_ecc_supported_groups_count * sizeof(USHORT));
1717 ext_len = (USHORT)(list_len + 2);
1718
1719 packet_buffer[offset] = (UCHAR)((ext & 0xFF00) >> 8);
1720 packet_buffer[offset + 1] = (UCHAR)(ext & 0x00FF);
1721 offset += 2;
1722
1723 packet_buffer[offset] = (UCHAR)((ext_len & 0xFF00) >> 8);
1724 packet_buffer[offset + 1] = (UCHAR)(ext_len & 0x00FF);
1725 offset += 2;
1726
1727 packet_buffer[offset] = (UCHAR)((list_len & 0xFF00) >> 8);
1728 packet_buffer[offset + 1] = (UCHAR)(list_len & 0x00FF);
1729 offset += 2;
1730
1731 for (i = 0; i < ecc_info -> nx_secure_tls_ecc_supported_groups_count; i++)
1732 {
1733 packet_buffer[offset] = (UCHAR)((ecc_info -> nx_secure_tls_ecc_supported_groups[i] & 0xFF00) >> 8);
1734 packet_buffer[offset + 1] = (UCHAR)(ecc_info -> nx_secure_tls_ecc_supported_groups[i] & 0x00FF);
1735 offset += 2;
1736 }
1737
1738 /* ec_point_formats Extension. */
1739 ext = NX_SECURE_TLS_EXTENSION_EC_POINT_FORMATS;
1740 ext_len = 2; /* ec_point_formats Length: 2. */
1741
1742 packet_buffer[offset] = (UCHAR)((ext & 0xFF00) >> 8);
1743 packet_buffer[offset + 1] = (UCHAR)(ext & 0x00FF);
1744 offset += 2;
1745
1746 packet_buffer[offset] = (UCHAR)((ext_len & 0xFF00) >> 8);
1747 packet_buffer[offset + 1] = (UCHAR)(ext_len & 0x00FF);
1748 offset += 2;
1749
1750 packet_buffer[offset] = 1;
1751 offset += 1;
1752
1753 packet_buffer[offset] = 0;
1754 offset += 1;
1755
1756 /* Return our updated packet offset. */
1757 *extension_length = (USHORT)(offset - *packet_offset);
1758 *packet_offset = offset;
1759
1760 return(NX_SUCCESS);
1761 }
1762 #endif /* NX_SECURE_ENABLE_ECC_CIPHERSUITE */
1763 #endif /* NX_SECURE_TLS_CLIENT_DISABLED */
1764
1765