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