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