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 #ifdef NX_SECURE_ENABLE_ECC_CIPHERSUITE
31
32 #ifndef NX_SECURE_DISABLE_X509
33 static UCHAR hash[64]; /* We concatenate MD5 and SHA-1 hashes into this buffer, OR SHA-256, SHA-384, SHA512. */
34 static UCHAR _nx_secure_padded_signature[512];
35 /* DER encodings (with OIDs for common algorithms) from RFC 8017.
36 * NOTE: This is the equivalent DER-encoding for the value "T" described in RFC 8017 section 9.2. */
37 static const UCHAR _NX_CRYPTO_DER_OID_MD5[] = {0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x02, 0x05, 0x00, 0x04, 0x10};
38 static const UCHAR _NX_CRYPTO_DER_OID_SHA_1[] = {0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14};
39 static const UCHAR _NX_CRYPTO_DER_OID_SHA_224[] = {0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04, 0x05, 0x00, 0x04, 0x1c};
40 static const UCHAR _NX_CRYPTO_DER_OID_SHA_256[] = {0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20};
41 static const UCHAR _NX_CRYPTO_DER_OID_SHA_384[] = {0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30};
42 static const UCHAR _NX_CRYPTO_DER_OID_SHA_512[] = {0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40};
43 #endif
44
45
46 /**************************************************************************/
47 /* */
48 /* FUNCTION RELEASE */
49 /* */
50 /* _nx_secure_tls_ecc_generate_keys PORTABLE C */
51 /* 6.2.1 */
52 /* AUTHOR */
53 /* */
54 /* Timothy Stapko, Microsoft Corporation */
55 /* */
56 /* DESCRIPTION */
57 /* */
58 /* This function is used to generate ECC key pairs (public, private) */
59 /* for use in TLS. TLS ECC keys need to be signed using a trusted */
60 /* certificate or other mechanism - this function handles the signature*/
61 /* generation and outputs the public key and it's signature in the */
62 /* proper over-the-wire format for TLS. The private key is also */
63 /* exported (conditionally) for later use (usually when used to */
64 /* calculate the shared secret. */
65 /* */
66 /* NOTE: The key sizes should contain the size of their respective */
67 /* buffers as input. The value will be replaced with the actual */
68 /* size of the generated key. */
69 /* */
70 /* INPUT */
71 /* */
72 /* ciphersuite Selected cipher suite */
73 /* protocol_version Selected TLS version */
74 /* tls_1_3 Whether TLS 1.3 is chosen */
75 /* tls_crypto_table TLS crypto methods */
76 /* tls_handshake_hash Metadata for handshake hash */
77 /* tls_ecc_curves ECC curves */
78 /* tls_key_material TLS key material */
79 /* tls_credentials TLS credentials */
80 /* ecc_named_curve IANA ECC curve identifier */
81 /* sign_key True/False generate signature */
82 /* public_key Signed ECC public key */
83 /* public_key_size Size of public key */
84 /* ecc_data ECC data (incl. private key) */
85 /* public_cipher_metadata Metadata for public cipher */
86 /* public_cipher_metadata_size Size of public cipher metadata*/
87 /* public_auth_metadata Metadata for public auth */
88 /* public_auth_metadata_size Size of public auth metadata */
89 /* */
90 /* OUTPUT */
91 /* */
92 /* status Completion status */
93 /* */
94 /* CALLS */
95 /* */
96 /* None */
97 /* */
98 /* CALLED BY */
99 /* */
100 /* Application Code */
101 /* */
102 /* RELEASE HISTORY */
103 /* */
104 /* DATE NAME DESCRIPTION */
105 /* */
106 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
107 /* 09-30-2020 Timothy Stapko Modified comment(s), update */
108 /* ECC find curve method, */
109 /* verified memcpy use cases, */
110 /* resulting in version 6.1 */
111 /* 04-25-2022 Yuxin Zhou Modified comment(s), removed */
112 /* internal unreachable logic, */
113 /* resulting in version 6.1.11 */
114 /* 10-31-2022 Yanwu Cai Modified comment(s), */
115 /* updated parameters list, */
116 /* resulting in version 6.2.0 */
117 /* 03-08-2023 Yanwu Cai Modified comment(s), */
118 /* fixed compiler errors when */
119 /* x509 is disabled, */
120 /* resulting in version 6.2.1 */
121 /* */
122 /**************************************************************************/
_nx_secure_tls_ecc_generate_keys(const NX_SECURE_TLS_CIPHERSUITE_INFO * ciphersuite,USHORT protocol_version,UCHAR tls_1_3,NX_SECURE_TLS_CRYPTO * tls_crypto_table,NX_SECURE_TLS_HANDSHAKE_HASH * tls_handshake_hash,NX_SECURE_TLS_ECC * tls_ecc_curves,NX_SECURE_TLS_KEY_MATERIAL * tls_key_material,NX_SECURE_TLS_CREDENTIALS * tls_credentials,UINT ecc_named_curve,USHORT sign_key,UCHAR * public_key,UINT * public_key_size,NX_SECURE_TLS_ECDHE_HANDSHAKE_DATA * ecc_data,VOID * public_cipher_metadata,ULONG public_cipher_metadata_size,VOID * public_auth_metadata,ULONG public_auth_metadata_size)123 UINT _nx_secure_tls_ecc_generate_keys(const NX_SECURE_TLS_CIPHERSUITE_INFO *ciphersuite, USHORT protocol_version, UCHAR tls_1_3,
124 NX_SECURE_TLS_CRYPTO *tls_crypto_table, NX_SECURE_TLS_HANDSHAKE_HASH *tls_handshake_hash,
125 NX_SECURE_TLS_ECC *tls_ecc_curves, NX_SECURE_TLS_KEY_MATERIAL *tls_key_material,
126 NX_SECURE_TLS_CREDENTIALS *tls_credentials, UINT ecc_named_curve, USHORT sign_key,
127 UCHAR *public_key, UINT *public_key_size, NX_SECURE_TLS_ECDHE_HANDSHAKE_DATA *ecc_data,
128 VOID *public_cipher_metadata, ULONG public_cipher_metadata_size,
129 VOID *public_auth_metadata, ULONG public_auth_metadata_size)
130 {
131 UINT length;
132 UINT output_size;
133 UINT status;
134 NX_CRYPTO_EXTENDED_OUTPUT extended_output;
135 VOID *handler = NX_NULL;
136 const NX_CRYPTO_METHOD *curve_method;
137 const NX_CRYPTO_METHOD *ecdhe_method;
138 #ifndef NX_SECURE_DISABLE_X509
139 USHORT signature_length;
140 UINT signature_offset;
141 const UCHAR *der_encoding = NX_NULL;
142 UINT der_encoding_length = 0;
143 UINT hash_length;
144 const NX_CRYPTO_METHOD *curve_method_cert;
145 const NX_CRYPTO_METHOD *hash_method;
146 const NX_CRYPTO_METHOD *auth_method;
147 NX_SECURE_X509_CERT *certificate;
148 NX_SECURE_X509_CRYPTO *crypto_methods;
149 NX_SECURE_EC_PRIVATE_KEY *ec_privkey;
150 NX_SECURE_EC_PUBLIC_KEY *ec_pubkey;
151 USHORT signature_algorithm_id;
152 #endif
153
154 #if !(NX_SECURE_TLS_TLS_1_0_ENABLED) && !(NX_SECURE_TLS_TLS_1_1_ENABLED)
155 NX_PARAMETER_NOT_USED(protocol_version);
156 #endif
157
158 #if !(NX_SECURE_TLS_TLS_1_3_ENABLED) || (!(NX_SECURE_TLS_TLS_1_0_ENABLED) && !(NX_SECURE_TLS_TLS_1_1_ENABLED))
159 NX_PARAMETER_NOT_USED(tls_1_3);
160 NX_PARAMETER_NOT_USED(tls_crypto_table);
161 #endif
162 #ifdef NX_SECURE_DISABLE_X509
163 NX_PARAMETER_NOT_USED(tls_handshake_hash);
164 NX_PARAMETER_NOT_USED(tls_key_material);
165 NX_PARAMETER_NOT_USED(tls_credentials);
166 NX_PARAMETER_NOT_USED(sign_key);
167 NX_PARAMETER_NOT_USED(public_auth_metadata);
168 NX_PARAMETER_NOT_USED(public_auth_metadata_size);
169 #endif
170
171
172 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
173 if(tls_1_3)
174 {
175 ecdhe_method = tls_crypto_table -> nx_secure_tls_ecdhe_method;
176 }
177 else
178 #endif
179 {
180
181 /* Generate ECDHE key pair using ECDHE crypto method. */
182 ecdhe_method = ciphersuite -> nx_secure_tls_public_cipher;
183 }
184
185 /* Make sure we have a method to use. */
186 if (ecdhe_method == NX_NULL || ecdhe_method -> nx_crypto_operation == NX_NULL)
187 {
188 return(NX_SECURE_TLS_MISSING_CRYPTO_ROUTINE);
189 }
190
191 /* Set the curve we are using. */
192 ecc_data -> nx_secure_tls_ecdhe_named_curve = ecc_named_curve;
193
194 /* Find out which named curve the we are using. */
195 status = _nx_secure_tls_find_curve_method(tls_ecc_curves, (USHORT)ecc_named_curve, &curve_method, NX_NULL);
196 if(status != NX_SUCCESS)
197 {
198 return(status);
199 }
200
201 if (ecdhe_method -> nx_crypto_init != NX_NULL)
202 {
203 status = ecdhe_method -> nx_crypto_init((NX_CRYPTO_METHOD*)ecdhe_method,
204 NX_NULL,
205 0,
206 &handler,
207 public_cipher_metadata,
208 public_cipher_metadata_size);
209 if(status != NX_CRYPTO_SUCCESS)
210 {
211 return(status);
212 }
213 }
214
215 status = ecdhe_method -> nx_crypto_operation(NX_CRYPTO_EC_CURVE_SET, handler,
216 (NX_CRYPTO_METHOD*)ecdhe_method, NX_NULL, 0,
217 (UCHAR *)curve_method, sizeof(NX_CRYPTO_METHOD *), NX_NULL,
218 NX_NULL, 0,
219 public_cipher_metadata,
220 public_cipher_metadata_size,
221 NX_NULL, NX_NULL);
222 if (status != NX_CRYPTO_SUCCESS)
223 {
224 return(status);
225 }
226
227
228 /* Start to fill the public key buffer. */
229 length = 0;
230 output_size = *public_key_size;
231 *public_key_size = 0;
232
233 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
234 if(!tls_1_3)
235 #endif
236 {
237 /* ECCurveType: named_curve (3). */
238 public_key[length] = 3;
239 length += 1;
240
241 /* NamedCurve */
242 public_key[length] = (UCHAR)((ecc_data -> nx_secure_tls_ecdhe_named_curve & 0xFF00) >> 8);
243 public_key[length + 1] = (UCHAR)(ecc_data -> nx_secure_tls_ecdhe_named_curve & 0x00FF);
244 length += 2;
245 }
246
247
248 /* Generate the key pair and output the public key. */
249 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
250 if(tls_1_3)
251 {
252 extended_output.nx_crypto_extended_output_data = &public_key[length];
253 extended_output.nx_crypto_extended_output_length_in_byte = output_size - length;
254 }
255 else
256 #endif
257 {
258 extended_output.nx_crypto_extended_output_data = &public_key[length + 1];
259 extended_output.nx_crypto_extended_output_length_in_byte = output_size - (length + 1);
260 }
261 extended_output.nx_crypto_extended_output_actual_size = 0;
262 status = ecdhe_method -> nx_crypto_operation(NX_CRYPTO_DH_SETUP, handler,
263 (NX_CRYPTO_METHOD*)ecdhe_method, NX_NULL, 0,
264 NX_NULL, 0, NX_NULL,
265 (UCHAR *)&extended_output,
266 sizeof(extended_output),
267 public_cipher_metadata,
268 public_cipher_metadata_size,
269 NX_NULL, NX_NULL);
270 if (status != NX_CRYPTO_SUCCESS)
271 {
272 return(status);
273 }
274
275 #if (NX_SECURE_TLS_TLS_1_3_ENABLED)
276 if(!tls_1_3)
277 #endif
278 {
279 /* Put the length into the buffer before the key data. */
280 public_key[length] = (UCHAR)extended_output.nx_crypto_extended_output_actual_size;
281 length += 1;
282
283 }
284
285 length += (UINT)(extended_output.nx_crypto_extended_output_actual_size);
286
287 /* Export the private key for later use. */
288 extended_output.nx_crypto_extended_output_data = ecc_data -> nx_secure_tls_ecdhe_private_key;
289 extended_output.nx_crypto_extended_output_length_in_byte =
290 sizeof(ecc_data -> nx_secure_tls_ecdhe_private_key);
291 extended_output.nx_crypto_extended_output_actual_size = 0;
292 status = ecdhe_method -> nx_crypto_operation(NX_CRYPTO_DH_PRIVATE_KEY_EXPORT, handler,
293 (NX_CRYPTO_METHOD*)ecdhe_method, NX_NULL, 0,
294 NX_NULL, 0, NX_NULL,
295 (UCHAR *)&extended_output,
296 sizeof(extended_output),
297 public_cipher_metadata,
298 public_cipher_metadata_size,
299 NX_NULL, NX_NULL);
300 if (status != NX_CRYPTO_SUCCESS)
301 {
302 return(status);
303 }
304
305 /* Set the private key length. */
306 ecc_data -> nx_secure_tls_ecdhe_private_key_length = (USHORT)extended_output.nx_crypto_extended_output_actual_size;
307
308 /* Cleanup the ECC crypto state. */
309 if (ecdhe_method -> nx_crypto_cleanup)
310 {
311 status = ecdhe_method -> nx_crypto_cleanup(public_cipher_metadata);
312 if(status != NX_CRYPTO_SUCCESS)
313 {
314 return(status);
315 }
316 }
317
318 #ifndef NX_SECURE_DISABLE_X509
319
320 /* If signing the key, generate the signature now using the local device certificate (if available). */
321 if(sign_key == NX_TRUE)
322 {
323 /* Get the local certificate. */
324 if (tls_credentials -> nx_secure_tls_active_certificate != NX_NULL)
325 {
326 certificate = tls_credentials -> nx_secure_tls_active_certificate;
327 }
328 else
329 {
330 /* Get reference to local device certificate. NX_NULL is passed for name to get default entry. */
331 status = _nx_secure_x509_local_device_certificate_get(&tls_credentials -> nx_secure_tls_certificate_store,
332 NX_NULL, &certificate);
333 if (status != NX_SUCCESS)
334 {
335 certificate = NX_NULL;
336 }
337 }
338
339 if (certificate == NX_NULL)
340 {
341 /* No certificate found, error! */
342 return(NX_SECURE_TLS_CERTIFICATE_NOT_FOUND);
343 }
344
345
346 /* Find out the hash algorithm used for the signature. */
347 /* Map signature algorithm to internal ID. */
348 _nx_secure_tls_get_signature_algorithm_id((UINT)(ecc_data -> nx_secure_tls_ecdhe_signature_algorithm),
349 &signature_algorithm_id);
350
351 /* Get the crypto method. */
352 status = _nx_secure_x509_find_certificate_methods(certificate,
353 signature_algorithm_id,
354 &crypto_methods);
355 if (status)
356 {
357 return(NX_SECURE_TLS_UNSUPPORTED_SIGNATURE_ALGORITHM);
358 }
359
360 #if (NX_SECURE_TLS_TLS_1_0_ENABLED || NX_SECURE_TLS_TLS_1_1_ENABLED)
361 #ifdef NX_SECURE_ENABLE_DTLS
362 if ((ecc_data -> nx_secure_tls_ecdhe_signature_algorithm & 0xFF) == NX_SECURE_TLS_SIGNATURE_ALGORITHM_RSA &&
363 (protocol_version == NX_SECURE_TLS_VERSION_TLS_1_0 ||
364 protocol_version == NX_SECURE_TLS_VERSION_TLS_1_1 ||
365 protocol_version == NX_SECURE_DTLS_VERSION_1_0))
366 #else
367 if ((ecc_data -> nx_secure_tls_ecdhe_signature_algorithm & 0xFF) == NX_SECURE_TLS_SIGNATURE_ALGORITHM_RSA &&
368 (protocol_version == NX_SECURE_TLS_VERSION_TLS_1_0 ||
369 protocol_version == NX_SECURE_TLS_VERSION_TLS_1_1))
370 #endif /* NX_SECURE_ENABLE_DTLS */
371 {
372
373 /* TLS 1.0 and TLS 1.1 use MD5 + SHA1 hash for RSA signatures. */
374 hash_method = tls_crypto_table -> nx_secure_tls_handshake_hash_md5_method;
375 }
376 else
377 #endif /* NX_SECURE_TLS_TLS_1_0_ENABLED || NX_SECURE_TLS_TLS_1_1_ENABLED */
378 {
379 hash_method = crypto_methods -> nx_secure_x509_hash_method;
380 }
381
382 hash_length = hash_method -> nx_crypto_ICV_size_in_bits >> 3;
383
384 /* Calculate the hash: SHA(ClientHello.random + ServerHello.random +
385 ServerKeyExchange.params); */
386 if (hash_method -> nx_crypto_init)
387 {
388 status = hash_method -> nx_crypto_init((NX_CRYPTO_METHOD*)hash_method,
389 NX_NULL,
390 0,
391 &handler,
392 tls_handshake_hash -> nx_secure_tls_handshake_hash_scratch,
393 tls_handshake_hash -> nx_secure_tls_handshake_hash_scratch_size);
394
395 if(status != NX_CRYPTO_SUCCESS)
396 {
397 return(status);
398 }
399 }
400
401 if (hash_method -> nx_crypto_operation != NX_NULL)
402 {
403 status = hash_method -> nx_crypto_operation(NX_CRYPTO_HASH_INITIALIZE,
404 handler,
405 (NX_CRYPTO_METHOD*)hash_method,
406 NX_NULL,
407 0,
408 NX_NULL,
409 0,
410 NX_NULL,
411 NX_NULL,
412 0,
413 tls_handshake_hash -> nx_secure_tls_handshake_hash_scratch,
414 tls_handshake_hash -> nx_secure_tls_handshake_hash_scratch_size,
415 NX_NULL,
416 NX_NULL);
417
418 if(status != NX_CRYPTO_SUCCESS)
419 {
420 return(status);
421 }
422 }
423 else
424 {
425 return(NX_SECURE_TLS_MISSING_CRYPTO_ROUTINE);
426 }
427
428 status = hash_method -> nx_crypto_operation(NX_CRYPTO_HASH_UPDATE,
429 handler,
430 (NX_CRYPTO_METHOD*)hash_method,
431 NX_NULL,
432 0,
433 tls_key_material -> nx_secure_tls_client_random,
434 32,
435 NX_NULL,
436 NX_NULL,
437 0,
438 tls_handshake_hash -> nx_secure_tls_handshake_hash_scratch,
439 tls_handshake_hash -> nx_secure_tls_handshake_hash_scratch_size,
440 NX_NULL,
441 NX_NULL);
442
443 if(status != NX_CRYPTO_SUCCESS)
444 {
445 return(status);
446 }
447
448 status = hash_method -> nx_crypto_operation(NX_CRYPTO_HASH_UPDATE,
449 handler,
450 (NX_CRYPTO_METHOD*)hash_method,
451 NX_NULL,
452 0,
453 tls_key_material -> nx_secure_tls_server_random,
454 32,
455 NX_NULL,
456 NX_NULL,
457 0,
458 tls_handshake_hash -> nx_secure_tls_handshake_hash_scratch,
459 tls_handshake_hash -> nx_secure_tls_handshake_hash_scratch_size,
460 NX_NULL,
461 NX_NULL);
462
463 if(status != NX_CRYPTO_SUCCESS)
464 {
465 return(status);
466 }
467
468 status = hash_method -> nx_crypto_operation(NX_CRYPTO_HASH_UPDATE,
469 handler,
470 (NX_CRYPTO_METHOD*)hash_method,
471 NX_NULL,
472 0,
473 public_key,
474 length,
475 NX_NULL,
476 NX_NULL,
477 0,
478 tls_handshake_hash -> nx_secure_tls_handshake_hash_scratch,
479 tls_handshake_hash -> nx_secure_tls_handshake_hash_scratch_size,
480 NX_NULL,
481 NX_NULL);
482
483 if(status != NX_CRYPTO_SUCCESS)
484 {
485 return(status);
486 }
487
488 status = hash_method -> nx_crypto_operation(NX_CRYPTO_HASH_CALCULATE,
489 handler,
490 (NX_CRYPTO_METHOD*)hash_method,
491 NX_NULL,
492 0,
493 NX_NULL,
494 0,
495 NX_NULL,
496 hash,
497 hash_length,
498 tls_handshake_hash -> nx_secure_tls_handshake_hash_scratch,
499 tls_handshake_hash -> nx_secure_tls_handshake_hash_scratch_size,
500 NX_NULL,
501 NX_NULL);
502
503 if(status != NX_CRYPTO_SUCCESS)
504 {
505 return(status);
506 }
507
508 if (hash_method -> nx_crypto_cleanup)
509 {
510 status = hash_method -> nx_crypto_cleanup(tls_handshake_hash -> nx_secure_tls_handshake_hash_scratch);
511
512 if(status != NX_CRYPTO_SUCCESS)
513 {
514 return(status);
515 }
516 }
517 handler = NX_NULL;
518
519 #if (NX_SECURE_TLS_TLS_1_0_ENABLED || NX_SECURE_TLS_TLS_1_1_ENABLED)
520 #ifdef NX_SECURE_ENABLE_DTLS
521 if ((ecc_data -> nx_secure_tls_ecdhe_signature_algorithm & 0xFF) == NX_SECURE_TLS_SIGNATURE_ALGORITHM_RSA &&
522 (protocol_version == NX_SECURE_TLS_VERSION_TLS_1_0 ||
523 protocol_version == NX_SECURE_TLS_VERSION_TLS_1_1 ||
524 protocol_version == NX_SECURE_DTLS_VERSION_1_0))
525 #else
526 if ((ecc_data -> nx_secure_tls_ecdhe_signature_algorithm & 0xFF) == NX_SECURE_TLS_SIGNATURE_ALGORITHM_RSA &&
527 (protocol_version == NX_SECURE_TLS_VERSION_TLS_1_0 ||
528 protocol_version == NX_SECURE_TLS_VERSION_TLS_1_1))
529 #endif /* NX_SECURE_ENABLE_DTLS */
530 {
531 hash_method = tls_crypto_table -> nx_secure_tls_handshake_hash_sha1_method;;
532
533 /* Calculate the hash: SHA(ClientHello.random + ServerHello.random +
534 ServerKeyExchange.params); */
535 if (hash_method -> nx_crypto_init)
536 {
537 status = hash_method -> nx_crypto_init((NX_CRYPTO_METHOD*)hash_method,
538 NX_NULL,
539 0,
540 &handler,
541 tls_handshake_hash -> nx_secure_tls_handshake_hash_scratch,
542 tls_handshake_hash -> nx_secure_tls_handshake_hash_scratch_size);
543
544 if(status != NX_CRYPTO_SUCCESS)
545 {
546 return(status);
547 }
548 }
549
550 if (hash_method -> nx_crypto_operation != NX_NULL)
551 {
552 status = hash_method -> nx_crypto_operation(NX_CRYPTO_HASH_INITIALIZE,
553 handler,
554 (NX_CRYPTO_METHOD*)hash_method,
555 NX_NULL,
556 0,
557 NX_NULL,
558 0,
559 NX_NULL,
560 NX_NULL,
561 0,
562 tls_handshake_hash -> nx_secure_tls_handshake_hash_scratch,
563 tls_handshake_hash -> nx_secure_tls_handshake_hash_scratch_size,
564 NX_NULL,
565 NX_NULL);
566
567 if(status != NX_CRYPTO_SUCCESS)
568 {
569 return(status);
570 }
571 }
572 else
573 {
574 return(NX_SECURE_TLS_MISSING_CRYPTO_ROUTINE);
575 }
576
577 status = hash_method -> nx_crypto_operation(NX_CRYPTO_HASH_UPDATE,
578 handler,
579 (NX_CRYPTO_METHOD*)hash_method,
580 NX_NULL,
581 0,
582 tls_key_material -> nx_secure_tls_client_random,
583 32,
584 NX_NULL,
585 NX_NULL,
586 0,
587 tls_handshake_hash -> nx_secure_tls_handshake_hash_scratch,
588 tls_handshake_hash -> nx_secure_tls_handshake_hash_scratch_size,
589 NX_NULL,
590 NX_NULL);
591
592 if(status != NX_CRYPTO_SUCCESS)
593 {
594 return(status);
595 }
596
597 status = hash_method -> nx_crypto_operation(NX_CRYPTO_HASH_UPDATE,
598 handler,
599 (NX_CRYPTO_METHOD*)hash_method,
600 NX_NULL,
601 0,
602 tls_key_material -> nx_secure_tls_server_random,
603 32,
604 NX_NULL,
605 NX_NULL,
606 0,
607 tls_handshake_hash -> nx_secure_tls_handshake_hash_scratch,
608 tls_handshake_hash -> nx_secure_tls_handshake_hash_scratch_size,
609 NX_NULL,
610 NX_NULL);
611
612 if(status != NX_CRYPTO_SUCCESS)
613 {
614 return(status);
615 }
616
617 status = hash_method -> nx_crypto_operation(NX_CRYPTO_HASH_UPDATE,
618 handler,
619 (NX_CRYPTO_METHOD*)hash_method,
620 NX_NULL,
621 0,
622 public_key,
623 length,
624 NX_NULL,
625 NX_NULL,
626 0,
627 tls_handshake_hash -> nx_secure_tls_handshake_hash_scratch,
628 tls_handshake_hash -> nx_secure_tls_handshake_hash_scratch_size,
629 NX_NULL,
630 NX_NULL);
631
632 if(status != NX_CRYPTO_SUCCESS)
633 {
634 return(status);
635 }
636
637 status = hash_method -> nx_crypto_operation(NX_CRYPTO_HASH_CALCULATE,
638 handler,
639 (NX_CRYPTO_METHOD*)hash_method,
640 NX_NULL,
641 0,
642 NX_NULL,
643 0,
644 NX_NULL,
645 &hash[16],
646 hash_method -> nx_crypto_ICV_size_in_bits >> 3,
647 tls_handshake_hash -> nx_secure_tls_handshake_hash_scratch,
648 tls_handshake_hash -> nx_secure_tls_handshake_hash_scratch_size,
649 NX_NULL,
650 NX_NULL);
651
652 if(status != NX_CRYPTO_SUCCESS)
653 {
654 return(status);
655 }
656
657 if (hash_method -> nx_crypto_cleanup)
658 {
659 status = hash_method -> nx_crypto_cleanup(tls_handshake_hash -> nx_secure_tls_handshake_hash_scratch);
660
661 if(status != NX_CRYPTO_SUCCESS)
662 {
663 return(status);
664 }
665 }
666 handler = NX_NULL;
667 }
668 #endif /* NX_SECURE_TLS_TLS_1_0_ENABLED || NX_SECURE_TLS_TLS_1_1_ENABLED */
669
670 #if (NX_SECURE_TLS_TLS_1_0_ENABLED || NX_SECURE_TLS_TLS_1_1_ENABLED)
671 #ifdef NX_SECURE_ENABLE_DTLS
672 if (protocol_version != NX_SECURE_TLS_VERSION_TLS_1_0 &&
673 protocol_version != NX_SECURE_TLS_VERSION_TLS_1_1 &&
674 protocol_version != NX_SECURE_DTLS_VERSION_1_0)
675 #else
676 if (protocol_version != NX_SECURE_TLS_VERSION_TLS_1_0 &&
677 protocol_version != NX_SECURE_TLS_VERSION_TLS_1_1)
678 #endif /* NX_SECURE_ENABLE_DTLS */
679 #endif /* NX_SECURE_TLS_TLS_1_0_ENABLED || NX_SECURE_TLS_TLS_1_1_ENABLED */
680 {
681
682 /* Signature Hash Algorithm. */
683 public_key[length] = (UCHAR)((ecc_data -> nx_secure_tls_ecdhe_signature_algorithm & 0xFF00) >> 8);
684 public_key[length + 1] = (UCHAR)(ecc_data -> nx_secure_tls_ecdhe_signature_algorithm & 0x00FF);
685 length += 2;
686 }
687
688 /* Sign the hash. */
689 auth_method = ciphersuite -> nx_secure_tls_public_auth;
690 if ((ecc_data -> nx_secure_tls_ecdhe_signature_algorithm & 0xFF) == NX_SECURE_TLS_SIGNATURE_ALGORITHM_RSA &&
691 (auth_method -> nx_crypto_algorithm == NX_CRYPTO_DIGITAL_SIGNATURE_RSA ||
692 auth_method -> nx_crypto_algorithm == NX_CRYPTO_KEY_EXCHANGE_RSA))
693 {
694 signature_length = certificate -> nx_secure_x509_public_key.rsa_public_key.nx_secure_rsa_public_modulus_length;
695
696 /* Signature Length */
697 public_key[length] = (UCHAR)((signature_length & 0xFF00) >> 8);
698 public_key[length + 1] = (UCHAR)(signature_length & 0x00FF);
699 length += 2;
700
701 #if (NX_SECURE_TLS_TLS_1_0_ENABLED || NX_SECURE_TLS_TLS_1_1_ENABLED)
702 #ifdef NX_SECURE_ENABLE_DTLS
703 if ((ecc_data -> nx_secure_tls_ecdhe_signature_algorithm & 0xFF) == NX_SECURE_TLS_SIGNATURE_ALGORITHM_RSA &&
704 (protocol_version == NX_SECURE_TLS_VERSION_TLS_1_0 ||
705 protocol_version == NX_SECURE_TLS_VERSION_TLS_1_1 ||
706 protocol_version == NX_SECURE_DTLS_VERSION_1_0))
707 #else
708 if ((ecc_data -> nx_secure_tls_ecdhe_signature_algorithm & 0xFF) == NX_SECURE_TLS_SIGNATURE_ALGORITHM_RSA &&
709 (protocol_version == NX_SECURE_TLS_VERSION_TLS_1_0 ||
710 protocol_version == NX_SECURE_TLS_VERSION_TLS_1_1))
711 #endif /* NX_SECURE_ENABLE_DTLS */
712 {
713 hash_length += hash_method -> nx_crypto_ICV_size_in_bits >> 3;
714 der_encoding_length = 0;
715 }
716 else
717 #endif /* NX_SECURE_TLS_TLS_1_0_ENABLED || NX_SECURE_TLS_TLS_1_1_ENABLED */
718 {
719 switch ((ecc_data -> nx_secure_tls_ecdhe_signature_algorithm & 0xFF00) >> 8)
720 {
721 case NX_SECURE_TLS_HASH_ALGORITHM_MD5:
722 der_encoding = _NX_CRYPTO_DER_OID_MD5;
723 der_encoding_length = sizeof(_NX_CRYPTO_DER_OID_MD5);
724 break;
725 case NX_SECURE_TLS_HASH_ALGORITHM_SHA1:
726 der_encoding = _NX_CRYPTO_DER_OID_SHA_1;
727 der_encoding_length = sizeof(_NX_CRYPTO_DER_OID_SHA_1);
728 break;
729 case NX_SECURE_TLS_HASH_ALGORITHM_SHA224:
730 der_encoding = _NX_CRYPTO_DER_OID_SHA_224;
731 der_encoding_length = sizeof(_NX_CRYPTO_DER_OID_SHA_224);
732 break;
733 case NX_SECURE_TLS_HASH_ALGORITHM_SHA256:
734 der_encoding = _NX_CRYPTO_DER_OID_SHA_256;
735 der_encoding_length = sizeof(_NX_CRYPTO_DER_OID_SHA_256);
736 break;
737 case NX_SECURE_TLS_HASH_ALGORITHM_SHA384:
738 der_encoding = _NX_CRYPTO_DER_OID_SHA_384;
739 der_encoding_length = sizeof(_NX_CRYPTO_DER_OID_SHA_384);
740 break;
741 case NX_SECURE_TLS_HASH_ALGORITHM_SHA512:
742 der_encoding = _NX_CRYPTO_DER_OID_SHA_512;
743 der_encoding_length = sizeof(_NX_CRYPTO_DER_OID_SHA_512);
744 break;
745 default:
746 return(NX_SECURE_TLS_UNSUPPORTED_SIGNATURE_ALGORITHM);
747 }
748 }
749
750 /* Build the RSA signature. */
751 /* C-STAT: If signature_length is ever exactly equal to (der_encoding_length + hash_length)
752 then signature_offset will be 0 and the (signature_offset - 1) expression below
753 would result in a negative array subscript. Thus, also check for equality in the
754 second condition (a zero-length signature offset). */
755 signature_offset = signature_length - (der_encoding_length + hash_length);
756 if ((signature_offset > sizeof(_nx_secure_padded_signature)) ||
757 (signature_length > sizeof(_nx_secure_padded_signature)) ||
758 (signature_offset == 0))
759 {
760
761 /* Buffer too small. */
762 return(NX_SECURE_TLS_PACKET_BUFFER_TOO_SMALL);
763 }
764 NX_CRYPTO_MEMSET(_nx_secure_padded_signature, 0xff, signature_offset);
765 _nx_secure_padded_signature[0] = 0x0;
766 _nx_secure_padded_signature[1] = 0x1;
767 _nx_secure_padded_signature[signature_offset - 1] = 0x0;
768 #if (NX_SECURE_TLS_TLS_1_0_ENABLED || NX_SECURE_TLS_TLS_1_1_ENABLED)
769 if (der_encoding_length > 0)
770 #endif
771 {
772 NX_CRYPTO_MEMCPY(&_nx_secure_padded_signature[signature_offset], der_encoding, der_encoding_length); /* Use case of memcpy is verified. */
773 signature_offset += der_encoding_length;
774 }
775 NX_CRYPTO_MEMCPY(&_nx_secure_padded_signature[signature_offset], hash, hash_length); /* Use case of memcpy is verified. */
776 if (auth_method -> nx_crypto_init != NX_NULL)
777 {
778 /* Initialize the crypto method with public key. */
779 status = auth_method -> nx_crypto_init((NX_CRYPTO_METHOD*)auth_method,
780 (UCHAR *)certificate -> nx_secure_x509_public_key.rsa_public_key.nx_secure_rsa_public_modulus,
781 (NX_CRYPTO_KEY_SIZE)(certificate -> nx_secure_x509_public_key.rsa_public_key.nx_secure_rsa_public_modulus_length << 3),
782 &handler,
783 public_auth_metadata,
784 public_auth_metadata_size);
785 if (status != NX_CRYPTO_SUCCESS)
786 {
787 return(status);
788 }
789 }
790 if (auth_method -> nx_crypto_operation != NX_NULL)
791 {
792 /* Sign the hash we just generated using our local RSA private key (associated with our local cert). */
793 status = auth_method -> nx_crypto_operation(NX_CRYPTO_DECRYPT,
794 handler,
795 (NX_CRYPTO_METHOD*)auth_method,
796 (UCHAR *)certificate -> nx_secure_x509_private_key.rsa_private_key.nx_secure_rsa_private_exponent,
797 (NX_CRYPTO_KEY_SIZE)(certificate -> nx_secure_x509_private_key.rsa_private_key.nx_secure_rsa_private_exponent_length << 3),
798 _nx_secure_padded_signature,
799 signature_length,
800 NX_NULL,
801 &public_key[length],
802 signature_length,
803 public_auth_metadata,
804 public_auth_metadata_size,
805 NX_NULL, NX_NULL);
806 if (status != NX_CRYPTO_SUCCESS)
807 {
808 return(status);
809 }
810 }
811
812 length += signature_length;
813
814 if (auth_method -> nx_crypto_cleanup)
815 {
816 status = auth_method -> nx_crypto_cleanup(public_auth_metadata);
817
818 if(status != NX_CRYPTO_SUCCESS)
819 {
820 return(status);
821 }
822 }
823 }
824 else if ((ecc_data -> nx_secure_tls_ecdhe_signature_algorithm & 0xFF) == NX_SECURE_TLS_SIGNATURE_ALGORITHM_ECDSA &&
825 auth_method -> nx_crypto_algorithm == NX_CRYPTO_DIGITAL_SIGNATURE_ECDSA)
826 {
827 ec_privkey = &certificate -> nx_secure_x509_private_key.ec_private_key;
828 ec_pubkey = &certificate -> nx_secure_x509_public_key.ec_public_key;
829
830 /* Find out which named curve the local certificate is using. */
831 status = _nx_secure_tls_find_curve_method(tls_ecc_curves, (USHORT)(ec_privkey -> nx_secure_ec_named_curve), &curve_method_cert, NX_NULL);
832 if(status != NX_SUCCESS)
833 {
834 return(status);
835 }
836
837 if (auth_method -> nx_crypto_init != NX_NULL)
838 {
839 status = auth_method -> nx_crypto_init((NX_CRYPTO_METHOD*)auth_method,
840 (UCHAR *)ec_pubkey -> nx_secure_ec_public_key,
841 (NX_CRYPTO_KEY_SIZE)(ec_pubkey -> nx_secure_ec_public_key_length << 3),
842 &handler,
843 public_auth_metadata,
844 public_auth_metadata_size);
845 if (status != NX_CRYPTO_SUCCESS)
846 {
847 return(status);
848 }
849 }
850 if (auth_method -> nx_crypto_operation == NX_NULL)
851 {
852 return(NX_SECURE_TLS_MISSING_CRYPTO_ROUTINE);
853 }
854
855 status = auth_method -> nx_crypto_operation(NX_CRYPTO_EC_CURVE_SET, handler,
856 (NX_CRYPTO_METHOD*)auth_method, NX_NULL, 0,
857 (UCHAR *)curve_method_cert, sizeof(NX_CRYPTO_METHOD *), NX_NULL,
858 NX_NULL, 0,
859 public_auth_metadata,
860 public_auth_metadata_size,
861 NX_NULL, NX_NULL);
862 if (status != NX_CRYPTO_SUCCESS)
863 {
864 return(status);
865 }
866
867 /* Generate the signature and put it in the packet. */
868 extended_output.nx_crypto_extended_output_data = &public_key[length + 2];
869 extended_output.nx_crypto_extended_output_length_in_byte = output_size - length;
870 extended_output.nx_crypto_extended_output_actual_size = 0;
871 status = auth_method -> nx_crypto_operation(NX_CRYPTO_AUTHENTICATE, handler,
872 (NX_CRYPTO_METHOD*)auth_method,
873 (UCHAR *)ec_privkey -> nx_secure_ec_private_key,
874 (NX_CRYPTO_KEY_SIZE)(ec_privkey -> nx_secure_ec_private_key_length << 3),
875 hash,
876 hash_method -> nx_crypto_ICV_size_in_bits >> 3, NX_NULL,
877 (UCHAR *)&extended_output,
878 sizeof(extended_output),
879 public_auth_metadata,
880 public_auth_metadata_size,
881 NX_NULL, NX_NULL);
882 if (status != NX_CRYPTO_SUCCESS)
883 {
884 return(status);
885 }
886
887 if (auth_method -> nx_crypto_cleanup)
888 {
889 status = auth_method -> nx_crypto_cleanup(public_auth_metadata);
890
891 if(status != NX_CRYPTO_SUCCESS)
892 {
893 return(status);
894 }
895 }
896
897 /* Signature Length */
898 public_key[length] = (UCHAR)((extended_output.nx_crypto_extended_output_actual_size & 0xFF00) >> 8);
899 public_key[length + 1] = (UCHAR)(extended_output.nx_crypto_extended_output_actual_size & 0x00FF);
900
901 length += extended_output.nx_crypto_extended_output_actual_size + 2;
902 }
903 else
904 {
905 /* The signature algorithm is not supported. */
906 *public_key_size = 0;
907 return(NX_SECURE_TLS_UNSUPPORTED_SIGNATURE_ALGORITHM);
908 }
909 }
910 #endif
911
912 /* Return the length of our generated data. */
913 *public_key_size = length;
914
915 return(NX_SUCCESS);
916 }
917 #endif /* NX_SECURE_ENABLE_ECC_CIPHERSUITE */
918
919
920