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_DISABLE_SECURE_RENEGOTIATION
27 static UINT _nx_secure_tls_send_serverhello_sec_reneg_extension(NX_SECURE_TLS_SESSION *tls_session,
28 UCHAR *packet_buffer,
29 ULONG *packet_offset,
30 USHORT *extension_length,
31 ULONG available_size);
32 #endif
33
34 #if (NX_SECURE_TLS_TLS_1_3_ENABLED) && !defined(NX_SECURE_TLS_SERVER_DISABLED)
35 static UINT _nx_secure_tls_send_serverhello_supported_versions_extension(NX_SECURE_TLS_SESSION *tls_session,
36 UCHAR *packet_buffer, ULONG *packet_offset,
37 USHORT *extension_length,
38 ULONG available_size);
39
40 static UINT _nx_secure_tls_send_serverhello_key_share_extension(NX_SECURE_TLS_SESSION *tls_session,
41 UCHAR *packet_buffer, ULONG *packet_offset,
42 USHORT *extension_length,
43 ULONG available_size);
44
45 #ifdef NX_SECURE_ENABLE_PSK_CIPHERSUITES
46 static UINT _nx_secure_tls_send_serverhello_psk_extension(NX_SECURE_TLS_SESSION *tls_session,
47 UCHAR *packet_buffer, ULONG *packet_length,
48 USHORT *extension_length, ULONG available_size);
49 #endif
50
51 #endif
52
53 /**************************************************************************/
54 /* */
55 /* FUNCTION RELEASE */
56 /* */
57 /* _nx_secure_tls_send_serverhello_extensions PORTABLE C */
58 /* 6.2.1 */
59 /* AUTHOR */
60 /* */
61 /* Timothy Stapko, Microsoft Corporation */
62 /* */
63 /* DESCRIPTION */
64 /* */
65 /* This function generates a ServerHello extensions. */
66 /* */
67 /* INPUT */
68 /* */
69 /* tls_session TLS control block */
70 /* packet_buffer Outgoing TLS packet buffer */
71 /* packet_offset Offset into packet buffer */
72 /* available_size Available size of buffer */
73 /* */
74 /* OUTPUT */
75 /* */
76 /* status Completion status */
77 /* */
78 /* CALLS */
79 /* */
80 /* _nx_secure_tls_send_serverhello_sec_reneg_extension */
81 /* Send ServerHello Renegotiation*/
82 /* extension */
83 /* _nx_secure_tls_send_serverhello_ec_extension */
84 /* Send ClientHello EC extension */
85 /* */
86 /* CALLED BY */
87 /* */
88 /* _nx_secure_tls_send_serverhello Send TLS ServerHello */
89 /* */
90 /* RELEASE HISTORY */
91 /* */
92 /* DATE NAME DESCRIPTION */
93 /* */
94 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
95 /* 09-30-2020 Timothy Stapko Modified comment(s), */
96 /* fixed renegotiation bug, */
97 /* resulting in version 6.1 */
98 /* 04-25-2022 Yuxin Zhou Modified comment(s), */
99 /* removed unused code, */
100 /* resulting in version 6.1.11 */
101 /* 03-08-2023 Tiejun Zhou Modified comment(s), */
102 /* fixed compiler warnings, */
103 /* resulting in version 6.2.1 */
104 /* */
105 /**************************************************************************/
_nx_secure_tls_send_serverhello_extensions(NX_SECURE_TLS_SESSION * tls_session,UCHAR * packet_buffer,ULONG * packet_offset,ULONG available_size)106 UINT _nx_secure_tls_send_serverhello_extensions(NX_SECURE_TLS_SESSION *tls_session,
107 UCHAR *packet_buffer, ULONG *packet_offset,
108 ULONG available_size)
109 {
110 ULONG length = *packet_offset;
111 UCHAR *extension_offset;
112 #if !defined(NX_SECURE_TLS_DISABLE_SECURE_RENEGOTIATION) || ((NX_SECURE_TLS_TLS_1_3_ENABLED) && !defined(NX_SECURE_TLS_SERVER_DISABLED))
113 USHORT extension_length = 0;
114 #endif /* !defined(NX_SECURE_TLS_DISABLE_SECURE_RENEGOTIATION) || (NX_SECURE_TLS_TLS_1_3_ENABLED) */
115 USHORT total_extensions_length;
116 UINT status = NX_SUCCESS;
117
118 #if defined(NX_SECURE_TLS_DISABLE_SECURE_RENEGOTIATION) || (!NX_SECURE_TLS_TLS_1_3_ENABLED)
119 NX_PARAMETER_NOT_USED(tls_session);
120 #endif /* defined(NX_SECURE_TLS_DISABLE_SECURE_RENEGOTIATION) || (!NX_SECURE_TLS_TLS_1_3_ENABLED) */
121
122 if (available_size < (*packet_offset + 2u))
123 {
124
125 /* Packet buffer too small. */
126 return(NX_SECURE_TLS_PACKET_BUFFER_TOO_SMALL);
127 }
128
129 /* Save an offset to the beginning of the extensions so we can fill in the length
130 once all the extensions are added. */
131 extension_offset = &packet_buffer[length];
132
133 /* The extensions length field is two bytes. */
134 length += 2;
135 total_extensions_length = 0;
136
137 #ifndef NX_SECURE_TLS_DISABLE_SECURE_RENEGOTIATION
138 #if (NX_SECURE_TLS_TLS_1_3_ENABLED) && !defined(NX_SECURE_TLS_SERVER_DISABLED)
139 /* Renegotiation is deprecated in TLS 1.3 so don't send extension. */
140 if(!tls_session->nx_secure_tls_1_3)
141 #endif
142 {
143 /* We have to add renegotiation extensions in both initial sessions and renegotiating sessions. */
144 status = _nx_secure_tls_send_serverhello_sec_reneg_extension(tls_session, packet_buffer, &length,
145 &extension_length, available_size);
146 total_extensions_length = (USHORT)(total_extensions_length + extension_length);
147
148 if(status != NX_SUCCESS)
149 {
150 return(status);
151 }
152 }
153 #endif /* NX_SECURE_TLS_DISABLE_SECURE_RENEGOTIATION */
154
155
156 #if (NX_SECURE_TLS_TLS_1_3_ENABLED) && !defined(NX_SECURE_TLS_SERVER_DISABLED)
157 if(tls_session->nx_secure_tls_1_3)
158 {
159
160 /* MUST send the supported versions extension in all TLS 1.3 ServerHellos. */
161 status = _nx_secure_tls_send_serverhello_supported_versions_extension(tls_session, packet_buffer, &length,
162 &extension_length, available_size);
163 total_extensions_length = (USHORT)(total_extensions_length + extension_length);
164
165 if(status != NX_SUCCESS)
166 {
167 return(status);
168 }
169
170 /* MUST send the key share extension in all TLS 1.3 ServerHellos. */
171 status = _nx_secure_tls_send_serverhello_key_share_extension(tls_session, packet_buffer, &length,
172 &extension_length, available_size);
173
174 total_extensions_length = (USHORT)(total_extensions_length + extension_length);
175 if(status != NX_SUCCESS)
176 {
177 return(status);
178 }
179
180 #ifdef NX_SECURE_ENABLE_PSK_CIPHERSUITES
181 if ((tls_session -> nx_secure_tls_server_state != NX_SECURE_TLS_SERVER_STATE_SEND_HELLO_RETRY) &&
182 (tls_session->nx_secure_tls_credentials.nx_secure_tls_client_psk.nx_secure_tls_psk_data_size))
183 {
184
185 /* Send the PSK extension for PSK key exchange modes. */
186 status = _nx_secure_tls_send_serverhello_psk_extension(tls_session, packet_buffer, &length,
187 &extension_length, available_size);
188
189 total_extensions_length = (USHORT)(total_extensions_length + extension_length);
190 if (status != NX_SUCCESS)
191 {
192 return(status);
193 }
194 }
195 #endif
196 }
197 #endif
198
199
200
201 /* Make sure we actually wrote some extension data. If none, back up the packet pointer and length. */
202 if (total_extensions_length == 0)
203 {
204 /* No extensions written, back up our pointer and length. */
205 length -= 2;
206 }
207 else
208 {
209 /* Put the extensions length into the packet at our original offset and add
210 the total to our packet length. */
211 extension_offset[0] = (UCHAR)((total_extensions_length & 0xFF00) >> 8);
212 extension_offset[1] = (UCHAR)(total_extensions_length & 0x00FF);
213 }
214
215 *packet_offset = length;
216
217 return(status);
218 }
219
220
221 /**************************************************************************/
222 /* */
223 /* FUNCTION RELEASE */
224 /* */
225 /* _nx_secure_tls_send_serverhello_sec_reneg_extension PORTABLE C */
226 /* 6.1 */
227 /* AUTHOR */
228 /* */
229 /* Timothy Stapko, Microsoft Corporation */
230 /* */
231 /* DESCRIPTION */
232 /* */
233 /* This function adds the Secure Renegotiation Indication extension */
234 /* to an outgoing ServerHello record if the ServerHello is part of a */
235 /* renegotiation handshake. See RFC 5746 for more information. */
236 /* */
237 /* INPUT */
238 /* */
239 /* tls_session TLS control block */
240 /* packet_buffer Outgoing TLS packet buffer */
241 /* packet_offset Offset into packet buffer */
242 /* extension_length Return length of data */
243 /* available_size Available size of buffer */
244 /* */
245 /* OUTPUT */
246 /* */
247 /* status Completion status */
248 /* */
249 /* CALLS */
250 /* */
251 /* None */
252 /* */
253 /* CALLED BY */
254 /* */
255 /* _nx_secure_tls_send_serverhello_extensions */
256 /* Send TLS ServerHello extension*/
257 /* */
258 /* RELEASE HISTORY */
259 /* */
260 /* DATE NAME DESCRIPTION */
261 /* */
262 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
263 /* 09-30-2020 Timothy Stapko Modified comment(s), improved */
264 /* buffer length verification, */
265 /* verified memcpy use cases, */
266 /* fixed renegotiation bug, */
267 /* resulting in version 6.1 */
268 /* */
269 /**************************************************************************/
270 #ifndef NX_SECURE_TLS_DISABLE_SECURE_RENEGOTIATION
_nx_secure_tls_send_serverhello_sec_reneg_extension(NX_SECURE_TLS_SESSION * tls_session,UCHAR * packet_buffer,ULONG * packet_offset,USHORT * extension_length,ULONG available_size)271 static UINT _nx_secure_tls_send_serverhello_sec_reneg_extension(NX_SECURE_TLS_SESSION *tls_session,
272 UCHAR *packet_buffer,
273 ULONG *packet_offset,
274 USHORT *extension_length,
275 ULONG available_size)
276 {
277 ULONG offset;
278 USHORT ext;
279 UINT data_length;
280
281 /* Secure Renegotiation Indication Extensions structure (for serverhello):
282 * | 2 | 12 | 12 |
283 * | Ext Type | client_verify_data | server_verify_data |
284 */
285 /* From RFC 5746:
286 struct {
287 opaque renegotiated_connection<0..255>;
288 } RenegotiationInfo;
289
290 The contents of this extension are specified as follows.
291
292 - If this is the initial handshake for a connection, then the
293 "renegotiated_connection" field is of zero length in both the
294 ClientHello and the ServerHello. Thus, the entire encoding of the
295 extension is ff 01 00 01 00. The first two octets represent the
296 extension type, the third and fourth octets the length of the
297 extension itself, and the final octet the zero length byte for the
298 "renegotiated_connection" field.
299
300 - For ClientHellos that are renegotiating, this field contains the
301 "client_verify_data" specified in Section 3.1.
302
303 - For ServerHellos that are renegotiating, this field contains the
304 concatenation of client_verify_data and server_verify_data. For
305 current versions of TLS, this will be a 24-byte value (for SSLv3,
306 it will be a 72-byte value).
307 */
308
309 /* Start with our passed-in packet offset. */
310 offset = *packet_offset;
311
312 if (available_size < (offset + 2u))
313 {
314
315 /* Packet buffer too small. */
316 return(NX_SECURE_TLS_PACKET_BUFFER_TOO_SMALL);
317 }
318
319 /* The extension identifier. */
320 ext = NX_SECURE_TLS_EXTENSION_SECURE_RENEGOTIATION;
321
322 /* Put the extension ID into the packet. */
323 packet_buffer[offset] = (UCHAR)((ext & 0xFF00) >> 8);
324 packet_buffer[offset + 1] = (UCHAR)(ext & 0x00FF);
325 offset += 2;
326
327 /* See if this is the initial handshake or not. */
328 if (!tls_session -> nx_secure_tls_local_session_active)
329 {
330 /* The extension has zero data because this is an initial handshake. Send
331 the encoded extension as documented in the RFC. */
332
333 if (available_size < (offset + 3u))
334 {
335
336 /* Packet buffer too small. */
337 return(NX_SECURE_TLS_PACKET_BUFFER_TOO_SMALL);
338 }
339
340 /* Fill in the length of current extension. */
341 packet_buffer[offset] = 0x00;
342 packet_buffer[offset + 1] = 0x01;
343
344 /* Fill in the length of renegotiated connection field. */
345 packet_buffer[offset + 2] = 0x00;
346
347 offset += 3;
348 }
349 else
350 {
351 /* Fill in the length of current extension. */
352 if (available_size < (offset + 3u + 2 * NX_SECURE_TLS_FINISHED_HASH_SIZE))
353 {
354
355 /* Packet buffer too small. */
356 return(NX_SECURE_TLS_PACKET_BUFFER_TOO_SMALL);
357 }
358
359 data_length = (NX_SECURE_TLS_FINISHED_HASH_SIZE * 2) + 1;
360 packet_buffer[offset] = (UCHAR)((data_length & 0xFF00) >> 8);
361 packet_buffer[offset + 1] = (UCHAR)(data_length & 0x00FF);
362 offset += 2;
363
364 /* The extension actually has a second length field of 1 byte that needs to be populated. */
365 /* Fill in the length of renegotiated connection field. */
366 packet_buffer[offset] = (UCHAR)((NX_SECURE_TLS_FINISHED_HASH_SIZE * 2) & 0x00FF);
367 offset++;
368
369 /* Copy the verify data into the packet. */
370 NX_SECURE_MEMCPY(&packet_buffer[offset], tls_session -> nx_secure_tls_remote_verify_data, NX_SECURE_TLS_FINISHED_HASH_SIZE); /* Use case of memcpy is verified. lgtm[cpp/banned-api-usage-required-any] */
371 offset += NX_SECURE_TLS_FINISHED_HASH_SIZE;
372 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] */
373 offset += NX_SECURE_TLS_FINISHED_HASH_SIZE;
374 }
375
376 /* Return the amount of data we wrote. */
377 *extension_length = (USHORT)(offset - *packet_offset);
378
379 /* Return our updated packet offset. */
380 *packet_offset = offset;
381
382
383 return(NX_SUCCESS);
384 }
385 #endif
386
387
388 /**************************************************************************/
389 /* */
390 /* FUNCTION RELEASE */
391 /* */
392 /* _nx_secure_tls_send_clienthello_supported_versions_extension */
393 /* PORTABLE C */
394 /* 6.1 */
395 /* AUTHOR */
396 /* */
397 /* Timothy Stapko, Microsoft Corporation */
398 /* */
399 /* DESCRIPTION */
400 /* */
401 /* This function adds the Supported Versions extension, added in TLS */
402 /* v1.3. */
403 /* */
404 /* INPUT */
405 /* */
406 /* tls_session TLS control block */
407 /* packet_buffer Outgoing TLS packet buffer */
408 /* packet_offset Offset into packet buffer */
409 /* extension_length Return length of data */
410 /* available_size Available size of buffer */
411 /* */
412 /* OUTPUT */
413 /* */
414 /* status Completion status */
415 /* */
416 /* CALLS */
417 /* */
418 /* None */
419 /* */
420 /* CALLED BY */
421 /* */
422 /* _nx_secure_tls_send_clienthello_extensions */
423 /* Send TLS ClientHello extension*/
424 /* */
425 /* RELEASE HISTORY */
426 /* */
427 /* DATE NAME DESCRIPTION */
428 /* */
429 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
430 /* 09-30-2020 Timothy Stapko Modified comment(s), */
431 /* resulting in version 6.1 */
432 /* */
433 /**************************************************************************/
434 #if (NX_SECURE_TLS_TLS_1_3_ENABLED) && !defined(NX_SECURE_TLS_SERVER_DISABLED)
_nx_secure_tls_send_serverhello_supported_versions_extension(NX_SECURE_TLS_SESSION * tls_session,UCHAR * packet_buffer,ULONG * packet_offset,USHORT * extension_length,ULONG available_size)435 static UINT _nx_secure_tls_send_serverhello_supported_versions_extension(NX_SECURE_TLS_SESSION *tls_session,
436 UCHAR *packet_buffer, ULONG *packet_offset,
437 USHORT *extension_length, ULONG available_size)
438 {
439 ULONG offset;
440 USHORT ext;
441 UINT data_length;
442
443
444 /* Supported Versions Extension structure:
445 * | 2 | 2 | 2 |
446 * | Ext Type | Extension length | Selected TLS Versions |
447 */
448 NX_PARAMETER_NOT_USED(tls_session);
449
450 /* Start with our passed-in packet offset. */
451 offset = *packet_offset;
452
453 if (available_size < (offset + 6u))
454 {
455
456 /* Packet buffer too small. */
457 return(NX_SECURE_TLS_PACKET_BUFFER_TOO_SMALL);
458 }
459
460 /* The extension identifier. */
461 ext = NX_SECURE_TLS_EXTENSION_SUPPORTED_VERSIONS;
462
463 /* Put the extension ID into the packet. */
464 packet_buffer[offset] = (UCHAR)((ext & 0xFF00) >> 8);
465 packet_buffer[offset + 1] = (UCHAR)(ext & 0x00FF);
466 offset += 2;
467
468 data_length = (UINT)(2);
469
470 /* Set the total extension length. */
471 packet_buffer[offset] = (UCHAR)((data_length & 0xFF00) >> 8);
472 packet_buffer[offset + 1] = (UCHAR)(data_length & 0x00FF);
473 offset += 2;
474
475
476 /* Set the version value. */
477 packet_buffer[offset] = 0x03; //(UCHAR)((NX_SECURE_TLS_VERSION_TLS_1_3 & 0xFF00) >> 8);
478 packet_buffer[offset + 1] = 0x04; //(UCHAR)(NX_SECURE_TLS_VERSION_TLS_1_3 & 0x00FF);
479 offset += 2;
480
481 /* Return the amount of data we wrote. */
482 *extension_length = (USHORT)(offset - *packet_offset);
483
484 /* Return our updated packet offset. */
485 *packet_offset = offset;
486
487
488 return(NX_SUCCESS);
489 }
490 #endif
491
492 /**************************************************************************/
493 /* */
494 /* FUNCTION RELEASE */
495 /* */
496 /* _nx_secure_tls_send_serverhello_key_share_extension PORTABLE C */
497 /* 6.1.9 */
498 /* AUTHOR */
499 /* */
500 /* Timothy Stapko, Microsoft Corporation */
501 /* */
502 /* DESCRIPTION */
503 /* */
504 /* This function adds the Key Share extension, added in TLS */
505 /* v1.3. */
506 /* */
507 /* INPUT */
508 /* */
509 /* tls_session TLS control block */
510 /* packet_buffer Outgoing TLS packet buffer */
511 /* packet_offset Offset into packet buffer */
512 /* extension_length Return length of data */
513 /* available_size Available size of buffer */
514 /* */
515 /* OUTPUT */
516 /* */
517 /* status Completion status */
518 /* */
519 /* CALLS */
520 /* */
521 /* None */
522 /* */
523 /* CALLED BY */
524 /* */
525 /* _nx_secure_tls_send_clienthello_extensions */
526 /* Send TLS ClientHello extension*/
527 /* */
528 /* RELEASE HISTORY */
529 /* */
530 /* DATE NAME DESCRIPTION */
531 /* */
532 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
533 /* 09-30-2020 Timothy Stapko Modified comment(s), */
534 /* verified memcpy use cases, */
535 /* resulting in version 6.1 */
536 /* 10-15-2021 Timothy Stapko Modified comment(s), fixed */
537 /* compilation issue with */
538 /* TLS 1.3 and disabling TLS */
539 /* server, */
540 /* resulting in version 6.1.9 */
541 /* */
542 /**************************************************************************/
543 #if (NX_SECURE_TLS_TLS_1_3_ENABLED) && !defined(NX_SECURE_TLS_SERVER_DISABLED)
_nx_secure_tls_send_serverhello_key_share_extension(NX_SECURE_TLS_SESSION * tls_session,UCHAR * packet_buffer,ULONG * packet_offset,USHORT * extension_length,ULONG available_size)544 static UINT _nx_secure_tls_send_serverhello_key_share_extension(NX_SECURE_TLS_SESSION *tls_session,
545 UCHAR *packet_buffer, ULONG *packet_offset,
546 USHORT *extension_length,
547 ULONG available_size)
548 {
549 #ifndef NX_SECURE_TLS_SERVER_DISABLED
550 ULONG offset;
551 ULONG length_offset;
552 USHORT ext;
553 UINT i;
554 UINT entry_length;
555 UINT key_length;
556 UINT data_length;
557 NX_SECURE_TLS_ECDHE_HANDSHAKE_DATA *ecdhe_data;
558 USHORT named_curve;
559
560 /* Key Share Extension structure (From TLS 1.3 RFC 8446):
561 * struct {
562 * NamedGroup group;
563 * opaque key_exchange<1..2^16-1>;
564 * } KeyShareEntry;
565 *
566 * In a ServerHello message, the "extension_data" field of this
567 * extension contains a KeyShareServerHello value:
568 *
569 * struct {
570 * KeyShareEntry server_share;
571 * } KeyShareServerHello;
572 *
573 * server_share: A single KeyShareEntry value that is in the same group
574 * as one of the client's shares.
575 *
576 * If using (EC)DHE key establishment, servers offer exactly one
577 * KeyShareEntry in the ServerHello. This value MUST be in the same
578 * group as the KeyShareEntry value offered by the client that the
579 * server has selected for the negotiated key exchange. Servers
580 * MUST NOT send a KeyShareEntry for any group not indicated in the
581 * client's "supported_groups" extension and MUST NOT send a
582 * KeyShareEntry when using the "psk_ke" PskKeyExchangeMode. If using
583 * (EC)DHE key establishment and a HelloRetryRequest containing a
584 * "key_share" extension was received by the client, the client MUST
585 * verify that the selected NamedGroup in the ServerHello is the same as
586 * that in the HelloRetryRequest. If this check fails, the client MUST
587 * abort the handshake with an "illegal_parameter" alert.
588 *
589 * Diffie-Hellman [DH] parameters for both clients and servers are
590 * encoded in the opaque key_exchange field of a KeyShareEntry in a
591 * KeyShare structure. The opaque value contains the Diffie-Hellman
592 * public value (Y = g^X mod p) for the specified group (see [RFC7919]
593 * for group definitions) encoded as a big-endian integer and padded to
594 * the left with zeros to the size of p in bytes.
595 *
596 * ECDHE structure for key_exchange (For secp256r1, secp384r1 and secp521r1)
597 * struct {
598 * uint8 legacy_form = 4;
599 * opaque X[coordinate_length];
600 * opaque Y[coordinate_length];
601 * } UncompressedPointRepresentation;
602 *
603 * X and Y respectively are the binary representations of the x and y
604 * values in network byte order. There are no internal length markers,
605 * so each number representation occupies as many octets as implied by
606 * the curve parameters. For P-256 this means that each of X and Y use
607 * 32 octets, padded on the left by zeros if necessary. For P-384 they
608 * take 48 octets each, and for P-521 they take 66 octets each.
609 *
610 * The X,Y point is the public key (Q) which is generated using the following:
611 * - The public key to put into the KeyShareEntry.key_exchange
612 * structure is the result of applying the ECDH scalar multiplication
613 * function to the secret key of appropriate length (into scalar
614 * input) and the standard public basepoint (into u-coordinate point
615 * input).
616 *
617 * - The ECDH shared secret is the result of applying the ECDH scalar
618 * multiplication function to the secret key (into scalar input) and
619 * the peer's public key (into u-coordinate point input). The output
620 * is used raw, with no processing.
621 *
622 * NamedGroup examples: secp256r1(0x0017), secp384r1(0x0018), secp521r1(0x0019)
623 * | 2 | 2 | 2 | 2 | <key_len> |
624 * | Ext Type | Extension length | Named Group | key_len | key_exchange data |
625 */
626
627 /* Start with our passed-in packet offset. */
628 offset = *packet_offset;
629
630 if (available_size < (offset + 2u))
631 {
632
633 /* Packet buffer too small. */
634 return(NX_SECURE_TLS_PACKET_BUFFER_TOO_SMALL);
635 }
636
637 /* The extension identifier. */
638 ext = NX_SECURE_TLS_EXTENSION_KEY_SHARE;
639
640 if (tls_session == NX_NULL)
641 {
642 return(NX_PTR_ERROR);
643 }
644
645 /* Put the extension ID into the packet. */
646 packet_buffer[offset] = (UCHAR)((ext & 0xFF00) >> 8);
647 packet_buffer[offset + 1] = (UCHAR)(ext & 0x00FF);
648 offset += 2;
649
650 i = tls_session -> nx_secure_tls_key_material.nx_secure_tls_ecc_key_data_selected;
651 ecdhe_data = &(tls_session -> nx_secure_tls_key_material.nx_secure_tls_ecc_key_data[i]);
652 named_curve = (USHORT)(ecdhe_data -> nx_secure_tls_ecdhe_named_curve);
653 if (tls_session -> nx_secure_tls_server_state == NX_SECURE_TLS_SERVER_STATE_SEND_HELLO_RETRY)
654 {
655
656 if (available_size < (offset + 4u))
657 {
658
659 /* Packet buffer too small. */
660 return(NX_SECURE_TLS_PACKET_BUFFER_TOO_SMALL);
661 }
662
663 /* Put the fixed length into the packet. */
664 packet_buffer[offset] = 0;
665 packet_buffer[offset + 1] = 2;
666 offset += 2;
667
668 /* Put the selected group into the packet. */
669 packet_buffer[offset] = (UCHAR)((named_curve & 0xFF00) >> 8);;
670 packet_buffer[offset + 1] = (UCHAR)(named_curve & 0x00FF);
671 offset += 2;
672
673 /* Return the amount of data we wrote. */
674 *extension_length = (USHORT)(offset - *packet_offset);
675
676 /* Return our updated packet offset. */
677 *packet_offset = offset;
678
679 return(NX_SUCCESS);
680 }
681
682 /* Add Total Length (2 bytes) to packet after we fill in the key data. */
683 length_offset = offset;
684 data_length = 0;
685 offset += 2;
686
687 /* Key length will differ for each curve. For p256, 32 octets per coordinate, plus the "legacy_form" byte. */
688 key_length = ecdhe_data->nx_secure_tls_ecdhe_public_key_length;
689
690 /* Entry is named group(2) + key len(2) + key data(key len). */
691 entry_length = 2 + 2 + key_length;
692
693 if (available_size < (offset + 4u + key_length))
694 {
695
696 /* Packet buffer too small. */
697 return(NX_SECURE_TLS_PACKET_BUFFER_TOO_SMALL);
698 }
699
700 /* Set the named group. */
701 packet_buffer[offset] = (UCHAR)((named_curve & 0xFF00) >> 8);;
702 packet_buffer[offset + 1] = (UCHAR)(named_curve & 0x00FF);
703 offset += 2;
704
705 /* Set the key length. */
706 packet_buffer[offset] = (UCHAR)((key_length & 0xFF00) >> 8);;
707 packet_buffer[offset + 1] = (UCHAR)(key_length & 0x00FF);
708 offset += 2;
709
710 /* Set the key data from our already-generated ECC keys. */
711 NX_SECURE_MEMCPY(&packet_buffer[offset], &ecdhe_data->nx_secure_tls_ecdhe_public_key[0], key_length); /* Use case of memcpy is verified. */
712 offset += (key_length);
713
714 /* Get the length of the entire extension. */
715 data_length = data_length + (UINT)(entry_length);
716
717 /* Go back and set the total extension length. */
718 packet_buffer[length_offset] = (UCHAR)((data_length & 0xFF00) >> 8);
719 packet_buffer[length_offset + 1] = (UCHAR)(data_length & 0x00FF);
720
721 /* Return the amount of data we wrote. */
722 *extension_length = (USHORT)(offset - *packet_offset);
723
724 /* Return our updated packet offset. */
725 *packet_offset = offset;
726
727
728 return(NX_SUCCESS);
729 #else
730 /* Server is disabled, we shouldn't be processing a ClientHello - error! */
731 return(NX_SECURE_TLS_INVALID_STATE);
732 #endif
733 }
734 #endif
735
736 /**************************************************************************/
737 /* */
738 /* FUNCTION RELEASE */
739 /* */
740 /* _nx_secure_tls_send_serverhello_psk_extension PORTABLE C */
741 /* 6.1 */
742 /* AUTHOR */
743 /* */
744 /* Timothy Stapko, Microsoft Corporation */
745 /* */
746 /* DESCRIPTION */
747 /* */
748 /* This function adds the pre_shared_key extension, added in TLS */
749 /* v1.3. */
750 /* */
751 /* INPUT */
752 /* */
753 /* tls_session TLS control block */
754 /* packet_buffer Outgoing TLS packet buffer */
755 /* packet_length Length of data in packet */
756 /* extension_length Return length of data */
757 /* available_size Available size of buffer */
758 /* */
759 /* OUTPUT */
760 /* */
761 /* status Completion status */
762 /* */
763 /* CALLS */
764 /* */
765 /* None */
766 /* */
767 /* CALLED BY */
768 /* */
769 /* _nx_secure_tls_send_serverhello_extensions */
770 /* Send TLS ServerHello extension*/
771 /* */
772 /* RELEASE HISTORY */
773 /* */
774 /* DATE NAME DESCRIPTION */
775 /* */
776 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
777 /* 09-30-2020 Timothy Stapko Modified comment(s), */
778 /* resulting in version 6.1 */
779 /* */
780 /**************************************************************************/
781
782 #if (NX_SECURE_TLS_TLS_1_3_ENABLED) && defined (NX_SECURE_ENABLE_PSK_CIPHERSUITES) && !defined(NX_SECURE_TLS_SERVER_DISABLED)
_nx_secure_tls_send_serverhello_psk_extension(NX_SECURE_TLS_SESSION * tls_session,UCHAR * packet_buffer,ULONG * packet_length,USHORT * extension_length,ULONG available_size)783 static UINT _nx_secure_tls_send_serverhello_psk_extension(NX_SECURE_TLS_SESSION *tls_session,
784 UCHAR *packet_buffer, ULONG *packet_length,
785 USHORT *extension_length, ULONG available_size)
786 {
787 ULONG offset;
788 USHORT ext;
789
790 /* Key Share Extension structure (From TLS 1.3 RFC 8446):
791 struct {
792 opaque identity<1..2^16-1>;
793 uint32 obfuscated_ticket_age;
794 } PskIdentity;
795
796 opaque PskBinderEntry<32..255>;
797
798 struct {
799 PskIdentity identities<7..2^16-1>;
800 PskBinderEntry binders<33..2^16-1>;
801 } OfferedPsks;
802
803 struct {
804 select (Handshake.msg_type) {
805 case client_hello: OfferedPsks;
806 case server_hello: uint16 selected_identity;
807 };
808 } PreSharedKeyExtension;
809
810 identity: A label for a key. For instance, a ticket (as defined in
811 Appendix B.3.4) or a label for a pre-shared key established
812 externally.
813
814 obfuscated_ticket_age: An obfuscated version of the age of the key.
815 Section 4.2.11.1 describes how to form this value for identities
816 established via the NewSessionTicket message. For identities
817 established externally, an obfuscated_ticket_age of 0 SHOULD be
818 used, and servers MUST ignore the value.
819
820 identities: A list of the identities that the client is willing to
821 negotiate with the server. If sent alongside the "early_data"
822 extension (see Section 4.2.10), the first identity is the one used
823 for 0-RTT data.
824
825 binders: A series of HMAC values, one for each value in the
826 identities list and in the same order, computed as described
827 below.
828
829 selected_identity: The server's chosen identity expressed as a
830 (0-based) index into the identities in the client's list.
831
832
833 ServerHello extension layout:
834 | 2 | 2 | 2 |
835 | Ext Type | Extension length | Selected ID |
836 */
837 NX_PARAMETER_NOT_USED(tls_session);
838
839 /* Start with our passed-in packet offset. */
840 offset = *packet_length;
841
842 /* The extension identifier. */
843 ext = NX_SECURE_TLS_EXTENSION_PRE_SHARED_KEY;
844
845 if (tls_session == NX_NULL)
846 {
847 return(NX_PTR_ERROR);
848 }
849
850 if (available_size < (offset + 6u))
851 {
852
853 /* Packet buffer too small. */
854 return(NX_SECURE_TLS_PACKET_BUFFER_TOO_SMALL);
855 }
856
857 /* Put the extension ID into the packet. */
858 packet_buffer[offset] = (UCHAR)((ext & 0xFF00) >> 8);
859 packet_buffer[offset + 1] = (UCHAR)(ext & 0x00FF);
860 offset += 2;
861
862 /* The total extension length - only the uint16 of the selected identity field. */
863 packet_buffer[offset] = (UCHAR)(0);
864 packet_buffer[offset + 1] = (UCHAR)(2);
865 offset += 2;
866
867 /* The selected_identity index into the ClientHello PSK list. */
868 packet_buffer[offset] = (UCHAR)(0);
869 packet_buffer[offset + 1] = (UCHAR)(0);
870 offset += 2;
871
872
873 /* Return the amount of data we wrote. */
874 *extension_length = (USHORT)(offset - *packet_length);
875
876 /* Return our updated packet offset. */
877 *packet_length = offset;
878
879 return(NX_SUCCESS);
880 }
881 #endif
882
883
884