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