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 #ifdef NX_SECURE_ENABLE_DTLS
26 #include "nx_secure_dtls.h"
27 #endif /* NX_SECURE_ENABLE_DTLS */
28
29 #ifndef NX_SECURE_DISABLE_X509
30 static UCHAR handshake_hash[64 + 34 + 32]; /* We concatenate MD5 and SHA-1 hashes into this buffer, OR SHA-256. */
31 static UCHAR _nx_secure_decrypted_signature[600];
32
33 #if (NX_SECURE_TLS_TLS_1_2_ENABLED)
34 static const UCHAR _NX_SECURE_OID_SHA256[] = {0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20};
35 #endif
36 #endif
37
38 /**************************************************************************/
39 /* */
40 /* FUNCTION RELEASE */
41 /* */
42 /* _nx_secure_tls_process_certificate_verify PORTABLE C */
43 /* 6.2.1 */
44 /* AUTHOR */
45 /* */
46 /* Timothy Stapko, Microsoft Corporation */
47 /* */
48 /* DESCRIPTION */
49 /* */
50 /* This function processes an incoming CertificateVerify message, */
51 /* which is sent by the remote client as a response to a */
52 /* CertificateRequest message sent by this TLS server. */
53 /* */
54 /* INPUT */
55 /* */
56 /* tls_session TLS control block */
57 /* packet_buffer Pointer to message data */
58 /* message_length Length of message data (bytes)*/
59 /* */
60 /* OUTPUT */
61 /* */
62 /* status Completion status */
63 /* */
64 /* CALLS */
65 /* */
66 /* [nx_crypto_operation] Public-key operation (eg RSA) */
67 /* used to verify keys */
68 /* [nx_crypto_init] Initialize the public-key */
69 /* operation */
70 /* _nx_secure_x509_local_device_certificate_get */
71 /* Get the local certificate */
72 /* _nx_secure_tls_find_curve_method Find named curve used */
73 /* _nx_secure_x509_find_certificate_methods */
74 /* Find signature crypto methods */
75 /* */
76 /* CALLED BY */
77 /* */
78 /* None */
79 /* */
80 /* RELEASE HISTORY */
81 /* */
82 /* DATE NAME DESCRIPTION */
83 /* */
84 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
85 /* 09-30-2020 Timothy Stapko Modified comment(s), update */
86 /* ECC find curve method, */
87 /* verified memcpy use cases, */
88 /* resulting in version 6.1 */
89 /* 04-02-2021 Timothy Stapko Modified comment(s), */
90 /* updated X.509 return value, */
91 /* resulting in version 6.1.6 */
92 /* 08-02-2021 Timothy Stapko Modified comment(s), added */
93 /* hash clone and cleanup, */
94 /* resulting in version 6.1.8 */
95 /* 04-25-2022 Yuxin Zhou Modified comment(s), */
96 /* removed unnecessary code, */
97 /* resulting in version 6.1.11 */
98 /* 10-31-2022 Yanwu Cai Modified comment(s), */
99 /* updated parameters list, */
100 /* resulting in version 6.2.0 */
101 /* 03-08-2023 Yanwu Cai Modified comment(s), */
102 /* fixed compiler errors when */
103 /* x509 is disabled, */
104 /* resulting in version 6.2.1 */
105 /* */
106 /**************************************************************************/
_nx_secure_tls_process_certificate_verify(NX_SECURE_TLS_SESSION * tls_session,UCHAR * packet_buffer,UINT message_length)107 UINT _nx_secure_tls_process_certificate_verify(NX_SECURE_TLS_SESSION *tls_session,
108 UCHAR *packet_buffer, UINT message_length)
109 {
110 #ifndef NX_SECURE_DISABLE_X509
111 UINT length = 0;
112 UINT data_size = 0;
113 USHORT signature_algorithm;
114 UINT signature_length = 0;
115 UINT i;
116 INT compare_value = 1; /* Initialized to 1 to ensure that we fail if anything goes wrong with the comparison. */
117 UCHAR *received_signature = NX_NULL;
118 UCHAR *working_ptr;
119 NX_SECURE_X509_CRYPTO *crypto_methods;
120 const NX_CRYPTO_METHOD *public_cipher_method;
121 const NX_CRYPTO_METHOD *hash_method = NX_NULL;
122 NX_SECURE_X509_CERT *client_certificate;
123 UINT status;
124 VOID *handler = NX_NULL;
125 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
126 UINT handshake_hash_length = 0;
127 CHAR *metadata;
128 ULONG metadata_size;
129 const CHAR server_context[] = "TLS 1.3, server CertificateVerify\0"; /* Includes 0-byte separator. */
130 const CHAR client_context[] = "TLS 1.3, client CertificateVerify\0"; /* Includes 0-byte separator. */
131 #endif
132 #ifdef NX_SECURE_ENABLE_ECC_CIPHERSUITE
133 const NX_CRYPTO_METHOD *curve_method_cert;
134 NX_SECURE_EC_PUBLIC_KEY *ec_pubkey;
135 #endif /* NX_SECURE_ENABLE_ECC_CIPHERSUITE */
136
137 /*
138 ==== TLS 1.0/1.1 structure (hashes are of all handshake messages to this point) ====
139 struct {
140 Signature signature;
141 } CertificateVerify;
142
143 struct {
144 select (SignatureAlgorithm) {
145 case anonymous: struct { };
146 case rsa:
147 digitally-signed struct {
148 opaque md5_hash[16];
149 opaque sha_hash[20];
150 };
151 case dsa:
152 digitally-signed struct {
153 opaque sha_hash[20];
154 };
155 };
156 };
157 } Signature;
158
159 ==== TLS 1.2 structure (signature is generally PKCS#1 encoded) ====
160 struct {
161 digitally-signed struct {
162 opaque handshake_messages[handshake_messages_length];
163 }
164 } CertificateVerify;
165
166 struct {
167 SignatureAndHashAlgorithm algorithm;
168 opaque signature<0..2^16-1>;
169 } DigitallySigned
170 */
171
172
173 /* Get reference to remote device certificate so we can get the public key for signature verification. */
174 status = _nx_secure_x509_remote_endpoint_certificate_get(&tls_session -> nx_secure_tls_credentials.nx_secure_tls_certificate_store,
175 &client_certificate);
176
177 if (status)
178 {
179 /* No certificate found, error! */
180 return(NX_SECURE_TLS_CERTIFICATE_NOT_FOUND);
181 }
182
183 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
184 if (tls_session -> nx_secure_tls_1_3)
185 {
186 /* TLS1.3 uses RSASSA-PSS instead of RSASSA-PKCS. RSASSA-PSS is not supported now. */
187 switch ((UINT)((packet_buffer[0] << 8) + packet_buffer[1]))
188 {
189 case NX_SECURE_TLS_SIGNATURE_ECDSA_SHA256:
190 signature_algorithm = NX_SECURE_TLS_X509_TYPE_ECDSA_SHA_256;
191 break;
192 case NX_SECURE_TLS_SIGNATURE_ECDSA_SHA384:
193 signature_algorithm = NX_SECURE_TLS_X509_TYPE_ECDSA_SHA_384;
194 break;
195 case NX_SECURE_TLS_SIGNATURE_ECDSA_SHA512:
196 signature_algorithm = NX_SECURE_TLS_X509_TYPE_ECDSA_SHA_512;
197 break;
198 default:
199 return(NX_SECURE_TLS_UNSUPPORTED_CERT_SIGN_ALG);
200 }
201 }
202 else
203 #endif
204 {
205 signature_algorithm = NX_SECURE_TLS_X509_TYPE_RSA_SHA_256;
206 #ifdef NX_SECURE_ENABLE_ECC_CIPHERSUITE
207 if (client_certificate -> nx_secure_x509_public_algorithm == NX_SECURE_TLS_X509_TYPE_EC)
208 {
209 signature_algorithm = NX_SECURE_TLS_X509_TYPE_ECDSA_SHA_256;
210 }
211 #endif /* NX_SECURE_ENABLE_ECC_CIPHERSUITE */
212 }
213
214 /* Find certificate crypto methods for the local certificate. */
215 status = _nx_secure_x509_find_certificate_methods(client_certificate, signature_algorithm, &crypto_methods);
216 if (status != NX_SUCCESS)
217 {
218
219 /* Translate some X.509 return values into TLS return values. */
220 return(NX_SECURE_TLS_UNKNOWN_CERT_SIG_ALGORITHM);
221 }
222
223 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
224 if(tls_session -> nx_secure_tls_1_3)
225 {
226 /* TLS 1.3 certificate verify uses a different scheme. The signature is calculated over
227 a concatenation of the following (RFC 8446):
228 - A string that consists of octet 32 (0x20) repeated 64 times
229 - The context string
230 - A single 0 byte which serves as the separator
231 - The content to be signed
232 */
233
234 UCHAR *transcript_hash = tls_session -> nx_secure_tls_key_material.nx_secure_tls_transcript_hashes[NX_SECURE_TLS_TRANSCRIPT_IDX_CERTIFICATE];
235
236 /* Set octet padding bytes. */
237 NX_SECURE_MEMSET(&handshake_hash[0], 0x20, 64);
238
239 if (tls_session -> nx_secure_tls_socket_type == NX_SECURE_TLS_SESSION_TYPE_CLIENT)
240 {
241 /* Copy in context string and 0-byte separator. */
242 NX_SECURE_MEMCPY(&handshake_hash[64], server_context, 34); /* Use case of memcpy is verified. */
243 }
244 else
245 {
246 /* Copy in context string and 0-byte separator. */
247 NX_SECURE_MEMCPY(&handshake_hash[64], client_context, 34); /* Use case of memcpy is verified. */
248 }
249
250 /* Copy in transcript hash. */
251 NX_SECURE_MEMCPY(&handshake_hash[64 + 34], transcript_hash, 32); /* Use case of memcpy is verified. */
252
253 handshake_hash_length = 130;
254
255
256 /* Generate a hash of the data we just produced. */
257 /* Use SHA-256 for now... */
258 hash_method = crypto_methods -> nx_secure_x509_hash_method;
259
260 metadata = tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_scratch;
261 metadata_size = tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_scratch_size;
262
263
264 /* Hash the data using the chosen hash method. */
265 if (hash_method -> nx_crypto_init)
266 {
267 status = hash_method -> nx_crypto_init((NX_CRYPTO_METHOD*)hash_method,
268 NX_NULL,
269 0,
270 &handler,
271 metadata,
272 metadata_size);
273
274 if(status != NX_CRYPTO_SUCCESS)
275 {
276 return(status);
277 }
278 }
279
280 if (hash_method -> nx_crypto_operation != NX_NULL)
281 {
282 status = hash_method -> nx_crypto_operation(NX_CRYPTO_HASH_INITIALIZE,
283 handler,
284 (NX_CRYPTO_METHOD*)hash_method,
285 NX_NULL,
286 0,
287 NX_NULL,
288 0,
289 NX_NULL,
290 NX_NULL,
291 0,
292 metadata,
293 metadata_size,
294 NX_NULL,
295 NX_NULL);
296
297 if(status != NX_CRYPTO_SUCCESS)
298 {
299 return(status);
300 }
301 }
302
303 if (hash_method -> nx_crypto_operation != NX_NULL)
304 {
305 status = hash_method -> nx_crypto_operation(NX_CRYPTO_HASH_UPDATE,
306 tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_sha256_handler,
307 (NX_CRYPTO_METHOD*)hash_method,
308 NX_NULL,
309 0,
310 handshake_hash,
311 handshake_hash_length,
312 NX_NULL,
313 NX_NULL,
314 0,
315 metadata,
316 metadata_size,
317 NX_NULL,
318 NX_NULL);
319
320 if(status != NX_CRYPTO_SUCCESS)
321 {
322 return(status);
323 }
324 }
325
326
327 if (hash_method -> nx_crypto_operation != NX_NULL)
328 {
329 status = hash_method -> nx_crypto_operation(NX_CRYPTO_HASH_CALCULATE,
330 tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_sha256_handler,
331 (NX_CRYPTO_METHOD*)hash_method,
332 NX_NULL,
333 0,
334 NX_NULL,
335 0,
336 NX_NULL,
337 &handshake_hash[0],
338 sizeof(handshake_hash),
339 metadata,
340 metadata_size,
341 NX_NULL,
342 NX_NULL);
343
344 if(status != NX_CRYPTO_SUCCESS)
345 {
346 return(status);
347 }
348 }
349
350 handshake_hash_length = (hash_method -> nx_crypto_ICV_size_in_bits) >> 3;
351 }
352 else
353 #endif
354
355 /* Generate the handshake message hash that will need to match the received signature. */
356 #if (NX_SECURE_TLS_TLS_1_2_ENABLED)
357 #ifdef NX_SECURE_ENABLE_DTLS
358 if (tls_session -> nx_secure_tls_protocol_version == NX_SECURE_TLS_VERSION_TLS_1_2 ||
359 tls_session -> nx_secure_tls_protocol_version == NX_SECURE_DTLS_VERSION_1_2)
360 #else
361 if (tls_session -> nx_secure_tls_protocol_version == NX_SECURE_TLS_VERSION_TLS_1_2)
362 #endif /* NX_SECURE_ENABLE_DTLS */
363 {
364 /* Calculate our final signature length for later offset calculations. */
365 signature_length = 19 + 32; /* DER encoding (19) + SHA-256 hash size (32) */
366
367 /* Generate a hash of all sent and received handshake messages to this point (not a Finished hash!). */
368 /* Copy over the handshake hash state into a local structure to do the intermediate calculation. */
369 NX_SECURE_HASH_METADATA_CLONE(tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_scratch, /* lgtm[cpp/banned-api-usage-required-any] */
370 tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_sha256_metadata,
371 tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_sha256_metadata_size); /* Use case of memcpy is verified. */
372
373 /* Use SHA-256 for now... */
374 hash_method = tls_session -> nx_secure_tls_crypto_table -> nx_secure_tls_handshake_hash_sha256_method;
375 if (hash_method -> nx_crypto_operation != NX_NULL)
376 {
377 status = hash_method -> nx_crypto_operation(NX_CRYPTO_HASH_CALCULATE,
378 tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_sha256_handler,
379 (NX_CRYPTO_METHOD*)hash_method,
380 NX_NULL,
381 0,
382 NX_NULL,
383 0,
384 NX_NULL,
385 &handshake_hash[0],
386 sizeof(handshake_hash),
387 tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_scratch,
388 tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_sha256_metadata_size,
389 NX_NULL,
390 NX_NULL);
391 }
392
393 NX_SECURE_HASH_CLONE_CLEANUP(tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_scratch,
394 tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_sha256_metadata_size);
395
396 if (status != NX_CRYPTO_SUCCESS)
397 {
398 /* Something failed in the hash calculation. */
399 return(status);
400 }
401 }
402
403 #endif
404
405 #if (NX_SECURE_TLS_TLS_1_0_ENABLED || NX_SECURE_TLS_TLS_1_1_ENABLED)
406 #ifdef NX_SECURE_ENABLE_DTLS
407 if (tls_session -> nx_secure_tls_protocol_version == NX_SECURE_TLS_VERSION_TLS_1_0 ||
408 tls_session -> nx_secure_tls_protocol_version == NX_SECURE_TLS_VERSION_TLS_1_1 ||
409 tls_session -> nx_secure_tls_protocol_version == NX_SECURE_DTLS_VERSION_1_0)
410 #else
411 if (tls_session -> nx_secure_tls_protocol_version == NX_SECURE_TLS_VERSION_TLS_1_0 ||
412 tls_session -> nx_secure_tls_protocol_version == NX_SECURE_TLS_VERSION_TLS_1_1)
413 #endif /* NX_SECURE_ENABLE_DTLS */
414 {
415 /* Signature size is the size of SHA-1 (20) + MD5 (16). */
416 signature_length = 36;
417
418 /* Copy over the handshake hash metadata into scratch metadata area to do the intermediate calculation. */
419 NX_SECURE_HASH_METADATA_CLONE(tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_scratch +
420 tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_sha1_metadata_size,
421 tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_md5_metadata,
422 tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_md5_metadata_size); /* Use case of memcpy is verified. */
423
424 /* Finalize the handshake message hashes that we started at the beginning of the handshake. */
425 hash_method = tls_session -> nx_secure_tls_crypto_table -> nx_secure_tls_handshake_hash_md5_method;
426 if (hash_method -> nx_crypto_operation != NX_NULL)
427 {
428 status = hash_method -> nx_crypto_operation(NX_CRYPTO_HASH_CALCULATE,
429 tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_md5_handler,
430 (NX_CRYPTO_METHOD*)hash_method,
431 NX_NULL,
432 0,
433 NX_NULL,
434 0,
435 NX_NULL,
436 &handshake_hash[0],
437 16,
438 tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_scratch +
439 tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_sha1_metadata_size,
440 tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_md5_metadata_size,
441 NX_NULL,
442 NX_NULL);
443 }
444
445 NX_SECURE_HASH_CLONE_CLEANUP(tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_scratch +
446 tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_sha1_metadata_size,
447 tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_md5_metadata_size);
448
449 if (status != NX_CRYPTO_SUCCESS)
450 {
451
452 /* Something failed in the hash calculation. */
453 return(status);
454 }
455
456 NX_SECURE_HASH_METADATA_CLONE(tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_scratch,
457 tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_sha1_metadata,
458 tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_sha1_metadata_size); /* Use case of memcpy is verified. */
459
460 hash_method = tls_session -> nx_secure_tls_crypto_table -> nx_secure_tls_handshake_hash_sha1_method;
461 if (hash_method -> nx_crypto_operation != NX_NULL)
462 {
463 status = hash_method -> nx_crypto_operation(NX_CRYPTO_HASH_CALCULATE,
464 tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_sha1_handler,
465 (NX_CRYPTO_METHOD*)hash_method,
466 NX_NULL,
467 0,
468 NX_NULL,
469 0,
470 NX_NULL,
471 &handshake_hash[16],
472 sizeof(handshake_hash) - 16,
473 tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_scratch,
474 tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_sha1_metadata_size,
475 NX_NULL,
476 NX_NULL);
477
478
479 }
480
481 NX_SECURE_HASH_CLONE_CLEANUP(tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_scratch,
482 tls_session -> nx_secure_tls_handshake_hash.nx_secure_tls_handshake_hash_sha1_metadata_size);
483
484 if (status != NX_CRYPTO_SUCCESS)
485 {
486
487 /* Something failed in the hash calculation. */
488 #ifdef NX_SECURE_KEY_CLEAR
489 NX_SECURE_MEMSET(handshake_hash, 0, sizeof(handshake_hash));
490 #endif /* NX_SECURE_KEY_CLEAR */
491 return(status);
492 }
493 }
494 #endif
495
496
497 /* Make sure we found a supported version (essentially an assertion check). */
498 if (hash_method == NX_NULL)
499 {
500 /* No hash method means we don't need to clear "handshake_hash" buffer. */
501 return(NX_SECURE_TLS_UNSUPPORTED_TLS_VERSION);
502 }
503
504
505 /* Start with a clear buffer for our decrypted signature data. */
506 NX_SECURE_MEMSET(_nx_secure_decrypted_signature, 0x0, sizeof(_nx_secure_decrypted_signature));
507
508 length = 0;
509
510 /* Get our public-key crypto method. */
511 public_cipher_method = crypto_methods -> nx_secure_x509_public_cipher_method;
512
513
514 /* Use RSA? */
515 if (client_certificate -> nx_secure_x509_public_algorithm == NX_SECURE_TLS_X509_TYPE_RSA)
516 {
517 #if (NX_SECURE_TLS_TLS_1_2_ENABLED || NX_SECURE_TLS_TLS_1_3_ENABLED)
518 #ifdef NX_SECURE_ENABLE_DTLS
519 if (tls_session -> nx_secure_tls_protocol_version == NX_SECURE_TLS_VERSION_TLS_1_2 ||
520 tls_session -> nx_secure_tls_protocol_version == NX_SECURE_DTLS_VERSION_1_2)
521 #elif (NX_SECURE_TLS_TLS_1_0_ENABLED || NX_SECURE_TLS_TLS_1_1_ENABLED)
522 if (tls_session -> nx_secure_tls_protocol_version == NX_SECURE_TLS_VERSION_TLS_1_2)
523 #endif /* NX_SECURE_ENABLE_DTLS */
524 {
525 /* Check the signature method. */
526 if (packet_buffer[0] != NX_SECURE_TLS_HASH_ALGORITHM_SHA256 ||
527 packet_buffer[1] != NX_SECURE_TLS_SIGNATURE_ALGORITHM_RSA)
528 {
529 return(NX_SECURE_TLS_UNKNOWN_CERT_SIG_ALGORITHM);
530 }
531
532 /* Get the length of the encrypted signature data. */
533 length = (UINT)((packet_buffer[2] << 8) + packet_buffer[3]);
534
535 if (length != client_certificate -> nx_secure_x509_public_key.rsa_public_key.nx_secure_rsa_public_modulus_length)
536 {
537 return(NX_SECURE_TLS_CERTIFICATE_SIG_CHECK_FAILED);
538 }
539
540 /* Pointer to the received signature that we need to check. */
541 received_signature = &packet_buffer[4];
542 }
543 #endif
544
545 #if (NX_SECURE_TLS_TLS_1_0_ENABLED || NX_SECURE_TLS_TLS_1_1_ENABLED)
546 #ifdef NX_SECURE_ENABLE_DTLS
547 if (tls_session -> nx_secure_tls_protocol_version == NX_SECURE_TLS_VERSION_TLS_1_0 ||
548 tls_session -> nx_secure_tls_protocol_version == NX_SECURE_TLS_VERSION_TLS_1_1 ||
549 tls_session -> nx_secure_tls_protocol_version == NX_SECURE_DTLS_VERSION_1_0)
550 #else
551 if (tls_session -> nx_secure_tls_protocol_version == NX_SECURE_TLS_VERSION_TLS_1_0 ||
552 tls_session -> nx_secure_tls_protocol_version == NX_SECURE_TLS_VERSION_TLS_1_1)
553 #endif /* NX_SECURE_ENABLE_DTLS */
554 {
555 /* Get the length of the encrypted signature data. */
556 length = (UINT)((packet_buffer[0] << 8) + packet_buffer[1]);
557
558 if (length != client_certificate -> nx_secure_x509_public_key.rsa_public_key.nx_secure_rsa_public_modulus_length)
559 {
560 return(NX_SECURE_TLS_CERTIFICATE_SIG_CHECK_FAILED);
561 }
562
563 /* Pointer to the received signature that we need to check. */
564 received_signature = &packet_buffer[2];
565 }
566 #endif
567
568 /* Length sanity check. */
569 if (length > message_length )
570 {
571 /* Incoming message was too long! */
572 return(NX_SECURE_TLS_INCORRECT_MESSAGE_LENGTH);
573 }
574
575 /* If using RSA, the length is equal to the key size. */
576 data_size = client_certificate -> nx_secure_x509_public_key.rsa_public_key.nx_secure_rsa_public_modulus_length;
577
578 if (public_cipher_method -> nx_crypto_init != NX_NULL)
579 {
580 /* Initialize the crypto method with public key. */
581 status = public_cipher_method -> nx_crypto_init((NX_CRYPTO_METHOD*)public_cipher_method,
582 (UCHAR *)client_certificate -> nx_secure_x509_public_key.rsa_public_key.nx_secure_rsa_public_modulus,
583 (NX_CRYPTO_KEY_SIZE)(client_certificate -> nx_secure_x509_public_key.rsa_public_key.nx_secure_rsa_public_modulus_length << 3),
584 &handler,
585 client_certificate -> nx_secure_x509_public_cipher_metadata_area,
586 client_certificate -> nx_secure_x509_public_cipher_metadata_size);
587
588 if (status != NX_CRYPTO_SUCCESS)
589 {
590 /* Something failed in setting up the public cipher. */
591 #ifdef NX_SECURE_KEY_CLEAR
592 NX_SECURE_MEMSET(handshake_hash, 0, sizeof(handshake_hash));
593 #endif /* NX_SECURE_KEY_CLEAR */
594 return(status);
595 }
596 }
597
598 if (public_cipher_method -> nx_crypto_operation != NX_NULL)
599 {
600 /* Decrypt the hash we received using the remote host's public key. */
601 status = public_cipher_method -> nx_crypto_operation(NX_CRYPTO_DECRYPT,
602 handler,
603 (NX_CRYPTO_METHOD*)public_cipher_method,
604 (UCHAR *)client_certificate -> nx_secure_x509_public_key.rsa_public_key.nx_secure_rsa_public_exponent,
605 (NX_CRYPTO_KEY_SIZE)(client_certificate -> nx_secure_x509_public_key.rsa_public_key.nx_secure_rsa_public_exponent_length << 3),
606 received_signature,
607 data_size,
608 NX_NULL,
609 _nx_secure_decrypted_signature,
610 sizeof(_nx_secure_decrypted_signature),
611 client_certificate -> nx_secure_x509_public_cipher_metadata_area,
612 client_certificate -> nx_secure_x509_public_cipher_metadata_size,
613 NX_NULL, NX_NULL);
614
615 if (status != NX_CRYPTO_SUCCESS)
616 {
617 /* Something failed in the cipher operation. */
618 #ifdef NX_SECURE_KEY_CLEAR
619 NX_SECURE_MEMSET(handshake_hash, 0, sizeof(handshake_hash));
620 #endif /* NX_SECURE_KEY_CLEAR */
621 return(status);
622 }
623 }
624
625 if (public_cipher_method -> nx_crypto_cleanup)
626 {
627 status = public_cipher_method -> nx_crypto_cleanup(client_certificate -> nx_secure_x509_public_cipher_metadata_area);
628
629 if (status != NX_CRYPTO_SUCCESS)
630 {
631 /* Something failed in the cipher operation. */
632 #ifdef NX_SECURE_KEY_CLEAR
633 NX_SECURE_MEMSET(handshake_hash, 0, sizeof(handshake_hash));
634 NX_SECURE_MEMSET(_nx_secure_decrypted_signature, 0, sizeof(_nx_secure_decrypted_signature));
635 #endif /* NX_SECURE_KEY_CLEAR */
636 return(status);
637 }
638 }
639
640 /* Check PKCS-1 Signature padding. The scheme is to start with the block type (0x00, 0x01 for signing)
641 then pad with 0xFF bytes (for signing) followed with a single 0 byte right before the payload,
642 which comes at the end of the RSA block. */
643
644 /* Block type is 0x00, 0x01 for signatures */
645 if (_nx_secure_decrypted_signature[0] != 0x0 && _nx_secure_decrypted_signature[1] != 0x1)
646 {
647 #ifdef NX_SECURE_KEY_CLEAR
648 NX_SECURE_MEMSET(handshake_hash, 0, sizeof(handshake_hash));
649 NX_SECURE_MEMSET(_nx_secure_decrypted_signature, 0, sizeof(_nx_secure_decrypted_signature));
650 #endif /* NX_SECURE_KEY_CLEAR */
651 /* Unknown block type. */
652 return(NX_SECURE_TLS_PADDING_CHECK_FAILED);
653 }
654
655 /* Check padding. */
656 for (i = 2; i < (data_size - signature_length - 1); ++i)
657 {
658 if (_nx_secure_decrypted_signature[i] != (UCHAR)0xFF)
659 {
660 #ifdef NX_SECURE_KEY_CLEAR
661 NX_SECURE_MEMSET(handshake_hash, 0, sizeof(handshake_hash));
662 NX_SECURE_MEMSET(_nx_secure_decrypted_signature, 0, sizeof(_nx_secure_decrypted_signature));
663 #endif /* NX_SECURE_KEY_CLEAR */
664 /* Bad padding value. */
665 return(NX_SECURE_TLS_PADDING_CHECK_FAILED);
666 }
667 }
668
669 /* Check the received handshake hash against what we generated above. */
670
671 #if (NX_SECURE_TLS_TLS_1_2_ENABLED || NX_SECURE_TLS_TLS_1_3_ENABLED)
672 #ifdef NX_SECURE_ENABLE_DTLS
673 if (tls_session -> nx_secure_tls_protocol_version == NX_SECURE_TLS_VERSION_TLS_1_2 ||
674 tls_session -> nx_secure_tls_protocol_version == NX_SECURE_DTLS_VERSION_1_2)
675 #elif (NX_SECURE_TLS_TLS_1_0_ENABLED || NX_SECURE_TLS_TLS_1_1_ENABLED)
676 if (tls_session -> nx_secure_tls_protocol_version == NX_SECURE_TLS_VERSION_TLS_1_2)
677 #endif /* NX_SECURE_ENABLE_DTLS */
678 {
679 /* Get a working pointer into the padded signature buffer. All PKCS-1 encoded data
680 comes at the end of the RSA encrypted block. */
681 working_ptr = &_nx_secure_decrypted_signature[data_size - signature_length];
682
683 /* Check the DER encoding. */
684 compare_value = NX_SECURE_MEMCMP(&working_ptr[0], _NX_SECURE_OID_SHA256, 19);
685
686 /* Check the handshake hash. */
687 compare_value += NX_SECURE_MEMCMP(&working_ptr[19], handshake_hash, 32);
688 }
689 #endif
690
691 #if (NX_SECURE_TLS_TLS_1_0_ENABLED || NX_SECURE_TLS_TLS_1_1_ENABLED)
692 #ifdef NX_SECURE_ENABLE_DTLS
693 if (tls_session -> nx_secure_tls_protocol_version == NX_SECURE_TLS_VERSION_TLS_1_0 ||
694 tls_session -> nx_secure_tls_protocol_version == NX_SECURE_TLS_VERSION_TLS_1_1 ||
695 tls_session -> nx_secure_tls_protocol_version == NX_SECURE_DTLS_VERSION_1_0)
696 #else
697 if (tls_session -> nx_secure_tls_protocol_version == NX_SECURE_TLS_VERSION_TLS_1_0 ||
698 tls_session -> nx_secure_tls_protocol_version == NX_SECURE_TLS_VERSION_TLS_1_1)
699 #endif /* NX_SECURE_ENABLE_DTLS */
700 {
701 /* Get a working pointer into the padded signature buffer. All PKCS-1 encoded data
702 comes at the end of the RSA encrypted block. */
703 working_ptr = &_nx_secure_decrypted_signature[data_size - signature_length];
704
705 /* Now put the data into the padded buffer - must be at the end. */
706 compare_value = NX_SECURE_MEMCMP(working_ptr, handshake_hash, 36);
707 }
708 #endif
709
710 }
711 #ifdef NX_SECURE_ENABLE_ECC_CIPHERSUITE
712 else if (client_certificate -> nx_secure_x509_public_algorithm == NX_SECURE_TLS_X509_TYPE_EC)
713 {
714 /* Verify the ECDSA signature. */
715
716 #if (NX_SECURE_TLS_TLS_1_2_ENABLED || NX_SECURE_TLS_TLS_1_3_ENABLED)
717 #ifdef NX_SECURE_ENABLE_DTLS
718 if (tls_session -> nx_secure_tls_protocol_version == NX_SECURE_TLS_VERSION_TLS_1_2 ||
719 tls_session -> nx_secure_tls_protocol_version == NX_SECURE_DTLS_VERSION_1_2)
720 #elif (NX_SECURE_TLS_TLS_1_0_ENABLED || NX_SECURE_TLS_TLS_1_1_ENABLED)
721 if (tls_session -> nx_secure_tls_protocol_version == NX_SECURE_TLS_VERSION_TLS_1_2)
722 #endif /* NX_SECURE_ENABLE_DTLS */
723 {
724 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
725 if (tls_session -> nx_secure_tls_1_3)
726 {
727 data_size = handshake_hash_length;
728 }
729 else
730 #endif
731 {
732
733 /* Check the signature method. */
734 if(packet_buffer[0] != NX_SECURE_TLS_HASH_ALGORITHM_SHA256 ||
735 packet_buffer[1] != NX_SECURE_TLS_SIGNATURE_ALGORITHM_ECDSA)
736 {
737 #ifdef NX_SECURE_KEY_CLEAR
738 NX_SECURE_MEMSET(handshake_hash, 0, sizeof(handshake_hash));
739 NX_SECURE_MEMSET(_nx_secure_decrypted_signature, 0, sizeof(_nx_secure_decrypted_signature));
740 #endif /* NX_SECURE_KEY_CLEAR */
741 return(NX_SECURE_TLS_UNKNOWN_CERT_SIG_ALGORITHM);
742 }
743
744 /* Hash size is SHA-256 hash size (32). */
745 data_size = 32;
746 }
747
748 /* Get the length of the ECDSA signature data. */
749 length = (UINT)((packet_buffer[2] << 8) + packet_buffer[3]);
750
751 /* Pointer to the received signature that we need to check. */
752 received_signature = &packet_buffer[4];
753 }
754 #endif
755
756 #if (NX_SECURE_TLS_TLS_1_0_ENABLED || NX_SECURE_TLS_TLS_1_1_ENABLED)
757 #ifdef NX_SECURE_ENABLE_DTLS
758 if (tls_session -> nx_secure_tls_protocol_version == NX_SECURE_TLS_VERSION_TLS_1_0 ||
759 tls_session -> nx_secure_tls_protocol_version == NX_SECURE_TLS_VERSION_TLS_1_1 ||
760 tls_session -> nx_secure_tls_protocol_version == NX_SECURE_DTLS_VERSION_1_0)
761 #else
762 if (tls_session -> nx_secure_tls_protocol_version == NX_SECURE_TLS_VERSION_TLS_1_0 ||
763 tls_session -> nx_secure_tls_protocol_version == NX_SECURE_TLS_VERSION_TLS_1_1)
764 #endif /* NX_SECURE_ENABLE_DTLS */
765 {
766 /* Get the length of the ECDSA signature data. */
767 length = (UINT)((packet_buffer[0] << 8) + packet_buffer[1]);
768
769 /* Pointer to the received signature that we need to check. */
770 received_signature = &packet_buffer[2];
771
772 /* Hash size is the size of SHA-1 (20) + MD5 (16). */
773 data_size = 36;
774 }
775 #endif
776
777 ec_pubkey = &client_certificate -> nx_secure_x509_public_key.ec_public_key;
778
779 /* Find out which named curve the remote certificate is using. */
780 status = _nx_secure_tls_find_curve_method(&tls_session -> nx_secure_tls_ecc, (USHORT)(ec_pubkey -> nx_secure_ec_named_curve), &curve_method_cert, NX_NULL);
781
782 if (status != NX_SUCCESS)
783 {
784 #ifdef NX_SECURE_KEY_CLEAR
785 /* Clear secrets on errors. */
786 NX_SECURE_MEMSET(handshake_hash, 0, sizeof(handshake_hash));
787 NX_SECURE_MEMSET(_nx_secure_decrypted_signature, 0, sizeof(_nx_secure_decrypted_signature));
788 #endif /* NX_SECURE_KEY_CLEAR */
789
790 /* The remote certificate is using an unsupported curve. */
791 return(NX_SECURE_TLS_UNSUPPORTED_ECC_CURVE);
792 }
793
794 if (public_cipher_method -> nx_crypto_init != NX_NULL)
795 {
796 status = public_cipher_method -> nx_crypto_init((NX_CRYPTO_METHOD*)public_cipher_method,
797 (UCHAR *)ec_pubkey -> nx_secure_ec_public_key,
798 (NX_CRYPTO_KEY_SIZE)(ec_pubkey -> nx_secure_ec_public_key_length << 3),
799 &handler,
800 client_certificate -> nx_secure_x509_public_cipher_metadata_area,
801 client_certificate -> nx_secure_x509_public_cipher_metadata_size);
802 if (status != NX_CRYPTO_SUCCESS)
803 {
804 #ifdef NX_SECURE_KEY_CLEAR
805 NX_SECURE_MEMSET(handshake_hash, 0, sizeof(handshake_hash));
806 NX_SECURE_MEMSET(_nx_secure_decrypted_signature, 0, sizeof(_nx_secure_decrypted_signature));
807 #endif /* NX_SECURE_KEY_CLEAR */
808 return(status);
809 }
810 }
811 if (public_cipher_method -> nx_crypto_operation == NX_NULL)
812 {
813 #ifdef NX_SECURE_KEY_CLEAR
814 NX_SECURE_MEMSET(handshake_hash, 0, sizeof(handshake_hash));
815 NX_SECURE_MEMSET(_nx_secure_decrypted_signature, 0, sizeof(_nx_secure_decrypted_signature));
816 #endif /* NX_SECURE_KEY_CLEAR */
817 return(NX_SECURE_TLS_MISSING_CRYPTO_ROUTINE);
818 }
819
820 status = public_cipher_method -> nx_crypto_operation(NX_CRYPTO_EC_CURVE_SET, handler,
821 (NX_CRYPTO_METHOD*)public_cipher_method, NX_NULL, 0,
822 (UCHAR *)curve_method_cert, sizeof(NX_CRYPTO_METHOD *), NX_NULL,
823 NX_NULL, 0,
824 client_certificate -> nx_secure_x509_public_cipher_metadata_area,
825 client_certificate -> nx_secure_x509_public_cipher_metadata_size,
826 NX_NULL, NX_NULL);
827 if (status != NX_CRYPTO_SUCCESS)
828 {
829 #ifdef NX_SECURE_KEY_CLEAR
830 NX_SECURE_MEMSET(handshake_hash, 0, sizeof(handshake_hash));
831 NX_SECURE_MEMSET(_nx_secure_decrypted_signature, 0, sizeof(_nx_secure_decrypted_signature));
832 #endif /* NX_SECURE_KEY_CLEAR */
833 return(status);
834 }
835
836 if (((ULONG)packet_buffer + message_length) < ((ULONG)received_signature + length))
837 {
838 return(NX_SECURE_X509_ASN1_LENGTH_TOO_LONG);
839 }
840
841 status = public_cipher_method -> nx_crypto_operation(NX_CRYPTO_VERIFY, handler,
842 (NX_CRYPTO_METHOD*)public_cipher_method,
843 (UCHAR *)ec_pubkey -> nx_secure_ec_public_key,
844 (NX_CRYPTO_KEY_SIZE)(ec_pubkey -> nx_secure_ec_public_key_length << 3),
845 handshake_hash,
846 data_size,
847 NX_NULL,
848 received_signature,
849 length,
850 client_certificate -> nx_secure_x509_public_cipher_metadata_area,
851 client_certificate -> nx_secure_x509_public_cipher_metadata_size,
852 NX_NULL, NX_NULL);
853 if (status == NX_CRYPTO_SUCCESS)
854 {
855 compare_value = 0;
856 }
857 else
858 {
859 compare_value = 1;
860 }
861
862 if (public_cipher_method -> nx_crypto_cleanup)
863 {
864 status = public_cipher_method -> nx_crypto_cleanup(client_certificate -> nx_secure_x509_public_cipher_metadata_area);
865 if(status != NX_CRYPTO_SUCCESS)
866 {
867 #ifdef NX_SECURE_KEY_CLEAR
868 NX_SECURE_MEMSET(handshake_hash, 0, sizeof(handshake_hash));
869 NX_SECURE_MEMSET(_nx_secure_decrypted_signature, 0, sizeof(_nx_secure_decrypted_signature));
870 #endif /* NX_SECURE_KEY_CLEAR */
871 return(status);
872 }
873 }
874
875 }
876 #endif /* NX_SECURE_ENABLE_ECC_CIPHERSUITE */
877 else
878 {
879 /* Unknown or unsupported public-key operation.
880 No secrets to clear. */
881 return(NX_SECURE_TLS_UNSUPPORTED_PUBLIC_CIPHER);
882 }
883
884
885 #ifdef NX_SECURE_KEY_CLEAR
886 NX_SECURE_MEMSET(handshake_hash, 0, sizeof(handshake_hash));
887 NX_SECURE_MEMSET(_nx_secure_decrypted_signature, 0, sizeof(_nx_secure_decrypted_signature));
888 #endif /* NX_SECURE_KEY_CLEAR */
889
890 if (compare_value)
891 {
892 /* The hash value did not compare, so something has gone wrong. */
893 return(NX_SECURE_TLS_CERTIFICATE_VERIFY_FAILURE);
894 }
895
896 return(NX_SUCCESS);
897 #else
898 NX_PARAMETER_NOT_USED(tls_session);
899 NX_PARAMETER_NOT_USED(packet_buffer);
900 NX_PARAMETER_NOT_USED(message_length);
901
902 return(NX_NOT_SUPPORTED);
903 #endif
904 }
905
906