1 /*
2 * Encryption functions
3 *
4 * Copyright (C) 2013-2020, Joachim Metz <joachim.metz@gmail.com>
5 *
6 * Refer to AUTHORS for acknowledgements.
7 *
8 * This program is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU Lesser General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program. If not, see <https://www.gnu.org/licenses/>.
20 */
21
22 #include <common.h>
23 #include <byte_stream.h>
24 #include <memory.h>
25 #include <types.h>
26
27 #include "libluksde_definitions.h"
28 #include "libluksde_encryption.h"
29 #include "libluksde_libcaes.h"
30 #include "libluksde_libcerror.h"
31 #include "libluksde_libcnotify.h"
32 #include "libluksde_libfcrypto.h"
33 #include "libluksde_libhmac.h"
34
35 /* Creates an encryption context
36 * Make sure the value context is referencing, is set to NULL
37 * Returns 1 if successful or -1 on error
38 */
libluksde_encryption_initialize(libluksde_encryption_context_t ** context,int method,int chaining_mode,int initialization_vector_mode,int essiv_hashing_method,libcerror_error_t ** error)39 int libluksde_encryption_initialize(
40 libluksde_encryption_context_t **context,
41 int method,
42 int chaining_mode,
43 int initialization_vector_mode,
44 int essiv_hashing_method,
45 libcerror_error_t **error )
46 {
47 static char *function = "libluksde_encryption_initialize";
48 int encryption_mode = 0;
49 int result = 0;
50
51 if( context == NULL )
52 {
53 libcerror_error_set(
54 error,
55 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
56 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
57 "%s: invalid context.",
58 function );
59
60 return( -1 );
61 }
62 if( *context != NULL )
63 {
64 libcerror_error_set(
65 error,
66 LIBCERROR_ERROR_DOMAIN_RUNTIME,
67 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
68 "%s: invalid context value already set.",
69 function );
70
71 return( -1 );
72 }
73 if( method == LIBLUKSDE_ENCRYPTION_METHOD_AES )
74 {
75 if( chaining_mode == LIBLUKSDE_ENCRYPTION_CHAINING_MODE_CBC )
76 {
77 encryption_mode = LIBLUKSDE_ENCRYPTION_MODE_AES_CBC;
78 }
79 else if( chaining_mode == LIBLUKSDE_ENCRYPTION_CHAINING_MODE_ECB )
80 {
81 encryption_mode = LIBLUKSDE_ENCRYPTION_MODE_AES_ECB;
82 }
83 else if( chaining_mode == LIBLUKSDE_ENCRYPTION_CHAINING_MODE_XTS )
84 {
85 encryption_mode = LIBLUKSDE_ENCRYPTION_MODE_AES_XTS;
86 }
87 }
88 else if( method == LIBLUKSDE_ENCRYPTION_METHOD_ARC4 )
89 {
90 if( chaining_mode == LIBLUKSDE_ENCRYPTION_CHAINING_MODE_CBC )
91 {
92 encryption_mode = LIBLUKSDE_ENCRYPTION_MODE_RC4_CBC;
93 }
94 else if( chaining_mode == LIBLUKSDE_ENCRYPTION_CHAINING_MODE_ECB )
95 {
96 encryption_mode = LIBLUKSDE_ENCRYPTION_MODE_RC4_ECB;
97 }
98 }
99 else if( method == LIBLUKSDE_ENCRYPTION_METHOD_SERPENT )
100 {
101 if( chaining_mode == LIBLUKSDE_ENCRYPTION_CHAINING_MODE_CBC )
102 {
103 encryption_mode = LIBLUKSDE_ENCRYPTION_MODE_SERPENT_CBC;
104 }
105 else if( chaining_mode == LIBLUKSDE_ENCRYPTION_CHAINING_MODE_ECB )
106 {
107 encryption_mode = LIBLUKSDE_ENCRYPTION_MODE_SERPENT_ECB;
108 }
109 }
110 if( encryption_mode == 0 )
111 {
112 libcerror_error_set(
113 error,
114 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
115 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
116 "%s: unsupported method and chaining mode.",
117 function );
118
119 return( -1 );
120 }
121 *context = memory_allocate_structure(
122 libluksde_encryption_context_t );
123
124 if( *context == NULL )
125 {
126 libcerror_error_set(
127 error,
128 LIBCERROR_ERROR_DOMAIN_MEMORY,
129 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
130 "%s: unable to create context.",
131 function );
132
133 goto on_error;
134 }
135 if( memory_set(
136 *context,
137 0,
138 sizeof( libluksde_encryption_context_t ) ) == NULL )
139 {
140 libcerror_error_set(
141 error,
142 LIBCERROR_ERROR_DOMAIN_MEMORY,
143 LIBCERROR_MEMORY_ERROR_SET_FAILED,
144 "%s: unable to clear context.",
145 function );
146
147 memory_free(
148 *context );
149
150 *context = NULL;
151
152 return( -1 );
153 }
154 switch( encryption_mode )
155 {
156 case LIBLUKSDE_ENCRYPTION_MODE_AES_CBC:
157 case LIBLUKSDE_ENCRYPTION_MODE_AES_ECB:
158 result = libcaes_context_initialize(
159 &( ( *context )->aes_decryption_context ),
160 error );
161 break;
162
163 case LIBLUKSDE_ENCRYPTION_MODE_AES_XTS:
164 result = libcaes_tweaked_context_initialize(
165 &( ( *context )->aes_xts_decryption_context ),
166 error );
167 break;
168
169 case LIBLUKSDE_ENCRYPTION_MODE_RC4_CBC:
170 case LIBLUKSDE_ENCRYPTION_MODE_RC4_ECB:
171 result = libfcrypto_rc4_context_initialize(
172 &( ( *context )->rc4_decryption_context ),
173 error );
174 break;
175
176 case LIBLUKSDE_ENCRYPTION_MODE_SERPENT_CBC:
177 case LIBLUKSDE_ENCRYPTION_MODE_SERPENT_ECB:
178 result = libfcrypto_serpent_context_initialize(
179 &( ( *context )->serpent_decryption_context ),
180 error );
181 break;
182
183 default:
184 result = 0;
185 break;
186 }
187 if( result != 1 )
188 {
189 libcerror_error_set(
190 error,
191 LIBCERROR_ERROR_DOMAIN_RUNTIME,
192 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
193 "%s: unable to initialize decryption context.",
194 function );
195
196 goto on_error;
197 }
198 switch( encryption_mode )
199 {
200 case LIBLUKSDE_ENCRYPTION_MODE_AES_CBC:
201 case LIBLUKSDE_ENCRYPTION_MODE_AES_ECB:
202 result = libcaes_context_initialize(
203 &( ( *context )->aes_encryption_context ),
204 error );
205 break;
206
207 case LIBLUKSDE_ENCRYPTION_MODE_AES_XTS:
208 result = libcaes_tweaked_context_initialize(
209 &( ( *context )->aes_xts_encryption_context ),
210 error );
211 break;
212
213 case LIBLUKSDE_ENCRYPTION_MODE_RC4_CBC:
214 case LIBLUKSDE_ENCRYPTION_MODE_RC4_ECB:
215 result = libfcrypto_rc4_context_initialize(
216 &( ( *context )->rc4_encryption_context ),
217 error );
218 break;
219
220 case LIBLUKSDE_ENCRYPTION_MODE_SERPENT_CBC:
221 case LIBLUKSDE_ENCRYPTION_MODE_SERPENT_ECB:
222 result = libfcrypto_serpent_context_initialize(
223 &( ( *context )->serpent_encryption_context ),
224 error );
225 break;
226
227 default:
228 result = 0;
229 break;
230 }
231 if( result != 1 )
232 {
233 libcerror_error_set(
234 error,
235 LIBCERROR_ERROR_DOMAIN_RUNTIME,
236 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
237 "%s: unable to initialize encryption context.",
238 function );
239
240 goto on_error;
241 }
242 if( initialization_vector_mode == LIBLUKSDE_INITIALIZATION_VECTOR_MODE_ESSIV )
243 {
244 switch( encryption_mode )
245 {
246 case LIBLUKSDE_ENCRYPTION_MODE_AES_CBC:
247 case LIBLUKSDE_ENCRYPTION_MODE_AES_ECB:
248 result = libcaes_context_initialize(
249 &( ( *context )->essiv_encryption_context ),
250 error );
251 break;
252
253 default:
254 result = 0;
255 break;
256 }
257 if( result != 1 )
258 {
259 libcerror_error_set(
260 error,
261 LIBCERROR_ERROR_DOMAIN_RUNTIME,
262 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
263 "%s: unable to initialize ESSIV encryption context.",
264 function );
265
266 goto on_error;
267 }
268 }
269 ( *context )->encryption_mode = encryption_mode;
270 ( *context )->initialization_vector_mode = initialization_vector_mode;
271 ( *context )->essiv_hashing_method = essiv_hashing_method;
272
273 return( 1 );
274
275 on_error:
276 if( *context != NULL )
277 {
278 if( ( *context )->serpent_encryption_context != NULL )
279 {
280 libfcrypto_serpent_context_free(
281 &( ( *context )->serpent_encryption_context ),
282 NULL );
283 }
284 if( ( *context )->serpent_decryption_context != NULL )
285 {
286 libfcrypto_serpent_context_free(
287 &( ( *context )->serpent_decryption_context ),
288 NULL );
289 }
290 if( ( *context )->rc4_encryption_context != NULL )
291 {
292 libfcrypto_rc4_context_free(
293 &( ( *context )->rc4_encryption_context ),
294 NULL );
295 }
296 if( ( *context )->rc4_decryption_context != NULL )
297 {
298 libfcrypto_rc4_context_free(
299 &( ( *context )->rc4_decryption_context ),
300 NULL );
301 }
302 if( ( *context )->aes_xts_encryption_context != NULL )
303 {
304 libcaes_tweaked_context_free(
305 &( ( *context )->aes_xts_encryption_context ),
306 NULL );
307 }
308 if( ( *context )->aes_xts_decryption_context != NULL )
309 {
310 libcaes_tweaked_context_free(
311 &( ( *context )->aes_xts_decryption_context ),
312 NULL );
313 }
314 if( ( *context )->aes_encryption_context != NULL )
315 {
316 libcaes_context_free(
317 &( ( *context )->aes_encryption_context ),
318 NULL );
319 }
320 if( ( *context )->aes_decryption_context != NULL )
321 {
322 libcaes_context_free(
323 &( ( *context )->aes_decryption_context ),
324 NULL );
325 }
326 memory_free(
327 *context );
328
329 *context = NULL;
330 }
331 return( -1 );
332 }
333
334 /* Frees an encryption context
335 * Returns 1 if successful or -1 on error
336 */
libluksde_encryption_free(libluksde_encryption_context_t ** context,libcerror_error_t ** error)337 int libluksde_encryption_free(
338 libluksde_encryption_context_t **context,
339 libcerror_error_t **error )
340 {
341 static char *function = "libluksde_encryption_free";
342 int result = 1;
343
344 if( context == NULL )
345 {
346 libcerror_error_set(
347 error,
348 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
349 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
350 "%s: invalid context.",
351 function );
352
353 return( -1 );
354 }
355 if( *context != NULL )
356 {
357 if( ( *context )->aes_decryption_context != NULL )
358 {
359 if( libcaes_context_free(
360 &( ( *context )->aes_decryption_context ),
361 error ) != 1 )
362 {
363 libcerror_error_set(
364 error,
365 LIBCERROR_ERROR_DOMAIN_RUNTIME,
366 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
367 "%s: unable to free AES decryption context.",
368 function );
369
370 result = -1;
371 }
372 }
373 if( ( *context )->aes_encryption_context != NULL )
374 {
375 if( libcaes_context_free(
376 &( ( *context )->aes_encryption_context ),
377 error ) != 1 )
378 {
379 libcerror_error_set(
380 error,
381 LIBCERROR_ERROR_DOMAIN_RUNTIME,
382 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
383 "%s: unable to free AES encryption context.",
384 function );
385
386 result = -1;
387 }
388 }
389 if( ( *context )->aes_xts_decryption_context != NULL )
390 {
391 if( libcaes_tweaked_context_free(
392 &( ( *context )->aes_xts_decryption_context ),
393 error ) != 1 )
394 {
395 libcerror_error_set(
396 error,
397 LIBCERROR_ERROR_DOMAIN_RUNTIME,
398 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
399 "%s: unable to free AES-XTS decryption context.",
400 function );
401
402 result = -1;
403 }
404 }
405 if( ( *context )->aes_xts_encryption_context != NULL )
406 {
407 if( libcaes_tweaked_context_free(
408 &( ( *context )->aes_xts_encryption_context ),
409 error ) != 1 )
410 {
411 libcerror_error_set(
412 error,
413 LIBCERROR_ERROR_DOMAIN_RUNTIME,
414 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
415 "%s: unable to free AES-XTS encryption context.",
416 function );
417
418 result = -1;
419 }
420 }
421 if( ( *context )->rc4_decryption_context != NULL )
422 {
423 if( libfcrypto_rc4_context_free(
424 &( ( *context )->rc4_decryption_context ),
425 error ) != 1 )
426 {
427 libcerror_error_set(
428 error,
429 LIBCERROR_ERROR_DOMAIN_RUNTIME,
430 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
431 "%s: unable to free RC4 decryption context.",
432 function );
433
434 result = -1;
435 }
436 }
437 if( ( *context )->rc4_encryption_context != NULL )
438 {
439 if( libfcrypto_rc4_context_free(
440 &( ( *context )->rc4_encryption_context ),
441 error ) != 1 )
442 {
443 libcerror_error_set(
444 error,
445 LIBCERROR_ERROR_DOMAIN_RUNTIME,
446 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
447 "%s: unable to free RC4 encryption context.",
448 function );
449
450 result = -1;
451 }
452 }
453 if( ( *context )->serpent_decryption_context != NULL )
454 {
455 if( libfcrypto_serpent_context_free(
456 &( ( *context )->serpent_decryption_context ),
457 error ) != 1 )
458 {
459 libcerror_error_set(
460 error,
461 LIBCERROR_ERROR_DOMAIN_RUNTIME,
462 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
463 "%s: unable to free Serpent decryption context.",
464 function );
465
466 result = -1;
467 }
468 }
469 if( ( *context )->serpent_encryption_context != NULL )
470 {
471 if( libfcrypto_serpent_context_free(
472 &( ( *context )->serpent_encryption_context ),
473 error ) != 1 )
474 {
475 libcerror_error_set(
476 error,
477 LIBCERROR_ERROR_DOMAIN_RUNTIME,
478 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
479 "%s: unable to free Serpent encryption context.",
480 function );
481
482 result = -1;
483 }
484 }
485 if( ( *context )->essiv_encryption_context != NULL )
486 {
487 if( libcaes_context_free(
488 &( ( *context )->essiv_encryption_context ),
489 error ) != 1 )
490 {
491 libcerror_error_set(
492 error,
493 LIBCERROR_ERROR_DOMAIN_RUNTIME,
494 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
495 "%s: unable to free ESSIV encryption context.",
496 function );
497
498 result = -1;
499 }
500 }
501 memory_free(
502 *context );
503
504 *context = NULL;
505 }
506 return( result );
507 }
508
509 /* Sets the de- and encryption key
510 * Returns 1 if successful or -1 on error
511 */
libluksde_encryption_set_key(libluksde_encryption_context_t * context,const uint8_t * key,size_t key_size,libcerror_error_t ** error)512 int libluksde_encryption_set_key(
513 libluksde_encryption_context_t *context,
514 const uint8_t *key,
515 size_t key_size,
516 libcerror_error_t **error )
517 {
518 uint8_t essiv_key[ 32 ];
519
520 static char *function = "libluksde_encryption_set_key";
521 size_t key_bit_size = 0;
522 int result = 0;
523
524 if( context == NULL )
525 {
526 libcerror_error_set(
527 error,
528 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
529 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
530 "%s: invalid context.",
531 function );
532
533 return( -1 );
534 }
535 if( key == NULL )
536 {
537 libcerror_error_set(
538 error,
539 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
540 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
541 "%s: invalid key.",
542 function );
543
544 return( -1 );
545 }
546 if( key_size > (size_t) SSIZE_MAX )
547 {
548 libcerror_error_set(
549 error,
550 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
551 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
552 "%s: invalid key size value exceeds maximum.",
553 function );
554
555 return( -1 );
556 }
557 key_bit_size = key_size * 8;
558
559 switch( context->encryption_mode )
560 {
561 case LIBLUKSDE_ENCRYPTION_MODE_AES_CBC:
562 case LIBLUKSDE_ENCRYPTION_MODE_AES_ECB:
563 result = libcaes_context_set_key(
564 context->aes_decryption_context,
565 LIBCAES_CRYPT_MODE_DECRYPT,
566 key,
567 key_bit_size,
568 error );
569 break;
570
571 case LIBLUKSDE_ENCRYPTION_MODE_AES_XTS:
572 key_bit_size /= 2;
573 key_size /= 2;
574
575 result = libcaes_tweaked_context_set_keys(
576 context->aes_xts_decryption_context,
577 LIBCAES_CRYPT_MODE_DECRYPT,
578 key,
579 key_bit_size,
580 &( key[ key_size ] ),
581 key_bit_size,
582 error );
583 break;
584
585 case LIBLUKSDE_ENCRYPTION_MODE_RC4_CBC:
586 case LIBLUKSDE_ENCRYPTION_MODE_RC4_ECB:
587 result = libfcrypto_rc4_context_set_key(
588 context->rc4_decryption_context,
589 key,
590 key_bit_size,
591 error );
592 break;
593
594 case LIBLUKSDE_ENCRYPTION_MODE_SERPENT_CBC:
595 case LIBLUKSDE_ENCRYPTION_MODE_SERPENT_ECB:
596 result = libfcrypto_serpent_context_set_key(
597 context->serpent_decryption_context,
598 key,
599 key_bit_size,
600 error );
601 break;
602
603 default:
604 break;
605 }
606 if( result != 1 )
607 {
608 libcerror_error_set(
609 error,
610 LIBCERROR_ERROR_DOMAIN_RUNTIME,
611 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
612 "%s: unable to set key in decryption context.",
613 function );
614
615 goto on_error;
616 }
617 switch( context->encryption_mode )
618 {
619 case LIBLUKSDE_ENCRYPTION_MODE_AES_CBC:
620 case LIBLUKSDE_ENCRYPTION_MODE_AES_ECB:
621 result = libcaes_context_set_key(
622 context->aes_encryption_context,
623 LIBCAES_CRYPT_MODE_ENCRYPT,
624 key,
625 key_bit_size,
626 error );
627 break;
628
629 case LIBLUKSDE_ENCRYPTION_MODE_AES_XTS:
630 result = libcaes_tweaked_context_set_keys(
631 context->aes_xts_encryption_context,
632 LIBCAES_CRYPT_MODE_ENCRYPT,
633 key,
634 key_bit_size,
635 &( key[ key_size ] ),
636 key_bit_size,
637 error );
638 break;
639
640 case LIBLUKSDE_ENCRYPTION_MODE_RC4_CBC:
641 case LIBLUKSDE_ENCRYPTION_MODE_RC4_ECB:
642 result = libfcrypto_rc4_context_set_key(
643 context->rc4_encryption_context,
644 key,
645 key_bit_size,
646 error );
647 break;
648
649 case LIBLUKSDE_ENCRYPTION_MODE_SERPENT_CBC:
650 case LIBLUKSDE_ENCRYPTION_MODE_SERPENT_ECB:
651 result = libfcrypto_serpent_context_set_key(
652 context->serpent_encryption_context,
653 key,
654 key_bit_size,
655 error );
656 break;
657
658 default:
659 break;
660 }
661 if( result != 1 )
662 {
663 libcerror_error_set(
664 error,
665 LIBCERROR_ERROR_DOMAIN_RUNTIME,
666 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
667 "%s: unable to set key in encryption context.",
668 function );
669
670 goto on_error;
671 }
672 if( context->initialization_vector_mode == LIBLUKSDE_INITIALIZATION_VECTOR_MODE_ESSIV )
673 {
674 if( memory_set(
675 essiv_key,
676 0,
677 32 ) == NULL )
678 {
679 libcerror_error_set(
680 error,
681 LIBCERROR_ERROR_DOMAIN_MEMORY,
682 LIBCERROR_MEMORY_ERROR_SET_FAILED,
683 "%s: unable to clear ESSIV key.",
684 function );
685
686 goto on_error;
687 }
688 switch( context->essiv_hashing_method )
689 {
690 case LIBLUKSDE_HASHING_METHOD_SHA1:
691 result = libhmac_sha1_calculate(
692 key,
693 key_size,
694 essiv_key,
695 32,
696 error );
697 break;
698
699 case LIBLUKSDE_HASHING_METHOD_SHA256:
700 result = libhmac_sha256_calculate(
701 key,
702 key_size,
703 essiv_key,
704 32,
705 error );
706 break;
707
708 default:
709 break;
710 }
711 if( result != 1 )
712 {
713 libcerror_error_set(
714 error,
715 LIBCERROR_ERROR_DOMAIN_RUNTIME,
716 LIBCERROR_RUNTIME_ERROR_GENERIC,
717 "%s: unable to compute ESSIV encryption key.",
718 function );
719
720 goto on_error;
721 }
722 switch( context->encryption_mode )
723 {
724 case LIBLUKSDE_ENCRYPTION_MODE_AES_CBC:
725 case LIBLUKSDE_ENCRYPTION_MODE_AES_ECB:
726 result = libcaes_context_set_key(
727 context->essiv_encryption_context,
728 LIBCAES_CRYPT_MODE_ENCRYPT,
729 essiv_key,
730 key_bit_size,
731 error );
732 break;
733
734 default:
735 break;
736 }
737 if( result != 1 )
738 {
739 libcerror_error_set(
740 error,
741 LIBCERROR_ERROR_DOMAIN_RUNTIME,
742 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
743 "%s: unable to set key in ESSIV encryption context.",
744 function );
745
746 goto on_error;
747 }
748 if( memory_set(
749 essiv_key,
750 0,
751 32 ) == NULL )
752 {
753 libcerror_error_set(
754 error,
755 LIBCERROR_ERROR_DOMAIN_MEMORY,
756 LIBCERROR_MEMORY_ERROR_SET_FAILED,
757 "%s: unable to clear ESSIV key.",
758 function );
759
760 goto on_error;
761 }
762 }
763 return( 1 );
764
765 on_error:
766 if( context->initialization_vector_mode == LIBLUKSDE_INITIALIZATION_VECTOR_MODE_ESSIV )
767 {
768 memory_set(
769 essiv_key,
770 0,
771 32 );
772 }
773 return( -1 );
774 }
775
776 /* De- or encrypts a block of data
777 * Returns 1 if successful or -1 on error
778 */
libluksde_encryption_crypt(libluksde_encryption_context_t * context,int mode,const uint8_t * input_data,size_t input_data_size,uint8_t * output_data,size_t output_data_size,uint64_t sector_number,libcerror_error_t ** error)779 int libluksde_encryption_crypt(
780 libluksde_encryption_context_t *context,
781 int mode,
782 const uint8_t *input_data,
783 size_t input_data_size,
784 uint8_t *output_data,
785 size_t output_data_size,
786 uint64_t sector_number,
787 libcerror_error_t **error )
788 {
789 uint8_t block_key_data[ 16 ];
790 uint8_t initialization_vector[ 16 ];
791
792 static char *function = "libluksde_encryption_crypt";
793 size_t data_offset = 0;
794 uint64_t block_key = 0;
795 int result = 0;
796
797 if( context == NULL )
798 {
799 libcerror_error_set(
800 error,
801 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
802 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
803 "%s: invalid context.",
804 function );
805
806 return( -1 );
807 }
808 if( ( mode != LIBLUKSDE_ENCRYPTION_CRYPT_MODE_DECRYPT )
809 && ( mode != LIBLUKSDE_ENCRYPTION_CRYPT_MODE_ENCRYPT ) )
810 {
811 libcerror_error_set(
812 error,
813 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
814 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
815 "%s: unsupported mode.",
816 function );
817
818 return( -1 );
819 }
820 if( output_data_size < input_data_size )
821 {
822 libcerror_error_set(
823 error,
824 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
825 LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
826 "%s: output data size value too small.",
827 function );
828
829 return( -1 );
830 }
831 if( memory_set(
832 initialization_vector,
833 0,
834 16 ) == NULL )
835 {
836 libcerror_error_set(
837 error,
838 LIBCERROR_ERROR_DOMAIN_MEMORY,
839 LIBCERROR_MEMORY_ERROR_SET_FAILED,
840 "%s: unable to clear initialization vector.",
841 function );
842
843 return( -1 );
844 }
845 switch( context->initialization_vector_mode )
846 {
847 case LIBLUKSDE_INITIALIZATION_VECTOR_MODE_BENBI:
848 block_key = ( sector_number << 5 ) + 1;
849
850 byte_stream_copy_from_uint64_big_endian(
851 &( initialization_vector[ 8 ] ),
852 block_key );
853
854 break;
855
856 case LIBLUKSDE_INITIALIZATION_VECTOR_MODE_ESSIV:
857 if( memory_set(
858 block_key_data,
859 0,
860 16 ) == NULL )
861 {
862 libcerror_error_set(
863 error,
864 LIBCERROR_ERROR_DOMAIN_MEMORY,
865 LIBCERROR_MEMORY_ERROR_SET_FAILED,
866 "%s: unable to clear block key data.",
867 function );
868
869 return( -1 );
870 }
871 byte_stream_copy_from_uint64_little_endian(
872 block_key_data,
873 sector_number );
874
875 /* The block key for the initialization vector is encrypted
876 * with the hash of the key
877 */
878 if( libcaes_crypt_ecb(
879 context->essiv_encryption_context,
880 LIBCAES_CRYPT_MODE_ENCRYPT,
881 block_key_data,
882 16,
883 initialization_vector,
884 16,
885 error ) != 1 )
886 {
887 libcerror_error_set(
888 error,
889 LIBCERROR_ERROR_DOMAIN_ENCRYPTION,
890 LIBCERROR_ENCRYPTION_ERROR_GENERIC,
891 "%s: unable to encrypt initialization vector.",
892 function );
893
894 return( -1 );
895 }
896 break;
897
898 case LIBLUKSDE_INITIALIZATION_VECTOR_MODE_NONE:
899 case LIBLUKSDE_INITIALIZATION_VECTOR_MODE_NULL:
900 break;
901
902 case LIBLUKSDE_INITIALIZATION_VECTOR_MODE_PLAIN32:
903 byte_stream_copy_from_uint32_little_endian(
904 initialization_vector,
905 (uint32_t) sector_number );
906
907 break;
908
909 case LIBLUKSDE_INITIALIZATION_VECTOR_MODE_PLAIN64:
910 byte_stream_copy_from_uint64_little_endian(
911 initialization_vector,
912 sector_number );
913
914 break;
915
916 default:
917 libcerror_error_set(
918 error,
919 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
920 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
921 "%s: unsupported initialization vector mode.",
922 function );
923
924 return( -1 );
925 }
926 #if defined( HAVE_DEBUG_OUTPUT )
927 if( libcnotify_verbose != 0 )
928 {
929 libcnotify_printf(
930 "%s: initialization vector data:\n",
931 function );
932 libcnotify_print_data(
933 initialization_vector,
934 16,
935 0 );
936 }
937 #endif
938 if( mode == LIBLUKSDE_ENCRYPTION_CRYPT_MODE_ENCRYPT )
939 {
940 switch( context->encryption_mode )
941 {
942 case LIBLUKSDE_ENCRYPTION_MODE_AES_CBC:
943 result = libcaes_crypt_cbc(
944 context->aes_encryption_context,
945 LIBCAES_CRYPT_MODE_ENCRYPT,
946 initialization_vector,
947 16,
948 input_data,
949 input_data_size,
950 output_data,
951 output_data_size,
952 error );
953 break;
954
955 case LIBLUKSDE_ENCRYPTION_MODE_AES_ECB:
956 while( data_offset < input_data_size )
957 {
958 /* The libcaes_crypt_ecb function encrypts 16 bytes at a time
959 */
960 result = libcaes_crypt_ecb(
961 context->aes_encryption_context,
962 LIBCAES_CRYPT_MODE_ENCRYPT,
963 &( input_data[ data_offset ] ),
964 input_data_size - data_offset,
965 &( output_data[ data_offset ] ),
966 output_data_size - data_offset,
967 error );
968
969 if( result != 1 )
970 {
971 break;
972 }
973 data_offset += 16;
974 }
975 break;
976
977 case LIBLUKSDE_ENCRYPTION_MODE_AES_XTS:
978 result = libcaes_crypt_xts(
979 context->aes_xts_encryption_context,
980 LIBCAES_CRYPT_MODE_ENCRYPT,
981 initialization_vector,
982 16,
983 input_data,
984 input_data_size,
985 output_data,
986 output_data_size,
987 error );
988 break;
989
990 case LIBLUKSDE_ENCRYPTION_MODE_RC4_CBC:
991 case LIBLUKSDE_ENCRYPTION_MODE_RC4_ECB:
992 result = libfcrypto_rc4_crypt(
993 context->rc4_encryption_context,
994 &( input_data[ data_offset ] ),
995 input_data_size - data_offset,
996 &( output_data[ data_offset ] ),
997 output_data_size - data_offset,
998 error );
999
1000 if( result != 1 )
1001 {
1002 break;
1003 }
1004 break;
1005
1006 case LIBLUKSDE_ENCRYPTION_MODE_SERPENT_CBC:
1007 case LIBLUKSDE_ENCRYPTION_MODE_SERPENT_ECB:
1008 while( data_offset < input_data_size )
1009 {
1010 /* The libfcrypto_serpent_crypt_ecb function encrypts 16 bytes at a time
1011 */
1012 result = libfcrypto_serpent_crypt_ecb(
1013 context->serpent_encryption_context,
1014 LIBFCRYPTO_SERPENT_CRYPT_MODE_ENCRYPT,
1015 &( input_data[ data_offset ] ),
1016 input_data_size - data_offset,
1017 &( output_data[ data_offset ] ),
1018 output_data_size - data_offset,
1019 error );
1020
1021 if( result != 1 )
1022 {
1023 break;
1024 }
1025 data_offset += 16;
1026 }
1027 break;
1028
1029 default:
1030 result = 0;
1031 break;
1032 }
1033 if( result != 1 )
1034 {
1035 libcerror_error_set(
1036 error,
1037 LIBCERROR_ERROR_DOMAIN_ENCRYPTION,
1038 LIBCERROR_ENCRYPTION_ERROR_GENERIC,
1039 "%s: unable to encrypt output data.",
1040 function );
1041
1042 return( -1 );
1043 }
1044 }
1045 else
1046 {
1047 switch( context->encryption_mode )
1048 {
1049 case LIBLUKSDE_ENCRYPTION_MODE_AES_CBC:
1050 result = libcaes_crypt_cbc(
1051 context->aes_decryption_context,
1052 LIBCAES_CRYPT_MODE_DECRYPT,
1053 initialization_vector,
1054 16,
1055 input_data,
1056 input_data_size,
1057 output_data,
1058 output_data_size,
1059 error );
1060 break;
1061
1062 case LIBLUKSDE_ENCRYPTION_MODE_AES_ECB:
1063 while( data_offset < input_data_size )
1064 {
1065 /* The libcaes_crypt_ecb function decrypts 16 bytes at a time
1066 */
1067 result = libcaes_crypt_ecb(
1068 context->aes_decryption_context,
1069 LIBCAES_CRYPT_MODE_DECRYPT,
1070 &( input_data[ data_offset ] ),
1071 input_data_size - data_offset,
1072 &( output_data[ data_offset ] ),
1073 output_data_size - data_offset,
1074 error );
1075
1076 if( result != 1 )
1077 {
1078 break;
1079 }
1080 data_offset += 16;
1081 }
1082 break;
1083
1084 case LIBLUKSDE_ENCRYPTION_MODE_AES_XTS:
1085 result = libcaes_crypt_xts(
1086 context->aes_xts_decryption_context,
1087 LIBCAES_CRYPT_MODE_DECRYPT,
1088 initialization_vector,
1089 16,
1090 input_data,
1091 input_data_size,
1092 output_data,
1093 output_data_size,
1094 error );
1095 break;
1096
1097 case LIBLUKSDE_ENCRYPTION_MODE_RC4_CBC:
1098 case LIBLUKSDE_ENCRYPTION_MODE_RC4_ECB:
1099 result = libfcrypto_rc4_crypt(
1100 context->rc4_decryption_context,
1101 input_data,
1102 input_data_size,
1103 output_data,
1104 output_data_size,
1105 error );
1106
1107 if( result != 1 )
1108 {
1109 break;
1110 }
1111 break;
1112
1113 case LIBLUKSDE_ENCRYPTION_MODE_SERPENT_CBC:
1114 result = libfcrypto_serpent_crypt_cbc(
1115 context->serpent_decryption_context,
1116 LIBFCRYPTO_SERPENT_CRYPT_MODE_DECRYPT,
1117 initialization_vector,
1118 16,
1119 input_data,
1120 input_data_size,
1121 output_data,
1122 output_data_size,
1123 error );
1124
1125 if( result != 1 )
1126 {
1127 break;
1128 }
1129 break;
1130
1131 case LIBLUKSDE_ENCRYPTION_MODE_SERPENT_ECB:
1132 while( data_offset < input_data_size )
1133 {
1134 /* The libfcrypto_serpent_crypt_ecb function decrypts 16 bytes at a time
1135 */
1136 result = libfcrypto_serpent_crypt_ecb(
1137 context->serpent_decryption_context,
1138 LIBFCRYPTO_SERPENT_CRYPT_MODE_DECRYPT,
1139 &( input_data[ data_offset ] ),
1140 input_data_size - data_offset,
1141 &( output_data[ data_offset ] ),
1142 output_data_size - data_offset,
1143 error );
1144
1145 if( result != 1 )
1146 {
1147 break;
1148 }
1149 data_offset += 16;
1150 }
1151 break;
1152
1153 default:
1154 result = 0;
1155 break;
1156 }
1157 if( result != 1 )
1158 {
1159 libcerror_error_set(
1160 error,
1161 LIBCERROR_ERROR_DOMAIN_ENCRYPTION,
1162 LIBCERROR_ENCRYPTION_ERROR_GENERIC,
1163 "%s: unable to decrypt output data.",
1164 function );
1165
1166 return( -1 );
1167 }
1168 }
1169 return( 1 );
1170 }
1171
1172