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 Crypto Component */
17 /** */
18 /** 3DES Encryption Standard (Triple DES) */
19 /** */
20 /**************************************************************************/
21 /**************************************************************************/
22
23 #include "nx_crypto_3des.h"
24
25
26 /**************************************************************************/
27 /* */
28 /* FUNCTION RELEASE */
29 /* */
30 /* _nx_crypto_3des_key_set PORTABLE C */
31 /* 6.1.11 */
32 /* AUTHOR */
33 /* */
34 /* Timothy Stapko, Microsoft Corporation */
35 /* */
36 /* DESCRIPTION */
37 /* */
38 /* This function sets up the encryption keys for the 3DES algorithm. */
39 /* It must be called before either _nx_crypto_3des_encrypt or */
40 /* _nx_crypto_3des_decrypt can be called. */
41 /* */
42 /* INPUT */
43 /* */
44 /* context 3DES context pointer */
45 /* key 24 bytes key */
46 /* */
47 /* OUTPUT */
48 /* */
49 /* status Completion status */
50 /* */
51 /* CALLS */
52 /* */
53 /* _nx_crypto_des_key_set Set the key for DES */
54 /* */
55 /* CALLED BY */
56 /* */
57 /* _nx_crypto_method_3des_init Init the method for 3DES */
58 /* */
59 /* RELEASE HISTORY */
60 /* */
61 /* DATE NAME DESCRIPTION */
62 /* */
63 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
64 /* 09-30-2020 Timothy Stapko Modified comment(s), */
65 /* resulting in version 6.1 */
66 /* 04-25-2022 Timothy Stapko Modified comments(s), added */
67 /* warning supression for */
68 /* obsolete DES/3DES, */
69 /* resulting in version 6.1.11 */
70 /* */
71 /**************************************************************************/
_nx_crypto_3des_key_set(NX_CRYPTO_3DES * context,UCHAR key[24])72 NX_CRYPTO_KEEP UINT _nx_crypto_3des_key_set(NX_CRYPTO_3DES *context, UCHAR key[24])
73 {
74
75 _nx_crypto_des_key_set(&context -> des_1, key); /* lgtm[cpp/weak-cryptographic-algorithm] */
76
77 _nx_crypto_des_key_set(&context -> des_2, key + 8); /* lgtm[cpp/weak-cryptographic-algorithm] */
78
79 _nx_crypto_des_key_set(&context -> des_3, key + 16); /* lgtm[cpp/weak-cryptographic-algorithm] */
80
81 return(NX_CRYPTO_SUCCESS);
82 }
83
84
85 /**************************************************************************/
86 /* */
87 /* FUNCTION RELEASE */
88 /* */
89 /* _nx_crypto_3des_encrypt PORTABLE C */
90 /* 6.1.11 */
91 /* AUTHOR */
92 /* */
93 /* Timothy Stapko, Microsoft Corporation */
94 /* */
95 /* DESCRIPTION */
96 /* */
97 /* This function uses the 3DES algorithm to encrypt 8-bytes (64-bits). */
98 /* The result is 8 encrypted bytes. Note that the caller must make */
99 /* sure the source and destination are 8-bytes in size! */
100 /* */
101 /* INPUT */
102 /* */
103 /* context 3DES context pointer */
104 /* source 8-byte source */
105 /* destination 8-byte destination */
106 /* length The length of output buffer */
107 /* */
108 /* OUTPUT */
109 /* */
110 /* status Completion status */
111 /* */
112 /* CALLS */
113 /* */
114 /* _nx_crypto_des_encrypt Perform DES mode encryption */
115 /* _nx_crypto_des_decrypt Perform DES mode decryption */
116 /* */
117 /* CALLED BY */
118 /* */
119 /* _nx_crypto_method_3des_operation Handle 3DES encrypt or decrypt*/
120 /* */
121 /* RELEASE HISTORY */
122 /* */
123 /* DATE NAME DESCRIPTION */
124 /* */
125 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
126 /* 09-30-2020 Timothy Stapko Modified comment(s), */
127 /* resulting in version 6.1 */
128 /* 04-25-2022 Timothy Stapko Modified comments(s), added */
129 /* warning supression for */
130 /* obsolete DES/3DES, */
131 /* resulting in version 6.1.11 */
132 /* */
133 /**************************************************************************/
_nx_crypto_3des_encrypt(NX_CRYPTO_3DES * context,UCHAR source[8],UCHAR destination[8],UINT length)134 NX_CRYPTO_KEEP UINT _nx_crypto_3des_encrypt(NX_CRYPTO_3DES *context, UCHAR source[8],
135 UCHAR destination[8], UINT length)
136 {
137
138 /* ciphertext = EK3(DK2(EK1(plaintext)))
139 I.e., DES encrypt with K1, DES decrypt with K2, then DES encrypt with K3. */
140 _nx_crypto_des_encrypt(&context -> des_1, source, destination, length); /* lgtm[cpp/weak-cryptographic-algorithm] */
141
142 _nx_crypto_des_decrypt(&context -> des_2, destination, destination, length); /* lgtm[cpp/weak-cryptographic-algorithm] */
143
144 _nx_crypto_des_encrypt(&context -> des_3, destination, destination, length); /* lgtm[cpp/weak-cryptographic-algorithm] */
145
146 /* Return successful completion. */
147 return(NX_CRYPTO_SUCCESS);
148 }
149
150
151 /**************************************************************************/
152 /* */
153 /* FUNCTION RELEASE */
154 /* */
155 /* _nx_crypto_3des_decrypt PORTABLE C */
156 /* 6.1.11 */
157 /* AUTHOR */
158 /* */
159 /* Timothy Stapko, Microsoft Corporation */
160 /* */
161 /* DESCRIPTION */
162 /* */
163 /* This function uses the 3DES algorithm to decrypt 8-bytes (64-bits). */
164 /* The result is 8 original source bytes. Note that the caller must */
165 /* make sure the source and destination are 8-bytes in size! */
166 /* */
167 /* INPUT */
168 /* */
169 /* context 3DES context pointer */
170 /* source 8-byte source */
171 /* destination 8-byte destination */
172 /* length The length of output buffer */
173 /* */
174 /* OUTPUT */
175 /* */
176 /* status Completion status */
177 /* */
178 /* CALLS */
179 /* */
180 /* _nx_crypto_des_encrypt Perform DES mode encryption */
181 /* _nx_crypto_des_decrypt Perform DES mode decryption */
182 /* */
183 /* CALLED BY */
184 /* */
185 /* _nx_crypto_method_3des_operation Handle 3DES encrypt or decrypt*/
186 /* */
187 /* RELEASE HISTORY */
188 /* */
189 /* DATE NAME DESCRIPTION */
190 /* */
191 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
192 /* 09-30-2020 Timothy Stapko Modified comment(s), */
193 /* resulting in version 6.1 */
194 /* 04-25-2022 Timothy Stapko Modified comments(s), added */
195 /* warning supression for */
196 /* obsolete DES/3DES, */
197 /* resulting in version 6.1.11 */
198 /* */
199 /**************************************************************************/
_nx_crypto_3des_decrypt(NX_CRYPTO_3DES * context,UCHAR source[8],UCHAR destination[8],UINT length)200 NX_CRYPTO_KEEP UINT _nx_crypto_3des_decrypt(NX_CRYPTO_3DES *context, UCHAR source[8],
201 UCHAR destination[8], UINT length)
202 {
203
204
205 /*
206 plaintext = DK1(EK2(DK3(ciphertext)))
207 I.e., decrypt with K3, encrypt with K2, then decrypt with K1.
208 */
209 _nx_crypto_des_decrypt(&context -> des_3, source, destination, length); /* lgtm[cpp/weak-cryptographic-algorithm] */
210
211 _nx_crypto_des_encrypt(&context -> des_2, destination, destination, length); /* lgtm[cpp/weak-cryptographic-algorithm] */
212
213 _nx_crypto_des_decrypt(&context -> des_1, destination, destination, length); /* lgtm[cpp/weak-cryptographic-algorithm] */
214
215
216 /* Return successful completion. */
217 return(NX_CRYPTO_SUCCESS);
218 }
219
220
221 /**************************************************************************/
222 /* */
223 /* FUNCTION RELEASE */
224 /* */
225 /* _nx_crypto_method_3des_init PORTABLE C */
226 /* 6.3.0 */
227 /* AUTHOR */
228 /* */
229 /* Timothy Stapko, Microsoft Corporation */
230 /* */
231 /* DESCRIPTION */
232 /* */
233 /* This function is the common crypto method init callback for */
234 /* Microsoft supported 3DES cryptographic algorithm. */
235 /* */
236 /* INPUT */
237 /* */
238 /* method Pointer to crypto method */
239 /* key Pointer to key */
240 /* key_size_in_bits Length of key size in bits */
241 /* handler Returned crypto handler */
242 /* crypto_metadata Metadata area */
243 /* crypto_metadata_size Size of the metadata area */
244 /* */
245 /* OUTPUT */
246 /* */
247 /* status Completion status */
248 /* */
249 /* CALLS */
250 /* */
251 /* _nx_crypto_3des_key_set Set the key for 3DES */
252 /* */
253 /* CALLED BY */
254 /* */
255 /* Application Code */
256 /* */
257 /* RELEASE HISTORY */
258 /* */
259 /* DATE NAME DESCRIPTION */
260 /* */
261 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
262 /* 09-30-2020 Timothy Stapko Modified comment(s), */
263 /* resulting in version 6.1 */
264 /* 04-25-2022 Timothy Stapko Modified comments(s), added */
265 /* warning supression for */
266 /* obsolete DES/3DES, */
267 /* resulting in version 6.1.11 */
268 /* 10-31-2023 Yanwu Cai Modified comment(s), */
269 /* resulting in version 6.3.0 */
270 /* */
271 /**************************************************************************/
_nx_crypto_method_3des_init(struct NX_CRYPTO_METHOD_STRUCT * method,UCHAR * key,NX_CRYPTO_KEY_SIZE key_size_in_bits,VOID ** handle,VOID * crypto_metadata,ULONG crypto_metadata_size)272 NX_CRYPTO_KEEP UINT _nx_crypto_method_3des_init(struct NX_CRYPTO_METHOD_STRUCT *method,
273 UCHAR *key, NX_CRYPTO_KEY_SIZE key_size_in_bits,
274 VOID **handle,
275 VOID *crypto_metadata,
276 ULONG crypto_metadata_size)
277 {
278 NX_CRYPTO_3DES *triple_des_context_ptr;
279
280 NX_CRYPTO_PARAMETER_NOT_USED(handle);
281
282 NX_CRYPTO_STATE_CHECK
283
284 /* Validate input parameters. */
285 if ((method == NX_CRYPTO_NULL) || (key == NX_CRYPTO_NULL) || (crypto_metadata == NX_CRYPTO_NULL))
286 {
287 return(NX_CRYPTO_PTR_ERROR);
288 }
289
290 /* Verify the metadata address is 4-byte aligned. */
291 if((((ULONG)crypto_metadata) & 0x3) != 0)
292 {
293 return(NX_CRYPTO_PTR_ERROR);
294 }
295
296 if(crypto_metadata_size < sizeof(NX_CRYPTO_3DES))
297 {
298 return(NX_CRYPTO_PTR_ERROR);
299 }
300
301
302 if (key_size_in_bits != NX_CRYPTO_3DES_KEY_LEN_IN_BITS) /* lgtm[cpp/weak-cryptographic-algorithm] */
303 {
304 return(NX_CRYPTO_UNSUPPORTED_KEY_SIZE);
305 }
306
307 triple_des_context_ptr = (NX_CRYPTO_3DES *)(crypto_metadata);
308
309
310 _nx_crypto_3des_key_set(triple_des_context_ptr, key); /* lgtm[cpp/weak-cryptographic-algorithm] */
311
312 return(NX_CRYPTO_SUCCESS);
313 }
314
315
316 /**************************************************************************/
317 /* */
318 /* FUNCTION RELEASE */
319 /* */
320 /* _nx_crypto_method_3des_cleanup PORTABLE C */
321 /* 6.1 */
322 /* AUTHOR */
323 /* */
324 /* Timothy Stapko, Microsoft Corporation */
325 /* */
326 /* DESCRIPTION */
327 /* */
328 /* This function cleans up the crypto metadata. */
329 /* */
330 /* INPUT */
331 /* */
332 /* crypto_metadata Crypto metadata */
333 /* */
334 /* OUTPUT */
335 /* */
336 /* status Completion status */
337 /* */
338 /* CALLS */
339 /* */
340 /* NX_CRYPTO_MEMSET Set the memory */
341 /* */
342 /* CALLED BY */
343 /* */
344 /* Application Code */
345 /* */
346 /* RELEASE HISTORY */
347 /* */
348 /* DATE NAME DESCRIPTION */
349 /* */
350 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
351 /* 09-30-2020 Timothy Stapko Modified comment(s), */
352 /* resulting in version 6.1 */
353 /* */
354 /**************************************************************************/
_nx_crypto_method_3des_cleanup(VOID * crypto_metadata)355 NX_CRYPTO_KEEP UINT _nx_crypto_method_3des_cleanup(VOID *crypto_metadata)
356 {
357
358 NX_CRYPTO_STATE_CHECK
359
360 #ifdef NX_SECURE_KEY_CLEAR
361 if (!crypto_metadata)
362 return (NX_CRYPTO_SUCCESS);
363
364 /* Clean up the crypto metadata. */
365 NX_CRYPTO_MEMSET(crypto_metadata, 0, sizeof(NX_CRYPTO_3DES));
366 #else
367 NX_CRYPTO_PARAMETER_NOT_USED(crypto_metadata);
368 #endif/* NX_SECURE_KEY_CLEAR */
369
370 return(NX_CRYPTO_SUCCESS);
371 }
372
373
374 /**************************************************************************/
375 /* */
376 /* FUNCTION RELEASE */
377 /* */
378 /* _nx_crypto_method_3des_operation PORTABLE C */
379 /* 6.3.0 */
380 /* AUTHOR */
381 /* */
382 /* Timothy Stapko, Microsoft Corporation */
383 /* */
384 /* DESCRIPTION */
385 /* */
386 /* This function handles 3des encrypt or decrypt operations. */
387 /* */
388 /* INPUT */
389 /* */
390 /* op Operation Type */
391 /* Encrypt, Decrypt, Authenticate*/
392 /* handler Pointer to crypto context */
393 /* method Pointer to crypto method */
394 /* key Pointer to key */
395 /* key_size_in_bits Length of key size in bits */
396 /* input Input Stream */
397 /* input_length_in_byte Input Stream Length */
398 /* iv_ptr Initialized Vector */
399 /* output Output Stream */
400 /* output_length_in_byte Output Stream Length */
401 /* crypto_metadata Metadata area */
402 /* crypto_metadata_size Size of the metadata area */
403 /* packet_ptr Pointer to packet */
404 /* nx_crypto_hw_process_callback Callback function pointer */
405 /* */
406 /* OUTPUT */
407 /* */
408 /* status Completion status */
409 /* */
410 /* CALLS */
411 /* */
412 /* _nx_crypto_cbc_encrypt Perform CBC mode encryption */
413 /* _nx_crypto_cbc_decrypt Perform CBC mode decryption */
414 /* */
415 /* CALLED BY */
416 /* */
417 /* Application Code */
418 /* */
419 /* RELEASE HISTORY */
420 /* */
421 /* DATE NAME DESCRIPTION */
422 /* */
423 /* 05-19-2020 Timothy Stapko Initial Version 6.0 */
424 /* 09-30-2020 Timothy Stapko Modified comment(s), */
425 /* resulting in version 6.1 */
426 /* 04-25-2022 Timothy Stapko Modified comments(s), added */
427 /* warning supression for */
428 /* obsolete DES/3DES, */
429 /* resulting in version 6.1.11 */
430 /* 10-31-2023 Yanwu Cai Modified comment(s), */
431 /* resulting in version 6.3.0 */
432 /* */
433 /**************************************************************************/
_nx_crypto_method_3des_operation(UINT op,VOID * handler,struct NX_CRYPTO_METHOD_STRUCT * method,UCHAR * key,NX_CRYPTO_KEY_SIZE key_size_in_bits,UCHAR * input,ULONG input_length_in_byte,UCHAR * iv_ptr,UCHAR * output,ULONG output_length_in_byte,VOID * crypto_metadata,ULONG crypto_metadata_size,VOID * packet_ptr,VOID (* nx_crypto_hw_process_callback)(VOID * packet_ptr,UINT status))434 NX_CRYPTO_KEEP UINT _nx_crypto_method_3des_operation(UINT op, /* Encrypt, Decrypt, Authenticate */
435 VOID *handler, /* Crypto handler */
436 struct NX_CRYPTO_METHOD_STRUCT *method,
437 UCHAR *key,
438 NX_CRYPTO_KEY_SIZE key_size_in_bits,
439 UCHAR *input,
440 ULONG input_length_in_byte,
441 UCHAR *iv_ptr,
442 UCHAR *output,
443 ULONG output_length_in_byte,
444 VOID *crypto_metadata,
445 ULONG crypto_metadata_size,
446 VOID *packet_ptr,
447 VOID (*nx_crypto_hw_process_callback)(VOID *packet_ptr, UINT status))
448 {
449 UINT status = NX_CRYPTO_NOT_SUCCESSFUL;
450 NX_CRYPTO_3DES *context;
451
452 NX_CRYPTO_PARAMETER_NOT_USED(handler);
453 NX_CRYPTO_PARAMETER_NOT_USED(key);
454 NX_CRYPTO_PARAMETER_NOT_USED(key_size_in_bits);
455 NX_CRYPTO_PARAMETER_NOT_USED(output_length_in_byte);
456 NX_CRYPTO_PARAMETER_NOT_USED(packet_ptr);
457 NX_CRYPTO_PARAMETER_NOT_USED(nx_crypto_hw_process_callback);
458
459 NX_CRYPTO_STATE_CHECK
460
461 if (op == NX_CRYPTO_AUTHENTICATE)
462 {
463 /* Incorrect Operation. */
464 return(NX_CRYPTO_NOT_SUCCESSFUL);
465 }
466
467 if ((method == NX_CRYPTO_NULL) || (crypto_metadata == NX_CRYPTO_NULL))
468 {
469 return(NX_CRYPTO_PTR_ERROR);
470 }
471
472 /* Verify the metadata address is 4-byte aligned. */
473 if((((ULONG)crypto_metadata) & 0x3) != 0)
474 {
475 return(NX_CRYPTO_PTR_ERROR);
476 }
477
478 if(crypto_metadata_size < sizeof(NX_CRYPTO_3DES))
479 {
480 return(NX_CRYPTO_PTR_ERROR);
481 }
482
483 if (method -> nx_crypto_algorithm != NX_CRYPTO_ENCRYPTION_3DES_CBC) /* lgtm[cpp/weak-cryptographic-algorithm] */
484 {
485 /* Incorrect method. */
486 return(NX_CRYPTO_INVALID_ALGORITHM);
487 }
488
489 context = (NX_CRYPTO_3DES *)crypto_metadata;
490
491 switch (op)
492 {
493 case NX_CRYPTO_DECRYPT:
494 {
495 status = _nx_crypto_cbc_decrypt_init(&(context -> nx_crypto_cbc_context),
496 iv_ptr, method -> nx_crypto_IV_size_in_bits >> 3);
497 if (status)
498 {
499 break;
500 }
501
502 status = _nx_crypto_cbc_decrypt(context, &(context -> nx_crypto_cbc_context),
503 (UINT (*)(VOID *, UCHAR *, UCHAR *, UINT))_nx_crypto_3des_decrypt,
504 input, output, input_length_in_byte,
505 (NX_CRYPTO_3DES_BLOCK_SIZE_IN_BITS >> 3)); /* lgtm[cpp/weak-cryptographic-algorithm] */
506 } break;
507
508 case NX_CRYPTO_ENCRYPT:
509 {
510 status = _nx_crypto_cbc_encrypt_init(&(context -> nx_crypto_cbc_context),
511 iv_ptr, method -> nx_crypto_IV_size_in_bits >> 3);
512 if (status)
513 {
514 break;
515 }
516
517 status = _nx_crypto_cbc_encrypt(context, &(context -> nx_crypto_cbc_context),
518 (UINT (*)(VOID *, UCHAR *, UCHAR *, UINT))_nx_crypto_3des_encrypt,
519 input, output, input_length_in_byte,
520 (NX_CRYPTO_3DES_BLOCK_SIZE_IN_BITS >> 3)); /* lgtm[cpp/weak-cryptographic-algorithm] */
521 } break;
522
523 case NX_CRYPTO_DECRYPT_INITIALIZE:
524 {
525 status = _nx_crypto_cbc_decrypt_init(&(context -> nx_crypto_cbc_context),
526 iv_ptr, method -> nx_crypto_IV_size_in_bits >> 3);
527 } break;
528
529 case NX_CRYPTO_ENCRYPT_INITIALIZE:
530 {
531 status = _nx_crypto_cbc_encrypt_init(&(context -> nx_crypto_cbc_context),
532 iv_ptr, method -> nx_crypto_IV_size_in_bits >> 3);
533 } break;
534
535 case NX_CRYPTO_DECRYPT_UPDATE:
536 {
537 status = _nx_crypto_cbc_decrypt(context, &(context -> nx_crypto_cbc_context),
538 (UINT (*)(VOID *, UCHAR *, UCHAR *, UINT))_nx_crypto_3des_decrypt,
539 input, output, input_length_in_byte,
540 (NX_CRYPTO_3DES_BLOCK_SIZE_IN_BITS >> 3)); /* lgtm[cpp/weak-cryptographic-algorithm] */
541 } break;
542
543 case NX_CRYPTO_ENCRYPT_UPDATE:
544 {
545 status = _nx_crypto_cbc_encrypt(context, &(context -> nx_crypto_cbc_context),
546 (UINT (*)(VOID *, UCHAR *, UCHAR *, UINT))_nx_crypto_3des_encrypt,
547 input, output, input_length_in_byte,
548 (NX_CRYPTO_3DES_BLOCK_SIZE_IN_BITS >> 3)); /* lgtm[cpp/weak-cryptographic-algorithm] */
549 } break;
550
551 case NX_CRYPTO_ENCRYPT_CALCULATE:
552 /* fallthrough */
553 case NX_CRYPTO_DECRYPT_CALCULATE:
554 {
555
556 /* Nothing to do. */
557 status = NX_CRYPTO_SUCCESS;
558 } break;
559
560 default:
561 {
562 status = NX_CRYPTO_INVALID_ALGORITHM;
563 } break;
564 }
565
566 return status;
567 }
568
569