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 /** Datagram Transport Layer Security (DTLS) */
19 /** */
20 /**************************************************************************/
21 /**************************************************************************/
22
23 #define NX_SECURE_SOURCE_CODE
24
25 #include "nx_secure_dtls.h"
26
27 #ifdef NX_SECURE_ENABLE_DTLS
28 #ifdef NX_SECURE_ENABLE_ECJPAKE_CIPHERSUITE
29 extern NX_CRYPTO_METHOD crypto_method_ec_secp256;
30 #endif /* NX_SECURE_ENABLE_ECJPAKE_CIPHERSUITE */
31
32 #if defined(NX_SECURE_ENABLE_ECC_CIPHERSUITE) && !defined(NX_SECURE_DISABLE_X509)
33 static UINT _nx_secure_dtls_check_ciphersuite(const NX_SECURE_TLS_CIPHERSUITE_INFO *ciphersuite_info,
34 NX_SECURE_X509_CERT *cert, UINT selected_curve,
35 UINT cert_curve_supported);
36 #endif /* NX_SECURE_ENABLE_ECC_CIPHERSUITE && !NX_SECURE_DISABLE_X509 */
37
38 /**************************************************************************/
39 /* */
40 /* FUNCTION RELEASE */
41 /* */
42 /* _nx_secure_dtls_process_clienthello PORTABLE C */
43 /* 6.2.1 */
44 /* AUTHOR */
45 /* */
46 /* Timothy Stapko, Microsoft Corporation */
47 /* */
48 /* DESCRIPTION */
49 /* */
50 /* This function processes an incoming ClientHello message from a */
51 /* remote host, kicking off a DTLS handshake. */
52 /* */
53 /* INPUT */
54 /* */
55 /* dtls_session DTLS control block */
56 /* packet_buffer Pointer to message data */
57 /* message_length Length of message data (bytes)*/
58 /* */
59 /* OUTPUT */
60 /* */
61 /* status Completion status */
62 /* */
63 /* CALLS */
64 /* */
65 /* _nx_secure_tls_check_protocol_version Check protocol version */
66 /* _nx_secure_tls_ciphersuite_lookup Get cipher information */
67 /* _nx_secure_tls_proc_clienthello_sec_sa_extension */
68 /* Process ECC extensions */
69 /* _nx_secure_dtls_check_ciphersuite Check if ECC suite is usable */
70 /* _nx_secure_x509_local_device_certificate_get */
71 /* Get the local certificate */
72 /* [nx_crypto_init] Initialize crypto */
73 /* [nx_crypto_operation] Crypto operation */
74 /* */
75 /* CALLED BY */
76 /* */
77 /* _nx_secure_dtls_server_handshake DTLS server state machine */
78 /* */
79 /* RELEASE HISTORY */
80 /* */
81 /* DATE NAME DESCRIPTION */
82 /* */
83 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
84 /* 09-30-2020 Timothy Stapko Modified comment(s), added */
85 /* priority ciphersuite logic, */
86 /* verified memcpy use cases, */
87 /* fixed configuration problem */
88 /* that would result in */
89 /* compiler error, fixed */
90 /* renegotiation bug, */
91 /* improved negotiation logic, */
92 /* resulting in version 6.1 */
93 /* 12-31-2020 Timothy Stapko Modified comment(s), */
94 /* improved buffer length */
95 /* verification, */
96 /* resulting in version 6.1.3 */
97 /* 03-08-2023 Yanwu Cai Modified comment(s), */
98 /* fixed compiler errors when */
99 /* x509 is disabled, */
100 /* resulting in version 6.2.1 */
101 /* */
102 /**************************************************************************/
_nx_secure_dtls_process_clienthello(NX_SECURE_DTLS_SESSION * dtls_session,UCHAR * packet_buffer,UINT message_length)103 UINT _nx_secure_dtls_process_clienthello(NX_SECURE_DTLS_SESSION *dtls_session, UCHAR *packet_buffer,
104 UINT message_length)
105 {
106 USHORT ciphersuite_list_length;
107 UCHAR compression_methods_length;
108 USHORT cipher_entry;
109 UCHAR session_id_length;
110 UINT i;
111 UINT status;
112 USHORT protocol_version;
113 UINT total_extensions_length;
114 const NX_SECURE_TLS_CIPHERSUITE_INFO *ciphersuite_info = NX_NULL;
115 USHORT ciphersuite_priority;
116 USHORT new_ciphersuite_priority = 0;
117 NX_SECURE_TLS_SESSION *tls_session;
118 NX_SECURE_TLS_HELLO_EXTENSION extension_data[NX_SECURE_TLS_HELLO_EXTENSIONS_MAX];
119 UINT num_extensions = NX_SECURE_TLS_HELLO_EXTENSIONS_MAX;
120 UCHAR *ciphersuite_list;
121 UCHAR *packet_buffer_start;
122 #ifdef NX_SECURE_ENABLE_ECJPAKE_CIPHERSUITE
123 INT extension_total_length;
124 USHORT extension_length;
125 USHORT extension_type;
126 USHORT supported_ec_length;
127 UCHAR ec_point_formats_length;
128 UCHAR supported_ec_match, ec_point_formats_match, zkp_verified;
129 const NX_CRYPTO_METHOD *crypto_method;
130 NX_SECURE_TLS_PSK_STORE *psk_store;
131 #endif /* NX_SECURE_ENABLE_ECJPAKE_CIPHERSUITE */
132 #if defined(NX_SECURE_ENABLE_ECC_CIPHERSUITE) && !defined(NX_SECURE_DISABLE_X509)
133 NX_SECURE_X509_CERT *cert;
134 UINT selected_curve;
135 UINT cert_curve;
136 UINT cert_curve_supported;
137 NX_SECURE_EC_PUBLIC_KEY *ec_pubkey;
138 NX_SECURE_TLS_ECDHE_HANDSHAKE_DATA *ecdhe_data;
139 #endif /* NX_SECURE_ENABLE_ECC_CIPHERSUITE && !NX_SECURE_DISABLE_X509 */
140
141
142 /* Structure of ClientHello:
143 * | 2 | 4 + 28 | 1 | <SID len> | 2 | <CS Len> | 1 | <Comp Len> | 2 | <Ext. Len> |
144 * | TLS version | Random (time + random) | SID length | Session ID | CS Len | Ciphersuites |Comp Len | Compression |Ext. Len | Extensions |
145 */
146
147 if (message_length < 38)
148 {
149 /* Message was not the minimum required size for a ClientHello. */
150 return(NX_SECURE_TLS_INCORRECT_MESSAGE_LENGTH);
151 }
152
153 /* Get a pointer to the start of our packet buffer so we can read ahead later. */
154 packet_buffer_start = packet_buffer;
155
156 /* Get a reference to TLS state. */
157 tls_session = &dtls_session -> nx_secure_dtls_tls_session;
158
159 /* If we are currently in a session, we have a renegotiation handshake. */
160 if (tls_session -> nx_secure_tls_local_session_active)
161 {
162
163 /* Session renegotiation is disabled, send a "no_renegotiation" alert! */
164 return(NX_SECURE_TLS_NO_RENEGOTIATION_ERROR);
165 }
166
167 /* Client is establishing a TLS session with our server. */
168 /* Extract the protocol version - only part of the ClientHello message. */
169 protocol_version = (USHORT)(((USHORT)packet_buffer[0] << 8) | packet_buffer[1]);
170 packet_buffer += 2;
171
172
173 /* Check protocol version provided by client. */
174 status = _nx_secure_tls_check_protocol_version(tls_session, protocol_version, NX_SECURE_DTLS);
175
176 if (status != NX_SECURE_TLS_SUCCESS)
177 {
178 /* If we have an active session, this is a renegotiation attempt, treat the protocol error as
179 if we are starting a new session. */
180 if (status == NX_SECURE_TLS_UNSUPPORTED_TLS_VERSION || tls_session -> nx_secure_tls_local_session_active)
181 {
182 /* If the version isn't supported, it's not an issue - TLS is backward-compatible,
183 * so pick the highest version we do support. If the version isn't recognized,
184 * flag an error. */
185 _nx_secure_tls_highest_supported_version_negotiate(tls_session, &protocol_version, NX_SECURE_DTLS);
186
187 if (protocol_version == 0x0)
188 {
189 /* Error, no versions enabled. */
190 return(NX_SECURE_TLS_UNSUPPORTED_TLS_VERSION);
191 }
192 }
193 else
194 {
195 /* Protocol version unknown (not TLS or SSL!), return status. */
196 return(status);
197 }
198 }
199
200 /* Assign our protocol version to our socket. This is used for all further communications
201 * in this session. */
202 tls_session -> nx_secure_tls_protocol_version = protocol_version;
203
204 /* Save off the random value for key generation later. */
205 NX_SECURE_MEMCPY(tls_session -> nx_secure_tls_key_material.nx_secure_tls_client_random, packet_buffer, NX_SECURE_TLS_RANDOM_SIZE); /* Use case of memcpy is verified. */
206 packet_buffer += NX_SECURE_TLS_RANDOM_SIZE;
207
208 /* Extract the session ID if there is one. */
209 session_id_length = packet_buffer[0];
210 packet_buffer++;
211
212 /* If there is a session ID, copy it into our TLS socket structure. */
213 tls_session -> nx_secure_tls_session_id_length = session_id_length;
214 if (session_id_length > 0)
215 {
216 NX_SECURE_MEMCPY(tls_session -> nx_secure_tls_session_id, &packet_buffer[0], session_id_length); /* Use case of memcpy is verified. */
217 packet_buffer += session_id_length;
218 }
219
220 /* DTLS - there might be a cookie we need to save. */
221
222 /* Extract the cookie from the client. */
223 dtls_session -> nx_secure_dtls_cookie_length = packet_buffer[0];
224 packet_buffer += 1;
225
226 if (dtls_session -> nx_secure_dtls_cookie_length > sizeof(dtls_session -> nx_secure_dtls_cookie))
227 {
228 return(NX_SECURE_TLS_INCORRECT_MESSAGE_LENGTH);
229 }
230
231 if (dtls_session -> nx_secure_dtls_cookie_length > 0)
232 {
233 NX_SECURE_MEMCPY(dtls_session -> nx_secure_dtls_cookie, packet_buffer, dtls_session -> nx_secure_dtls_cookie_length); /* Use case of memcpy is verified. */
234 packet_buffer += dtls_session -> nx_secure_dtls_cookie_length;
235 }
236
237 /* Negotiate the ciphersuite we want to use. */
238 ciphersuite_list_length = (USHORT)((packet_buffer[0] << 8) + packet_buffer[1]);
239 packet_buffer += 2;
240
241 /* Make sure the list length makes sense. */
242 if (ciphersuite_list_length > message_length)
243 {
244 return(NX_SECURE_TLS_INCORRECT_MESSAGE_LENGTH);
245 }
246
247 ciphersuite_list = packet_buffer;
248 packet_buffer += ciphersuite_list_length;
249
250 /* Compression methods length - one byte. For now we only support the NULL method. */
251 compression_methods_length = packet_buffer[0];
252 packet_buffer += 1;
253
254 /* Message length overflow. */
255 if (((UINT)(packet_buffer - packet_buffer_start + compression_methods_length)) > message_length)
256 {
257 return(NX_SECURE_TLS_INCORRECT_MESSAGE_LENGTH);
258 }
259
260 /* Make sure NULL compression method is supported. */
261 status = NX_SECURE_TLS_BAD_COMPRESSION_METHOD;
262 for (i = 0; i < compression_methods_length; ++i)
263 {
264 if (packet_buffer[i] == 0x0)
265 {
266 status = NX_SUCCESS;
267 break;
268 }
269 }
270
271 /* Check for error. */
272 if (status != NX_SUCCESS)
273 {
274 return(status);
275 }
276
277 packet_buffer += compression_methods_length;
278
279 /* Padding data? */
280 if (message_length >= (UINT)(packet_buffer - packet_buffer_start + 2))
281 {
282
283 /* TLS Extensions come next. Get the total length of all extensions first. */
284 total_extensions_length = (USHORT)((packet_buffer[0] << 8) + packet_buffer[1]);
285
286 /* Message length overflow. */
287 if (((UINT)(packet_buffer - packet_buffer_start + 2) + total_extensions_length) > message_length)
288 {
289 return(NX_SECURE_TLS_INCORRECT_MESSAGE_LENGTH);
290 }
291
292 if (total_extensions_length > 0)
293 {
294 /* Process serverhello extensions. */
295 status = _nx_secure_tls_process_clienthello_extensions(tls_session, &packet_buffer[2], total_extensions_length, extension_data, &num_extensions, packet_buffer, message_length);
296
297 /* Check for error. */
298 if (status != NX_SUCCESS)
299 {
300 return(status);
301 }
302
303 /* If the server callback is set, invoke it now with the extensions that require application input. */
304 if (tls_session -> nx_secure_tls_session_server_callback != NX_NULL)
305 {
306 status = tls_session -> nx_secure_tls_session_server_callback(tls_session, extension_data, num_extensions);
307
308 /* Check for error. */
309 if (status != NX_SUCCESS)
310 {
311 return(status);
312 }
313 }
314 }
315 }
316
317 #if defined(NX_SECURE_ENABLE_ECC_CIPHERSUITE) && !defined(NX_SECURE_DISABLE_X509)
318
319 /* Get the local certificate. */
320 if (tls_session -> nx_secure_tls_credentials.nx_secure_tls_active_certificate != NX_NULL)
321 {
322 cert = tls_session -> nx_secure_tls_credentials.nx_secure_tls_active_certificate;
323 }
324 else
325 {
326 /* Get reference to local device certificate. NX_NULL is passed for name to get default entry. */
327 status = _nx_secure_x509_local_device_certificate_get(&tls_session -> nx_secure_tls_credentials.nx_secure_tls_certificate_store,
328 NX_NULL, &cert);
329 if (status != NX_SUCCESS)
330 {
331 cert = NX_NULL;
332 }
333 }
334
335 if (cert != NX_NULL && cert -> nx_secure_x509_public_algorithm == NX_SECURE_TLS_X509_TYPE_EC)
336 {
337 ec_pubkey = &cert -> nx_secure_x509_public_key.ec_public_key;
338 cert_curve = ec_pubkey -> nx_secure_ec_named_curve;
339 }
340 else
341 {
342 cert_curve = 0;
343 }
344
345 ecdhe_data = (NX_SECURE_TLS_ECDHE_HANDSHAKE_DATA *)tls_session -> nx_secure_tls_key_material.nx_secure_tls_new_key_material_data;
346
347 /* Parse the ECC extension of supported curve. */
348 status = _nx_secure_tls_proc_clienthello_sec_sa_extension(tls_session,
349 extension_data,
350 num_extensions,
351 &selected_curve,
352 (USHORT)cert_curve, &cert_curve_supported,
353 &ecdhe_data -> nx_secure_tls_ecdhe_signature_algorithm,
354 cert);
355
356 ecdhe_data -> nx_secure_tls_ecdhe_named_curve = selected_curve;
357
358 /* Select signature algorithm by certificate type. */
359 if (cert != NX_NULL && cert -> nx_secure_x509_public_algorithm == NX_SECURE_TLS_X509_TYPE_EC)
360 {
361 ecdhe_data -> nx_secure_tls_ecdhe_signature_algorithm =
362 (USHORT)((ecdhe_data -> nx_secure_tls_ecdhe_signature_algorithm & 0xFF00) | NX_SECURE_TLS_SIGNATURE_ALGORITHM_ECDSA);
363
364 if (cert_curve_supported == NX_FALSE)
365 {
366 /* The named curve in our server certificate is not supported by the client. */
367 return(NX_SECURE_TLS_NO_SUPPORTED_CIPHERS);
368 }
369 }
370 else if (cert != NX_NULL && cert -> nx_secure_x509_public_algorithm == NX_SECURE_TLS_X509_TYPE_RSA)
371 {
372 ecdhe_data -> nx_secure_tls_ecdhe_signature_algorithm =
373 (USHORT)((ecdhe_data -> nx_secure_tls_ecdhe_signature_algorithm & 0xFF00) | NX_SECURE_TLS_SIGNATURE_ALGORITHM_RSA);
374 }
375 #endif /* NX_SECURE_ENABLE_ECC_CIPHERSUITE && !NX_SECURE_DISABLE_X509 */
376
377 /* Set our initial priority to the maximum value - the size of our ciphersuite crypto table. */
378 ciphersuite_priority = (USHORT)(0xFFFFFFFF);
379
380 for (i = 0; i < ciphersuite_list_length; i += 2)
381 {
382 /* Loop through list of acceptable ciphersuites. */
383 cipher_entry = (USHORT)((ciphersuite_list[i] << 8) + ciphersuite_list[i + 1]);
384
385 status = _nx_secure_tls_ciphersuite_lookup(tls_session, cipher_entry, &ciphersuite_info, &new_ciphersuite_priority);
386
387 if (status == NX_SUCCESS && (new_ciphersuite_priority < ciphersuite_priority))
388 {
389 #if defined(NX_SECURE_ENABLE_ECC_CIPHERSUITE) && !defined(NX_SECURE_DISABLE_X509)
390 if (NX_SUCCESS == _nx_secure_dtls_check_ciphersuite(ciphersuite_info, cert, selected_curve, cert_curve_supported))
391 #endif /* NX_SECURE_ENABLE_ECC_CIPHERSUITE && !NX_SECURE_DISABLE_X509 */
392 {
393 tls_session -> nx_secure_tls_session_ciphersuite = ciphersuite_info;
394 ciphersuite_priority = new_ciphersuite_priority;
395 }
396 }
397 }
398
399 /* See if we found an acceptable ciphersuite. */
400 if (tls_session -> nx_secure_tls_session_ciphersuite == NX_NULL)
401 {
402
403 /* No supported ciphersuites found. */
404 return(NX_SECURE_TLS_NO_SUPPORTED_CIPHERS);
405 }
406
407 #ifdef NX_SECURE_ENABLE_ECJPAKE_CIPHERSUITE
408
409 /* Check if there are extensions. */
410 if ((ciphersuite_info -> nx_secure_tls_public_auth -> nx_crypto_algorithm == NX_CRYPTO_KEY_EXCHANGE_ECJPAKE) &&
411 (dtls_session -> nx_secure_dtls_cookie_length != 0))
412 {
413
414 if (packet_buffer - packet_buffer_start > (INT)message_length - 2)
415 {
416 return(NX_SECURE_TLS_HANDSHAKE_FAILURE);
417 }
418
419 extension_total_length = (packet_buffer[0] << 8) + packet_buffer[1];
420 packet_buffer += 2;
421
422 /* Make sure the extension length make sense. */
423 if (packet_buffer - packet_buffer_start + extension_total_length > (INT)message_length)
424 {
425 return(NX_SECURE_TLS_INCORRECT_MESSAGE_LENGTH);
426 }
427
428 supported_ec_match = 0;
429 ec_point_formats_match = 0;
430 zkp_verified = 0;
431
432 crypto_method = ciphersuite_info -> nx_secure_tls_public_auth;
433 if (crypto_method == NX_NULL)
434 {
435 return(NX_SECURE_TLS_HANDSHAKE_FAILURE);
436 }
437
438 if (crypto_method -> nx_crypto_init == NX_NULL)
439 {
440 return(NX_SECURE_TLS_HANDSHAKE_FAILURE);
441 }
442
443 if (tls_session -> nx_secure_tls_credentials.nx_secure_tls_psk_count == 0)
444 {
445 return(NX_SECURE_TLS_HANDSHAKE_FAILURE);
446 }
447
448 psk_store = &tls_session -> nx_secure_tls_credentials.nx_secure_tls_psk_store[0];
449 status = crypto_method -> nx_crypto_init((NX_CRYPTO_METHOD*)crypto_method,
450 psk_store -> nx_secure_tls_psk_data,
451 (USHORT)(psk_store -> nx_secure_tls_psk_data_size << 3),
452 NX_NULL,
453 tls_session -> nx_secure_public_auth_metadata_area,
454 tls_session -> nx_secure_public_auth_metadata_size);
455
456 if (status)
457 {
458 return(status);
459 }
460
461 status = crypto_method -> nx_crypto_operation(NX_CRYPTO_ECJPAKE_HASH_METHOD_SET,
462 NX_NULL,
463 (NX_CRYPTO_METHOD*)crypto_method,
464 NX_NULL,
465 (USHORT)(tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_sha256_metadata_size << 3),
466 (UCHAR *)(tls_session -> nx_secure_tls_crypto_table -> nx_secure_tls_handshake_hash_sha256_method),
467 sizeof(NX_CRYPTO_METHOD),
468 NX_NULL, NX_NULL, 0,
469 tls_session -> nx_secure_public_auth_metadata_area,
470 tls_session -> nx_secure_public_auth_metadata_size,
471 NX_NULL, NX_NULL);
472 if (status)
473 {
474 return(status);
475 }
476
477 status = crypto_method -> nx_crypto_operation(NX_CRYPTO_ECJPAKE_CURVE_SET,
478 NX_NULL,
479 (NX_CRYPTO_METHOD*)crypto_method,
480 NX_NULL, 0,
481 (UCHAR *)&crypto_method_ec_secp256,
482 sizeof(NX_CRYPTO_METHOD),
483 NX_NULL, NX_NULL, 0,
484 tls_session -> nx_secure_public_auth_metadata_area,
485 tls_session -> nx_secure_public_auth_metadata_size,
486 NX_NULL, NX_NULL);
487 if (status)
488 {
489 return(status);
490 }
491
492 /* Loop through all the extensions. */
493 while (extension_total_length > 0)
494 {
495 /* Get Extension Type. */
496 extension_type = (USHORT)((packet_buffer[0] << 8) + packet_buffer[1]);
497 packet_buffer += 2;
498
499 /* Get Extension Length. */
500 extension_length = (USHORT)((packet_buffer[0] << 8) + packet_buffer[1]);
501 packet_buffer += 2;
502
503 extension_total_length -= 4;
504
505 /* Make sure Extension Length is within the total extension length. */
506 if (extension_length > extension_total_length)
507 {
508 return(NX_SECURE_TLS_INCORRECT_MESSAGE_LENGTH);
509 }
510
511 extension_total_length -= extension_length;
512
513 switch (extension_type)
514 {
515 case NX_SECURE_TLS_EXTENSION_EC_GROUPS:
516 /* Supported Elliptic Curves Extension. */
517 supported_ec_length = (USHORT)((packet_buffer[0] << 8) + packet_buffer[1]);
518 packet_buffer += 2;
519
520 /* Make sure secp256r1 (23) format is supported. */
521 status = NX_SECURE_TLS_UNSUPPORTED_CIPHER;
522 for (i = 0; i < (UINT)(supported_ec_length >> 1); ++i)
523 {
524 if (packet_buffer[i * 2] == 0x0 && packet_buffer[i * 2 + 1] == 0x17)
525 {
526 status = NX_SUCCESS;
527 break;
528 }
529 }
530
531 /* Check for error. */
532 if (status != NX_SUCCESS)
533 {
534 return(status);
535 }
536
537 packet_buffer += supported_ec_length;
538 supported_ec_match = 1;
539 break;
540
541 case NX_SECURE_TLS_EXTENSION_EC_POINT_FORMATS:
542 /* ec_point_formats Extension. */
543 ec_point_formats_length = packet_buffer[0];
544 packet_buffer += 1;
545
546 /* Make sure uncompressed (0) format is supported. */
547 status = NX_SECURE_TLS_UNSUPPORTED_CIPHER;
548 for (i = 0; i < ec_point_formats_length; ++i)
549 {
550 if (packet_buffer[i] == 0x0)
551 {
552 status = NX_SUCCESS;
553 break;
554 }
555 }
556
557 /* Check for error. */
558 if (status != NX_SUCCESS)
559 {
560 return(status);
561 }
562
563 packet_buffer += ec_point_formats_length;
564 ec_point_formats_match = 1;
565 break;
566
567 case NX_SECURE_TLS_EXTENSION_ECJPAKE_KEY_KP_PAIR:
568 /* ecjpake_key_kp_pair Extension. */
569 status = crypto_method -> nx_crypto_operation(NX_CRYPTO_ECJPAKE_CLIENT_HELLO_PROCESS,
570 NX_NULL,
571 (NX_CRYPTO_METHOD*)crypto_method,
572 NX_NULL, 0,
573 packet_buffer, extension_length,
574 NX_NULL, NX_NULL, 0,
575 tls_session -> nx_secure_public_auth_metadata_area,
576 tls_session -> nx_secure_public_auth_metadata_size,
577 NX_NULL, NX_NULL);
578 if (status)
579 {
580 return(status);
581 }
582
583 packet_buffer += extension_length;
584
585 zkp_verified = 1;
586 break;
587 }
588 }
589
590 /* Make sure no extension is missing. */
591 if (supported_ec_match == 0 || ec_point_formats_match == 0 || zkp_verified == 0)
592 {
593 return(NX_SECURE_TLS_UNSUPPORTED_ECC_FORMAT);
594 }
595 }
596 #endif
597
598 #ifdef NX_SECURE_TLS_SERVER_DISABLED
599 /* If TLS Server is disabled and we have processed a ClientHello, something is wrong... */
600 tls_session -> nx_secure_tls_client_state = NX_SECURE_TLS_CLIENT_STATE_ERROR;
601 return(NX_SECURE_TLS_INVALID_STATE);
602 #else
603 if (dtls_session -> nx_secure_dtls_cookie_length == 0)
604 {
605 /* In DTLS, we actually send a HelloVerifyReqeust (expecting a second ClientHello in
606 * response) before sending our ServerHello. */
607 dtls_session -> nx_secure_dtls_tls_session.nx_secure_tls_server_state = NX_SECURE_TLS_SERVER_STATE_SEND_HELLO_VERIFY;
608 }
609 else
610 {
611 dtls_session -> nx_secure_dtls_tls_session.nx_secure_tls_server_state = NX_SECURE_TLS_SERVER_STATE_SEND_HELLO;
612 }
613 return(NX_SUCCESS);
614 #endif
615 }
616
617 /**************************************************************************/
618 /* */
619 /* FUNCTION RELEASE */
620 /* */
621 /* _nx_secure_dtls_check_ciphersuite PORTABLE C */
622 /* 6.1 */
623 /* AUTHOR */
624 /* */
625 /* Timothy Stapko, Microsoft Corporation */
626 /* */
627 /* DESCRIPTION */
628 /* */
629 /* This function checks whether the specified ciphersuite is */
630 /* suitable for the server certificate, the curve in the certificate */
631 /* and the common shared curve. */
632 /* */
633 /* INPUT */
634 /* */
635 /* ciphersuite_info The specified cipher suite */
636 /* cert Local server certificate */
637 /* selected_curve Curve selected for ECC */
638 /* cert_curve_supported If cert curve is supported */
639 /* */
640 /* OUTPUT */
641 /* */
642 /* status Completion status */
643 /* */
644 /* CALLS */
645 /* */
646 /* None */
647 /* */
648 /* CALLED BY */
649 /* */
650 /* _nx_secure_dtls_process_clienthello Process ClientHello */
651 /* */
652 /* RELEASE HISTORY */
653 /* */
654 /* DATE NAME DESCRIPTION */
655 /* */
656 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
657 /* 09-30-2020 Timothy Stapko Modified comment(s), */
658 /* resulting in version 6.1 */
659 /* */
660 /**************************************************************************/
661 #if defined(NX_SECURE_ENABLE_ECC_CIPHERSUITE) && !defined(NX_SECURE_DISABLE_X509)
_nx_secure_dtls_check_ciphersuite(const NX_SECURE_TLS_CIPHERSUITE_INFO * ciphersuite_info,NX_SECURE_X509_CERT * cert,UINT selected_curve,UINT cert_curve_supported)662 static UINT _nx_secure_dtls_check_ciphersuite(const NX_SECURE_TLS_CIPHERSUITE_INFO *ciphersuite_info,
663 NX_SECURE_X509_CERT *cert, UINT selected_curve,
664 UINT cert_curve_supported)
665 {
666 if (ciphersuite_info -> nx_secure_tls_public_cipher == NX_NULL)
667 {
668 return(NX_SUCCESS);
669 }
670
671 if (ciphersuite_info -> nx_secure_tls_public_auth == NX_NULL)
672 {
673 return(NX_SUCCESS);
674 }
675
676 switch (ciphersuite_info -> nx_secure_tls_public_cipher -> nx_crypto_algorithm)
677 {
678 case NX_CRYPTO_KEY_EXCHANGE_ECDHE:
679 if (selected_curve == NX_NULL || cert == NX_NULL)
680 {
681 /* No common named curve supported for ECDHE. */
682 return(NX_SECURE_TLS_UNSUPPORTED_PUBLIC_CIPHER);
683 }
684
685 if (ciphersuite_info -> nx_secure_tls_public_auth -> nx_crypto_algorithm == NX_CRYPTO_DIGITAL_SIGNATURE_ECDSA)
686 {
687 if (cert -> nx_secure_x509_public_algorithm != NX_SECURE_TLS_X509_TYPE_EC)
688 {
689 /* ECDSA auth requires EC certificate. */
690 return(NX_SECURE_TLS_UNSUPPORTED_PUBLIC_CIPHER);
691 }
692 }
693 else
694 {
695 if (cert -> nx_secure_x509_public_algorithm != NX_SECURE_TLS_X509_TYPE_RSA)
696 {
697 /* RSA auth requires RSA certificate. */
698 return(NX_SECURE_TLS_UNSUPPORTED_PUBLIC_CIPHER);
699 }
700 }
701
702 break;
703
704 case NX_CRYPTO_KEY_EXCHANGE_ECDH:
705 /* Check for ECDH_anon. */
706 if (ciphersuite_info -> nx_secure_tls_public_auth -> nx_crypto_algorithm == NX_CRYPTO_DIGITAL_SIGNATURE_ANONYMOUS)
707 {
708 if (selected_curve == NX_NULL)
709 {
710 /* No common named curve supported supported. */
711 return(NX_SECURE_TLS_UNSUPPORTED_PUBLIC_CIPHER);
712 }
713 }
714 else
715 {
716 /* ECDH key exchange requires an EC certificate. */
717 if (cert == NX_NULL || cert -> nx_secure_x509_public_algorithm != NX_SECURE_TLS_X509_TYPE_EC)
718 {
719 return(NX_SECURE_TLS_UNSUPPORTED_PUBLIC_CIPHER);
720 }
721
722 if (cert_curve_supported == NX_FALSE)
723 {
724 return(NX_SECURE_TLS_UNSUPPORTED_PUBLIC_CIPHER);
725 }
726
727 /* Check the signatureAlgorithm of the certificate to determine the public auth algorithm. */
728 if (ciphersuite_info -> nx_secure_tls_public_auth -> nx_crypto_algorithm == NX_CRYPTO_DIGITAL_SIGNATURE_ECDSA)
729 {
730 if (cert -> nx_secure_x509_signature_algorithm != NX_SECURE_TLS_X509_TYPE_ECDSA_SHA_1 &&
731 cert -> nx_secure_x509_signature_algorithm != NX_SECURE_TLS_X509_TYPE_ECDSA_SHA_224 &&
732 cert -> nx_secure_x509_signature_algorithm != NX_SECURE_TLS_X509_TYPE_ECDSA_SHA_256 &&
733 cert -> nx_secure_x509_signature_algorithm != NX_SECURE_TLS_X509_TYPE_ECDSA_SHA_384 &&
734 cert -> nx_secure_x509_signature_algorithm != NX_SECURE_TLS_X509_TYPE_ECDSA_SHA_512)
735 {
736 return(NX_SECURE_TLS_UNSUPPORTED_PUBLIC_CIPHER);
737 }
738 }
739 else
740 {
741 if (cert -> nx_secure_x509_signature_algorithm != NX_SECURE_TLS_X509_TYPE_RSA_MD5 &&
742 cert -> nx_secure_x509_signature_algorithm != NX_SECURE_TLS_X509_TYPE_RSA_SHA_1 &&
743 cert -> nx_secure_x509_signature_algorithm != NX_SECURE_TLS_X509_TYPE_RSA_SHA_256 &&
744 cert -> nx_secure_x509_signature_algorithm != NX_SECURE_TLS_X509_TYPE_RSA_SHA_384 &&
745 cert -> nx_secure_x509_signature_algorithm != NX_SECURE_TLS_X509_TYPE_RSA_SHA_512)
746 {
747 return(NX_SECURE_TLS_UNSUPPORTED_PUBLIC_CIPHER);
748 }
749 }
750 }
751 break;
752
753 case NX_CRYPTO_KEY_EXCHANGE_RSA:
754 if (cert == NX_NULL || cert -> nx_secure_x509_public_algorithm != NX_SECURE_TLS_X509_TYPE_RSA)
755 {
756 /* RSA key exchange requires RSA certificate. */
757 return(NX_SECURE_TLS_UNSUPPORTED_PUBLIC_CIPHER);
758 }
759 break;
760
761 default:
762 break;
763 }
764
765 return(NX_SUCCESS);
766 }
767 #endif /* NX_SECURE_ENABLE_ECC_CIPHERSUITE && !NX_SECURE_DISABLE_X509 */
768
769 #endif /* NX_SECURE_ENABLE_DTLS */
770
771