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 #if defined(NX_SECURE_ENABLE_ECC_CIPHERSUITE) && !defined(NX_SECURE_DISABLE_X509)
28 static UINT _nx_secure_tls_check_ciphersuite(const NX_SECURE_TLS_CIPHERSUITE_INFO *ciphersuite_info,
29 NX_SECURE_X509_CERT *cert, UINT selected_curve,
30 UINT cert_curve_supported);
31
32 #endif /* NX_SECURE_ENABLE_ECC_CIPHERSUITE && !NX_SECURE_DISABLE_X509 */
33
34 /**************************************************************************/
35 /* */
36 /* FUNCTION RELEASE */
37 /* */
38 /* _nx_secure_tls_process_clienthello PORTABLE C */
39 /* 6.2.1 */
40 /* AUTHOR */
41 /* */
42 /* Timothy Stapko, Microsoft Corporation */
43 /* */
44 /* DESCRIPTION */
45 /* */
46 /* This function processes an incoming ClientHello message from a */
47 /* remote host, kicking off a TLS handshake. */
48 /* */
49 /* INPUT */
50 /* */
51 /* tls_session TLS control block */
52 /* packet_buffer Pointer to message data */
53 /* message_length Length of message data (bytes)*/
54 /* */
55 /* OUTPUT */
56 /* */
57 /* status Completion status */
58 /* */
59 /* CALLS */
60 /* */
61 /* _nx_secure_tls_ciphersuite_lookup Lookup current ciphersuite */
62 /* _nx_secure_tls_check_protocol_version Check incoming TLS version */
63 /* _nx_secure_tls_newest_supported_version */
64 /* Get newest TLS version */
65 /* _nx_secure_tls_process_clienthello_extensions */
66 /* Process ClientHello extensions*/
67 /* _nx_secure_tls_proc_clienthello_sec_sa_extension */
68 /* Process ECC extensions */
69 /* _nx_secure_tls_check_ciphersuite Check if ECC suite is usable */
70 /* _nx_secure_tls_remote_certificate_free_all */
71 /* Free all remote certificates */
72 /* [_nx_secure_tls_session_renegotiate_callback_set] */
73 /* Renegotiation callback */
74 /* [_nx_secure_tls_session_server_callback_set] */
75 /* Server session callback */
76 /* _nx_secure_x509_local_device_certificate_get */
77 /* Get the local certificate */
78 /* */
79 /* CALLED BY */
80 /* */
81 /* _nx_secure_tls_server_handshake TLS Server state machine */
82 /* */
83 /* RELEASE HISTORY */
84 /* */
85 /* DATE NAME DESCRIPTION */
86 /* */
87 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
88 /* 09-30-2020 Timothy Stapko Modified comment(s), added */
89 /* priority ciphersuite logic, */
90 /* verified memcpy use cases, */
91 /* fixed renegotiation bug, */
92 /* improved negotiation logic, */
93 /* resulting in version 6.1 */
94 /* 10-15-2021 Timothy Stapko Modified comment(s), added */
95 /* ability to disable client */
96 /* initiated renegotiation, */
97 /* resulting in version 6.1.9 */
98 /* 04-25-2022 Yuxin Zhou Modified comment(s), fixed */
99 /* the bug of processing */
100 /* extensions, */
101 /* resulting in version 6.1.11 */
102 /* 10-31-2022 Yanwu Cai Modified comment(s), fixed */
103 /* TLS 1.3 version negotiation,*/
104 /* resulting in version 6.2.0 */
105 /* 03-08-2023 Yanwu Cai Modified comment(s), */
106 /* fixed compiler errors when */
107 /* x509 is disabled, */
108 /* resulting in version 6.2.1 */
109 /* */
110 /**************************************************************************/
_nx_secure_tls_process_clienthello(NX_SECURE_TLS_SESSION * tls_session,UCHAR * packet_buffer,UINT message_length)111 UINT _nx_secure_tls_process_clienthello(NX_SECURE_TLS_SESSION *tls_session, UCHAR *packet_buffer,
112 UINT message_length)
113 {
114 UINT length;
115 USHORT ciphersuite_list_length;
116 UCHAR compression_methods_length;
117 USHORT cipher_entry;
118 UCHAR session_id_length;
119 UINT i;
120 UINT status;
121 USHORT protocol_version;
122 USHORT newest_version;
123 UINT total_extensions_length;
124 const NX_SECURE_TLS_CIPHERSUITE_INFO *ciphersuite_info;
125 USHORT ciphersuite_priority;
126 USHORT new_ciphersuite_priority = 0;
127 NX_SECURE_TLS_HELLO_EXTENSION extension_data[NX_SECURE_TLS_HELLO_EXTENSIONS_MAX];
128 UINT num_extensions = NX_SECURE_TLS_HELLO_EXTENSIONS_MAX;
129 UCHAR *ciphersuite_list;
130 #if defined(NX_SECURE_ENABLE_ECC_CIPHERSUITE) && !defined(NX_SECURE_DISABLE_X509)
131 NX_SECURE_X509_CERT *cert;
132 UINT selected_curve;
133 UINT cert_curve;
134 UINT cert_curve_supported;
135 NX_SECURE_EC_PUBLIC_KEY *ec_pubkey;
136 NX_SECURE_TLS_ECDHE_HANDSHAKE_DATA *ecdhe_data;
137 #endif /* NX_SECURE_ENABLE_ECC_CIPHERSUITE && !NX_SECURE_DISABLE_X509 */
138 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
139 USHORT tls_1_3 = tls_session -> nx_secure_tls_1_3;
140 USHORT no_extension = NX_FALSE;
141 #endif
142
143 /* Structure of ClientHello:
144 * | 2 | 4 + 28 | 1 | <SID len> | 2 | <CS Len> | 1 | <Comp Len> | 2 | <Ext. Len> |
145 * | TLS version | Random (time + random) | SID length | Session ID | CS Len | Ciphersuites |Comp Len | Compression |Ext. Len | Extensions |
146 */
147
148 if (message_length < 38)
149 {
150 /* Message was not the minimum required size for a ClientHello. */
151 return(NX_SECURE_TLS_INCORRECT_MESSAGE_LENGTH);
152 }
153
154 /* Use our length as an index into the buffer. */
155 length = 0;
156
157 /* If we are currently in a session, we have a renegotiation handshake. */
158 if (tls_session -> nx_secure_tls_local_session_active)
159 {
160 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
161 if (tls_session->nx_secure_tls_1_3 == NX_TRUE)
162 {
163
164 /* RFC 8446, section 4.1.2, page 27.
165 * Server has negotiated TLS 1.3 and receives a ClientHello again.
166 * Send an unexpected message alert. */
167 return(NX_SECURE_TLS_UNEXPECTED_CLIENTHELLO);
168 }
169 #endif
170
171 #if !defined(NX_SECURE_TLS_DISABLE_SECURE_RENEGOTIATION)
172 /* If Client initiated renegotiation is enabled, handle the renegotiation
173 handshake if appropriate. Otherwise return "no renegotiation allowed" error. */
174 if (tls_session -> nx_secure_tls_renegotation_enabled && tls_session -> nx_secure_tls_secure_renegotiation
175 #if defined(NX_SECURE_TLS_DISABLE_CLIENT_INITIATED_RENEGOTIATION)
176 /* If client initiated renegotiation is disabled for TLS servers, only allow
177 server-initiated renegotiations requested by the server itself. */
178 && tls_session -> nx_secure_tls_server_renegotiation_requested
179 #endif
180 )
181 {
182 tls_session -> nx_secure_tls_renegotiation_handshake = NX_TRUE;
183
184 #ifndef NX_SECURE_DISABLE_X509
185
186 /* On a session resumption free all certificates for the new session.
187 * SESSION RESUMPTION: if session resumption is enabled, don't free!!
188 */
189 status = _nx_secure_tls_remote_certificate_free_all(tls_session);
190
191 if (status != NX_SUCCESS)
192 {
193 return(status);
194 }
195 #endif
196
197 /* Invoke user callback to notify application of renegotiation request. */
198 if (tls_session -> nx_secure_tls_session_renegotiation_callback != NX_NULL)
199 {
200 status = tls_session -> nx_secure_tls_session_renegotiation_callback(tls_session);
201
202 if (status != NX_SUCCESS)
203 {
204 return(status);
205 }
206 }
207
208 /* We don't want any more clienthellos to come in after this - only the first one
209 in response to our original request. */
210 tls_session -> nx_secure_tls_server_renegotiation_requested = NX_FALSE;
211 }
212 else
213 #endif /* NX_SECURE_TLS_DISABLE_SECURE_RENEGOTIATION */
214 {
215 /* Session renegotiation is disabled, so this is an error! */
216 return(NX_SECURE_TLS_NO_RENEGOTIATION_ERROR);
217 }
218 }
219
220 /* Client is establishing a TLS session with our server. */
221 /* Extract the protocol version - only part of the ClientHello message. */
222 protocol_version = (USHORT)((packet_buffer[length] << 8) | packet_buffer[length + 1]);
223 length += 2;
224
225 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
226 if (tls_session->nx_secure_tls_1_3 == NX_FALSE)
227 #endif
228 {
229
230 /* Check protocol version provided by client. */
231 status = _nx_secure_tls_check_protocol_version(tls_session, protocol_version, NX_SECURE_TLS);
232
233 if (status != NX_SECURE_TLS_SUCCESS)
234 {
235 /* If we have an active session, this is a renegotiation attempt, treat the protocol error as
236 if we are starting a new session. */
237 if (status == NX_SECURE_TLS_UNSUPPORTED_TLS_VERSION || tls_session -> nx_secure_tls_local_session_active)
238 {
239 /* If the version isn't supported, it's not an issue - TLS is backward-compatible,
240 * so negotiate the highest supported version. If the version isn't recognized,
241 * flag an error. */
242 _nx_secure_tls_highest_supported_version_negotiate(tls_session, &protocol_version, NX_SECURE_TLS);
243
244 if (protocol_version == 0x0)
245 {
246 /* Error, no versions enabled. */
247 return(NX_SECURE_TLS_UNSUPPORTED_TLS_VERSION);
248 }
249 }
250 else
251 {
252 /* Protocol version unknown (not TLS or SSL!), return status. */
253 return(status);
254 }
255 }
256 }
257
258 /* Assign our protocol version to our socket. This is used for all further communications
259 * in this session. */
260 tls_session -> nx_secure_tls_protocol_version = protocol_version;
261
262 /* Save off the random value for key generation later. */
263 NX_SECURE_MEMCPY(tls_session -> nx_secure_tls_key_material.nx_secure_tls_client_random, &packet_buffer[length], NX_SECURE_TLS_RANDOM_SIZE); /* Use case of memcpy is verified. lgtm[cpp/banned-api-usage-required-any] */
264 length += NX_SECURE_TLS_RANDOM_SIZE;
265
266 /* Extract the session ID if there is one. */
267 session_id_length = packet_buffer[length];
268 length++;
269
270 if ((length + session_id_length) > message_length)
271 {
272 return(NX_SECURE_TLS_INCORRECT_MESSAGE_LENGTH);
273 }
274
275 /* If there is a session ID, copy it into our TLS socket structure. */
276 tls_session -> nx_secure_tls_session_id_length = session_id_length;
277 if (session_id_length > 0)
278 {
279 NX_SECURE_MEMCPY(tls_session -> nx_secure_tls_session_id, &packet_buffer[length], session_id_length); /* Use case of memcpy is verified. lgtm[cpp/banned-api-usage-required-any] */
280 length += session_id_length;
281 }
282
283 /* Negotiate the ciphersuite we want to use. */
284 ciphersuite_list_length = (USHORT)((packet_buffer[length] << 8) + packet_buffer[length + 1]);
285 length += 2;
286
287 /* Make sure the list length makes sense. */
288 if (ciphersuite_list_length < 2 || (length + ciphersuite_list_length) > message_length)
289 {
290 return(NX_SECURE_TLS_INCORRECT_MESSAGE_LENGTH);
291 }
292
293 ciphersuite_list = &packet_buffer[length];
294
295 length += ciphersuite_list_length;
296
297 /* Compression methods length - one byte. For now we only support the NULL method. */
298 compression_methods_length = packet_buffer[length];
299 length++;
300
301 /* Message length overflow. */
302 if ((length + compression_methods_length) > message_length)
303 {
304 return(NX_SECURE_TLS_INCORRECT_MESSAGE_LENGTH);
305 }
306
307 /* Make sure NULL compression method is supported. */
308 status = NX_SECURE_TLS_BAD_COMPRESSION_METHOD;
309 for (i = 0; i < compression_methods_length; ++i)
310 {
311 if (packet_buffer[length + i] == 0x0)
312 {
313 status = NX_SUCCESS;
314 break;
315 }
316 }
317
318 /* Check for error. */
319 if (status != NX_SUCCESS)
320 {
321 return(status);
322 }
323
324 length += compression_methods_length;
325
326 /* Padding data? */
327 if (message_length >= (length + 2))
328 {
329
330 /* TLS Extensions come next. Get the total length of all extensions first. */
331 total_extensions_length = (USHORT)((packet_buffer[length] << 8) + packet_buffer[length + 1]);
332 length += 2;
333
334 /* Message length overflow. */
335 if ((length + total_extensions_length) > message_length)
336 {
337 return(NX_SECURE_TLS_INCORRECT_MESSAGE_LENGTH);
338 }
339
340 if (total_extensions_length > 0)
341 {
342 /* Process serverhello extensions. */
343 status = _nx_secure_tls_process_clienthello_extensions(tls_session, &packet_buffer[length], total_extensions_length, extension_data, &num_extensions, packet_buffer, message_length);
344
345 /* Check for error. */
346 if (status != NX_SUCCESS)
347 {
348 return(status);
349 }
350
351 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
352 if (tls_session -> nx_secure_tls_1_3 != tls_1_3)
353 {
354
355 /* Negotiate a version of TLS prior to TLS 1.3. */
356 return(status);
357 }
358 #endif
359
360 /* If the server callback is set, invoke it now with the extensions that require application input. */
361 if (tls_session -> nx_secure_tls_session_server_callback != NX_NULL)
362 {
363 status = tls_session -> nx_secure_tls_session_server_callback(tls_session, extension_data, num_extensions);
364
365 /* Check for error. */
366 if (status != NX_SUCCESS)
367 {
368 return(status);
369 }
370 }
371 }
372 else
373 {
374 num_extensions = 0;
375 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
376 no_extension = NX_TRUE;
377 #endif
378 }
379 }
380 else
381 {
382 num_extensions = 0;
383 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
384 no_extension = NX_TRUE;
385 #endif
386 }
387
388 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
389 if ((tls_session -> nx_secure_tls_1_3) && (no_extension == NX_TRUE))
390 {
391
392 /* Negotiate a version of TLS prior to TLS 1.3. */
393 if (tls_session -> nx_secure_tls_protocol_version_override == 0)
394 {
395 tls_session -> nx_secure_tls_1_3 = NX_FALSE;
396 #if !defined(NX_SECURE_TLS_DISABLE_SECURE_RENEGOTIATION)
397 tls_session -> nx_secure_tls_renegotation_enabled = NX_TRUE;
398 #endif /* NX_SECURE_TLS_DISABLE_SECURE_RENEGOTIATION */
399
400 return(NX_SUCCESS);
401 }
402 else
403 {
404
405 /* Protocol version is overridden to TLS 1.3. */
406 return(NX_SECURE_TLS_UNSUPPORTED_TLS_VERSION);
407 }
408 }
409 #endif
410
411 #if !defined(NX_SECURE_TLS_DISABLE_SECURE_RENEGOTIATION)
412 if ((tls_session -> nx_secure_tls_renegotiation_handshake) && (!tls_session -> nx_secure_tls_secure_renegotiation_verified))
413 {
414
415 /* The server did not receive the "renegotiation_info" extension, the handshake must be aborted. */
416 return(NX_SECURE_TLS_RENEGOTIATION_EXTENSION_ERROR);
417 }
418
419 tls_session -> nx_secure_tls_secure_renegotiation_verified = NX_FALSE;
420 #endif /* NX_SECURE_TLS_DISABLE_SECURE_RENEGOTIATION */
421
422 #if defined(NX_SECURE_ENABLE_ECC_CIPHERSUITE) && !defined(NX_SECURE_DISABLE_X509)
423
424 /* Get the local certificate. */
425 if (tls_session -> nx_secure_tls_credentials.nx_secure_tls_active_certificate != NX_NULL)
426 {
427 cert = tls_session -> nx_secure_tls_credentials.nx_secure_tls_active_certificate;
428 }
429 else
430 {
431 /* Get reference to local device certificate. NX_NULL is passed for name to get default entry. */
432 status = _nx_secure_x509_local_device_certificate_get(&tls_session -> nx_secure_tls_credentials.nx_secure_tls_certificate_store,
433 NX_NULL, &cert);
434 if (status != NX_SUCCESS)
435 {
436 cert = NX_NULL;
437 }
438 }
439
440 if (cert != NX_NULL && cert -> nx_secure_x509_public_algorithm == NX_SECURE_TLS_X509_TYPE_EC)
441 {
442 ec_pubkey = &cert -> nx_secure_x509_public_key.ec_public_key;
443 cert_curve = ec_pubkey -> nx_secure_ec_named_curve;
444 }
445 else
446 {
447 cert_curve = 0;
448 }
449
450 ecdhe_data = (NX_SECURE_TLS_ECDHE_HANDSHAKE_DATA *)tls_session -> nx_secure_tls_key_material.nx_secure_tls_new_key_material_data;
451
452 /* Parse the ECC extension of supported curve. */
453 status = _nx_secure_tls_proc_clienthello_sec_sa_extension(tls_session,
454 extension_data,
455 num_extensions,
456 &selected_curve,
457 (USHORT)cert_curve, &cert_curve_supported,
458 &ecdhe_data -> nx_secure_tls_ecdhe_signature_algorithm,
459 cert);
460
461 /* Check for error. */
462 if (status != NX_SUCCESS)
463 {
464 return(status);
465 }
466
467 ecdhe_data -> nx_secure_tls_ecdhe_named_curve = selected_curve;
468
469 /* Check if certificate curve is supported. */
470 if (cert != NX_NULL && cert -> nx_secure_x509_public_algorithm == NX_SECURE_TLS_X509_TYPE_EC)
471 {
472 if (cert_curve_supported == NX_FALSE)
473 {
474 /* The named curve in our server certificate is not supported by the client. */
475 return(NX_SECURE_TLS_NO_SUPPORTED_CIPHERS);
476 }
477 }
478 #endif /* NX_SECURE_ENABLE_ECC_CIPHERSUITE && !NX_SECURE_DISABLE_X509 */
479
480 /* Set our initial priority to the maximum value - the size of our ciphersuite crypto table. */
481 ciphersuite_priority = (USHORT)(0xFFFFFFFF);
482
483 for (i = 0; i < ciphersuite_list_length; i += 2)
484 {
485 /* Loop through list of acceptable ciphersuites. */
486 cipher_entry = (USHORT)((ciphersuite_list[i] << 8) + ciphersuite_list[i + 1]);
487
488 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
489 if ((tls_session -> nx_secure_tls_1_3 == NX_TRUE) ^ (ciphersuite_list[i] == 0x13))
490 {
491
492 /* Ciphersuites for TLS 1.3 can not be used by TLS 1.2. */
493 continue;
494 }
495 #endif
496
497 /* Look up the ciphersuite in our crypto table, then check the priority of the chosen ciphersuite. */
498 status = _nx_secure_tls_ciphersuite_lookup(tls_session, cipher_entry, &ciphersuite_info, &new_ciphersuite_priority);
499
500 /* Save the first ciphersuite we find - assume cipher table is in priority order. */
501 if ((status == NX_SUCCESS) && (new_ciphersuite_priority < ciphersuite_priority))
502 {
503 #if defined(NX_SECURE_ENABLE_ECC_CIPHERSUITE) && !defined(NX_SECURE_DISABLE_X509)
504 if (NX_SUCCESS == _nx_secure_tls_check_ciphersuite(ciphersuite_info, cert, selected_curve, cert_curve_supported))
505 #endif /* NX_SECURE_ENABLE_ECC_CIPHERSUITE */
506 {
507 /* Save the ciphersuite and its priority but continue processing the entire list to see if there
508 is a better ciphersuite available. */
509 tls_session -> nx_secure_tls_session_ciphersuite = ciphersuite_info;
510 ciphersuite_priority = new_ciphersuite_priority;
511 }
512 }
513
514 #if !defined(NX_SECURE_TLS_DISABLE_SECURE_RENEGOTIATION)
515 if (cipher_entry == TLS_EMPTY_RENEGOTIATION_INFO_SCSV)
516 {
517 if (tls_session -> nx_secure_tls_renegotiation_handshake)
518 {
519
520 /* When secure renegotiating, the server MUST verify that it
521 does not contain the TLS_EMPTY_RENEGOTIATION_INFO_SCSV SCSV. */
522 return(NX_SECURE_TLS_RENEGOTIATION_EXTENSION_ERROR);
523 }
524 else
525 {
526
527 /* Secure Renegotiation signalling ciphersuite value was encountered.
528 This indicates that the Client supports secure renegotiation. */
529 tls_session -> nx_secure_tls_secure_renegotiation = NX_TRUE;
530 }
531 }
532 #endif /* NX_SECURE_TLS_DISABLE_SECURE_RENEGOTIATION */
533
534
535 /* Check for the fallback notification SCSV. */
536 if (cipher_entry == TLS_FALLBACK_NOTIFY_SCSV)
537 {
538
539 /* A fallback is indicated by the Client, check the TLS version. */
540 _nx_secure_tls_newest_supported_version(tls_session, &newest_version, NX_SECURE_TLS);
541
542 if (protocol_version != newest_version)
543 {
544 return(NX_SECURE_TLS_INAPPROPRIATE_FALLBACK);
545 }
546 }
547 /* Continue searching client ciphersuite list to get highest-priority selection. */
548 }
549
550 #if !defined(NX_SECURE_TLS_DISABLE_SECURE_RENEGOTIATION) && defined(NX_SECURE_TLS_REQUIRE_RENEGOTIATION_EXT)
551 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
552 if (!tls_session -> nx_secure_tls_1_3)
553 #endif /* NX_SECURE_TLS_TLS_1_3_ENABLED */
554 {
555 if ((tls_session -> nx_secure_tls_renegotation_enabled) && (!tls_session -> nx_secure_tls_secure_renegotiation))
556 {
557
558 /* No "renegotiation_info" extension present, some servers may want to terminate the handshake. */
559 return(NX_SECURE_TLS_RENEGOTIATION_EXTENSION_ERROR);
560 }
561 }
562 #endif /* !NX_SECURE_TLS_DISABLE_SECURE_RENEGOTIATION && NX_SECURE_TLS_REQUIRE_RENEGOTIATION_EXT */
563
564 /* See if we found an acceptable ciphersuite. */
565 if (tls_session -> nx_secure_tls_session_ciphersuite == NX_NULL)
566 {
567
568 /* No supported ciphersuites found. */
569 return(NX_SECURE_TLS_NO_SUPPORTED_CIPHERS);
570 }
571
572 #ifdef NX_SECURE_TLS_SERVER_DISABLED
573 /* If TLS Server is disabled and we have processed a ClientHello, something is wrong... */
574 tls_session -> nx_secure_tls_client_state = NX_SECURE_TLS_CLIENT_STATE_ERROR;
575 return(NX_SECURE_TLS_INVALID_STATE);
576 #else
577 return(NX_SUCCESS);
578 #endif
579 }
580
581 /**************************************************************************/
582 /* */
583 /* FUNCTION RELEASE */
584 /* */
585 /* _nx_secure_tls_check_ciphersuite PORTABLE C */
586 /* 6.1 */
587 /* AUTHOR */
588 /* */
589 /* Timothy Stapko, Microsoft Corporation */
590 /* */
591 /* DESCRIPTION */
592 /* */
593 /* This function checks whether the specified ciphersuite is */
594 /* suitable for the server certificate, the curve in the certificate */
595 /* and the common shared curve. */
596 /* */
597 /* INPUT */
598 /* */
599 /* ciphersuite_info The specified cipher suite */
600 /* cert Local server certificate */
601 /* selected_curve Curve selected for ECC */
602 /* cert_curve_supported If cert curve is supported */
603 /* */
604 /* OUTPUT */
605 /* */
606 /* status Completion status */
607 /* */
608 /* CALLS */
609 /* */
610 /* None */
611 /* */
612 /* CALLED BY */
613 /* */
614 /* _nx_secure_tls_server_handshake TLS Server state machine */
615 /* */
616 /* RELEASE HISTORY */
617 /* */
618 /* DATE NAME DESCRIPTION */
619 /* */
620 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
621 /* 09-30-2020 Timothy Stapko Modified comment(s), */
622 /* resulting in version 6.1 */
623 /* */
624 /**************************************************************************/
625 #if defined(NX_SECURE_ENABLE_ECC_CIPHERSUITE) && !defined(NX_SECURE_DISABLE_X509)
_nx_secure_tls_check_ciphersuite(const NX_SECURE_TLS_CIPHERSUITE_INFO * ciphersuite_info,NX_SECURE_X509_CERT * cert,UINT selected_curve,UINT cert_curve_supported)626 static UINT _nx_secure_tls_check_ciphersuite(const NX_SECURE_TLS_CIPHERSUITE_INFO *ciphersuite_info,
627 NX_SECURE_X509_CERT *cert, UINT selected_curve,
628 UINT cert_curve_supported)
629 {
630 if (ciphersuite_info -> nx_secure_tls_public_cipher == NX_NULL)
631 {
632 return(NX_SUCCESS);
633 }
634
635 if (ciphersuite_info -> nx_secure_tls_public_auth == NX_NULL)
636 {
637 return(NX_SUCCESS);
638 }
639
640 switch (ciphersuite_info -> nx_secure_tls_public_cipher -> nx_crypto_algorithm)
641 {
642 case NX_CRYPTO_KEY_EXCHANGE_ECDHE:
643 if (selected_curve == 0 || cert == NX_NULL)
644 {
645 /* No common named curve supported for ECDHE. */
646 return(NX_SECURE_TLS_UNSUPPORTED_PUBLIC_CIPHER);
647 }
648
649 if (ciphersuite_info -> nx_secure_tls_public_auth -> nx_crypto_algorithm == NX_CRYPTO_DIGITAL_SIGNATURE_ECDSA)
650 {
651 if (cert -> nx_secure_x509_public_algorithm != NX_SECURE_TLS_X509_TYPE_EC)
652 {
653 /* ECDSA auth requires EC certificate. */
654 return(NX_SECURE_TLS_UNSUPPORTED_PUBLIC_CIPHER);
655 }
656 }
657 else
658 {
659 if (cert -> nx_secure_x509_public_algorithm != NX_SECURE_TLS_X509_TYPE_RSA)
660 {
661 /* RSA auth requires RSA certificate. */
662 return(NX_SECURE_TLS_UNSUPPORTED_PUBLIC_CIPHER);
663 }
664 }
665
666 break;
667
668 case NX_CRYPTO_KEY_EXCHANGE_ECDH:
669 if (selected_curve == 0)
670 {
671 /* No common named curve supported supported. */
672 return(NX_SECURE_TLS_UNSUPPORTED_PUBLIC_CIPHER);
673 }
674
675 /* Check for ECDH_anon. */
676 if (ciphersuite_info -> nx_secure_tls_public_auth -> nx_crypto_algorithm != NX_CRYPTO_DIGITAL_SIGNATURE_ANONYMOUS)
677 {
678 /* ECDH key exchange requires an EC certificate. */
679 if (cert == NX_NULL || cert -> nx_secure_x509_public_algorithm != NX_SECURE_TLS_X509_TYPE_EC)
680 {
681 return(NX_SECURE_TLS_UNSUPPORTED_PUBLIC_CIPHER);
682 }
683
684 if (cert_curve_supported == NX_FALSE)
685 {
686 return(NX_SECURE_TLS_UNSUPPORTED_PUBLIC_CIPHER);
687 }
688
689 /* Check the signatureAlgorithm of the certificate to determine the public auth algorithm. */
690 if (ciphersuite_info -> nx_secure_tls_public_auth -> nx_crypto_algorithm == NX_CRYPTO_DIGITAL_SIGNATURE_ECDSA)
691 {
692 if (cert -> nx_secure_x509_signature_algorithm != NX_SECURE_TLS_X509_TYPE_ECDSA_SHA_1 &&
693 cert -> nx_secure_x509_signature_algorithm != NX_SECURE_TLS_X509_TYPE_ECDSA_SHA_224 &&
694 cert -> nx_secure_x509_signature_algorithm != NX_SECURE_TLS_X509_TYPE_ECDSA_SHA_256 &&
695 cert -> nx_secure_x509_signature_algorithm != NX_SECURE_TLS_X509_TYPE_ECDSA_SHA_384 &&
696 cert -> nx_secure_x509_signature_algorithm != NX_SECURE_TLS_X509_TYPE_ECDSA_SHA_512)
697 {
698 return(NX_SECURE_TLS_UNSUPPORTED_PUBLIC_CIPHER);
699 }
700 }
701 else
702 {
703 if (cert -> nx_secure_x509_signature_algorithm != NX_SECURE_TLS_X509_TYPE_RSA_MD5 &&
704 cert -> nx_secure_x509_signature_algorithm != NX_SECURE_TLS_X509_TYPE_RSA_SHA_1 &&
705 cert -> nx_secure_x509_signature_algorithm != NX_SECURE_TLS_X509_TYPE_RSA_SHA_256 &&
706 cert -> nx_secure_x509_signature_algorithm != NX_SECURE_TLS_X509_TYPE_RSA_SHA_384 &&
707 cert -> nx_secure_x509_signature_algorithm != NX_SECURE_TLS_X509_TYPE_RSA_SHA_512)
708 {
709 return(NX_SECURE_TLS_UNSUPPORTED_PUBLIC_CIPHER);
710 }
711 }
712 }
713 break;
714
715 case NX_CRYPTO_KEY_EXCHANGE_RSA:
716 if (cert == NX_NULL || cert -> nx_secure_x509_public_algorithm != NX_SECURE_TLS_X509_TYPE_RSA)
717 {
718 /* RSA key exchange requires RSA certificate. */
719 return(NX_SECURE_TLS_UNSUPPORTED_PUBLIC_CIPHER);
720 }
721 break;
722
723 default:
724 break;
725 }
726
727 return(NX_SUCCESS);
728 }
729 #endif /* NX_SECURE_ENABLE_ECC_CIPHERSUITE && !NX_SECURE_DISABLE_X509 */
730