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