1 /*
2  * AES de/encryption context functions
3  *
4  * Copyright (C) 2011-2021, 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 #if defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_AES_H )
28 #include <openssl/sha.h>
29 
30 #elif defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_EVP_H )
31 #include <openssl/err.h>
32 #include <openssl/evp.h>
33 #endif
34 
35 #include "libcaes_context.h"
36 #include "libcaes_definitions.h"
37 #include "libcaes_libcerror.h"
38 #include "libcaes_types.h"
39 
40 #if !defined( LIBCAES_HAVE_AES_SUPPORT )
41 
42 /* FIPS-197 compliant AES encryption functions
43  *
44  * The AES block cipher was designed by Vincent Rijmen and Joan Daemen.
45  *
46  * http://csrc.nist.gov/encryption/aes/rijndael/Rijndael.pdf
47  * http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
48  */
49 
50 #define libcaes_calculate_forward_substitution_value( value, index0, index1, index2, index3 ) \
51 	value   = libcaes_forward_substitution_box[ index3 ]; \
52 	value <<= 8; \
53 	value  |= libcaes_forward_substitution_box[ index2 ]; \
54 	value <<= 8; \
55 	value  |= libcaes_forward_substitution_box[ index1 ]; \
56 	value <<= 8; \
57 	value  |= libcaes_forward_substitution_box[ index0 ];
58 
59 #define libcaes_calculate_forward_table_value( value, index0, index1, index2, index3 ) \
60 	value  = libcaes_forward_table0[ index0 ]; \
61 	value ^= libcaes_forward_table1[ index1 ]; \
62 	value ^= libcaes_forward_table2[ index2 ]; \
63 	value ^= libcaes_forward_table3[ index3 ];
64 
65 #define libcaes_calculate_reverse_substitution_value( value, index0, index1, index2, index3 ) \
66 	value   = libcaes_reverse_substitution_box[ index3 ]; \
67 	value <<= 8; \
68 	value  |= libcaes_reverse_substitution_box[ index2 ]; \
69 	value <<= 8; \
70 	value  |= libcaes_reverse_substitution_box[ index1 ]; \
71 	value <<= 8; \
72 	value  |= libcaes_reverse_substitution_box[ index0 ];
73 
74 #define libcaes_calculate_reverse_table_value( value, index0, index1, index2, index3 ) \
75 	value  = libcaes_reverse_table0[ index0 ]; \
76 	value ^= libcaes_reverse_table1[ index1 ]; \
77 	value ^= libcaes_reverse_table2[ index2 ]; \
78 	value ^= libcaes_reverse_table3[ index3 ];
79 
80 #define libcaes_calculate_forward_substitution_round( round_keys, values_32bit, cipher_values_32bit, substitution_value ) \
81 	libcaes_calculate_forward_substitution_value( \
82 	 substitution_value, \
83 	 ( cipher_values_32bit[ 0 ] & 0xff ), \
84 	 ( ( cipher_values_32bit[ 1 ] >> 8 ) & 0xff ), \
85 	 ( ( cipher_values_32bit[ 2 ] >> 16 ) & 0xff ), \
86 	 ( ( cipher_values_32bit[ 3 ] >> 24 ) & 0xff ) ); \
87 \
88 	values_32bit[ 0 ] = round_keys[ 0 ] ^ substitution_value; \
89 \
90 	libcaes_calculate_forward_substitution_value( \
91 	 substitution_value, \
92 	 ( cipher_values_32bit[ 1 ] & 0xff ), \
93 	 ( ( cipher_values_32bit[ 2 ] >> 8 ) & 0xff ), \
94 	 ( ( cipher_values_32bit[ 3 ] >> 16 ) & 0xff ), \
95 	 ( ( cipher_values_32bit[ 0 ] >> 24 ) & 0xff ) ); \
96 \
97 	values_32bit[ 1 ] = round_keys[ 1 ] ^ substitution_value; \
98 \
99 	libcaes_calculate_forward_substitution_value( \
100 	 substitution_value, \
101 	 ( cipher_values_32bit[ 2 ] & 0xff ), \
102 	 ( ( cipher_values_32bit[ 3 ] >> 8 ) & 0xff ), \
103 	 ( ( cipher_values_32bit[ 0 ] >> 16 ) & 0xff ), \
104 	 ( ( cipher_values_32bit[ 1 ] >> 24 ) & 0xff ) ); \
105 \
106 	values_32bit[ 2 ] = round_keys[ 2 ] ^ substitution_value; \
107 \
108 	libcaes_calculate_forward_substitution_value( \
109 	 substitution_value, \
110 	 ( cipher_values_32bit[ 3 ] & 0xff ), \
111 	 ( ( cipher_values_32bit[ 0 ] >> 8 ) & 0xff ), \
112 	 ( ( cipher_values_32bit[ 1 ] >> 16 ) & 0xff ), \
113 	 ( ( cipher_values_32bit[ 2 ] >> 24 ) & 0xff ) ); \
114 \
115 	values_32bit[ 3 ] = round_keys[ 3 ] ^ substitution_value;
116 
117 #define libcaes_calculate_forward_table_round( round_keys, values_32bit, cipher_values_32bit, table_value ) \
118 	libcaes_calculate_forward_table_value( \
119 	 table_value, \
120 	 ( cipher_values_32bit[ 0 ] & 0xff ), \
121 	 ( ( cipher_values_32bit[ 1 ] >> 8 ) & 0xff ), \
122 	 ( ( cipher_values_32bit[ 2 ] >> 16 ) & 0xff ), \
123 	 ( ( cipher_values_32bit[ 3 ] >> 24 ) & 0xff ) ); \
124 \
125 	values_32bit[ 0 ] = round_keys[ 0 ] ^ table_value; \
126 \
127 	libcaes_calculate_forward_table_value( \
128 	 table_value, \
129 	 ( cipher_values_32bit[ 1 ] & 0xff ), \
130 	 ( ( cipher_values_32bit[ 2 ] >> 8 ) & 0xff ), \
131 	 ( ( cipher_values_32bit[ 3 ] >> 16 ) & 0xff ), \
132 	 ( ( cipher_values_32bit[ 0 ] >> 24 ) & 0xff ) ); \
133 \
134 	values_32bit[ 1 ] = round_keys[ 1 ] ^ table_value; \
135 \
136 	libcaes_calculate_forward_table_value( \
137 	 table_value, \
138 	 ( cipher_values_32bit[ 2 ] & 0xff ), \
139 	 ( ( cipher_values_32bit[ 3 ] >> 8 ) & 0xff ), \
140 	 ( ( cipher_values_32bit[ 0 ] >> 16 ) & 0xff ), \
141 	 ( ( cipher_values_32bit[ 1 ] >> 24 ) & 0xff ) ); \
142 \
143 	values_32bit[ 2 ] = round_keys[ 2 ] ^ table_value; \
144 \
145 	libcaes_calculate_forward_table_value( \
146 	 table_value, \
147 	 ( cipher_values_32bit[ 3 ] & 0xff ), \
148 	 ( ( cipher_values_32bit[ 0 ] >> 8 ) & 0xff ), \
149 	 ( ( cipher_values_32bit[ 1 ] >> 16 ) & 0xff ), \
150 	 ( ( cipher_values_32bit[ 2 ] >> 24 ) & 0xff ) ); \
151 \
152 	values_32bit[ 3 ] = round_keys[ 3 ] ^ table_value;
153 
154 #define libcaes_calculate_reverse_substitution_round( round_keys, values_32bit, cipher_values_32bit, substitution_value ) \
155 	libcaes_calculate_reverse_substitution_value( \
156 	 substitution_value, \
157 	 ( cipher_values_32bit[ 0 ] & 0xff ), \
158 	 ( ( cipher_values_32bit[ 3 ] >> 8 ) & 0xff ), \
159 	 ( ( cipher_values_32bit[ 2 ] >> 16 ) & 0xff ), \
160 	 ( ( cipher_values_32bit[ 1 ] >> 24 ) & 0xff ) ); \
161 \
162 	values_32bit[ 0 ] = round_keys[ 0 ] ^ substitution_value; \
163 \
164 	libcaes_calculate_reverse_substitution_value( \
165 	 substitution_value, \
166 	 ( cipher_values_32bit[ 1 ] & 0xff ), \
167 	 ( ( cipher_values_32bit[ 0 ] >> 8 ) & 0xff ), \
168 	 ( ( cipher_values_32bit[ 3 ] >> 16 ) & 0xff ), \
169 	 ( ( cipher_values_32bit[ 2 ] >> 24 ) & 0xff ) ); \
170 \
171 	values_32bit[ 1 ] = round_keys[ 1 ] ^ substitution_value; \
172 \
173 	libcaes_calculate_reverse_substitution_value( \
174 	 substitution_value, \
175 	 ( cipher_values_32bit[ 2 ] & 0xff ), \
176 	 ( ( cipher_values_32bit[ 1 ] >> 8 ) & 0xff ), \
177 	 ( ( cipher_values_32bit[ 0 ] >> 16 ) & 0xff ), \
178 	 ( ( cipher_values_32bit[ 3 ] >> 24 ) & 0xff ) ); \
179 \
180 	values_32bit[ 2 ] = round_keys[ 2 ] ^ substitution_value; \
181 \
182 	libcaes_calculate_reverse_substitution_value( \
183 	 substitution_value, \
184 	 ( cipher_values_32bit[ 3 ] & 0xff ), \
185 	 ( ( cipher_values_32bit[ 2 ] >> 8 ) & 0xff ), \
186 	 ( ( cipher_values_32bit[ 1 ] >> 16 ) & 0xff ), \
187 	 ( ( cipher_values_32bit[ 0 ] >> 24 ) & 0xff ) ); \
188 \
189 	values_32bit[ 3 ] = round_keys[ 3 ] ^ substitution_value;
190 
191 #define libcaes_calculate_reverse_table_round( round_keys, values_32bit, cipher_values_32bit, table_value ) \
192 	libcaes_calculate_reverse_table_value( \
193 	 table_value, \
194 	 ( cipher_values_32bit[ 0 ] & 0xff ), \
195 	 ( ( cipher_values_32bit[ 3 ] >> 8 ) & 0xff ), \
196 	 ( ( cipher_values_32bit[ 2 ] >> 16 ) & 0xff ), \
197 	 ( ( cipher_values_32bit[ 1 ] >> 24 ) & 0xff ) ); \
198 \
199 	values_32bit[ 0 ] = round_keys[ 0 ] ^ table_value; \
200 \
201 	libcaes_calculate_reverse_table_value( \
202 	 table_value, \
203 	 ( cipher_values_32bit[ 1 ] & 0xff ), \
204 	 ( ( cipher_values_32bit[ 0 ] >> 8 ) & 0xff ), \
205 	 ( ( cipher_values_32bit[ 3 ] >> 16 ) & 0xff ), \
206 	 ( ( cipher_values_32bit[ 2 ] >> 24 ) & 0xff ) ); \
207 \
208 	values_32bit[ 1 ] = round_keys[ 1 ] ^ table_value; \
209 \
210 	libcaes_calculate_reverse_table_value( \
211 	 table_value, \
212 	 ( cipher_values_32bit[ 2 ] & 0xff ), \
213 	 ( ( cipher_values_32bit[ 1 ] >> 8 ) & 0xff ), \
214 	 ( ( cipher_values_32bit[ 0 ] >> 16 ) & 0xff ), \
215 	 ( ( cipher_values_32bit[ 3 ] >> 24 ) & 0xff ) ); \
216 \
217 	values_32bit[ 2 ] = round_keys[ 2 ] ^ table_value; \
218 \
219 	libcaes_calculate_reverse_table_value( \
220 	 table_value, \
221 	 ( cipher_values_32bit[ 3 ] & 0xff ), \
222 	 ( ( cipher_values_32bit[ 2 ] >> 8 ) & 0xff ), \
223 	 ( ( cipher_values_32bit[ 1 ] >> 16 ) & 0xff ), \
224 	 ( ( cipher_values_32bit[ 0 ] >> 24 ) & 0xff ) ); \
225 \
226 	values_32bit[ 3 ] = round_keys[ 3 ] ^ table_value;
227 
228 /* Forward S-box & tables
229  */
230 static uint8_t libcaes_forward_substitution_box[ 256 ];
231 
232 static uint32_t libcaes_forward_table0[ 256 ];
233 static uint32_t libcaes_forward_table1[ 256 ];
234 static uint32_t libcaes_forward_table2[ 256 ];
235 static uint32_t libcaes_forward_table3[ 256 ];
236 
237 /* Reverse S-box & tables
238  */
239 static uint8_t libcaes_reverse_substitution_box[ 256 ];
240 
241 static uint32_t libcaes_reverse_table0[ 256 ];
242 static uint32_t libcaes_reverse_table1[ 256 ];
243 static uint32_t libcaes_reverse_table2[ 256 ];
244 static uint32_t libcaes_reverse_table3[ 256 ];
245 
246 /* Round constants
247  */
248 static uint32_t libcaes_round_constants[ 10 ];
249 
250 static int libcaes_tables_initialized = 0;
251 
252 #endif /* !defined( LIBCAES_HAVE_AES_SUPPORT ) */
253 
254 /* Creates a context
255  * Make sure the value context is referencing, is set to NULL
256  * Returns 1 if successful or -1 on error
257  */
libcaes_context_initialize(libcaes_context_t ** context,libcerror_error_t ** error)258 int libcaes_context_initialize(
259      libcaes_context_t **context,
260      libcerror_error_t **error )
261 {
262 	libcaes_internal_context_t *internal_context = NULL;
263 	static char *function                        = "libcaes_context_initialize";
264 
265 #if defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_EVP_H ) && ( defined( HAVE_EVP_CRYPTO_AES_CBC ) || defined( HAVE_EVP_CRYPTO_AES_ECB ) )
266 	char error_string[ 256 ];
267 
268 	unsigned long error_code                     = 0;
269 #endif
270 
271 	if( context == NULL )
272 	{
273 		libcerror_error_set(
274 		 error,
275 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
276 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
277 		 "%s: invalid context.",
278 		 function );
279 
280 		return( -1 );
281 	}
282 	if( *context != NULL )
283 	{
284 		libcerror_error_set(
285 		 error,
286 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
287 		 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
288 		 "%s: invalid context value already set.",
289 		 function );
290 
291 		return( -1 );
292 	}
293 	internal_context = memory_allocate_structure(
294 	                    libcaes_internal_context_t );
295 
296 	if( internal_context == NULL )
297 	{
298 		libcerror_error_set(
299 		 error,
300 		 LIBCERROR_ERROR_DOMAIN_MEMORY,
301 		 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
302 		 "%s: unable to create context.",
303 		 function );
304 
305 		goto on_error;
306 	}
307 	if( memory_set(
308 	     internal_context,
309 	     0,
310 	     sizeof( libcaes_internal_context_t ) ) == NULL )
311 	{
312 		libcerror_error_set(
313 		 error,
314 		 LIBCERROR_ERROR_DOMAIN_MEMORY,
315 		 LIBCERROR_MEMORY_ERROR_SET_FAILED,
316 		 "%s: unable to clear context.",
317 		 function );
318 
319 		goto on_error;
320 	}
321 #if defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_AES_H ) && ( defined( HAVE_AES_CBC_ENCRYPT ) || defined( HAVE_AES_ECB_ENCRYPT ) )
322 	/* No additional initialization necessary */
323 
324 #elif defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_EVP_H ) && ( defined( HAVE_EVP_CRYPTO_AES_CBC ) || defined( HAVE_EVP_CRYPTO_AES_ECB ) )
325 #if defined( HAVE_EVP_CIPHER_CTX_INIT )
326 	EVP_CIPHER_CTX_init(
327 	 &( internal_context->internal_evp_cipher_context ) );
328 
329 	internal_context->evp_cipher_context = &( internal_context->internal_evp_cipher_context );
330 #else
331 	internal_context->evp_cipher_context = EVP_CIPHER_CTX_new();
332 
333 	if( internal_context->evp_cipher_context == NULL )
334 	{
335 		error_code = ERR_get_error();
336 
337 		ERR_error_string_n(
338 		 error_code,
339 		 error_string,
340 		 256 );
341 
342 		libcerror_error_set(
343 		 error,
344 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
345 		 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
346 		 "%s: unable to create EVP cipher context with error: %s.",
347 		 function,
348 		 error_string );
349 
350 		goto on_error;
351 	}
352 #endif /* defined( HAVE_EVP_CIPHER_CTX_INIT ) */
353 
354 	if( EVP_CIPHER_CTX_set_padding(
355 	     internal_context->evp_cipher_context,
356 	     1 ) != 1 )
357 	{
358 		error_code = ERR_get_error();
359 
360 		ERR_error_string_n(
361 		 error_code,
362 		 error_string,
363 		 256 );
364 
365 		libcerror_error_set(
366 		 error,
367 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
368 		 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
369 		 "%s: unable to set padding in context with error: %s.",
370 		 function,
371 		 error_string );
372 
373 #if defined( HAVE_EVP_CIPHER_CTX_CLEANUP )
374 		EVP_CIPHER_CTX_cleanup(
375 		 &( internal_context->internal_evp_cipher_context ) );
376 		ERR_remove_thread_state(
377 		 NULL );
378 #else
379 		EVP_CIPHER_CTX_free(
380 		 internal_context->evp_cipher_context );
381 #endif
382 		internal_context->evp_cipher_context = NULL;
383 
384 		goto on_error;
385 	}
386 #else
387 	if( libcaes_tables_initialized == 0 )
388 	{
389 		if( libcaes_initialize_tables(
390 		     error ) != 1 )
391 		{
392 			libcerror_error_set(
393 			 error,
394 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
395 			 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
396 			 "%s: unable to initialize tables.",
397 			 function );
398 
399 			goto on_error;
400 		}
401 		libcaes_tables_initialized = 1;
402 	}
403 #endif /* defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_AES_H ) && ( defined( HAVE_AES_CBC_ENCRYPT ) || defined( HAVE_AES_ECB_ENCRYPT ) ) */
404 
405 	*context = (libcaes_context_t *) internal_context;
406 
407 	return( 1 );
408 
409 on_error:
410 	if( internal_context != NULL )
411 	{
412 		memory_free(
413 		 internal_context );
414 	}
415 	return( -1 );
416 }
417 
418 /* Frees a context
419  * Returns 1 if successful or -1 on error
420  */
libcaes_context_free(libcaes_context_t ** context,libcerror_error_t ** error)421 int libcaes_context_free(
422      libcaes_context_t **context,
423      libcerror_error_t **error )
424 {
425 	libcaes_internal_context_t *internal_context = NULL;
426 	static char *function                        = "libcaes_context_free";
427 	int result                                   = 1;
428 
429 #if defined( HAVE_LIBCRYPTO ) && defined( HAVE_EVP_CIPHER_CTX_CLEANUP )
430 	char error_string[ 256 ];
431 
432 	unsigned long error_code                     = 0;
433 #endif
434 
435 	if( context == NULL )
436 	{
437 		libcerror_error_set(
438 		 error,
439 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
440 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
441 		 "%s: invalid context.",
442 		 function );
443 
444 		return( -1 );
445 	}
446 	if( *context != NULL )
447 	{
448 		internal_context = (libcaes_internal_context_t *) *context;
449 		*context         = NULL;
450 
451 #if defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_AES_H ) && ( defined( HAVE_AES_CBC_ENCRYPT ) || defined( HAVE_AES_ECB_ENCRYPT ) )
452 		/* No additional clean up necessary */
453 
454 #elif defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_EVP_H ) && ( defined( HAVE_EVP_CRYPTO_AES_CBC ) || defined( HAVE_EVP_CRYPTO_AES_ECB ) )
455 #if defined( HAVE_EVP_CIPHER_CTX_CLEANUP )
456 		if( EVP_CIPHER_CTX_cleanup(
457 		     &( internal_context->internal_evp_cipher_context ) ) != 1 )
458 		{
459 			error_code = ERR_get_error();
460 
461 			ERR_error_string_n(
462 			 error_code,
463 			 error_string,
464 			 256 );
465 
466 			libcerror_error_set(
467 			 error,
468 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
469 			 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
470 			 "%s: unable to clean up EVP cipher context with error: %s.",
471 			 function,
472 			 error_string );
473 
474 			result = -1;
475 		}
476 		/* Make sure the error state is removed otherwise OpenSSL will leak memory
477 		 */
478 		ERR_remove_thread_state(
479 		 NULL );
480 #else
481 		EVP_CIPHER_CTX_free(
482 		 internal_context->evp_cipher_context );
483 
484 #endif /* defined( HAVE_EVP_CIPHER_CTX_CLEANUP ) */
485 
486 		internal_context->evp_cipher_context = NULL;
487 #else
488 		/* No additional clean up necessary */
489 
490 #endif /* defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_AES_H ) && ( defined( HAVE_AES_CBC_ENCRYPT ) || defined( HAVE_AES_ECB_ENCRYPT ) ) */
491 
492 		memory_free(
493 		 internal_context );
494 	}
495 	return( result );
496 }
497 
498 /* Sets the key
499  * Returns 1 if successful or -1 on error
500  */
libcaes_context_set_key(libcaes_context_t * context,int mode,const uint8_t * key,size_t key_bit_size,libcerror_error_t ** error)501 int libcaes_context_set_key(
502      libcaes_context_t *context,
503      int mode,
504      const uint8_t *key,
505      size_t key_bit_size,
506      libcerror_error_t **error )
507 {
508 	libcaes_internal_context_t *internal_context = NULL;
509 	static char *function                        = "libcaes_context_set_key";
510 
511 	if( context == NULL )
512 	{
513 		libcerror_error_set(
514 		 error,
515 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
516 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
517 		 "%s: invalid context.",
518 		 function );
519 
520 		return( -1 );
521 	}
522 	internal_context = (libcaes_internal_context_t *) context;
523 
524 	if( ( mode != LIBCAES_CRYPT_MODE_DECRYPT )
525 	 && ( mode != LIBCAES_CRYPT_MODE_ENCRYPT ) )
526 	{
527 		libcerror_error_set(
528 		 error,
529 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
530 		 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
531 		 "%s: unsupported mode.",
532 		 function );
533 
534 		return( -1 );
535 	}
536 	if( ( key_bit_size != 128 )
537 	 && ( key_bit_size != 192 )
538 	 && ( key_bit_size != 256 ) )
539 	{
540 		libcerror_error_set(
541 		 error,
542 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
543 		 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
544 		 "%s: unsupported key bit size.",
545 		 function );
546 
547 		return( -1 );
548 	}
549 #if defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_AES_H ) && ( defined( HAVE_AES_CBC_ENCRYPT ) || defined( HAVE_AES_ECB_ENCRYPT ) )
550 	if( mode == LIBCAES_CRYPT_MODE_ENCRYPT )
551 	{
552 		if( AES_set_encrypt_key(
553 		     (unsigned char *) key,
554 		     (int) key_bit_size,
555 		     &( internal_context->key ) ) != 0 )
556 		{
557 			libcerror_error_set(
558 			 error,
559 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
560 			 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
561 			 "%s: unable to set encryption key.",
562 			 function );
563 
564 			return( -1 );
565 		}
566 	}
567 	else
568 	{
569 		if( AES_set_decrypt_key(
570 		     (unsigned char *) key,
571 		     (int) key_bit_size,
572 		     &( internal_context->key ) ) != 0 )
573 		{
574 			libcerror_error_set(
575 			 error,
576 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
577 			 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
578 			 "%s: unable to set decryption key.",
579 			 function );
580 
581 			return( -1 );
582 		}
583 	}
584 
585 #elif defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_EVP_H ) && ( defined( HAVE_EVP_CRYPTO_AES_CBC ) || defined( HAVE_EVP_CRYPTO_AES_ECB ) )
586 	if( key == NULL )
587 	{
588 		libcerror_error_set(
589 		 error,
590 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
591 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
592 		 "%s: invalid key.",
593 		 function );
594 
595 		return( -1 );
596 	}
597 	if( memory_copy(
598 	     internal_context->key,
599 	     key,
600 	     key_bit_size / 8 ) == NULL )
601 	{
602 		libcerror_error_set(
603 		 error,
604 		 LIBCERROR_ERROR_DOMAIN_MEMORY,
605 		 LIBCERROR_MEMORY_ERROR_COPY_FAILED,
606 		 "%s: unable to copy key.",
607 		 function );
608 
609 		return( -1 );
610 	}
611 	internal_context->key_bit_size = key_bit_size;
612 
613 #else
614 	if( mode == LIBCAES_CRYPT_MODE_ENCRYPT )
615 	{
616 		if( libcaes_internal_context_set_encryption_key(
617 		     internal_context,
618 		     key,
619 		     key_bit_size,
620 		     error ) != 1 )
621 		{
622 			libcerror_error_set(
623 			 error,
624 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
625 			 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
626 			 "%s: unable to set encryption key.",
627 			 function );
628 
629 			return( -1 );
630 		}
631 	}
632 	else
633 	{
634 		if( libcaes_internal_context_set_decryption_key(
635 		     internal_context,
636 		     key,
637 		     key_bit_size,
638 		     error ) != 1 )
639 		{
640 			libcerror_error_set(
641 			 error,
642 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
643 			 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
644 			 "%s: unable to set decryption key.",
645 			 function );
646 
647 			return( -1 );
648 		}
649 	}
650 #endif /* defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_AES_H ) && ( defined( HAVE_AES_CBC_ENCRYPT ) || defined( HAVE_AES_ECB_ENCRYPT ) ) */
651 
652 	return( 1 );
653 }
654 
655 #if !defined( LIBCAES_HAVE_AES_SUPPORT )
656 
657 /* Initializes the AES encryption and decryption tables
658  * Returns 1 if successful or -1 on error
659  */
libcaes_initialize_tables(libcerror_error_t ** error)660 int libcaes_initialize_tables(
661      libcerror_error_t **error )
662 {
663 	uint8_t logs_table[ 256 ];
664 	uint8_t powers_table[ 256 ];
665 
666 	static char *function        = "libcaes_initialize_tables";
667 	uint16_t byte_index          = 0;
668 	uint16_t table_index         = 0;
669 	uint8_t byte_value           = 0;
670 	uint8_t round_constant_index = 0;
671 	uint8_t substitution_value   = 0;
672 
673 	if( memory_set(
674 	     logs_table,
675 	     0,
676 	     sizeof( uint8_t ) * 256 ) == NULL )
677 	{
678 		libcerror_error_set(
679 		 error,
680 		 LIBCERROR_ERROR_DOMAIN_MEMORY,
681 		 LIBCERROR_MEMORY_ERROR_SET_FAILED,
682 		 "%s: unable to clear logs table.",
683 		 function );
684 
685 		return( -1 );
686 	}
687 	/* Fill the powers and logs tables over GF( 2^8 )
688 	 */
689 	byte_value = 1;
690 
691 	for( byte_index = 0;
692 	     byte_index < 256;
693 	     byte_index++ )
694 	{
695 		powers_table[ byte_index ] = byte_value;
696 		logs_table[ byte_value ]   = (uint8_t) byte_index;
697 
698 		if( ( byte_value & 0x80 ) == 0 )
699 		{
700 			byte_value ^= ( byte_value << 1 ) & 0xff;
701 		}
702 		else
703 		{
704 			byte_value ^= ( ( byte_value << 1 ) & 0xff ) ^ 0x1b;
705 		}
706 	}
707 	/* Fill the round constants
708 	 */
709 	byte_value = 1;
710 
711 	for( round_constant_index = 0;
712 	     round_constant_index < 10;
713 	     round_constant_index++ )
714 	{
715 		libcaes_round_constants[ round_constant_index ] = (uint32_t) byte_value;
716 
717 		if( ( byte_value & 0x80 ) == 0 )
718 		{
719 			byte_value = ( byte_value << 1 ) & 0xff;
720 		}
721 		else
722 		{
723 			byte_value = ( ( byte_value << 1 ) & 0xff ) ^ 0x1b;
724 		}
725 	}
726 	/* Fill the forward and reverse S-boxes
727 	 */
728 	libcaes_forward_substitution_box[ 0x00 ] = 0x63;
729 	libcaes_reverse_substitution_box[ 0x63 ] = 0x00;
730 
731 	for( byte_index = 1;
732 	     byte_index < 256;
733 	     byte_index++ )
734 	{
735 		table_index = 255 - logs_table[ byte_index ];
736 		byte_value  = powers_table[ table_index ];
737 
738 		substitution_value = ( ( byte_value << 1 ) & 0xff )
739 		                   | ( byte_value >> 7 );
740 
741 		byte_value ^= substitution_value;
742 
743 		substitution_value = ( ( substitution_value << 1 ) & 0xff )
744 		                   | ( substitution_value >> 7 );
745 
746 		byte_value ^= substitution_value;
747 
748 		substitution_value = ( ( substitution_value << 1 ) & 0xff )
749 		                   | ( substitution_value >> 7 );
750 
751 		byte_value ^= substitution_value;
752 
753 		substitution_value = ( ( substitution_value << 1 ) & 0xff )
754 		                   | ( substitution_value >> 7 );
755 
756 		substitution_value ^= byte_value ^ 0x63;
757 
758 		libcaes_forward_substitution_box[ byte_index ]         = substitution_value;
759 		libcaes_reverse_substitution_box[ substitution_value ] = (uint8_t) byte_index;
760 	}
761 	/* Fill the forward and reverse tables
762 	 */
763 	for( byte_index = 0;
764 	     byte_index < 256;
765 	     byte_index++ )
766 	{
767 		byte_value = libcaes_forward_substitution_box[ byte_index ];
768 
769 		if( ( byte_value & 0x80 ) == 0 )
770 		{
771 			substitution_value = ( byte_value << 1 ) & 0xff;
772 		}
773 		else
774 		{
775 			substitution_value = ( ( byte_value << 1 ) & 0xff ) ^ 0x1b;
776 		}
777 		libcaes_forward_table0[ byte_index ]   = byte_value ^ substitution_value;
778 		libcaes_forward_table0[ byte_index ] <<= 8;
779 		libcaes_forward_table0[ byte_index ]  |= byte_value;
780 		libcaes_forward_table0[ byte_index ] <<= 8;
781 		libcaes_forward_table0[ byte_index ]  |= byte_value;
782 		libcaes_forward_table0[ byte_index ] <<= 8;
783 		libcaes_forward_table0[ byte_index ]  |= substitution_value;
784 
785 		libcaes_forward_table1[ byte_index ] = byte_stream_bit_rotate_left(
786 		                                        libcaes_forward_table0[ byte_index ],
787 		                                        8 );
788 
789 		libcaes_forward_table2[ byte_index ] = byte_stream_bit_rotate_left(
790 		                                        libcaes_forward_table1[ byte_index ],
791 		                                        8 );
792 
793 		libcaes_forward_table3[ byte_index ] = byte_stream_bit_rotate_left(
794 		                                        libcaes_forward_table2[ byte_index ],
795 		                                        8 );
796 
797 		substitution_value = libcaes_reverse_substitution_box[ byte_index ];
798 
799 		libcaes_reverse_table0[ byte_index ] = 0;
800 
801 		if( substitution_value != 0 )
802 		{
803 			table_index  = logs_table[ 0x0b ];
804 			table_index += logs_table[ substitution_value ];
805 			table_index %= 255;
806 
807 			libcaes_reverse_table0[ byte_index ] ^= powers_table[ table_index ];
808 			libcaes_reverse_table0[ byte_index ] <<= 8;
809 
810 			table_index  = logs_table[ 0x0d ];
811 			table_index += logs_table[ substitution_value ];
812 			table_index %= 255;
813 
814 			libcaes_reverse_table0[ byte_index ] ^= powers_table[ table_index ];
815 			libcaes_reverse_table0[ byte_index ] <<= 8;
816 
817 			table_index  = logs_table[ 0x09 ];
818 			table_index += logs_table[ substitution_value ];
819 			table_index %= 255;
820 
821 			libcaes_reverse_table0[ byte_index ] ^= powers_table[ table_index ];
822 			libcaes_reverse_table0[ byte_index ] <<= 8;
823 
824 			table_index  = logs_table[ 0x0e ];
825 			table_index += logs_table[ substitution_value ];
826 			table_index %= 255;
827 
828 			libcaes_reverse_table0[ byte_index ] ^= powers_table[ table_index ];
829 		}
830 		libcaes_reverse_table1[ byte_index ] = byte_stream_bit_rotate_left(
831 		                                        libcaes_reverse_table0[ byte_index ],
832 		                                        8 );
833 
834 		libcaes_reverse_table2[ byte_index ] = byte_stream_bit_rotate_left(
835 		                                        libcaes_reverse_table1[ byte_index ],
836 		                                        8 );
837 
838 		libcaes_reverse_table3[ byte_index ] = byte_stream_bit_rotate_left(
839 		                                        libcaes_reverse_table2[ byte_index ],
840 		                                        8 );
841 	}
842 	return( 1 );
843 }
844 
845 /* Sets the AES decryption key
846  * Returns 1 if successful or -1 on error
847  */
libcaes_internal_context_set_decryption_key(libcaes_internal_context_t * internal_context,const uint8_t * key,size_t key_bit_size,libcerror_error_t ** error)848 int libcaes_internal_context_set_decryption_key(
849      libcaes_internal_context_t *internal_context,
850      const uint8_t *key,
851      size_t key_bit_size,
852      libcerror_error_t **error )
853 {
854 	libcaes_internal_context_t *encryption_context = NULL;
855 	static char *function                          = "libcaes_internal_context_set_decryption_key";
856 	uint32_t *encryption_round_keys                = NULL;
857 	uint32_t *round_keys                           = NULL;
858 	size_t round_keys_byte_offset                  = 0;
859 	uint8_t byte_value0                            = 0;
860 	uint8_t byte_value1                            = 0;
861 	uint8_t byte_value2                            = 0;
862 	uint8_t byte_value3                            = 0;
863 	int round_key_iterator                         = 0;
864 
865 	if( internal_context == NULL )
866 	{
867 		libcerror_error_set(
868 		 error,
869 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
870 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
871 		 "%s: invalid context.",
872 		 function );
873 
874 		return( -1 );
875 	}
876 	if( key == NULL )
877 	{
878 		libcerror_error_set(
879 		 error,
880 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
881 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
882 		 "%s: invalid key.",
883 		 function );
884 
885 		return( -1 );
886 	}
887 	if( ( key_bit_size != 128 )
888 	 && ( key_bit_size != 192 )
889 	 && ( key_bit_size != 256 ) )
890 	{
891 		libcerror_error_set(
892 		 error,
893 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
894 		 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
895 		 "%s: unsupported key bit size.",
896 		 function );
897 
898 		return( -1 );
899 	}
900 	if( key_bit_size == 128 )
901 	{
902 		internal_context->number_of_round_keys = 10;
903 	}
904 	else if( key_bit_size == 192 )
905 	{
906 		internal_context->number_of_round_keys = 12;
907 	}
908 	else if( key_bit_size == 256 )
909 	{
910 		internal_context->number_of_round_keys = 14;
911 	}
912 	/* Align the buffer to next 16-byte blocks
913 	 */
914 	internal_context->round_keys = (uint32_t *) ( 16 + ( (intptr_t) internal_context->round_keys_data & ~( 15 ) ) );
915 
916 	round_keys = internal_context->round_keys;
917 
918 	if( libcaes_context_initialize(
919 	     (libcaes_context_t **) &encryption_context,
920 	     error ) != 1 )
921 	{
922 		libcerror_error_set(
923 		 error,
924 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
925 		 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
926 		 "%s: unable to create encryption context.",
927 		 function );
928 
929 		goto on_error;
930 	}
931 	if( libcaes_internal_context_set_encryption_key(
932 	     encryption_context,
933 	     key,
934 	     key_bit_size,
935 	     error ) != 1 )
936 	{
937 		libcerror_error_set(
938 		 error,
939 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
940 		 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
941 		 "%s: unable to set encryption key.",
942 		 function );
943 
944 		goto on_error;
945 	}
946 	/* Point to the end of the round keys
947 	 */
948 	round_keys_byte_offset = encryption_context->number_of_round_keys * sizeof( uint32_t );
949 
950 	encryption_round_keys = &( encryption_context->round_keys[ round_keys_byte_offset ] );
951 
952 	round_keys[ 0 ] = encryption_round_keys[ 0 ];
953 	round_keys[ 1 ] = encryption_round_keys[ 1 ];
954 	round_keys[ 2 ] = encryption_round_keys[ 2 ];
955 	round_keys[ 3 ] = encryption_round_keys[ 3 ];
956 
957 	round_keys            += 4;
958 	encryption_round_keys -= 4;
959 
960 	for( round_key_iterator = internal_context->number_of_round_keys;
961 	     round_key_iterator > 1;
962 	     round_key_iterator-- )
963 	{
964 		byte_value0 = ( encryption_round_keys[ 0 ] & 0xff );
965 		byte_value1 = ( ( encryption_round_keys[ 0 ] >> 8 ) & 0xff );
966 		byte_value2 = ( ( encryption_round_keys[ 0 ] >> 16 ) & 0xff );
967 		byte_value3 = ( ( encryption_round_keys[ 0 ] >> 24 ) & 0xff );
968 
969 		byte_value0 = libcaes_forward_substitution_box[ byte_value0 ];
970 		byte_value1 = libcaes_forward_substitution_box[ byte_value1 ];
971 		byte_value2 = libcaes_forward_substitution_box[ byte_value2 ];
972 		byte_value3 = libcaes_forward_substitution_box[ byte_value3 ];
973 
974 		round_keys[ 0 ] = libcaes_reverse_table0[ byte_value0 ]
975 			        ^ libcaes_reverse_table1[ byte_value1 ]
976 			        ^ libcaes_reverse_table2[ byte_value2 ]
977 			        ^ libcaes_reverse_table3[ byte_value3 ];
978 
979 		byte_value0 = ( encryption_round_keys[ 1 ] & 0xff );
980 		byte_value1 = ( ( encryption_round_keys[ 1 ] >> 8 ) & 0xff );
981 		byte_value2 = ( ( encryption_round_keys[ 1 ] >> 16 ) & 0xff );
982 		byte_value3 = ( ( encryption_round_keys[ 1 ] >> 24 ) & 0xff );
983 
984 		byte_value0 = libcaes_forward_substitution_box[ byte_value0 ];
985 		byte_value1 = libcaes_forward_substitution_box[ byte_value1 ];
986 		byte_value2 = libcaes_forward_substitution_box[ byte_value2 ];
987 		byte_value3 = libcaes_forward_substitution_box[ byte_value3 ];
988 
989 		round_keys[ 1 ] = libcaes_reverse_table0[ byte_value0 ]
990 			        ^ libcaes_reverse_table1[ byte_value1 ]
991 			        ^ libcaes_reverse_table2[ byte_value2 ]
992 			        ^ libcaes_reverse_table3[ byte_value3 ];
993 
994 		byte_value0 = ( encryption_round_keys[ 2 ] & 0xff );
995 		byte_value1 = ( ( encryption_round_keys[ 2 ] >> 8 ) & 0xff );
996 		byte_value2 = ( ( encryption_round_keys[ 2 ] >> 16 ) & 0xff );
997 		byte_value3 = ( ( encryption_round_keys[ 2 ] >> 24 ) & 0xff );
998 
999 		byte_value0 = libcaes_forward_substitution_box[ byte_value0 ];
1000 		byte_value1 = libcaes_forward_substitution_box[ byte_value1 ];
1001 		byte_value2 = libcaes_forward_substitution_box[ byte_value2 ];
1002 		byte_value3 = libcaes_forward_substitution_box[ byte_value3 ];
1003 
1004 		round_keys[ 2 ] = libcaes_reverse_table0[ byte_value0 ]
1005 			        ^ libcaes_reverse_table1[ byte_value1 ]
1006 			        ^ libcaes_reverse_table2[ byte_value2 ]
1007 			        ^ libcaes_reverse_table3[ byte_value3 ];
1008 
1009 		byte_value0 = ( encryption_round_keys[ 3 ] & 0xff );
1010 		byte_value1 = ( ( encryption_round_keys[ 3 ] >> 8 ) & 0xff );
1011 		byte_value2 = ( ( encryption_round_keys[ 3 ] >> 16 ) & 0xff );
1012 		byte_value3 = ( ( encryption_round_keys[ 3 ] >> 24 ) & 0xff );
1013 
1014 		byte_value0 = libcaes_forward_substitution_box[ byte_value0 ];
1015 		byte_value1 = libcaes_forward_substitution_box[ byte_value1 ];
1016 		byte_value2 = libcaes_forward_substitution_box[ byte_value2 ];
1017 		byte_value3 = libcaes_forward_substitution_box[ byte_value3 ];
1018 
1019 		round_keys[ 3 ] = libcaes_reverse_table0[ byte_value0 ]
1020 			        ^ libcaes_reverse_table1[ byte_value1 ]
1021 			        ^ libcaes_reverse_table2[ byte_value2 ]
1022 			        ^ libcaes_reverse_table3[ byte_value3 ];
1023 
1024 		round_keys            += 4;
1025 		encryption_round_keys -= 4;
1026 	}
1027 	round_keys[ 0 ] = encryption_round_keys[ 0 ];
1028 	round_keys[ 1 ] = encryption_round_keys[ 1 ];
1029 	round_keys[ 2 ] = encryption_round_keys[ 2 ];
1030 	round_keys[ 3 ] = encryption_round_keys[ 3 ];
1031 
1032 	if( libcaes_context_free(
1033 	     (libcaes_context_t **) &encryption_context,
1034 	     error ) != 1 )
1035 	{
1036 		libcerror_error_set(
1037 		 error,
1038 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1039 		 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1040 		 "%s: unable to free encryption context.",
1041 		 function );
1042 
1043 		goto on_error;
1044 	}
1045 	return( 1 );
1046 
1047 on_error:
1048 	if( encryption_context != NULL )
1049 	{
1050 		libcaes_context_free(
1051 		 (libcaes_context_t **) &encryption_context,
1052 		 NULL );
1053 	}
1054 	return( -1 );
1055 }
1056 
1057 /* Sets the AES encryption key
1058  * Returns 1 if successful or -1 on error
1059  */
libcaes_internal_context_set_encryption_key(libcaes_internal_context_t * internal_context,const uint8_t * key,size_t key_bit_size,libcerror_error_t ** error)1060 int libcaes_internal_context_set_encryption_key(
1061      libcaes_internal_context_t *internal_context,
1062      const uint8_t *key,
1063      size_t key_bit_size,
1064      libcerror_error_t **error )
1065 {
1066 	static char *function    = "libcaes_internal_context_set_encryption_key";
1067 	uint32_t *round_keys     = NULL;
1068 	size_t key_index         = 0;
1069 	int round_constant_index = 0;
1070 
1071 	if( internal_context == NULL )
1072 	{
1073 		libcerror_error_set(
1074 		 error,
1075 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1076 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1077 		 "%s: invalid context.",
1078 		 function );
1079 
1080 		return( -1 );
1081 	}
1082 	if( key == NULL )
1083 	{
1084 		libcerror_error_set(
1085 		 error,
1086 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1087 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1088 		 "%s: invalid key.",
1089 		 function );
1090 
1091 		return( -1 );
1092 	}
1093 	if( ( key_bit_size != 128 )
1094 	 && ( key_bit_size != 192 )
1095 	 && ( key_bit_size != 256 ) )
1096 	{
1097 		libcerror_error_set(
1098 		 error,
1099 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1100 		 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1101 		 "%s: unsupported key bit size.",
1102 		 function );
1103 
1104 		return( -1 );
1105 	}
1106 	/* Align the buffer to next 16-byte blocks
1107 	 */
1108 	internal_context->round_keys = (uint32_t *) ( 16 + ( (intptr_t) internal_context->round_keys_data & ~( 15 ) ) );
1109 
1110 	round_keys = internal_context->round_keys;
1111 
1112 	for( key_index = 0;
1113 	     key_index < key_bit_size / 8;
1114 	     key_index += 4 )
1115 	{
1116 		byte_stream_copy_to_uint32_little_endian(
1117 	         &( key[ key_index ] ),
1118 	         round_keys[ round_constant_index ] );
1119 
1120 		round_constant_index++;
1121 	}
1122 	if( key_bit_size == 128 )
1123 	{
1124 		internal_context->number_of_round_keys = 10;
1125 
1126 		for( round_constant_index = 0;
1127 		     round_constant_index < 10;
1128 		     round_constant_index++ )
1129 		{
1130 			round_keys[ 4 ]  = libcaes_round_constants[ round_constant_index ];
1131 			round_keys[ 4 ] ^= round_keys[ 0 ];
1132 			round_keys[ 4 ] ^= (uint32_t) libcaes_forward_substitution_box[ ( round_keys[ 3 ] >> 8 ) & 0xff ];
1133 			round_keys[ 4 ] ^= ( (uint32_t) libcaes_forward_substitution_box[ ( round_keys[ 3 ] >> 16 ) & 0xff ] ) << 8;
1134 			round_keys[ 4 ] ^= ( (uint32_t) libcaes_forward_substitution_box[ ( round_keys[ 3 ] >> 24 ) & 0xff ] ) << 16;
1135 			round_keys[ 4 ] ^= ( (uint32_t) libcaes_forward_substitution_box[ ( round_keys[ 3 ] ) & 0xff ] ) << 24;
1136 
1137 			round_keys[ 5 ] = round_keys[ 1 ] ^ round_keys[ 4 ];
1138 			round_keys[ 6 ] = round_keys[ 2 ] ^ round_keys[ 5 ];
1139 			round_keys[ 7 ] = round_keys[ 3 ] ^ round_keys[ 6 ];
1140 
1141 			round_keys += 4;
1142 		}
1143 	}
1144 	else if( key_bit_size == 192 )
1145 	{
1146 		internal_context->number_of_round_keys = 12;
1147 
1148 		for( round_constant_index = 0;
1149 		     round_constant_index < 8;
1150 		     round_constant_index++ )
1151 		{
1152 			round_keys[ 6 ]  = libcaes_round_constants[ round_constant_index ];
1153 			round_keys[ 6 ] ^= round_keys[ 0 ];
1154 			round_keys[ 6 ] ^= (uint32_t) libcaes_forward_substitution_box[ ( round_keys[ 5 ] >> 8 ) & 0xff ];
1155 			round_keys[ 6 ] ^= ( (uint32_t) libcaes_forward_substitution_box[ ( round_keys[ 5 ] >> 16 ) & 0xff ] ) << 8;
1156 			round_keys[ 6 ] ^= ( (uint32_t) libcaes_forward_substitution_box[ ( round_keys[ 5 ] >> 24 ) & 0xff ] ) << 16;
1157 			round_keys[ 6 ] ^= ( (uint32_t) libcaes_forward_substitution_box[ ( round_keys[ 5 ] ) & 0xff ] ) << 24;
1158 
1159 			round_keys[ 7 ]  = round_keys[ 1 ] ^ round_keys[ 6 ];
1160 			round_keys[ 8 ]  = round_keys[ 2 ] ^ round_keys[ 7 ];
1161 			round_keys[ 9 ]  = round_keys[ 3 ] ^ round_keys[ 8 ];
1162 			round_keys[ 10 ] = round_keys[ 4 ] ^ round_keys[ 9 ];
1163 			round_keys[ 11 ] = round_keys[ 5 ] ^ round_keys[ 10 ];
1164 
1165 			round_keys += 6;
1166 		}
1167 	}
1168 	else if( key_bit_size == 256 )
1169 	{
1170 		internal_context->number_of_round_keys = 14;
1171 
1172 		for( round_constant_index = 0;
1173 		     round_constant_index < 7;
1174 		     round_constant_index++ )
1175 		{
1176 			round_keys[ 8 ]  = libcaes_round_constants[ round_constant_index ];
1177 			round_keys[ 8 ] ^= round_keys[ 0 ];
1178 			round_keys[ 8 ] ^= (uint32_t) libcaes_forward_substitution_box[ ( round_keys[ 7 ] >> 8 ) & 0xff ];
1179 			round_keys[ 8 ] ^= ( (uint32_t) libcaes_forward_substitution_box[ ( round_keys[ 7 ] >> 16 ) & 0xff ] ) << 8;
1180 			round_keys[ 8 ] ^= ( (uint32_t) libcaes_forward_substitution_box[ ( round_keys[ 7 ] >> 24 ) & 0xff ] ) << 16;
1181 			round_keys[ 8 ] ^= ( (uint32_t) libcaes_forward_substitution_box[ ( round_keys[ 7 ] ) & 0xff ] ) << 24;
1182 
1183 			round_keys[ 9 ]  = round_keys[ 1 ] ^ round_keys[ 8 ];
1184 			round_keys[ 10 ] = round_keys[ 2 ] ^ round_keys[ 9 ];
1185 			round_keys[ 11 ] = round_keys[ 3 ] ^ round_keys[ 10 ];
1186 
1187 			round_keys[ 12 ]  = round_keys[ 4 ];
1188 			round_keys[ 12 ] ^= (uint32_t) libcaes_forward_substitution_box[ ( round_keys[ 11 ] ) & 0xff ];
1189 			round_keys[ 12 ] ^= ( (uint32_t) libcaes_forward_substitution_box[ ( round_keys[ 11 ] >> 8 ) & 0xff ] ) << 8;
1190 			round_keys[ 12 ] ^= ( (uint32_t) libcaes_forward_substitution_box[ ( round_keys[ 11 ] >> 16 ) & 0xff ] ) << 16;
1191 			round_keys[ 12 ] ^= ( (uint32_t) libcaes_forward_substitution_box[ ( round_keys[ 11 ] >> 24 ) & 0xff ] ) << 24;
1192 
1193 			round_keys[ 13 ] = round_keys[ 5 ] ^ round_keys[ 12 ];
1194 			round_keys[ 14 ] = round_keys[ 6 ] ^ round_keys[ 13 ];
1195 			round_keys[ 15 ] = round_keys[ 7 ] ^ round_keys[ 14 ];
1196 
1197 			round_keys += 8;
1198 		}
1199 	}
1200 	return( 1 );
1201 }
1202 
1203 #endif /* !defined( LIBCAES_HAVE_AES_SUPPORT ) */
1204 
1205 #if defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_AES_H ) && defined( HAVE_AES_CBC_ENCRYPT )
1206 
1207 /* De- or encrypts a block of data using AES-CBC (Cipher Block Chaining) using OpenSSL
1208  * The size must be a multitude of the AES block size (16 byte)
1209  * Returns 1 if successful or -1 on error
1210  */
libcaes_crypt_cbc(libcaes_context_t * context,int mode,const uint8_t * initialization_vector,size_t initialization_vector_size,const uint8_t * input_data,size_t input_data_size,uint8_t * output_data,size_t output_data_size,libcerror_error_t ** error)1211 int libcaes_crypt_cbc(
1212      libcaes_context_t *context,
1213      int mode,
1214      const uint8_t *initialization_vector,
1215      size_t initialization_vector_size,
1216      const uint8_t *input_data,
1217      size_t input_data_size,
1218      uint8_t *output_data,
1219      size_t output_data_size,
1220      libcerror_error_t **error )
1221 {
1222 	uint8_t safe_initialization_vector[ 16 ];
1223 
1224 	libcaes_internal_context_t *internal_context = NULL;
1225 	static char *function                        = "libcaes_crypt_cbc";
1226 	int safe_mode                                = 0;
1227 
1228 	if( context == NULL )
1229 	{
1230 		libcerror_error_set(
1231 		 error,
1232 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1233 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1234 		 "%s: invalid context.",
1235 		 function );
1236 
1237 		return( -1 );
1238 	}
1239 	internal_context = (libcaes_internal_context_t *) context;
1240 
1241 	if( ( mode != LIBCAES_CRYPT_MODE_DECRYPT )
1242 	 && ( mode != LIBCAES_CRYPT_MODE_ENCRYPT ) )
1243 	{
1244 		libcerror_error_set(
1245 		 error,
1246 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1247 		 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1248 		 "%s: unsupported mode.",
1249 		 function );
1250 
1251 		return( -1 );
1252 	}
1253 	if( initialization_vector == NULL )
1254 	{
1255 		libcerror_error_set(
1256 		 error,
1257 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1258 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1259 		 "%s: invalid initialization vector.",
1260 		 function );
1261 
1262 		return( -1 );
1263 	}
1264 	if( initialization_vector_size != 16 )
1265 	{
1266 		libcerror_error_set(
1267 		 error,
1268 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1269 		 LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1270 		 "%s: invalid initialization vector size value out of bounds.",
1271 		 function );
1272 
1273 		return( -1 );
1274 	}
1275 	if( input_data == NULL )
1276 	{
1277 		libcerror_error_set(
1278 		 error,
1279 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1280 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1281 		 "%s: invalid input data.",
1282 		 function );
1283 
1284 		return( -1 );
1285 	}
1286 	if( input_data_size > (size_t) SSIZE_MAX )
1287 	{
1288 		libcerror_error_set(
1289 		 error,
1290 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1291 		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
1292 		 "%s: invalid input data size value exceeds maximum.",
1293 		 function );
1294 
1295 		return( -1 );
1296 	}
1297 	/* Check if the input data size is a multitude of 16-byte
1298 	 */
1299 	if( ( input_data_size & (size_t) 0x0f ) != 0 )
1300 	{
1301 		libcerror_error_set(
1302 		 error,
1303 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1304 		 LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1305 		 "%s: invalid input data size value out of bounds.",
1306 		 function );
1307 
1308 		return( -1 );
1309 	}
1310 	if( output_data == NULL )
1311 	{
1312 		libcerror_error_set(
1313 		 error,
1314 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1315 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1316 		 "%s: invalid output data.",
1317 		 function );
1318 
1319 		return( -1 );
1320 	}
1321 	if( output_data_size > (size_t) SSIZE_MAX )
1322 	{
1323 		libcerror_error_set(
1324 		 error,
1325 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1326 		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
1327 		 "%s: invalid output data size value exceeds maximum.",
1328 		 function );
1329 
1330 		return( -1 );
1331 	}
1332 	if( output_data_size < input_data_size )
1333 	{
1334 		libcerror_error_set(
1335 		 error,
1336 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1337 		 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1338 		 "%s: invalid ouput data size smaller than input data size.",
1339 		 function );
1340 
1341 		return( -1 );
1342 	}
1343 	if( mode == LIBCAES_CRYPT_MODE_ENCRYPT )
1344 	{
1345 		safe_mode = AES_ENCRYPT;
1346 	}
1347 	else
1348 	{
1349 		safe_mode = AES_DECRYPT;
1350 	}
1351 	/* AES_cbc_encrypt overwrites the data in the initialization vector
1352 	 */
1353 	if( memory_copy(
1354 	     safe_initialization_vector,
1355 	     initialization_vector,
1356 	     16 ) == NULL )
1357 	{
1358 		libcerror_error_set(
1359 		 error,
1360 		 LIBCERROR_ERROR_DOMAIN_MEMORY,
1361 		 LIBCERROR_MEMORY_ERROR_COPY_FAILED,
1362 		 "%s: unable to copy initialization vector.",
1363 		 function );
1364 
1365 		return( -1 );
1366 	}
1367 	AES_cbc_encrypt(
1368 	 (unsigned char *) input_data,
1369 	 (unsigned char *) output_data,
1370 	 input_data_size,
1371 	 &( internal_context->key ),
1372 	 (unsigned char *) safe_initialization_vector,
1373 	 safe_mode );
1374 
1375 	if( memory_set(
1376 	     safe_initialization_vector,
1377 	     0,
1378 	     16 ) == NULL )
1379 	{
1380 		libcerror_error_set(
1381 		 error,
1382 		 LIBCERROR_ERROR_DOMAIN_MEMORY,
1383 		 LIBCERROR_MEMORY_ERROR_SET_FAILED,
1384 		 "%s: unable to clear initialization vector.",
1385 		 function );
1386 
1387 		return( -1 );
1388 	}
1389 	return( 1 );
1390 }
1391 
1392 #elif defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_EVP_H ) && defined( HAVE_EVP_CRYPTO_AES_CBC )
1393 
1394 /* De- or encrypts a block of data using AES-CBC (Cipher Block Chaining) using OpenSSL EVP
1395  * The size must be a multitude of the AES block size (16 byte)
1396  * Returns 1 if successful or -1 on error
1397  */
libcaes_crypt_cbc(libcaes_context_t * context,int mode,const uint8_t * initialization_vector,size_t initialization_vector_size,const uint8_t * input_data,size_t input_data_size,uint8_t * output_data,size_t output_data_size,libcerror_error_t ** error)1398 int libcaes_crypt_cbc(
1399      libcaes_context_t *context,
1400      int mode,
1401      const uint8_t *initialization_vector,
1402      size_t initialization_vector_size,
1403      const uint8_t *input_data,
1404      size_t input_data_size,
1405      uint8_t *output_data,
1406      size_t output_data_size,
1407      libcerror_error_t **error )
1408 {
1409 	uint8_t block_data[ EVP_MAX_BLOCK_LENGTH ];
1410 	char error_string[ 256 ];
1411 
1412 	const EVP_CIPHER *cipher                     = NULL;
1413 	libcaes_internal_context_t *internal_context = NULL;
1414 	static char *function                        = "libcaes_crypt_cbc";
1415 	unsigned long error_code                     = 0;
1416 	int safe_output_data_size                    = 0;
1417 
1418 	if( context == NULL )
1419 	{
1420 		libcerror_error_set(
1421 		 error,
1422 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1423 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1424 		 "%s: invalid context.",
1425 		 function );
1426 
1427 		return( -1 );
1428 	}
1429 	internal_context = (libcaes_internal_context_t *) context;
1430 
1431 	if( ( mode != LIBCAES_CRYPT_MODE_DECRYPT )
1432 	 && ( mode != LIBCAES_CRYPT_MODE_ENCRYPT ) )
1433 	{
1434 		libcerror_error_set(
1435 		 error,
1436 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1437 		 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1438 		 "%s: unsupported mode.",
1439 		 function );
1440 
1441 		return( -1 );
1442 	}
1443 	if( initialization_vector == NULL )
1444 	{
1445 		libcerror_error_set(
1446 		 error,
1447 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1448 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1449 		 "%s: invalid initialization vector.",
1450 		 function );
1451 
1452 		return( -1 );
1453 	}
1454 	if( initialization_vector_size != 16 )
1455 	{
1456 		libcerror_error_set(
1457 		 error,
1458 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1459 		 LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1460 		 "%s: invalid initialization vector size value out of bounds.",
1461 		 function );
1462 
1463 		return( -1 );
1464 	}
1465 	if( input_data == NULL )
1466 	{
1467 		libcerror_error_set(
1468 		 error,
1469 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1470 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1471 		 "%s: invalid input data.",
1472 		 function );
1473 
1474 		return( -1 );
1475 	}
1476 	if( input_data_size > (size_t) INT_MAX )
1477 	{
1478 		libcerror_error_set(
1479 		 error,
1480 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1481 		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
1482 		 "%s: invalid input data size value exceeds maximum.",
1483 		 function );
1484 
1485 		return( -1 );
1486 	}
1487 	/* Check if the input data size is a multitude of 16-byte
1488 	 */
1489 	if( ( input_data_size & (size_t) 0x0f ) != 0 )
1490 	{
1491 		libcerror_error_set(
1492 		 error,
1493 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1494 		 LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1495 		 "%s: invalid input data size value out of bounds.",
1496 		 function );
1497 
1498 		return( -1 );
1499 	}
1500 	if( output_data == NULL )
1501 	{
1502 		libcerror_error_set(
1503 		 error,
1504 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1505 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1506 		 "%s: invalid output data.",
1507 		 function );
1508 
1509 		return( -1 );
1510 	}
1511 	if( output_data_size > (size_t) INT_MAX )
1512 	{
1513 		libcerror_error_set(
1514 		 error,
1515 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1516 		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
1517 		 "%s: invalid output data size value exceeds maximum.",
1518 		 function );
1519 
1520 		return( -1 );
1521 	}
1522 	if( output_data_size < input_data_size )
1523 	{
1524 		libcerror_error_set(
1525 		 error,
1526 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1527 		 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1528 		 "%s: invalid ouput data size smaller than input data size.",
1529 		 function );
1530 
1531 		return( -1 );
1532 	}
1533 	if( memory_set(
1534 	     block_data,
1535 	     0,
1536 	     EVP_MAX_BLOCK_LENGTH ) == NULL )
1537 	{
1538 		libcerror_error_set(
1539 		 error,
1540 		 LIBCERROR_ERROR_DOMAIN_MEMORY,
1541 		 LIBCERROR_MEMORY_ERROR_SET_FAILED,
1542 		 "%s: unable to clear input block data.",
1543 		 function );
1544 
1545 		return( -1 );
1546 	}
1547 	if( internal_context->key_bit_size == 128 )
1548 	{
1549 		cipher = EVP_aes_128_cbc();
1550 	}
1551 	else if( internal_context->key_bit_size == 192 )
1552 	{
1553 		cipher = EVP_aes_192_cbc();
1554 	}
1555 	else if( internal_context->key_bit_size == 256 )
1556 	{
1557 		cipher = EVP_aes_256_cbc();
1558 	}
1559 	if( EVP_CipherInit_ex(
1560 	     internal_context->evp_cipher_context,
1561 	     cipher,
1562 	     NULL,
1563 	     (unsigned char *) internal_context->key,
1564 	     (unsigned char *) initialization_vector,
1565 	     mode ) != 1 )
1566 	{
1567 		error_code = ERR_get_error();
1568 
1569 		ERR_error_string_n(
1570 		 error_code,
1571 		 error_string,
1572 		 256 );
1573 
1574 		libcerror_error_set(
1575 		 error,
1576 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1577 		 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1578 		 "%s: unable to initialize cipher with error: %s.",
1579 		 function,
1580 		 error_string );
1581 
1582 		return( -1 );
1583 	}
1584 	if( EVP_CipherUpdate(
1585 	     internal_context->evp_cipher_context,
1586 	     (unsigned char *) output_data,
1587 	     &safe_output_data_size,
1588 	     (unsigned char *) input_data,
1589 	     input_data_size ) != 1 )
1590 	{
1591 		error_code = ERR_get_error();
1592 
1593 		ERR_error_string_n(
1594 		 error_code,
1595 		 error_string,
1596 		 256 );
1597 
1598 		libcerror_error_set(
1599 		 error,
1600 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1601 		 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1602 		 "%s: unable to update cipher with error: %s.",
1603 		 function,
1604 		 error_string );
1605 
1606 		return( -1 );
1607 	}
1608 	/* Just ignore the output of this function
1609 	 */
1610 	EVP_CipherFinal_ex(
1611 	 internal_context->evp_cipher_context,
1612 	 (unsigned char *) block_data,
1613 	 &safe_output_data_size );
1614 
1615 	return( 1 );
1616 }
1617 
1618 #else
1619 
1620 /* De- or encrypts a block of data using AES-CBC (Cipher Block Chaining) using fallback implementation
1621  * The size must be a multitude of the AES block size (16 byte)
1622  * Returns 1 if successful or -1 on error
1623  */
libcaes_crypt_cbc(libcaes_context_t * context,int mode,const uint8_t * initialization_vector,size_t initialization_vector_size,const uint8_t * input_data,size_t input_data_size,uint8_t * output_data,size_t output_data_size,libcerror_error_t ** error)1624 int libcaes_crypt_cbc(
1625      libcaes_context_t *context,
1626      int mode,
1627      const uint8_t *initialization_vector,
1628      size_t initialization_vector_size,
1629      const uint8_t *input_data,
1630      size_t input_data_size,
1631      uint8_t *output_data,
1632      size_t output_data_size,
1633      libcerror_error_t **error )
1634 {
1635 	uint8_t internal_initialization_vector[ 16 ];
1636 
1637 	static char *function = "libcaes_crypt_cbc";
1638 	size_t data_offset    = 0;
1639 
1640 #if !defined( LIBCAES_UNFOLLED_LOOPS )
1641 	uint8_t block_index   = 0;
1642 #endif
1643 
1644 	if( context == NULL )
1645 	{
1646 		libcerror_error_set(
1647 		 error,
1648 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1649 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1650 		 "%s: invalid context.",
1651 		 function );
1652 
1653 		return( -1 );
1654 	}
1655 	if( ( mode != LIBCAES_CRYPT_MODE_DECRYPT )
1656 	 && ( mode != LIBCAES_CRYPT_MODE_ENCRYPT ) )
1657 	{
1658 		libcerror_error_set(
1659 		 error,
1660 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1661 		 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1662 		 "%s: unsupported mode.",
1663 		 function );
1664 
1665 		return( -1 );
1666 	}
1667 	if( initialization_vector == NULL )
1668 	{
1669 		libcerror_error_set(
1670 		 error,
1671 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1672 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1673 		 "%s: invalid initialization vector.",
1674 		 function );
1675 
1676 		return( -1 );
1677 	}
1678 	if( initialization_vector_size != 16 )
1679 	{
1680 		libcerror_error_set(
1681 		 error,
1682 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1683 		 LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1684 		 "%s: invalid initialization vector size value out of bounds.",
1685 		 function );
1686 
1687 		return( -1 );
1688 	}
1689 	if( input_data == NULL )
1690 	{
1691 		libcerror_error_set(
1692 		 error,
1693 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1694 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1695 		 "%s: invalid input data.",
1696 		 function );
1697 
1698 		return( -1 );
1699 	}
1700 	if( input_data_size > (size_t) SSIZE_MAX )
1701 	{
1702 		libcerror_error_set(
1703 		 error,
1704 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1705 		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
1706 		 "%s: invalid input data size value exceeds maximum.",
1707 		 function );
1708 
1709 		return( -1 );
1710 	}
1711 	if( input_data_size < 16 )
1712 	{
1713 		libcerror_error_set(
1714 		 error,
1715 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1716 		 LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
1717 		 "%s: invalid input data size value too small.",
1718 		 function );
1719 
1720 		return( -1 );
1721 	}
1722 	/* Check if the input data size is a multitude of 16-byte
1723 	 */
1724 	if( ( input_data_size & (size_t) 0x0f ) != 0 )
1725 	{
1726 		libcerror_error_set(
1727 		 error,
1728 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1729 		 LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1730 		 "%s: invalid input data size value out of bounds.",
1731 		 function );
1732 
1733 		return( -1 );
1734 	}
1735 	if( output_data == NULL )
1736 	{
1737 		libcerror_error_set(
1738 		 error,
1739 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1740 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1741 		 "%s: invalid output data.",
1742 		 function );
1743 
1744 		return( -1 );
1745 	}
1746 	if( output_data_size > (size_t) SSIZE_MAX )
1747 	{
1748 		libcerror_error_set(
1749 		 error,
1750 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1751 		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
1752 		 "%s: invalid output data size value exceeds maximum.",
1753 		 function );
1754 
1755 		return( -1 );
1756 	}
1757 	if( output_data_size < input_data_size )
1758 	{
1759 		libcerror_error_set(
1760 		 error,
1761 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
1762 		 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1763 		 "%s: invalid ouput data size smaller than input data size.",
1764 		 function );
1765 
1766 		return( -1 );
1767 	}
1768 	if( memory_copy(
1769 	     internal_initialization_vector,
1770 	     initialization_vector,
1771 	     16 ) == NULL )
1772 	{
1773 		libcerror_error_set(
1774 		 error,
1775 		 LIBCERROR_ERROR_DOMAIN_MEMORY,
1776 		 LIBCERROR_MEMORY_ERROR_COPY_FAILED,
1777 		 "%s: unable to copy initialization vector.",
1778 		 function );
1779 
1780 		goto on_error;
1781 	}
1782 	if( ( mode == LIBCAES_CRYPT_MODE_ENCRYPT )
1783 	 && ( output_data != input_data ) )
1784 	{
1785 		if( memory_copy(
1786 		     output_data,
1787 		     input_data,
1788 		     input_data_size ) == NULL )
1789 		{
1790 			libcerror_error_set(
1791 			 error,
1792 			 LIBCERROR_ERROR_DOMAIN_MEMORY,
1793 			 LIBCERROR_MEMORY_ERROR_COPY_FAILED,
1794 			 "%s: unable to copy input data to output data.",
1795 			 function );
1796 
1797 			goto on_error;
1798 		}
1799 	}
1800 	while( data_offset <= ( input_data_size - 16 ) )
1801 	{
1802 		if( mode == LIBCAES_CRYPT_MODE_ENCRYPT )
1803 		{
1804 #if defined( LIBCAES_UNFOLLED_LOOPS )
1805 			output_data[ data_offset++ ] ^= internal_initialization_vector[ 0 ];
1806 			output_data[ data_offset++ ] ^= internal_initialization_vector[ 1 ];
1807 			output_data[ data_offset++ ] ^= internal_initialization_vector[ 2 ];
1808 			output_data[ data_offset++ ] ^= internal_initialization_vector[ 3 ];
1809 			output_data[ data_offset++ ] ^= internal_initialization_vector[ 4 ];
1810 			output_data[ data_offset++ ] ^= internal_initialization_vector[ 5 ];
1811 			output_data[ data_offset++ ] ^= internal_initialization_vector[ 6 ];
1812 			output_data[ data_offset++ ] ^= internal_initialization_vector[ 7 ];
1813 			output_data[ data_offset++ ] ^= internal_initialization_vector[ 8 ];
1814 			output_data[ data_offset++ ] ^= internal_initialization_vector[ 9 ];
1815 			output_data[ data_offset++ ] ^= internal_initialization_vector[ 10 ];
1816 			output_data[ data_offset++ ] ^= internal_initialization_vector[ 11 ];
1817 			output_data[ data_offset++ ] ^= internal_initialization_vector[ 12 ];
1818 			output_data[ data_offset++ ] ^= internal_initialization_vector[ 13 ];
1819 			output_data[ data_offset++ ] ^= internal_initialization_vector[ 14 ];
1820 			output_data[ data_offset++ ] ^= internal_initialization_vector[ 15 ];
1821 #else
1822 			for( block_index = 0;
1823 			     block_index < 16;
1824 			     block_index++ )
1825 			{
1826 				output_data[ data_offset++ ] ^= internal_initialization_vector[ block_index ];
1827 			}
1828 #endif
1829 			data_offset -= 16;
1830 
1831 			if( libcaes_crypt_ecb(
1832 			     context,
1833 			     LIBCAES_CRYPT_MODE_ENCRYPT,
1834 			     &( output_data[ data_offset ] ),
1835 			     16,
1836 			     &( output_data[ data_offset ] ),
1837 			     16,
1838 			     error ) != 1 )
1839 			{
1840 				libcerror_error_set(
1841 				 error,
1842 				 LIBCERROR_ERROR_DOMAIN_ENCRYPTION,
1843 				 LIBCERROR_ENCRYPTION_ERROR_ENCRYPT_FAILED,
1844 				 "%s: unable to encrypt output data.",
1845 				 function );
1846 
1847 				goto on_error;
1848 			}
1849 			if( memory_copy(
1850 			     internal_initialization_vector,
1851 			     &( output_data[ data_offset ] ),
1852 			     16 ) == NULL )
1853 			{
1854 				libcerror_error_set(
1855 				 error,
1856 				 LIBCERROR_ERROR_DOMAIN_MEMORY,
1857 				 LIBCERROR_MEMORY_ERROR_COPY_FAILED,
1858 				 "%s: unable to copy enrypted output data to initialization vector.",
1859 				 function );
1860 
1861 				goto on_error;
1862 			}
1863 		}
1864 		else
1865 		{
1866 			if( libcaes_crypt_ecb(
1867 			     context,
1868 			     LIBCAES_CRYPT_MODE_DECRYPT,
1869 			     &( input_data[ data_offset ] ),
1870 			     16,
1871 			     &( output_data[ data_offset ] ),
1872 			     16,
1873 			     error ) != 1 )
1874 			{
1875 				libcerror_error_set(
1876 				 error,
1877 				 LIBCERROR_ERROR_DOMAIN_ENCRYPTION,
1878 				 LIBCERROR_ENCRYPTION_ERROR_GENERIC,
1879 				 "%s: unable to decrypt output data.",
1880 				 function );
1881 
1882 				goto on_error;
1883 			}
1884 #if defined( LIBCAES_UNFOLLED_LOOPS )
1885 			output_data[ data_offset++ ] ^= internal_initialization_vector[ 0 ];
1886 			output_data[ data_offset++ ] ^= internal_initialization_vector[ 1 ];
1887 			output_data[ data_offset++ ] ^= internal_initialization_vector[ 2 ];
1888 			output_data[ data_offset++ ] ^= internal_initialization_vector[ 3 ];
1889 			output_data[ data_offset++ ] ^= internal_initialization_vector[ 4 ];
1890 			output_data[ data_offset++ ] ^= internal_initialization_vector[ 5 ];
1891 			output_data[ data_offset++ ] ^= internal_initialization_vector[ 6 ];
1892 			output_data[ data_offset++ ] ^= internal_initialization_vector[ 7 ];
1893 			output_data[ data_offset++ ] ^= internal_initialization_vector[ 8 ];
1894 			output_data[ data_offset++ ] ^= internal_initialization_vector[ 9 ];
1895 			output_data[ data_offset++ ] ^= internal_initialization_vector[ 10 ];
1896 			output_data[ data_offset++ ] ^= internal_initialization_vector[ 11 ];
1897 			output_data[ data_offset++ ] ^= internal_initialization_vector[ 12 ];
1898 			output_data[ data_offset++ ] ^= internal_initialization_vector[ 13 ];
1899 			output_data[ data_offset++ ] ^= internal_initialization_vector[ 14 ];
1900 			output_data[ data_offset++ ] ^= internal_initialization_vector[ 15 ];
1901 #else
1902 			for( block_index = 0;
1903 			     block_index < 16;
1904 			     block_index++ )
1905 			{
1906 				output_data[ data_offset++ ] ^= internal_initialization_vector[ block_index ];
1907 			}
1908 #endif
1909 			data_offset -= 16;
1910 
1911 			if( memory_copy(
1912 			     internal_initialization_vector,
1913 			     &( input_data[ data_offset ] ),
1914 			     16 ) == NULL )
1915 			{
1916 				libcerror_error_set(
1917 				 error,
1918 				 LIBCERROR_ERROR_DOMAIN_MEMORY,
1919 				 LIBCERROR_MEMORY_ERROR_COPY_FAILED,
1920 				 "%s: unable to copy enrypted input data to initialization vector.",
1921 				 function );
1922 
1923 				goto on_error;
1924 			}
1925 		}
1926 		data_offset += 16;
1927   	}
1928 	if( memory_set(
1929 	     internal_initialization_vector,
1930 	     0,
1931 	     16 ) == NULL )
1932 	{
1933 		libcerror_error_set(
1934 		 error,
1935 		 LIBCERROR_ERROR_DOMAIN_MEMORY,
1936 		 LIBCERROR_MEMORY_ERROR_SET_FAILED,
1937 		 "%s: unable to clear initialization vector.",
1938 		 function );
1939 
1940 		goto on_error;
1941 	}
1942 	return( 1 );
1943 
1944 on_error:
1945 	memory_set(
1946 	 internal_initialization_vector,
1947 	 0,
1948 	 16 );
1949 
1950 	return( -1 );
1951 }
1952 
1953 #endif /* defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_AES_H ) && defined( HAVE_AES_CBC_ENCRYPT ) */
1954 
1955 /* De- or encrypts a block of data using AES-CCM (Counter with CBC-MAC)
1956  * Note that the key must be set in encryption mode (LIBCAES_CRYPT_MODE_ENCRYPT) for both de- and encryption.
1957  * Returns 1 if successful or -1 on error
1958  */
libcaes_crypt_ccm(libcaes_context_t * context,int mode,const uint8_t * nonce,size_t nonce_size,const uint8_t * input_data,size_t input_data_size,uint8_t * output_data,size_t output_data_size,libcerror_error_t ** error)1959 int libcaes_crypt_ccm(
1960      libcaes_context_t *context,
1961      int mode,
1962      const uint8_t *nonce,
1963      size_t nonce_size,
1964      const uint8_t *input_data,
1965      size_t input_data_size,
1966      uint8_t *output_data,
1967      size_t output_data_size,
1968      libcerror_error_t **error )
1969 {
1970 	uint8_t block_data[ 16 ];
1971 	uint8_t internal_initialization_vector[ 16 ];
1972 
1973 	static char *function      = "libcaes_crypt_ccm";
1974 	size_t data_offset         = 0;
1975 	size_t remaining_data_size = 0;
1976 	uint8_t block_index        = 0;
1977 
1978 	if( context == NULL )
1979 	{
1980 		libcerror_error_set(
1981 		 error,
1982 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1983 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1984 		 "%s: invalid context.",
1985 		 function );
1986 
1987 		return( -1 );
1988 	}
1989 	if( ( mode != LIBCAES_CRYPT_MODE_DECRYPT )
1990 	 && ( mode != LIBCAES_CRYPT_MODE_ENCRYPT ) )
1991 	{
1992 		libcerror_error_set(
1993 		 error,
1994 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1995 		 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1996 		 "%s: unsupported mode.",
1997 		 function );
1998 
1999 		return( -1 );
2000 	}
2001 	if( nonce == NULL )
2002 	{
2003 		libcerror_error_set(
2004 		 error,
2005 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2006 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2007 		 "%s: invalid nonce.",
2008 		 function );
2009 
2010 		return( -1 );
2011 	}
2012 	if( nonce_size >= (size_t) 15 )
2013 	{
2014 		libcerror_error_set(
2015 		 error,
2016 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2017 		 LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
2018 		 "%s: invalid nonce size value out of bounds.",
2019 		 function );
2020 
2021 		return( -1 );
2022 	}
2023 	if( input_data == NULL )
2024 	{
2025 		libcerror_error_set(
2026 		 error,
2027 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2028 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2029 		 "%s: invalid input data.",
2030 		 function );
2031 
2032 		return( -1 );
2033 	}
2034 	if( input_data_size > (size_t) SSIZE_MAX )
2035 	{
2036 		libcerror_error_set(
2037 		 error,
2038 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2039 		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
2040 		 "%s: invalid input data size value exceeds maximum.",
2041 		 function );
2042 
2043 		return( -1 );
2044 	}
2045 	if( input_data_size < 16 )
2046 	{
2047 		libcerror_error_set(
2048 		 error,
2049 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2050 		 LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
2051 		 "%s: invalid input data size value too small.",
2052 		 function );
2053 
2054 		return( -1 );
2055 	}
2056 	if( output_data == NULL )
2057 	{
2058 		libcerror_error_set(
2059 		 error,
2060 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2061 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2062 		 "%s: invalid output data.",
2063 		 function );
2064 
2065 		return( -1 );
2066 	}
2067 	if( output_data_size > (size_t) SSIZE_MAX )
2068 	{
2069 		libcerror_error_set(
2070 		 error,
2071 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2072 		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
2073 		 "%s: invalid output data size value exceeds maximum.",
2074 		 function );
2075 
2076 		return( -1 );
2077 	}
2078 	/* The IV consists of:
2079 	 * 1 byte size value formatted as: 15 - nonce size - 1
2080 	 * a maximum of 14 bytes containing nonce bytes
2081 	 * 1 byte counter
2082 	 */
2083 	if( memory_set(
2084 	     internal_initialization_vector,
2085 	     0,
2086 	     16 ) == NULL )
2087 	{
2088 		libcerror_error_set(
2089 		 error,
2090 		 LIBCERROR_ERROR_DOMAIN_MEMORY,
2091 		 LIBCERROR_MEMORY_ERROR_SET_FAILED,
2092 		 "%s: unable to clear initialization vector.",
2093 		 function );
2094 
2095 		goto on_error;
2096 	}
2097 	if( memory_copy(
2098 	     &( internal_initialization_vector[ 1 ] ),
2099 	     nonce,
2100 	     nonce_size ) == NULL )
2101 	{
2102 		libcerror_error_set(
2103 		 error,
2104 		 LIBCERROR_ERROR_DOMAIN_MEMORY,
2105 		 LIBCERROR_MEMORY_ERROR_COPY_FAILED,
2106 		 "%s: unable to copy nonce to initialization vector.",
2107 		 function );
2108 
2109 		goto on_error;
2110 	}
2111 	internal_initialization_vector[ 0 ] = 15 - (uint8_t) nonce_size - 1;
2112 
2113 	if( memory_copy(
2114 	     output_data,
2115 	     input_data,
2116 	     input_data_size ) == NULL )
2117 	{
2118 		libcerror_error_set(
2119 		 error,
2120 		 LIBCERROR_ERROR_DOMAIN_MEMORY,
2121 		 LIBCERROR_MEMORY_ERROR_COPY_FAILED,
2122 		 "%s: unable to copy input data to output data.",
2123 		 function );
2124 
2125 		goto on_error;
2126 	}
2127 	while( data_offset <= ( input_data_size - 16 ) )
2128 	{
2129 		if( libcaes_crypt_ecb(
2130 		     context,
2131 		     LIBCAES_CRYPT_MODE_ENCRYPT,
2132 		     internal_initialization_vector,
2133 		     16,
2134 		     block_data,
2135 		     16,
2136 		     error ) != 1 )
2137 		{
2138 			libcerror_error_set(
2139 			 error,
2140 			 LIBCERROR_ERROR_DOMAIN_ENCRYPTION,
2141 			 LIBCERROR_ENCRYPTION_ERROR_ENCRYPT_FAILED,
2142 			 "%s: unable to encrypt initialization vector.",
2143 			 function );
2144 
2145 			goto on_error;
2146 		}
2147 #if defined( LIBCAES_UNFOLLED_LOOPS )
2148 		output_data[ data_offset++ ] ^= block_data[ 0 ];
2149 		output_data[ data_offset++ ] ^= block_data[ 1 ];
2150 		output_data[ data_offset++ ] ^= block_data[ 2 ];
2151 		output_data[ data_offset++ ] ^= block_data[ 3 ];
2152 		output_data[ data_offset++ ] ^= block_data[ 4 ];
2153 		output_data[ data_offset++ ] ^= block_data[ 5 ];
2154 		output_data[ data_offset++ ] ^= block_data[ 6 ];
2155 		output_data[ data_offset++ ] ^= block_data[ 7 ];
2156 		output_data[ data_offset++ ] ^= block_data[ 8 ];
2157 		output_data[ data_offset++ ] ^= block_data[ 9 ];
2158 		output_data[ data_offset++ ] ^= block_data[ 10 ];
2159 		output_data[ data_offset++ ] ^= block_data[ 11 ];
2160 		output_data[ data_offset++ ] ^= block_data[ 12 ];
2161 		output_data[ data_offset++ ] ^= block_data[ 13 ];
2162 		output_data[ data_offset++ ] ^= block_data[ 14 ];
2163 		output_data[ data_offset++ ] ^= block_data[ 15 ];
2164 #else
2165 		for( block_index = 0;
2166 		     block_index < 16;
2167 		     block_index++ )
2168 		{
2169 			output_data[ data_offset++ ] ^= block_data[ block_index ];
2170 		}
2171 #endif
2172 		internal_initialization_vector[ 15 ] += 1;
2173 	}
2174 	if( data_offset < input_data_size )
2175 	{
2176 		remaining_data_size = input_data_size - data_offset;
2177 
2178 		if( libcaes_crypt_ecb(
2179 		     context,
2180 		     LIBCAES_CRYPT_MODE_ENCRYPT,
2181 		     internal_initialization_vector,
2182 		     16,
2183 		     block_data,
2184 		     16,
2185 		     error ) != 1 )
2186 		{
2187 			libcerror_error_set(
2188 			 error,
2189 			 LIBCERROR_ERROR_DOMAIN_ENCRYPTION,
2190 			 LIBCERROR_ENCRYPTION_ERROR_ENCRYPT_FAILED,
2191 			 "%s: unable to encrypt initialization vector.",
2192 			 function );
2193 
2194 			goto on_error;
2195 		}
2196 		for( block_index = 0;
2197 		     block_index < (uint8_t) remaining_data_size;
2198 		     block_index++ )
2199 		{
2200 			output_data[ data_offset++ ] ^= block_data[ block_index ];
2201 		}
2202 	}
2203 	if( memory_set(
2204 	     block_data,
2205 	     0,
2206 	     16 ) == NULL )
2207 	{
2208 		libcerror_error_set(
2209 		 error,
2210 		 LIBCERROR_ERROR_DOMAIN_MEMORY,
2211 		 LIBCERROR_MEMORY_ERROR_SET_FAILED,
2212 		 "%s: unable to clear block data.",
2213 		 function );
2214 
2215 		goto on_error;
2216 	}
2217 	if( memory_set(
2218 	     internal_initialization_vector,
2219 	     0,
2220 	     16 ) == NULL )
2221 	{
2222 		libcerror_error_set(
2223 		 error,
2224 		 LIBCERROR_ERROR_DOMAIN_MEMORY,
2225 		 LIBCERROR_MEMORY_ERROR_SET_FAILED,
2226 		 "%s: unable to clear initialization vector.",
2227 		 function );
2228 
2229 		goto on_error;
2230 	}
2231 	return( 1 );
2232 
2233 on_error:
2234 	memory_set(
2235 	 block_data,
2236 	 0,
2237 	 16 );
2238 
2239 	memory_set(
2240 	 internal_initialization_vector,
2241 	 0,
2242 	 16 );
2243 
2244 	return( -1 );
2245 }
2246 
2247 /* De- or encrypts a block of data using AES-CFB (Cipher Feedback Mode)
2248  * Note that the key must be set with mode LIBCAES_CRYPT_MODE_ENCRYPT
2249  * Returns 1 if successful or -1 on error
2250  */
libcaes_crypt_cfb(libcaes_context_t * context,int mode,const uint8_t * initialization_vector,size_t initialization_vector_size,const uint8_t * input_data,size_t input_data_size,uint8_t * output_data,size_t output_data_size,libcerror_error_t ** error)2251 int libcaes_crypt_cfb(
2252      libcaes_context_t *context,
2253      int mode,
2254      const uint8_t *initialization_vector,
2255      size_t initialization_vector_size,
2256      const uint8_t *input_data,
2257      size_t input_data_size,
2258      uint8_t *output_data,
2259      size_t output_data_size,
2260      libcerror_error_t **error )
2261 {
2262 	uint8_t internal_initialization_vector[ 16 ];
2263 
2264 	static char *function              = "libcaes_crypt_cfb";
2265 	size_t data_offset                 = 0;
2266 	size_t initialization_vector_index = 0;
2267 	uint8_t byte_value                 = 0;
2268 
2269 	if( ( mode != LIBCAES_CRYPT_MODE_DECRYPT )
2270 	 && ( mode != LIBCAES_CRYPT_MODE_ENCRYPT ) )
2271 	{
2272 		libcerror_error_set(
2273 		 error,
2274 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2275 		 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
2276 		 "%s: unsupported mode.",
2277 		 function );
2278 
2279 		return( -1 );
2280 	}
2281 	if( initialization_vector == NULL )
2282 	{
2283 		libcerror_error_set(
2284 		 error,
2285 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2286 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2287 		 "%s: invalid initialization vector.",
2288 		 function );
2289 
2290 		return( -1 );
2291 	}
2292 	if( initialization_vector_size != 16 )
2293 	{
2294 		libcerror_error_set(
2295 		 error,
2296 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2297 		 LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
2298 		 "%s: invalid initialization vector size value out of bounds.",
2299 		 function );
2300 
2301 		return( -1 );
2302 	}
2303 	if( input_data == NULL )
2304 	{
2305 		libcerror_error_set(
2306 		 error,
2307 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2308 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2309 		 "%s: invalid input data.",
2310 		 function );
2311 
2312 		return( -1 );
2313 	}
2314 	if( input_data_size > (size_t) SSIZE_MAX )
2315 	{
2316 		libcerror_error_set(
2317 		 error,
2318 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2319 		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
2320 		 "%s: invalid input data size value exceeds maximum.",
2321 		 function );
2322 
2323 		return( -1 );
2324 	}
2325 	if( input_data_size < 16 )
2326 	{
2327 		libcerror_error_set(
2328 		 error,
2329 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2330 		 LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
2331 		 "%s: invalid input data size value too small.",
2332 		 function );
2333 
2334 		return( -1 );
2335 	}
2336 	/* Check if the input data size is a multitude of 16-byte
2337 	 */
2338 	if( ( input_data_size & (size_t) 0x0f ) != 0 )
2339 	{
2340 		libcerror_error_set(
2341 		 error,
2342 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2343 		 LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
2344 		 "%s: invalid input data size value out of bounds.",
2345 		 function );
2346 
2347 		return( -1 );
2348 	}
2349 	if( output_data == NULL )
2350 	{
2351 		libcerror_error_set(
2352 		 error,
2353 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2354 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2355 		 "%s: invalid output data.",
2356 		 function );
2357 
2358 		return( -1 );
2359 	}
2360 	if( output_data_size > (size_t) SSIZE_MAX )
2361 	{
2362 		libcerror_error_set(
2363 		 error,
2364 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2365 		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
2366 		 "%s: invalid output data size value exceeds maximum.",
2367 		 function );
2368 
2369 		return( -1 );
2370 	}
2371 	if( output_data_size > input_data_size )
2372 	{
2373 		libcerror_error_set(
2374 		 error,
2375 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2376 		 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
2377 		 "%s: invalid ouput data size value exceeds input data size.",
2378 		 function );
2379 
2380 		return( -1 );
2381 	}
2382 	if( memory_copy(
2383 	     internal_initialization_vector,
2384 	     initialization_vector,
2385 	     16 ) == NULL )
2386 	{
2387 		libcerror_error_set(
2388 		 error,
2389 		 LIBCERROR_ERROR_DOMAIN_MEMORY,
2390 		 LIBCERROR_MEMORY_ERROR_COPY_FAILED,
2391 		 "%s: unable to copy initialization vector.",
2392 		 function );
2393 
2394 		goto on_error;
2395 	}
2396 	initialization_vector_index = 16;
2397 
2398 	for( data_offset = 0;
2399 	     data_offset < input_data_size;
2400 	     data_offset++ )
2401 	{
2402 		if( initialization_vector_index > 15 )
2403 		{
2404 			if( libcaes_crypt_ecb(
2405 			     context,
2406 			     LIBCAES_CRYPT_MODE_ENCRYPT,
2407 			     internal_initialization_vector,
2408 			     initialization_vector_size,
2409 			     internal_initialization_vector,
2410 			     initialization_vector_size,
2411 			     error ) != 1 )
2412 			{
2413 				libcerror_error_set(
2414 				 error,
2415 				 LIBCERROR_ERROR_DOMAIN_ENCRYPTION,
2416 				 LIBCERROR_ENCRYPTION_ERROR_GENERIC,
2417 				 "%s: unable to de/encrypt initialization vector.",
2418 				 function );
2419 
2420 				goto on_error;
2421 			}
2422 			initialization_vector_index = 0;
2423 		}
2424 		output_data[ data_offset ] = input_data[ data_offset ] ^ internal_initialization_vector[ initialization_vector_index ];
2425 
2426 		if( mode == LIBCAES_CRYPT_MODE_ENCRYPT )
2427 		{
2428 			byte_value = output_data[ data_offset ];
2429 		}
2430 		else
2431 		{
2432 			byte_value = input_data[ data_offset ];
2433 		}
2434 		internal_initialization_vector[ initialization_vector_index++ ] = byte_value;
2435 	}
2436 	if( memory_set(
2437 	     internal_initialization_vector,
2438 	     0,
2439 	     16 ) == NULL )
2440 	{
2441 		libcerror_error_set(
2442 		 error,
2443 		 LIBCERROR_ERROR_DOMAIN_MEMORY,
2444 		 LIBCERROR_MEMORY_ERROR_SET_FAILED,
2445 		 "%s: unable to clear initialization vector.",
2446 		 function );
2447 
2448 		goto on_error;
2449 	}
2450 	return( 1 );
2451 
2452 on_error:
2453 	memory_set(
2454 	 internal_initialization_vector,
2455 	 0,
2456 	 16 );
2457 
2458 	return( -1 );
2459 }
2460 
2461 #if defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_AES_H ) && defined( HAVE_AES_ECB_ENCRYPT )
2462 
2463 /* De- or encrypts a block of data using AES-ECB (Electronic CodeBook) using OpenSSL
2464  * The size must be a multitude of the AES block size (16 byte)
2465  * Returns 1 if successful or -1 on error
2466  */
libcaes_crypt_ecb(libcaes_context_t * context,int mode,const uint8_t * input_data,size_t input_data_size,uint8_t * output_data,size_t output_data_size,libcerror_error_t ** error)2467 int libcaes_crypt_ecb(
2468      libcaes_context_t *context,
2469      int mode,
2470      const uint8_t *input_data,
2471      size_t input_data_size,
2472      uint8_t *output_data,
2473      size_t output_data_size,
2474      libcerror_error_t **error )
2475 {
2476 	libcaes_internal_context_t *internal_context = NULL;
2477 	static char *function                        = "libcaes_crypt_ecb";
2478 	int result                                   = 1;
2479 	int safe_mode                                = 0;
2480 
2481 	if( context == NULL )
2482 	{
2483 		libcerror_error_set(
2484 		 error,
2485 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2486 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2487 		 "%s: invalid context.",
2488 		 function );
2489 
2490 		return( -1 );
2491 	}
2492 	internal_context = (libcaes_internal_context_t *) context;
2493 
2494 	if( ( mode != LIBCAES_CRYPT_MODE_DECRYPT )
2495 	 && ( mode != LIBCAES_CRYPT_MODE_ENCRYPT ) )
2496 	{
2497 		libcerror_error_set(
2498 		 error,
2499 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2500 		 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
2501 		 "%s: unsupported mode.",
2502 		 function );
2503 
2504 		return( -1 );
2505 	}
2506 	if( input_data == NULL )
2507 	{
2508 		libcerror_error_set(
2509 		 error,
2510 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2511 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2512 		 "%s: invalid input data.",
2513 		 function );
2514 
2515 		return( -1 );
2516 	}
2517 	if( input_data_size > (size_t) SSIZE_MAX )
2518 	{
2519 		libcerror_error_set(
2520 		 error,
2521 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2522 		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
2523 		 "%s: invalid input data size value exceeds maximum.",
2524 		 function );
2525 
2526 		return( -1 );
2527 	}
2528 	if( input_data_size < 16 )
2529 	{
2530 		libcerror_error_set(
2531 		 error,
2532 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2533 		 LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
2534 		 "%s: invalid input data size value too small.",
2535 		 function );
2536 
2537 		return( -1 );
2538 	}
2539 	if( output_data == NULL )
2540 	{
2541 		libcerror_error_set(
2542 		 error,
2543 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2544 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2545 		 "%s: invalid output data.",
2546 		 function );
2547 
2548 		return( -1 );
2549 	}
2550 	if( output_data_size > (size_t) SSIZE_MAX )
2551 	{
2552 		libcerror_error_set(
2553 		 error,
2554 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2555 		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
2556 		 "%s: invalid output data size value exceeds maximum.",
2557 		 function );
2558 
2559 		return( -1 );
2560 	}
2561 	if( output_data_size < input_data_size )
2562 	{
2563 		libcerror_error_set(
2564 		 error,
2565 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2566 		 LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
2567 		 "%s: invalid ouput data size smaller than input data size.",
2568 		 function );
2569 
2570 		return( -1 );
2571 	}
2572 	if( mode == LIBCAES_CRYPT_MODE_ENCRYPT )
2573 	{
2574 		safe_mode = AES_ENCRYPT;
2575 	}
2576 	else
2577 	{
2578 		safe_mode = AES_DECRYPT;
2579 	}
2580 	AES_ecb_encrypt(
2581 	 (unsigned char *) input_data,
2582 	 (unsigned char *) output_data,
2583 	 &( internal_context->key ),
2584 	 safe_mode );
2585 
2586 	return( result );
2587 }
2588 
2589 #elif defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_EVP_H ) && defined( HAVE_EVP_CRYPTO_AES_ECB )
2590 
2591 /* De- or encrypts a block of data using AES-ECB (Electronic CodeBook) using OpenSSL EVP
2592  * The size must be a multitude of the AES block size (16 byte)
2593  * Returns 1 if successful or -1 on error
2594  */
libcaes_crypt_ecb(libcaes_context_t * context,int mode,const uint8_t * input_data,size_t input_data_size,uint8_t * output_data,size_t output_data_size,libcerror_error_t ** error)2595 int libcaes_crypt_ecb(
2596      libcaes_context_t *context,
2597      int mode,
2598      const uint8_t *input_data,
2599      size_t input_data_size,
2600      uint8_t *output_data,
2601      size_t output_data_size,
2602      libcerror_error_t **error )
2603 {
2604 	uint8_t block_data[ EVP_MAX_BLOCK_LENGTH ];
2605 	char error_string[ 256 ];
2606 
2607 	const EVP_CIPHER *cipher                     = NULL;
2608 	libcaes_internal_context_t *internal_context = NULL;
2609 	static char *function                        = "libcaes_crypt_ecb";
2610 	unsigned long error_code                     = 0;
2611 	int result                                   = 1;
2612 	int safe_output_data_size                    = 0;
2613 
2614 	if( context == NULL )
2615 	{
2616 		libcerror_error_set(
2617 		 error,
2618 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2619 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2620 		 "%s: invalid context.",
2621 		 function );
2622 
2623 		return( -1 );
2624 	}
2625 	internal_context = (libcaes_internal_context_t *) context;
2626 
2627 	if( ( mode != LIBCAES_CRYPT_MODE_DECRYPT )
2628 	 && ( mode != LIBCAES_CRYPT_MODE_ENCRYPT ) )
2629 	{
2630 		libcerror_error_set(
2631 		 error,
2632 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2633 		 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
2634 		 "%s: unsupported mode.",
2635 		 function );
2636 
2637 		return( -1 );
2638 	}
2639 	if( input_data == NULL )
2640 	{
2641 		libcerror_error_set(
2642 		 error,
2643 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2644 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2645 		 "%s: invalid input data.",
2646 		 function );
2647 
2648 		return( -1 );
2649 	}
2650 	if( input_data_size > (size_t) INT_MAX )
2651 	{
2652 		libcerror_error_set(
2653 		 error,
2654 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2655 		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
2656 		 "%s: invalid input data size value exceeds maximum.",
2657 		 function );
2658 
2659 		return( -1 );
2660 	}
2661 	if( input_data_size < 16 )
2662 	{
2663 		libcerror_error_set(
2664 		 error,
2665 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2666 		 LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
2667 		 "%s: invalid input data size value too small.",
2668 		 function );
2669 
2670 		return( -1 );
2671 	}
2672 	if( output_data == NULL )
2673 	{
2674 		libcerror_error_set(
2675 		 error,
2676 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2677 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2678 		 "%s: invalid output data.",
2679 		 function );
2680 
2681 		return( -1 );
2682 	}
2683 	if( output_data_size > (size_t) INT_MAX )
2684 	{
2685 		libcerror_error_set(
2686 		 error,
2687 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2688 		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
2689 		 "%s: invalid output data size value exceeds maximum.",
2690 		 function );
2691 
2692 		return( -1 );
2693 	}
2694 	if( output_data_size < input_data_size )
2695 	{
2696 		libcerror_error_set(
2697 		 error,
2698 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2699 		 LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
2700 		 "%s: invalid ouput data size smaller than input data size.",
2701 		 function );
2702 
2703 		return( -1 );
2704 	}
2705 	if( memory_set(
2706 	     block_data,
2707 	     0,
2708 	     EVP_MAX_BLOCK_LENGTH ) == NULL )
2709 	{
2710 		libcerror_error_set(
2711 		 error,
2712 		 LIBCERROR_ERROR_DOMAIN_MEMORY,
2713 		 LIBCERROR_MEMORY_ERROR_SET_FAILED,
2714 		 "%s: unable to clear block data.",
2715 		 function );
2716 
2717 		return( -1 );
2718 	}
2719 	if( internal_context->key_bit_size == 128 )
2720 	{
2721 		cipher = EVP_aes_128_ecb();
2722 	}
2723 	else if( internal_context->key_bit_size == 192 )
2724 	{
2725 		cipher = EVP_aes_192_ecb();
2726 	}
2727 	else if( internal_context->key_bit_size == 256 )
2728 	{
2729 		cipher = EVP_aes_256_ecb();
2730 	}
2731 	if( EVP_CipherInit_ex(
2732 	     internal_context->evp_cipher_context,
2733 	     cipher,
2734 	     NULL,
2735 	     (unsigned char *) internal_context->key,
2736 	     NULL,
2737 	     mode ) != 1 )
2738 	{
2739 		error_code = ERR_get_error();
2740 
2741 		ERR_error_string_n(
2742 		 error_code,
2743 		 error_string,
2744 		 256 );
2745 
2746 		libcerror_error_set(
2747 		 error,
2748 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2749 		 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2750 		 "%s: unable to initialize cipher with error: %s.",
2751 		 function,
2752 		 error_string );
2753 
2754 		return( -1 );
2755 	}
2756 	if( EVP_CipherUpdate(
2757 	     internal_context->evp_cipher_context,
2758 	     (unsigned char *) output_data,
2759 	     &safe_output_data_size,
2760 	     (unsigned char *) input_data,
2761 	     16 ) != 1 )
2762 	{
2763 		error_code = ERR_get_error();
2764 
2765 		ERR_error_string_n(
2766 		 error_code,
2767 		 error_string,
2768 		 256 );
2769 
2770 		libcerror_error_set(
2771 		 error,
2772 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
2773 		 LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2774 		 "%s: unable to update cipher with error: %s.",
2775 		 function,
2776 		 error_string );
2777 
2778 		return( -1 );
2779 	}
2780 	/* Just ignore the output of this function
2781 	 */
2782 	EVP_CipherFinal_ex(
2783 	 internal_context->evp_cipher_context,
2784 	 (unsigned char *) block_data,
2785 	 &safe_output_data_size );
2786 
2787 	return( result );
2788 }
2789 
2790 #else
2791 
2792 /* De- or encrypts a block of data using AES-ECB (Electronic CodeBook) using fallback implementation
2793  * The size must be a multitude of the AES block size (16 byte)
2794  * Returns 1 if successful or -1 on error
2795  */
libcaes_crypt_ecb(libcaes_context_t * context,int mode,const uint8_t * input_data,size_t input_data_size,uint8_t * output_data,size_t output_data_size,libcerror_error_t ** error)2796 int libcaes_crypt_ecb(
2797      libcaes_context_t *context,
2798      int mode,
2799      const uint8_t *input_data,
2800      size_t input_data_size,
2801      uint8_t *output_data,
2802      size_t output_data_size,
2803      libcerror_error_t **error )
2804 {
2805 	uint32_t cipher_values_32bit[ 4 ];
2806 	uint32_t values_32bit[ 4 ];
2807 
2808 	libcaes_internal_context_t *internal_context = NULL;
2809 	uint32_t *round_keys                         = NULL;
2810 	static char *function                        = "libcaes_crypt_ecb";
2811 	size_t data_offset                           = 0;
2812 	uint32_t substitution_value                  = 0;
2813 	uint32_t table_value                         = 0;
2814 	int result                                   = 1;
2815 	int round_key_iterator                       = 0;
2816 
2817 	if( context == NULL )
2818 	{
2819 		libcerror_error_set(
2820 		 error,
2821 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2822 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2823 		 "%s: invalid context.",
2824 		 function );
2825 
2826 		return( -1 );
2827 	}
2828 	internal_context = (libcaes_internal_context_t *) context;
2829 
2830 	if( ( mode != LIBCAES_CRYPT_MODE_DECRYPT )
2831 	 && ( mode != LIBCAES_CRYPT_MODE_ENCRYPT ) )
2832 	{
2833 		libcerror_error_set(
2834 		 error,
2835 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2836 		 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
2837 		 "%s: unsupported mode.",
2838 		 function );
2839 
2840 		return( -1 );
2841 	}
2842 	if( input_data == NULL )
2843 	{
2844 		libcerror_error_set(
2845 		 error,
2846 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2847 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2848 		 "%s: invalid input data.",
2849 		 function );
2850 
2851 		return( -1 );
2852 	}
2853 	if( input_data_size > (size_t) SSIZE_MAX )
2854 	{
2855 		libcerror_error_set(
2856 		 error,
2857 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2858 		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
2859 		 "%s: invalid input data size value exceeds maximum.",
2860 		 function );
2861 
2862 		return( -1 );
2863 	}
2864 	if( input_data_size < 16 )
2865 	{
2866 		libcerror_error_set(
2867 		 error,
2868 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2869 		 LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
2870 		 "%s: invalid input data size value too small.",
2871 		 function );
2872 
2873 		return( -1 );
2874 	}
2875 	if( output_data == NULL )
2876 	{
2877 		libcerror_error_set(
2878 		 error,
2879 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2880 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2881 		 "%s: invalid output data.",
2882 		 function );
2883 
2884 		return( -1 );
2885 	}
2886 	if( output_data_size > (size_t) SSIZE_MAX )
2887 	{
2888 		libcerror_error_set(
2889 		 error,
2890 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2891 		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
2892 		 "%s: invalid output data size value exceeds maximum.",
2893 		 function );
2894 
2895 		return( -1 );
2896 	}
2897 	if( output_data_size < input_data_size )
2898 	{
2899 		libcerror_error_set(
2900 		 error,
2901 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2902 		 LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
2903 		 "%s: invalid ouput data size smaller than input data size.",
2904 		 function );
2905 
2906 		return( -1 );
2907 	}
2908 	while( data_offset < input_data_size )
2909 	{
2910 		byte_stream_copy_to_uint32_little_endian(
2911 		 &( input_data[ data_offset ] ),
2912 		 values_32bit[ 0 ] );
2913 
2914 		byte_stream_copy_to_uint32_little_endian(
2915 		 &( input_data[ data_offset + 4 ] ),
2916 		 values_32bit[ 1 ] );
2917 
2918 		byte_stream_copy_to_uint32_little_endian(
2919 		 &( input_data[ data_offset + 8 ] ),
2920 		 values_32bit[ 2 ] );
2921 
2922 		byte_stream_copy_to_uint32_little_endian(
2923 		 &( input_data[ data_offset + 12 ] ),
2924 		 values_32bit[ 3 ] );
2925 
2926 		round_keys = internal_context->round_keys;
2927 
2928 		values_32bit[ 0 ] ^= round_keys[ 0 ];
2929 		values_32bit[ 1 ] ^= round_keys[ 1 ];
2930 		values_32bit[ 2 ] ^= round_keys[ 2 ];
2931 		values_32bit[ 3 ] ^= round_keys[ 3 ];
2932 
2933 		round_keys += 4;
2934 
2935 		if( mode == LIBCAES_CRYPT_MODE_ENCRYPT )
2936 		{
2937 			for( round_key_iterator = ( internal_context->number_of_round_keys / 2 );
2938 			     round_key_iterator > 1;
2939 			     round_key_iterator-- )
2940 			{
2941 				libcaes_calculate_forward_table_round(
2942 				 round_keys,
2943 				 cipher_values_32bit,
2944 				 values_32bit,
2945 				 table_value );
2946 
2947 				round_keys += 4;
2948 
2949 				libcaes_calculate_forward_table_round(
2950 				 round_keys,
2951 				 values_32bit,
2952 				 cipher_values_32bit,
2953 				 table_value );
2954 
2955 				round_keys += 4;
2956 			}
2957 			libcaes_calculate_forward_table_round(
2958 			 round_keys,
2959 			 cipher_values_32bit,
2960 			 values_32bit,
2961 			 table_value );
2962 
2963 			round_keys += 4;
2964 
2965 			libcaes_calculate_forward_substitution_round(
2966 			 round_keys,
2967 			 values_32bit,
2968 			 cipher_values_32bit,
2969 			 substitution_value );
2970 		}
2971 		else
2972 		{
2973 			for( round_key_iterator = ( internal_context->number_of_round_keys / 2 );
2974 			     round_key_iterator > 1;
2975 			     round_key_iterator-- )
2976 			{
2977 				libcaes_calculate_reverse_table_round(
2978 				 round_keys,
2979 				 cipher_values_32bit,
2980 				 values_32bit,
2981 				 table_value );
2982 
2983 				round_keys += 4;
2984 
2985 				libcaes_calculate_reverse_table_round(
2986 				 round_keys,
2987 				 values_32bit,
2988 				 cipher_values_32bit,
2989 				 table_value );
2990 
2991 				round_keys += 4;
2992 			}
2993 			libcaes_calculate_reverse_table_round(
2994 			 round_keys,
2995 			 cipher_values_32bit,
2996 			 values_32bit,
2997 			 table_value );
2998 
2999 			round_keys += 4;
3000 
3001 			libcaes_calculate_reverse_substitution_round(
3002 			 round_keys,
3003 			 values_32bit,
3004 			 cipher_values_32bit,
3005 			 table_value );
3006 		}
3007 		byte_stream_copy_from_uint32_little_endian(
3008 		 &( output_data[ data_offset ] ),
3009 		 values_32bit[ 0 ] );
3010 
3011 		byte_stream_copy_from_uint32_little_endian(
3012 		 &( output_data[ data_offset + 4 ] ),
3013 		 values_32bit[ 1 ] );
3014 
3015 		byte_stream_copy_from_uint32_little_endian(
3016 		 &( output_data[ data_offset + 8 ] ),
3017 		 values_32bit[ 2 ] );
3018 
3019 		byte_stream_copy_from_uint32_little_endian(
3020 		 &( output_data[ data_offset + 12 ] ),
3021 		 values_32bit[ 3 ] );
3022 
3023 		if( memory_set(
3024 		     values_32bit,
3025 		     0,
3026 		     sizeof( uint32_t ) * 4 ) == NULL )
3027 		{
3028 			libcerror_error_set(
3029 			 error,
3030 			 LIBCERROR_ERROR_DOMAIN_MEMORY,
3031 			 LIBCERROR_MEMORY_ERROR_SET_FAILED,
3032 			 "%s: unable to clear values 32-bit.",
3033 			 function );
3034 
3035 			result = -1;
3036 		}
3037 		if( memory_set(
3038 		     cipher_values_32bit,
3039 		     0,
3040 		     sizeof( uint32_t ) * 4 ) == NULL )
3041 		{
3042 			libcerror_error_set(
3043 			 error,
3044 			 LIBCERROR_ERROR_DOMAIN_MEMORY,
3045 			 LIBCERROR_MEMORY_ERROR_SET_FAILED,
3046 			 "%s: unable to clear cipher values 32-bit.",
3047 			 function );
3048 
3049 			result = -1;
3050 		}
3051 		data_offset += 16;
3052 	}
3053 	return( result );
3054 }
3055 
3056 #endif /* defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_AES_H ) && defined( HAVE_AES_ECB_ENCRYPT ) */
3057 
3058