Coverage Report

Created: 2024-02-25 07:19

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