Coverage Report

Created: 2026-10-22 07:28

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libcaes/libcaes/libcaes_context.c
Line
Count
Source
1
/*
2
 * AES de/encryption context functions
3
 *
4
 * Copyright (C) 2011-2026, 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
512
  value   = libcaes_forward_substitution_box[ index3 ]; \
56
512
  value <<= 8; \
57
512
  value  |= libcaes_forward_substitution_box[ index2 ]; \
58
512
  value <<= 8; \
59
512
  value  |= libcaes_forward_substitution_box[ index1 ]; \
60
512
  value <<= 8; \
61
512
  value  |= libcaes_forward_substitution_box[ index0 ];
62
63
#define libcaes_calculate_forward_table_value( value, index0, index1, index2, index3 ) \
64
4.60k
  value  = libcaes_forward_table0[ index0 ]; \
65
4.60k
  value ^= libcaes_forward_table1[ index1 ]; \
66
4.60k
  value ^= libcaes_forward_table2[ index2 ]; \
67
4.60k
  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
128
  libcaes_calculate_forward_substitution_value( \
86
128
   substitution_value, \
87
128
   ( cipher_values_32bit[ 0 ] & 0xff ), \
88
128
   ( ( cipher_values_32bit[ 1 ] >> 8 ) & 0xff ), \
89
128
   ( ( cipher_values_32bit[ 2 ] >> 16 ) & 0xff ), \
90
128
   ( ( cipher_values_32bit[ 3 ] >> 24 ) & 0xff ) ); \
91
128
\
92
128
  values_32bit[ 0 ] = round_keys[ 0 ] ^ substitution_value; \
93
128
\
94
128
  libcaes_calculate_forward_substitution_value( \
95
128
   substitution_value, \
96
128
   ( cipher_values_32bit[ 1 ] & 0xff ), \
97
128
   ( ( cipher_values_32bit[ 2 ] >> 8 ) & 0xff ), \
98
128
   ( ( cipher_values_32bit[ 3 ] >> 16 ) & 0xff ), \
99
128
   ( ( cipher_values_32bit[ 0 ] >> 24 ) & 0xff ) ); \
100
128
\
101
128
  values_32bit[ 1 ] = round_keys[ 1 ] ^ substitution_value; \
102
128
\
103
128
  libcaes_calculate_forward_substitution_value( \
104
128
   substitution_value, \
105
128
   ( cipher_values_32bit[ 2 ] & 0xff ), \
106
128
   ( ( cipher_values_32bit[ 3 ] >> 8 ) & 0xff ), \
107
128
   ( ( cipher_values_32bit[ 0 ] >> 16 ) & 0xff ), \
108
128
   ( ( cipher_values_32bit[ 1 ] >> 24 ) & 0xff ) ); \
109
128
\
110
128
  values_32bit[ 2 ] = round_keys[ 2 ] ^ substitution_value; \
111
128
\
112
128
  libcaes_calculate_forward_substitution_value( \
113
128
   substitution_value, \
114
128
   ( cipher_values_32bit[ 3 ] & 0xff ), \
115
128
   ( ( cipher_values_32bit[ 0 ] >> 8 ) & 0xff ), \
116
128
   ( ( cipher_values_32bit[ 1 ] >> 16 ) & 0xff ), \
117
128
   ( ( cipher_values_32bit[ 2 ] >> 24 ) & 0xff ) ); \
118
128
\
119
128
  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
1.15k
  libcaes_calculate_forward_table_value( \
123
1.15k
   table_value, \
124
1.15k
   ( cipher_values_32bit[ 0 ] & 0xff ), \
125
1.15k
   ( ( cipher_values_32bit[ 1 ] >> 8 ) & 0xff ), \
126
1.15k
   ( ( cipher_values_32bit[ 2 ] >> 16 ) & 0xff ), \
127
1.15k
   ( ( cipher_values_32bit[ 3 ] >> 24 ) & 0xff ) ); \
128
1.15k
\
129
1.15k
  values_32bit[ 0 ] = round_keys[ 0 ] ^ table_value; \
130
1.15k
\
131
1.15k
  libcaes_calculate_forward_table_value( \
132
1.15k
   table_value, \
133
1.15k
   ( cipher_values_32bit[ 1 ] & 0xff ), \
134
1.15k
   ( ( cipher_values_32bit[ 2 ] >> 8 ) & 0xff ), \
135
1.15k
   ( ( cipher_values_32bit[ 3 ] >> 16 ) & 0xff ), \
136
1.15k
   ( ( cipher_values_32bit[ 0 ] >> 24 ) & 0xff ) ); \
137
1.15k
\
138
1.15k
  values_32bit[ 1 ] = round_keys[ 1 ] ^ table_value; \
139
1.15k
\
140
1.15k
  libcaes_calculate_forward_table_value( \
141
1.15k
   table_value, \
142
1.15k
   ( cipher_values_32bit[ 2 ] & 0xff ), \
143
1.15k
   ( ( cipher_values_32bit[ 3 ] >> 8 ) & 0xff ), \
144
1.15k
   ( ( cipher_values_32bit[ 0 ] >> 16 ) & 0xff ), \
145
1.15k
   ( ( cipher_values_32bit[ 1 ] >> 24 ) & 0xff ) ); \
146
1.15k
\
147
1.15k
  values_32bit[ 2 ] = round_keys[ 2 ] ^ table_value; \
148
1.15k
\
149
1.15k
  libcaes_calculate_forward_table_value( \
150
1.15k
   table_value, \
151
1.15k
   ( cipher_values_32bit[ 3 ] & 0xff ), \
152
1.15k
   ( ( cipher_values_32bit[ 0 ] >> 8 ) & 0xff ), \
153
1.15k
   ( ( cipher_values_32bit[ 1 ] >> 16 ) & 0xff ), \
154
1.15k
   ( ( cipher_values_32bit[ 2 ] >> 24 ) & 0xff ) ); \
155
1.15k
\
156
1.15k
  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
6.45k
{
266
6.45k
  libcaes_internal_context_t *internal_context = NULL;
267
6.45k
  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
6.45k
  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
6.45k
  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
6.45k
  internal_context = memory_allocate_structure(
298
6.45k
                      libcaes_internal_context_t );
299
300
6.45k
  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
6.45k
  if( memory_set(
312
6.45k
       internal_context,
313
6.45k
       0,
314
6.45k
       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
6.45k
  if( libcaes_tables_initialized == 0 )
359
9
  {
360
9
    if( libcaes_initialize_tables(
361
9
         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
9
    libcaes_tables_initialized = 1;
373
9
  }
374
6.45k
#endif /* defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_AES_H ) && ( defined( HAVE_AES_CBC_ENCRYPT ) || defined( HAVE_AES_ECB_ENCRYPT ) ) */
375
376
6.45k
  *context = (libcaes_context_t *) internal_context;
377
378
6.45k
  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
6.45k
}
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
6.45k
{
396
6.45k
  libcaes_internal_context_t *internal_context = NULL;
397
6.45k
  static char *function                        = "libcaes_context_free";
398
6.45k
  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
6.45k
  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
6.45k
  if( *context != NULL )
418
6.45k
  {
419
6.45k
    internal_context = (libcaes_internal_context_t *) *context;
420
6.45k
    *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
6.45k
#endif /* defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_AES_H ) && ( defined( HAVE_AES_CBC_ENCRYPT ) || defined( HAVE_AES_ECB_ENCRYPT ) ) */
462
463
6.45k
    memory_free(
464
6.45k
     internal_context );
465
6.45k
  }
466
6.45k
  return( result );
467
6.45k
}
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
4.92k
{
479
4.92k
  libcaes_internal_context_t *internal_context = NULL;
480
4.92k
  static char *function                        = "libcaes_context_set_key";
481
482
4.92k
  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
4.92k
  internal_context = (libcaes_internal_context_t *) context;
494
495
4.92k
  if( ( mode != LIBCAES_CRYPT_MODE_DECRYPT )
496
3.39k
   && ( 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
4.92k
  if( ( key_bit_size != 128 )
508
1.88k
   && ( key_bit_size != 192 )
509
1.88k
   && ( key_bit_size != 256 ) )
510
1
  {
511
1
    libcerror_error_set(
512
1
     error,
513
1
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
514
1
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
515
1
     "%s: unsupported key bit size.",
516
1
     function );
517
518
1
    return( -1 );
519
1
  }
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
4.92k
  if( mode == LIBCAES_CRYPT_MODE_ENCRYPT )
586
3.39k
  {
587
3.39k
    if( libcaes_internal_context_set_encryption_key(
588
3.39k
         internal_context,
589
3.39k
         key,
590
3.39k
         key_bit_size,
591
3.39k
         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
3.39k
  }
603
1.52k
  else
604
1.52k
  {
605
1.52k
    if( libcaes_internal_context_set_decryption_key(
606
1.52k
         internal_context,
607
1.52k
         key,
608
1.52k
         key_bit_size,
609
1.52k
         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
1.52k
  }
621
4.92k
#endif /* defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_AES_H ) && ( defined( HAVE_AES_CBC_ENCRYPT ) || defined( HAVE_AES_ECB_ENCRYPT ) ) */
622
623
4.92k
  return( 1 );
624
4.92k
}
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
9
{
634
9
  uint8_t logs_table[ 256 ];
635
9
  uint8_t powers_table[ 256 ];
636
637
9
  static char *function        = "libcaes_initialize_tables";
638
9
  uint16_t byte_index          = 0;
639
9
  uint16_t table_index         = 0;
640
9
  uint8_t byte_value           = 0;
641
9
  uint8_t log_value            = 0;
642
9
  uint8_t round_constant_index = 0;
643
9
  uint8_t substitution_value   = 0;
644
645
9
  if( memory_set(
646
9
       logs_table,
647
9
       0,
648
9
       sizeof( uint8_t ) * 256 ) == NULL )
649
0
  {
650
0
    libcerror_error_set(
651
0
     error,
652
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
653
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
654
0
     "%s: unable to clear logs table.",
655
0
     function );
656
657
0
    return( -1 );
658
0
  }
659
  /* Fill the powers and logs tables over GF( 2^8 )
660
   */
661
9
  byte_value = 1;
662
663
9
  for( byte_index = 0;
664
2.31k
       byte_index < 256;
665
2.30k
       byte_index++ )
666
2.30k
  {
667
2.30k
    powers_table[ byte_index ] = byte_value;
668
2.30k
    logs_table[ byte_value ]   = (uint8_t) byte_index;
669
670
2.30k
    if( ( byte_value & 0x80 ) == 0 )
671
1.15k
    {
672
1.15k
      byte_value ^= ( byte_value << 1 ) & 0xff;
673
1.15k
    }
674
1.15k
    else
675
1.15k
    {
676
1.15k
      byte_value ^= ( ( byte_value << 1 ) & 0xff ) ^ 0x1b;
677
1.15k
    }
678
2.30k
  }
679
  /* Fill the round constants
680
   */
681
9
  byte_value = 1;
682
683
9
  for( round_constant_index = 0;
684
99
       round_constant_index < 10;
685
90
       round_constant_index++ )
686
90
  {
687
90
    libcaes_round_constants[ round_constant_index ] = (uint32_t) byte_value;
688
689
90
    if( ( byte_value & 0x80 ) == 0 )
690
81
    {
691
81
      byte_value = ( byte_value << 1 ) & 0xff;
692
81
    }
693
9
    else
694
9
    {
695
9
      byte_value = ( ( byte_value << 1 ) & 0xff ) ^ 0x1b;
696
9
    }
697
90
  }
698
699
  /* Fill the forward and reverse S-boxes
700
   */
701
9
  libcaes_forward_substitution_box[ 0x00 ] = 0x63;
702
9
  libcaes_reverse_substitution_box[ 0x63 ] = 0x00;
703
704
9
  for( byte_index = 1;
705
2.30k
       byte_index < 256;
706
2.29k
       byte_index++ )
707
2.29k
  {
708
2.29k
    table_index = 255 - logs_table[ byte_index ];
709
2.29k
    byte_value  = powers_table[ table_index ];
710
711
2.29k
    substitution_value = ( ( byte_value << 1 ) & 0xff )
712
2.29k
                       | ( byte_value >> 7 );
713
714
2.29k
    byte_value ^= substitution_value;
715
716
2.29k
    substitution_value = ( ( substitution_value << 1 ) & 0xff )
717
2.29k
                       | ( substitution_value >> 7 );
718
719
2.29k
    byte_value ^= substitution_value;
720
721
2.29k
    substitution_value = ( ( substitution_value << 1 ) & 0xff )
722
2.29k
                       | ( substitution_value >> 7 );
723
724
2.29k
    byte_value ^= substitution_value;
725
726
2.29k
    substitution_value = ( ( substitution_value << 1 ) & 0xff )
727
2.29k
                       | ( substitution_value >> 7 );
728
729
2.29k
    substitution_value ^= byte_value ^ 0x63;
730
731
2.29k
    libcaes_forward_substitution_box[ byte_index ]         = substitution_value;
732
2.29k
    libcaes_reverse_substitution_box[ substitution_value ] = (uint8_t) byte_index;
733
2.29k
  }
734
  /* Fill the forward and reverse tables
735
   */
736
9
  for( byte_index = 0;
737
2.31k
       byte_index < 256;
738
2.30k
       byte_index++ )
739
2.30k
  {
740
2.30k
    byte_value = libcaes_forward_substitution_box[ byte_index ];
741
742
2.30k
    if( ( byte_value & 0x80 ) == 0 )
743
1.15k
    {
744
1.15k
      substitution_value = ( byte_value << 1 ) & 0xff;
745
1.15k
    }
746
1.15k
    else
747
1.15k
    {
748
1.15k
      substitution_value = ( ( byte_value << 1 ) & 0xff ) ^ 0x1b;
749
1.15k
    }
750
2.30k
    libcaes_forward_table0[ byte_index ]   = byte_value ^ substitution_value;
751
2.30k
    libcaes_forward_table0[ byte_index ] <<= 8;
752
2.30k
    libcaes_forward_table0[ byte_index ]  |= byte_value;
753
2.30k
    libcaes_forward_table0[ byte_index ] <<= 8;
754
2.30k
    libcaes_forward_table0[ byte_index ]  |= byte_value;
755
2.30k
    libcaes_forward_table0[ byte_index ] <<= 8;
756
2.30k
    libcaes_forward_table0[ byte_index ]  |= substitution_value;
757
758
2.30k
    libcaes_forward_table1[ byte_index ] = byte_stream_bit_rotate_left(
759
2.30k
                                            libcaes_forward_table0[ byte_index ],
760
2.30k
                                            8 );
761
762
2.30k
    libcaes_forward_table2[ byte_index ] = byte_stream_bit_rotate_left(
763
2.30k
                                            libcaes_forward_table1[ byte_index ],
764
2.30k
                                            8 );
765
766
2.30k
    libcaes_forward_table3[ byte_index ] = byte_stream_bit_rotate_left(
767
2.30k
                                            libcaes_forward_table2[ byte_index ],
768
2.30k
                                            8 );
769
770
2.30k
    substitution_value = libcaes_reverse_substitution_box[ byte_index ];
771
772
2.30k
    libcaes_reverse_table0[ byte_index ] = 0;
773
774
2.30k
    if( substitution_value != 0 )
775
2.29k
    {
776
2.29k
      log_value = logs_table[ substitution_value ];
777
778
2.29k
      table_index = (logs_table[ 0x0b ] + log_value) % 255;
779
780
2.29k
      libcaes_reverse_table0[ byte_index ] ^= powers_table[ table_index ];
781
2.29k
      libcaes_reverse_table0[ byte_index ] <<= 8;
782
783
2.29k
      table_index = ( logs_table[ 0x0d ] + log_value ) % 255;
784
785
2.29k
      libcaes_reverse_table0[ byte_index ] ^= powers_table[ table_index ];
786
2.29k
      libcaes_reverse_table0[ byte_index ] <<= 8;
787
788
2.29k
      table_index = ( logs_table[ 0x09 ] + log_value ) % 255;
789
790
2.29k
      libcaes_reverse_table0[ byte_index ] ^= powers_table[ table_index ];
791
2.29k
      libcaes_reverse_table0[ byte_index ] <<= 8;
792
793
2.29k
      table_index = ( logs_table[ 0x0e ] + log_value ) % 255;
794
795
2.29k
      libcaes_reverse_table0[ byte_index ] ^= powers_table[ table_index ];
796
2.29k
    }
797
2.30k
    libcaes_reverse_table1[ byte_index ] = byte_stream_bit_rotate_left(
798
2.30k
                                            libcaes_reverse_table0[ byte_index ],
799
2.30k
                                            8 );
800
801
2.30k
    libcaes_reverse_table2[ byte_index ] = byte_stream_bit_rotate_left(
802
2.30k
                                            libcaes_reverse_table1[ byte_index ],
803
2.30k
                                            8 );
804
805
2.30k
    libcaes_reverse_table3[ byte_index ] = byte_stream_bit_rotate_left(
806
2.30k
                                            libcaes_reverse_table2[ byte_index ],
807
2.30k
                                            8 );
808
2.30k
  }
809
9
  return( 1 );
810
9
}
811
812
/* Sets the AES decryption key
813
 * Returns 1 if successful or -1 on error
814
 */
815
int libcaes_internal_context_set_decryption_key(
816
     libcaes_internal_context_t *internal_context,
817
     const uint8_t *key,
818
     size_t key_bit_size,
819
     libcerror_error_t **error )
820
1.52k
{
821
1.52k
  libcaes_internal_context_t *encryption_context = NULL;
822
1.52k
  static char *function                          = "libcaes_internal_context_set_decryption_key";
823
1.52k
  uint32_t *encryption_round_keys                = NULL;
824
1.52k
  uint32_t *round_keys                           = NULL;
825
1.52k
  size_t round_keys_byte_offset                  = 0;
826
1.52k
  uint8_t byte_value0                            = 0;
827
1.52k
  uint8_t byte_value1                            = 0;
828
1.52k
  uint8_t byte_value2                            = 0;
829
1.52k
  uint8_t byte_value3                            = 0;
830
1.52k
  int round_key_iterator                         = 0;
831
832
1.52k
  if( internal_context == NULL )
833
0
  {
834
0
    libcerror_error_set(
835
0
     error,
836
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
837
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
838
0
     "%s: invalid context.",
839
0
     function );
840
841
0
    return( -1 );
842
0
  }
843
1.52k
  if( key == NULL )
844
0
  {
845
0
    libcerror_error_set(
846
0
     error,
847
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
848
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
849
0
     "%s: invalid key.",
850
0
     function );
851
852
0
    return( -1 );
853
0
  }
854
1.52k
  if( ( key_bit_size != 128 )
855
207
   && ( key_bit_size != 192 )
856
207
   && ( key_bit_size != 256 ) )
857
0
  {
858
0
    libcerror_error_set(
859
0
     error,
860
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
861
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
862
0
     "%s: unsupported key bit size.",
863
0
     function );
864
865
0
    return( -1 );
866
0
  }
867
1.52k
  if( key_bit_size == 128 )
868
1.31k
  {
869
1.31k
    internal_context->number_of_round_keys = 10;
870
1.31k
  }
871
207
  else if( key_bit_size == 192 )
872
0
  {
873
0
    internal_context->number_of_round_keys = 12;
874
0
  }
875
207
  else if( key_bit_size == 256 )
876
207
  {
877
207
    internal_context->number_of_round_keys = 14;
878
207
  }
879
  /* Align the buffer to next 16-byte blocks
880
   */
881
1.52k
  internal_context->round_keys = (uint32_t *) ( 16 + ( (intptr_t) internal_context->round_keys_data & ~( 15 ) ) );
882
883
1.52k
  round_keys = internal_context->round_keys;
884
885
1.52k
  if( libcaes_context_initialize(
886
1.52k
       (libcaes_context_t **) &encryption_context,
887
1.52k
       error ) != 1 )
888
0
  {
889
0
    libcerror_error_set(
890
0
     error,
891
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
892
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
893
0
     "%s: unable to create encryption context.",
894
0
     function );
895
896
0
    goto on_error;
897
0
  }
898
1.52k
  if( libcaes_internal_context_set_encryption_key(
899
1.52k
       encryption_context,
900
1.52k
       key,
901
1.52k
       key_bit_size,
902
1.52k
       error ) != 1 )
903
0
  {
904
0
    libcerror_error_set(
905
0
     error,
906
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
907
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
908
0
     "%s: unable to set encryption key.",
909
0
     function );
910
911
0
    goto on_error;
912
0
  }
913
  /* Point to the end of the round keys
914
   */
915
1.52k
  round_keys_byte_offset = encryption_context->number_of_round_keys * sizeof( uint32_t );
916
917
1.52k
  encryption_round_keys = &( encryption_context->round_keys[ round_keys_byte_offset ] );
918
919
1.52k
  round_keys[ 0 ] = encryption_round_keys[ 0 ];
920
1.52k
  round_keys[ 1 ] = encryption_round_keys[ 1 ];
921
1.52k
  round_keys[ 2 ] = encryption_round_keys[ 2 ];
922
1.52k
  round_keys[ 3 ] = encryption_round_keys[ 3 ];
923
924
1.52k
  round_keys            += 4;
925
1.52k
  encryption_round_keys -= 4;
926
927
1.52k
  for( round_key_iterator = internal_context->number_of_round_keys;
928
16.0k
       round_key_iterator > 1;
929
14.5k
       round_key_iterator-- )
930
14.5k
  {
931
14.5k
    byte_value0 = ( encryption_round_keys[ 0 ] & 0xff );
932
14.5k
    byte_value1 = ( ( encryption_round_keys[ 0 ] >> 8 ) & 0xff );
933
14.5k
    byte_value2 = ( ( encryption_round_keys[ 0 ] >> 16 ) & 0xff );
934
14.5k
    byte_value3 = ( ( encryption_round_keys[ 0 ] >> 24 ) & 0xff );
935
936
14.5k
    byte_value0 = libcaes_forward_substitution_box[ byte_value0 ];
937
14.5k
    byte_value1 = libcaes_forward_substitution_box[ byte_value1 ];
938
14.5k
    byte_value2 = libcaes_forward_substitution_box[ byte_value2 ];
939
14.5k
    byte_value3 = libcaes_forward_substitution_box[ byte_value3 ];
940
941
14.5k
    round_keys[ 0 ] = libcaes_reverse_table0[ byte_value0 ]
942
14.5k
              ^ libcaes_reverse_table1[ byte_value1 ]
943
14.5k
              ^ libcaes_reverse_table2[ byte_value2 ]
944
14.5k
              ^ libcaes_reverse_table3[ byte_value3 ];
945
946
14.5k
    byte_value0 = ( encryption_round_keys[ 1 ] & 0xff );
947
14.5k
    byte_value1 = ( ( encryption_round_keys[ 1 ] >> 8 ) & 0xff );
948
14.5k
    byte_value2 = ( ( encryption_round_keys[ 1 ] >> 16 ) & 0xff );
949
14.5k
    byte_value3 = ( ( encryption_round_keys[ 1 ] >> 24 ) & 0xff );
950
951
14.5k
    byte_value0 = libcaes_forward_substitution_box[ byte_value0 ];
952
14.5k
    byte_value1 = libcaes_forward_substitution_box[ byte_value1 ];
953
14.5k
    byte_value2 = libcaes_forward_substitution_box[ byte_value2 ];
954
14.5k
    byte_value3 = libcaes_forward_substitution_box[ byte_value3 ];
955
956
14.5k
    round_keys[ 1 ] = libcaes_reverse_table0[ byte_value0 ]
957
14.5k
              ^ libcaes_reverse_table1[ byte_value1 ]
958
14.5k
              ^ libcaes_reverse_table2[ byte_value2 ]
959
14.5k
              ^ libcaes_reverse_table3[ byte_value3 ];
960
961
14.5k
    byte_value0 = ( encryption_round_keys[ 2 ] & 0xff );
962
14.5k
    byte_value1 = ( ( encryption_round_keys[ 2 ] >> 8 ) & 0xff );
963
14.5k
    byte_value2 = ( ( encryption_round_keys[ 2 ] >> 16 ) & 0xff );
964
14.5k
    byte_value3 = ( ( encryption_round_keys[ 2 ] >> 24 ) & 0xff );
965
966
14.5k
    byte_value0 = libcaes_forward_substitution_box[ byte_value0 ];
967
14.5k
    byte_value1 = libcaes_forward_substitution_box[ byte_value1 ];
968
14.5k
    byte_value2 = libcaes_forward_substitution_box[ byte_value2 ];
969
14.5k
    byte_value3 = libcaes_forward_substitution_box[ byte_value3 ];
970
971
14.5k
    round_keys[ 2 ] = libcaes_reverse_table0[ byte_value0 ]
972
14.5k
              ^ libcaes_reverse_table1[ byte_value1 ]
973
14.5k
              ^ libcaes_reverse_table2[ byte_value2 ]
974
14.5k
              ^ libcaes_reverse_table3[ byte_value3 ];
975
976
14.5k
    byte_value0 = ( encryption_round_keys[ 3 ] & 0xff );
977
14.5k
    byte_value1 = ( ( encryption_round_keys[ 3 ] >> 8 ) & 0xff );
978
14.5k
    byte_value2 = ( ( encryption_round_keys[ 3 ] >> 16 ) & 0xff );
979
14.5k
    byte_value3 = ( ( encryption_round_keys[ 3 ] >> 24 ) & 0xff );
980
981
14.5k
    byte_value0 = libcaes_forward_substitution_box[ byte_value0 ];
982
14.5k
    byte_value1 = libcaes_forward_substitution_box[ byte_value1 ];
983
14.5k
    byte_value2 = libcaes_forward_substitution_box[ byte_value2 ];
984
14.5k
    byte_value3 = libcaes_forward_substitution_box[ byte_value3 ];
985
986
14.5k
    round_keys[ 3 ] = libcaes_reverse_table0[ byte_value0 ]
987
14.5k
              ^ libcaes_reverse_table1[ byte_value1 ]
988
14.5k
              ^ libcaes_reverse_table2[ byte_value2 ]
989
14.5k
              ^ libcaes_reverse_table3[ byte_value3 ];
990
991
14.5k
    round_keys            += 4;
992
14.5k
    encryption_round_keys -= 4;
993
14.5k
  }
994
1.52k
  round_keys[ 0 ] = encryption_round_keys[ 0 ];
995
1.52k
  round_keys[ 1 ] = encryption_round_keys[ 1 ];
996
1.52k
  round_keys[ 2 ] = encryption_round_keys[ 2 ];
997
1.52k
  round_keys[ 3 ] = encryption_round_keys[ 3 ];
998
999
1.52k
  if( libcaes_context_free(
1000
1.52k
       (libcaes_context_t **) &encryption_context,
1001
1.52k
       error ) != 1 )
1002
0
  {
1003
0
    libcerror_error_set(
1004
0
     error,
1005
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1006
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1007
0
     "%s: unable to free encryption context.",
1008
0
     function );
1009
1010
0
    goto on_error;
1011
0
  }
1012
1.52k
  return( 1 );
1013
1014
0
on_error:
1015
0
  if( encryption_context != NULL )
1016
0
  {
1017
0
    libcaes_context_free(
1018
0
     (libcaes_context_t **) &encryption_context,
1019
0
     NULL );
1020
0
  }
1021
0
  return( -1 );
1022
1.52k
}
1023
1024
/* Sets the AES encryption key
1025
 * Returns 1 if successful or -1 on error
1026
 */
1027
int libcaes_internal_context_set_encryption_key(
1028
     libcaes_internal_context_t *internal_context,
1029
     const uint8_t *key,
1030
     size_t key_bit_size,
1031
     libcerror_error_t **error )
1032
4.92k
{
1033
4.92k
  static char *function    = "libcaes_internal_context_set_encryption_key";
1034
4.92k
  uint32_t *round_keys     = NULL;
1035
4.92k
  size_t key_index         = 0;
1036
4.92k
  int round_constant_index = 0;
1037
1038
4.92k
  if( internal_context == NULL )
1039
0
  {
1040
0
    libcerror_error_set(
1041
0
     error,
1042
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1043
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1044
0
     "%s: invalid context.",
1045
0
     function );
1046
1047
0
    return( -1 );
1048
0
  }
1049
4.92k
  if( key == NULL )
1050
0
  {
1051
0
    libcerror_error_set(
1052
0
     error,
1053
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1054
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1055
0
     "%s: invalid key.",
1056
0
     function );
1057
1058
0
    return( -1 );
1059
0
  }
1060
4.92k
  if( ( key_bit_size != 128 )
1061
1.88k
   && ( key_bit_size != 192 )
1062
1.88k
   && ( key_bit_size != 256 ) )
1063
0
  {
1064
0
    libcerror_error_set(
1065
0
     error,
1066
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1067
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1068
0
     "%s: unsupported key bit size.",
1069
0
     function );
1070
1071
0
    return( -1 );
1072
0
  }
1073
  /* Align the buffer to next 16-byte blocks
1074
   */
1075
4.92k
  internal_context->round_keys = (uint32_t *) ( 16 + ( (intptr_t) internal_context->round_keys_data & ~( 15 ) ) );
1076
1077
4.92k
  round_keys = internal_context->round_keys;
1078
1079
4.92k
  for( key_index = 0;
1080
32.1k
       key_index < key_bit_size / 8;
1081
27.2k
       key_index += 4 )
1082
27.2k
  {
1083
27.2k
    byte_stream_copy_to_uint32_little_endian(
1084
27.2k
           &( key[ key_index ] ),
1085
27.2k
           round_keys[ round_constant_index ] );
1086
1087
27.2k
    round_constant_index++;
1088
27.2k
  }
1089
4.92k
  if( key_bit_size == 128 )
1090
3.04k
  {
1091
3.04k
    internal_context->number_of_round_keys = 10;
1092
1093
3.04k
    for( round_constant_index = 0;
1094
33.4k
         round_constant_index < 10;
1095
30.4k
         round_constant_index++ )
1096
30.4k
    {
1097
30.4k
      round_keys[ 4 ]  = libcaes_round_constants[ round_constant_index ];
1098
30.4k
      round_keys[ 4 ] ^= round_keys[ 0 ];
1099
30.4k
      round_keys[ 4 ] ^= (uint32_t) libcaes_forward_substitution_box[ ( round_keys[ 3 ] >> 8 ) & 0xff ];
1100
30.4k
      round_keys[ 4 ] ^= ( (uint32_t) libcaes_forward_substitution_box[ ( round_keys[ 3 ] >> 16 ) & 0xff ] ) << 8;
1101
30.4k
      round_keys[ 4 ] ^= ( (uint32_t) libcaes_forward_substitution_box[ ( round_keys[ 3 ] >> 24 ) & 0xff ] ) << 16;
1102
30.4k
      round_keys[ 4 ] ^= ( (uint32_t) libcaes_forward_substitution_box[ ( round_keys[ 3 ] ) & 0xff ] ) << 24;
1103
1104
30.4k
      round_keys[ 5 ] = round_keys[ 1 ] ^ round_keys[ 4 ];
1105
30.4k
      round_keys[ 6 ] = round_keys[ 2 ] ^ round_keys[ 5 ];
1106
30.4k
      round_keys[ 7 ] = round_keys[ 3 ] ^ round_keys[ 6 ];
1107
1108
30.4k
      round_keys += 4;
1109
30.4k
    }
1110
3.04k
  }
1111
1.88k
  else if( key_bit_size == 192 )
1112
0
  {
1113
0
    internal_context->number_of_round_keys = 12;
1114
1115
0
    for( round_constant_index = 0;
1116
0
         round_constant_index < 8;
1117
0
         round_constant_index++ )
1118
0
    {
1119
0
      round_keys[ 6 ]  = libcaes_round_constants[ round_constant_index ];
1120
0
      round_keys[ 6 ] ^= round_keys[ 0 ];
1121
0
      round_keys[ 6 ] ^= (uint32_t) libcaes_forward_substitution_box[ ( round_keys[ 5 ] >> 8 ) & 0xff ];
1122
0
      round_keys[ 6 ] ^= ( (uint32_t) libcaes_forward_substitution_box[ ( round_keys[ 5 ] >> 16 ) & 0xff ] ) << 8;
1123
0
      round_keys[ 6 ] ^= ( (uint32_t) libcaes_forward_substitution_box[ ( round_keys[ 5 ] >> 24 ) & 0xff ] ) << 16;
1124
0
      round_keys[ 6 ] ^= ( (uint32_t) libcaes_forward_substitution_box[ ( round_keys[ 5 ] ) & 0xff ] ) << 24;
1125
1126
0
      round_keys[ 7 ]  = round_keys[ 1 ] ^ round_keys[ 6 ];
1127
0
      round_keys[ 8 ]  = round_keys[ 2 ] ^ round_keys[ 7 ];
1128
0
      round_keys[ 9 ]  = round_keys[ 3 ] ^ round_keys[ 8 ];
1129
0
      round_keys[ 10 ] = round_keys[ 4 ] ^ round_keys[ 9 ];
1130
0
      round_keys[ 11 ] = round_keys[ 5 ] ^ round_keys[ 10 ];
1131
1132
0
      round_keys += 6;
1133
0
    }
1134
0
  }
1135
1.88k
  else if( key_bit_size == 256 )
1136
1.88k
  {
1137
1.88k
    internal_context->number_of_round_keys = 14;
1138
1139
1.88k
    for( round_constant_index = 0;
1140
15.0k
         round_constant_index < 7;
1141
13.1k
         round_constant_index++ )
1142
13.1k
    {
1143
13.1k
      round_keys[ 8 ]  = libcaes_round_constants[ round_constant_index ];
1144
13.1k
      round_keys[ 8 ] ^= round_keys[ 0 ];
1145
13.1k
      round_keys[ 8 ] ^= (uint32_t) libcaes_forward_substitution_box[ ( round_keys[ 7 ] >> 8 ) & 0xff ];
1146
13.1k
      round_keys[ 8 ] ^= ( (uint32_t) libcaes_forward_substitution_box[ ( round_keys[ 7 ] >> 16 ) & 0xff ] ) << 8;
1147
13.1k
      round_keys[ 8 ] ^= ( (uint32_t) libcaes_forward_substitution_box[ ( round_keys[ 7 ] >> 24 ) & 0xff ] ) << 16;
1148
13.1k
      round_keys[ 8 ] ^= ( (uint32_t) libcaes_forward_substitution_box[ ( round_keys[ 7 ] ) & 0xff ] ) << 24;
1149
1150
13.1k
      round_keys[ 9 ]  = round_keys[ 1 ] ^ round_keys[ 8 ];
1151
13.1k
      round_keys[ 10 ] = round_keys[ 2 ] ^ round_keys[ 9 ];
1152
13.1k
      round_keys[ 11 ] = round_keys[ 3 ] ^ round_keys[ 10 ];
1153
1154
13.1k
      round_keys[ 12 ]  = round_keys[ 4 ];
1155
13.1k
      round_keys[ 12 ] ^= (uint32_t) libcaes_forward_substitution_box[ ( round_keys[ 11 ] ) & 0xff ];
1156
13.1k
      round_keys[ 12 ] ^= ( (uint32_t) libcaes_forward_substitution_box[ ( round_keys[ 11 ] >> 8 ) & 0xff ] ) << 8;
1157
13.1k
      round_keys[ 12 ] ^= ( (uint32_t) libcaes_forward_substitution_box[ ( round_keys[ 11 ] >> 16 ) & 0xff ] ) << 16;
1158
13.1k
      round_keys[ 12 ] ^= ( (uint32_t) libcaes_forward_substitution_box[ ( round_keys[ 11 ] >> 24 ) & 0xff ] ) << 24;
1159
1160
13.1k
      round_keys[ 13 ] = round_keys[ 5 ] ^ round_keys[ 12 ];
1161
13.1k
      round_keys[ 14 ] = round_keys[ 6 ] ^ round_keys[ 13 ];
1162
13.1k
      round_keys[ 15 ] = round_keys[ 7 ] ^ round_keys[ 14 ];
1163
1164
13.1k
      round_keys += 8;
1165
13.1k
    }
1166
1.88k
  }
1167
4.92k
  return( 1 );
1168
4.92k
}
1169
1170
#endif /* !defined( LIBCAES_HAVE_AES_SUPPORT ) */
1171
1172
#if defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_AES_H ) && defined( HAVE_AES_CBC_ENCRYPT )
1173
1174
/* De- or encrypts a block of data using AES-CBC (Cipher Block Chaining) using OpenSSL
1175
 * The size must be a multitude of the AES block size (16 byte)
1176
 * Returns 1 if successful or -1 on error
1177
 */
1178
int libcaes_crypt_cbc(
1179
     libcaes_context_t *context,
1180
     int mode,
1181
     const uint8_t *initialization_vector,
1182
     size_t initialization_vector_size,
1183
     const uint8_t *input_data,
1184
     size_t input_data_size,
1185
     uint8_t *output_data,
1186
     size_t output_data_size,
1187
     libcerror_error_t **error )
1188
{
1189
  uint8_t safe_initialization_vector[ 16 ];
1190
1191
  libcaes_internal_context_t *internal_context = NULL;
1192
  static char *function                        = "libcaes_crypt_cbc";
1193
  int safe_mode                                = 0;
1194
1195
  if( context == NULL )
1196
  {
1197
    libcerror_error_set(
1198
     error,
1199
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1200
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1201
     "%s: invalid context.",
1202
     function );
1203
1204
    return( -1 );
1205
  }
1206
  internal_context = (libcaes_internal_context_t *) context;
1207
1208
  if( ( mode != LIBCAES_CRYPT_MODE_DECRYPT )
1209
   && ( mode != LIBCAES_CRYPT_MODE_ENCRYPT ) )
1210
  {
1211
    libcerror_error_set(
1212
     error,
1213
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1214
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1215
     "%s: unsupported mode.",
1216
     function );
1217
1218
    return( -1 );
1219
  }
1220
  if( initialization_vector == NULL )
1221
  {
1222
    libcerror_error_set(
1223
     error,
1224
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1225
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1226
     "%s: invalid initialization vector.",
1227
     function );
1228
1229
    return( -1 );
1230
  }
1231
  if( initialization_vector_size != 16 )
1232
  {
1233
    libcerror_error_set(
1234
     error,
1235
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1236
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1237
     "%s: invalid initialization vector size value out of bounds.",
1238
     function );
1239
1240
    return( -1 );
1241
  }
1242
  if( input_data == NULL )
1243
  {
1244
    libcerror_error_set(
1245
     error,
1246
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1247
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1248
     "%s: invalid input data.",
1249
     function );
1250
1251
    return( -1 );
1252
  }
1253
  /* Check if the input data size is a multitude of 16-byte
1254
   */
1255
  if( ( ( input_data_size & (size_t) 0x0f ) != 0 )
1256
   || ( input_data_size > (size_t) SSIZE_MAX ) )
1257
  {
1258
    libcerror_error_set(
1259
     error,
1260
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1261
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1262
     "%s: invalid input data size value out of bounds.",
1263
     function );
1264
1265
    return( -1 );
1266
  }
1267
  if( output_data == NULL )
1268
  {
1269
    libcerror_error_set(
1270
     error,
1271
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1272
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1273
     "%s: invalid output data.",
1274
     function );
1275
1276
    return( -1 );
1277
  }
1278
  if( ( output_data_size < input_data_size )
1279
   || ( output_data_size > (size_t) SSIZE_MAX ) )
1280
  {
1281
    libcerror_error_set(
1282
     error,
1283
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1284
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1285
     "%s: invalid output data size value out of bounds.",
1286
     function );
1287
1288
    return( -1 );
1289
  }
1290
  if( mode == LIBCAES_CRYPT_MODE_ENCRYPT )
1291
  {
1292
    safe_mode = AES_ENCRYPT;
1293
  }
1294
  else
1295
  {
1296
    safe_mode = AES_DECRYPT;
1297
  }
1298
  /* AES_cbc_encrypt overwrites the data in the initialization vector
1299
   */
1300
  if( memory_copy(
1301
       safe_initialization_vector,
1302
       initialization_vector,
1303
       16 ) == NULL )
1304
  {
1305
    libcerror_error_set(
1306
     error,
1307
     LIBCERROR_ERROR_DOMAIN_MEMORY,
1308
     LIBCERROR_MEMORY_ERROR_COPY_FAILED,
1309
     "%s: unable to copy initialization vector.",
1310
     function );
1311
1312
    return( -1 );
1313
  }
1314
  AES_cbc_encrypt(
1315
   (unsigned char *) input_data,
1316
   (unsigned char *) output_data,
1317
   input_data_size,
1318
   &( internal_context->key ),
1319
   (unsigned char *) safe_initialization_vector,
1320
   safe_mode );
1321
1322
  if( memory_set(
1323
       safe_initialization_vector,
1324
       0,
1325
       16 ) == NULL )
1326
  {
1327
    libcerror_error_set(
1328
     error,
1329
     LIBCERROR_ERROR_DOMAIN_MEMORY,
1330
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
1331
     "%s: unable to clear initialization vector.",
1332
     function );
1333
1334
    return( -1 );
1335
  }
1336
  return( 1 );
1337
}
1338
1339
#elif defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_EVP_H ) && defined( HAVE_EVP_CRYPTO_AES_CBC )
1340
1341
/* De- or encrypts a block of data using AES-CBC (Cipher Block Chaining) using OpenSSL EVP
1342
 * The size must be a multitude of the AES block size (16 byte)
1343
 * Returns 1 if successful or -1 on error
1344
 */
1345
int libcaes_crypt_cbc(
1346
     libcaes_context_t *context,
1347
     int mode,
1348
     const uint8_t *initialization_vector,
1349
     size_t initialization_vector_size,
1350
     const uint8_t *input_data,
1351
     size_t input_data_size,
1352
     uint8_t *output_data,
1353
     size_t output_data_size,
1354
     libcerror_error_t **error )
1355
{
1356
  uint8_t block_data[ EVP_MAX_BLOCK_LENGTH ];
1357
  char error_string[ 256 ];
1358
1359
#if defined( HAVE_EVP_CIPHERINIT_EX2 )
1360
  OSSL_PARAM parameters[2];
1361
1362
  EVP_CIPHER *cipher                           = NULL;
1363
  const char *cipher_string                    = NULL;
1364
  unsigned int padding                         = 0;
1365
#else
1366
  const EVP_CIPHER *cipher                     = NULL;
1367
#endif
1368
1369
  libcaes_internal_context_t *internal_context = NULL;
1370
  static char *function                        = "libcaes_crypt_cbc";
1371
  unsigned long error_code                     = 0;
1372
  int safe_output_data_size                    = 0;
1373
1374
  if( context == NULL )
1375
  {
1376
    libcerror_error_set(
1377
     error,
1378
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1379
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1380
     "%s: invalid context.",
1381
     function );
1382
1383
    return( -1 );
1384
  }
1385
  internal_context = (libcaes_internal_context_t *) context;
1386
1387
  if( ( internal_context->key_bit_size != 128 )
1388
   && ( internal_context->key_bit_size != 192 )
1389
   && ( internal_context->key_bit_size != 256 ) )
1390
  {
1391
    libcerror_error_set(
1392
     error,
1393
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1394
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1395
     "%s: invalid context - unsupported key bit size.",
1396
     function );
1397
1398
    return( -1 );
1399
  }
1400
  if( ( mode != LIBCAES_CRYPT_MODE_DECRYPT )
1401
   && ( mode != LIBCAES_CRYPT_MODE_ENCRYPT ) )
1402
  {
1403
    libcerror_error_set(
1404
     error,
1405
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1406
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1407
     "%s: unsupported mode.",
1408
     function );
1409
1410
    return( -1 );
1411
  }
1412
  if( initialization_vector == NULL )
1413
  {
1414
    libcerror_error_set(
1415
     error,
1416
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1417
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1418
     "%s: invalid initialization vector.",
1419
     function );
1420
1421
    return( -1 );
1422
  }
1423
  if( initialization_vector_size != 16 )
1424
  {
1425
    libcerror_error_set(
1426
     error,
1427
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1428
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1429
     "%s: invalid initialization vector size value out of bounds.",
1430
     function );
1431
1432
    return( -1 );
1433
  }
1434
  if( input_data == NULL )
1435
  {
1436
    libcerror_error_set(
1437
     error,
1438
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1439
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1440
     "%s: invalid input data.",
1441
     function );
1442
1443
    return( -1 );
1444
  }
1445
  /* Check if the input data size is a multitude of 16-byte
1446
   */
1447
  if( ( ( input_data_size & (size_t) 0x0f ) != 0 )
1448
   || ( input_data_size > (size_t) INT_MAX ) )
1449
  {
1450
    libcerror_error_set(
1451
     error,
1452
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1453
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1454
     "%s: invalid input data size value out of bounds.",
1455
     function );
1456
1457
    return( -1 );
1458
  }
1459
  if( output_data == NULL )
1460
  {
1461
    libcerror_error_set(
1462
     error,
1463
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1464
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1465
     "%s: invalid output data.",
1466
     function );
1467
1468
    return( -1 );
1469
  }
1470
  if( ( output_data_size < input_data_size )
1471
   || ( output_data_size > (size_t) INT_MAX ) )
1472
  {
1473
    libcerror_error_set(
1474
     error,
1475
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1476
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1477
     "%s: invalid output data size value out of bounds.",
1478
     function );
1479
1480
    return( -1 );
1481
  }
1482
  if( memory_set(
1483
       block_data,
1484
       0,
1485
       EVP_MAX_BLOCK_LENGTH ) == NULL )
1486
  {
1487
    libcerror_error_set(
1488
     error,
1489
     LIBCERROR_ERROR_DOMAIN_MEMORY,
1490
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
1491
     "%s: unable to clear input block data.",
1492
     function );
1493
1494
    goto on_error;
1495
  }
1496
#if defined( HAVE_EVP_CIPHERINIT_EX2 )
1497
  if( EVP_CIPHER_CTX_reset(
1498
       internal_context->evp_cipher_context ) != 1 )
1499
  {
1500
    error_code = ERR_get_error();
1501
1502
    ERR_error_string_n(
1503
     error_code,
1504
     error_string,
1505
     256 );
1506
1507
    libcerror_error_set(
1508
     error,
1509
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1510
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1511
     "%s: unable to reset cipher context with error: %s.",
1512
     function,
1513
     error_string );
1514
1515
    goto on_error;
1516
  }
1517
  if( internal_context->key_bit_size == 128 )
1518
  {
1519
    cipher_string = "AES-128-CBC";
1520
  }
1521
  else if( internal_context->key_bit_size == 192 )
1522
  {
1523
    cipher_string = "AES-192-CBC";
1524
  }
1525
  else if( internal_context->key_bit_size == 256 )
1526
  {
1527
    cipher_string = "AES-256-CBC";
1528
  }
1529
  cipher = EVP_CIPHER_fetch(
1530
            NULL,
1531
            cipher_string,
1532
            NULL );
1533
1534
  if( cipher == NULL )
1535
  {
1536
    libcerror_error_set(
1537
     error,
1538
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1539
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1540
     "%s: missing cipher.",
1541
     function );
1542
1543
    goto on_error;
1544
  }
1545
  parameters[0] = OSSL_PARAM_construct_uint(
1546
                   OSSL_CIPHER_PARAM_PADDING,
1547
                   &padding );
1548
1549
  parameters[1] = OSSL_PARAM_construct_end();
1550
1551
  if( EVP_CipherInit_ex2(
1552
       internal_context->evp_cipher_context,
1553
       cipher,
1554
       (unsigned char *) internal_context->key,
1555
       (unsigned char *) initialization_vector,
1556
       mode,
1557
       parameters ) != 1 )
1558
  {
1559
    error_code = ERR_get_error();
1560
1561
    ERR_error_string_n(
1562
     error_code,
1563
     error_string,
1564
     256 );
1565
1566
    libcerror_error_set(
1567
     error,
1568
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1569
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1570
     "%s: unable to initialize cipher with error: %s.",
1571
     function,
1572
     error_string );
1573
1574
    goto on_error;
1575
  }
1576
#else
1577
  if( internal_context->key_bit_size == 128 )
1578
  {
1579
    cipher = EVP_aes_128_cbc();
1580
  }
1581
  else if( internal_context->key_bit_size == 192 )
1582
  {
1583
    cipher = EVP_aes_192_cbc();
1584
  }
1585
  else if( internal_context->key_bit_size == 256 )
1586
  {
1587
    cipher = EVP_aes_256_cbc();
1588
  }
1589
  if( EVP_CipherInit_ex(
1590
       internal_context->evp_cipher_context,
1591
       cipher,
1592
       NULL,
1593
       (unsigned char *) internal_context->key,
1594
       (unsigned char *) initialization_vector,
1595
       mode ) != 1 )
1596
  {
1597
    error_code = ERR_get_error();
1598
1599
    ERR_error_string_n(
1600
     error_code,
1601
     error_string,
1602
     256 );
1603
1604
    libcerror_error_set(
1605
     error,
1606
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1607
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1608
     "%s: unable to initialize cipher with error: %s.",
1609
     function,
1610
     error_string );
1611
1612
    goto on_error;
1613
  }
1614
  if( EVP_CIPHER_CTX_set_padding(
1615
       internal_context->evp_cipher_context,
1616
       1 ) != 1 )
1617
  {
1618
    error_code = ERR_get_error();
1619
1620
    ERR_error_string_n(
1621
     error_code,
1622
     error_string,
1623
     256 );
1624
1625
    libcerror_error_set(
1626
     error,
1627
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1628
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1629
     "%s: unable to set padding in context with error: %s.",
1630
     function,
1631
     error_string );
1632
1633
    goto on_error;
1634
  }
1635
#endif /* defined( HAVE_EVP_CIPHERINIT_EX2 ) */
1636
1637
  if( EVP_CipherUpdate(
1638
       internal_context->evp_cipher_context,
1639
       (unsigned char *) output_data,
1640
       &safe_output_data_size,
1641
       (unsigned char *) input_data,
1642
       input_data_size ) != 1 )
1643
  {
1644
    error_code = ERR_get_error();
1645
1646
    ERR_error_string_n(
1647
     error_code,
1648
     error_string,
1649
     256 );
1650
1651
    libcerror_error_set(
1652
     error,
1653
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1654
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1655
     "%s: unable to update cipher with error: %s.",
1656
     function,
1657
     error_string );
1658
1659
    goto on_error;
1660
  }
1661
  /* Just ignore the output of this function
1662
   */
1663
  EVP_CipherFinal_ex(
1664
   internal_context->evp_cipher_context,
1665
   (unsigned char *) block_data,
1666
   &safe_output_data_size );
1667
1668
#if defined( HAVE_EVP_CIPHERINIT_EX2 )
1669
  EVP_CIPHER_free(
1670
   cipher );
1671
#endif
1672
  return( 1 );
1673
1674
on_error:
1675
#if defined( HAVE_EVP_CIPHERINIT_EX2 )
1676
  if( cipher != NULL )
1677
  {
1678
    EVP_CIPHER_free(
1679
     cipher );
1680
  }
1681
#endif
1682
  return( -1 );
1683
}
1684
1685
#else
1686
1687
/* De- or encrypts a block of data using AES-CBC (Cipher Block Chaining) using fallback implementation
1688
 * The size must be a multitude of the AES block size (16 byte)
1689
 * Returns 1 if successful or -1 on error
1690
 */
1691
int libcaes_crypt_cbc(
1692
     libcaes_context_t *context,
1693
     int mode,
1694
     const uint8_t *initialization_vector,
1695
     size_t initialization_vector_size,
1696
     const uint8_t *input_data,
1697
     size_t input_data_size,
1698
     uint8_t *output_data,
1699
     size_t output_data_size,
1700
     libcerror_error_t **error )
1701
9.91k
{
1702
9.91k
  uint8_t internal_initialization_vector[ 16 ];
1703
1704
9.91k
  static char *function = "libcaes_crypt_cbc";
1705
9.91k
  size_t data_offset    = 0;
1706
1707
#if !defined( LIBCAES_UNFOLLED_LOOPS )
1708
  uint8_t block_index   = 0;
1709
#endif
1710
1711
9.91k
  if( context == NULL )
1712
0
  {
1713
0
    libcerror_error_set(
1714
0
     error,
1715
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1716
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1717
0
     "%s: invalid context.",
1718
0
     function );
1719
1720
0
    return( -1 );
1721
0
  }
1722
9.91k
  if( ( mode != LIBCAES_CRYPT_MODE_DECRYPT )
1723
50
   && ( mode != LIBCAES_CRYPT_MODE_ENCRYPT ) )
1724
0
  {
1725
0
    libcerror_error_set(
1726
0
     error,
1727
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1728
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1729
0
     "%s: unsupported mode.",
1730
0
     function );
1731
1732
0
    return( -1 );
1733
0
  }
1734
9.91k
  if( initialization_vector == NULL )
1735
0
  {
1736
0
    libcerror_error_set(
1737
0
     error,
1738
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1739
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1740
0
     "%s: invalid initialization vector.",
1741
0
     function );
1742
1743
0
    return( -1 );
1744
0
  }
1745
9.91k
  if( initialization_vector_size != 16 )
1746
0
  {
1747
0
    libcerror_error_set(
1748
0
     error,
1749
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1750
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1751
0
     "%s: invalid initialization vector size value out of bounds.",
1752
0
     function );
1753
1754
0
    return( -1 );
1755
0
  }
1756
9.91k
  if( input_data == NULL )
1757
0
  {
1758
0
    libcerror_error_set(
1759
0
     error,
1760
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1761
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1762
0
     "%s: invalid input data.",
1763
0
     function );
1764
1765
0
    return( -1 );
1766
0
  }
1767
  /* Check if the input data size is a multitude of 16-byte
1768
   */
1769
9.91k
  if( ( ( input_data_size & (size_t) 0x0f ) != 0 )
1770
9.90k
   || ( input_data_size < 16 )
1771
9.90k
   || ( input_data_size > (size_t) SSIZE_MAX ) )
1772
7
  {
1773
7
    libcerror_error_set(
1774
7
     error,
1775
7
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1776
7
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1777
7
     "%s: invalid input data size value out of bounds.",
1778
7
     function );
1779
1780
7
    return( -1 );
1781
7
  }
1782
9.90k
  if( output_data == NULL )
1783
0
  {
1784
0
    libcerror_error_set(
1785
0
     error,
1786
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1787
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1788
0
     "%s: invalid output data.",
1789
0
     function );
1790
1791
0
    return( -1 );
1792
0
  }
1793
9.90k
  if( ( output_data_size < input_data_size )
1794
9.86k
   || ( output_data_size > (size_t) SSIZE_MAX ) )
1795
41
  {
1796
41
    libcerror_error_set(
1797
41
     error,
1798
41
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1799
41
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1800
41
     "%s: invalid output data size value of bounds.",
1801
41
     function );
1802
1803
41
    return( -1 );
1804
41
  }
1805
9.86k
  if( memory_copy(
1806
9.86k
       internal_initialization_vector,
1807
9.86k
       initialization_vector,
1808
9.86k
       16 ) == NULL )
1809
0
  {
1810
0
    libcerror_error_set(
1811
0
     error,
1812
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
1813
0
     LIBCERROR_MEMORY_ERROR_COPY_FAILED,
1814
0
     "%s: unable to copy initialization vector.",
1815
0
     function );
1816
1817
0
    goto on_error;
1818
0
  }
1819
9.86k
  if( ( mode == LIBCAES_CRYPT_MODE_ENCRYPT )
1820
4
   && ( output_data != input_data ) )
1821
4
  {
1822
4
    if( memory_copy(
1823
4
         output_data,
1824
4
         input_data,
1825
4
         input_data_size ) == NULL )
1826
0
    {
1827
0
      libcerror_error_set(
1828
0
       error,
1829
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
1830
0
       LIBCERROR_MEMORY_ERROR_COPY_FAILED,
1831
0
       "%s: unable to copy input data to output data.",
1832
0
       function );
1833
1834
0
      goto on_error;
1835
0
    }
1836
4
  }
1837
306k
  while( data_offset <= ( input_data_size - 16 ) )
1838
296k
  {
1839
296k
    if( mode == LIBCAES_CRYPT_MODE_ENCRYPT )
1840
10
    {
1841
10
#if defined( LIBCAES_UNFOLLED_LOOPS )
1842
10
      output_data[ data_offset++ ] ^= internal_initialization_vector[ 0 ];
1843
10
      output_data[ data_offset++ ] ^= internal_initialization_vector[ 1 ];
1844
10
      output_data[ data_offset++ ] ^= internal_initialization_vector[ 2 ];
1845
10
      output_data[ data_offset++ ] ^= internal_initialization_vector[ 3 ];
1846
10
      output_data[ data_offset++ ] ^= internal_initialization_vector[ 4 ];
1847
10
      output_data[ data_offset++ ] ^= internal_initialization_vector[ 5 ];
1848
10
      output_data[ data_offset++ ] ^= internal_initialization_vector[ 6 ];
1849
10
      output_data[ data_offset++ ] ^= internal_initialization_vector[ 7 ];
1850
10
      output_data[ data_offset++ ] ^= internal_initialization_vector[ 8 ];
1851
10
      output_data[ data_offset++ ] ^= internal_initialization_vector[ 9 ];
1852
10
      output_data[ data_offset++ ] ^= internal_initialization_vector[ 10 ];
1853
10
      output_data[ data_offset++ ] ^= internal_initialization_vector[ 11 ];
1854
10
      output_data[ data_offset++ ] ^= internal_initialization_vector[ 12 ];
1855
10
      output_data[ data_offset++ ] ^= internal_initialization_vector[ 13 ];
1856
10
      output_data[ data_offset++ ] ^= internal_initialization_vector[ 14 ];
1857
10
      output_data[ data_offset++ ] ^= internal_initialization_vector[ 15 ];
1858
#else
1859
      for( block_index = 0;
1860
           block_index < 16;
1861
           block_index++ )
1862
      {
1863
        output_data[ data_offset++ ] ^= internal_initialization_vector[ block_index ];
1864
      }
1865
#endif
1866
10
      data_offset -= 16;
1867
1868
10
      if( libcaes_crypt_ecb(
1869
10
           context,
1870
10
           LIBCAES_CRYPT_MODE_ENCRYPT,
1871
10
           &( output_data[ data_offset ] ),
1872
10
           16,
1873
10
           &( output_data[ data_offset ] ),
1874
10
           16,
1875
10
           error ) != 1 )
1876
0
      {
1877
0
        libcerror_error_set(
1878
0
         error,
1879
0
         LIBCERROR_ERROR_DOMAIN_ENCRYPTION,
1880
0
         LIBCERROR_ENCRYPTION_ERROR_ENCRYPT_FAILED,
1881
0
         "%s: unable to encrypt output data.",
1882
0
         function );
1883
1884
0
        goto on_error;
1885
0
      }
1886
10
      if( memory_copy(
1887
10
           internal_initialization_vector,
1888
10
           &( output_data[ data_offset ] ),
1889
10
           16 ) == NULL )
1890
0
      {
1891
0
        libcerror_error_set(
1892
0
         error,
1893
0
         LIBCERROR_ERROR_DOMAIN_MEMORY,
1894
0
         LIBCERROR_MEMORY_ERROR_COPY_FAILED,
1895
0
         "%s: unable to copy enrypted output data to initialization vector.",
1896
0
         function );
1897
1898
0
        goto on_error;
1899
0
      }
1900
10
    }
1901
296k
    else
1902
296k
    {
1903
296k
      if( libcaes_crypt_ecb(
1904
296k
           context,
1905
296k
           LIBCAES_CRYPT_MODE_DECRYPT,
1906
296k
           &( input_data[ data_offset ] ),
1907
296k
           16,
1908
296k
           &( output_data[ data_offset ] ),
1909
296k
           16,
1910
296k
           error ) != 1 )
1911
0
      {
1912
0
        libcerror_error_set(
1913
0
         error,
1914
0
         LIBCERROR_ERROR_DOMAIN_ENCRYPTION,
1915
0
         LIBCERROR_ENCRYPTION_ERROR_GENERIC,
1916
0
         "%s: unable to decrypt output data.",
1917
0
         function );
1918
1919
0
        goto on_error;
1920
0
      }
1921
296k
#if defined( LIBCAES_UNFOLLED_LOOPS )
1922
296k
      output_data[ data_offset++ ] ^= internal_initialization_vector[ 0 ];
1923
296k
      output_data[ data_offset++ ] ^= internal_initialization_vector[ 1 ];
1924
296k
      output_data[ data_offset++ ] ^= internal_initialization_vector[ 2 ];
1925
296k
      output_data[ data_offset++ ] ^= internal_initialization_vector[ 3 ];
1926
296k
      output_data[ data_offset++ ] ^= internal_initialization_vector[ 4 ];
1927
296k
      output_data[ data_offset++ ] ^= internal_initialization_vector[ 5 ];
1928
296k
      output_data[ data_offset++ ] ^= internal_initialization_vector[ 6 ];
1929
296k
      output_data[ data_offset++ ] ^= internal_initialization_vector[ 7 ];
1930
296k
      output_data[ data_offset++ ] ^= internal_initialization_vector[ 8 ];
1931
296k
      output_data[ data_offset++ ] ^= internal_initialization_vector[ 9 ];
1932
296k
      output_data[ data_offset++ ] ^= internal_initialization_vector[ 10 ];
1933
296k
      output_data[ data_offset++ ] ^= internal_initialization_vector[ 11 ];
1934
296k
      output_data[ data_offset++ ] ^= internal_initialization_vector[ 12 ];
1935
296k
      output_data[ data_offset++ ] ^= internal_initialization_vector[ 13 ];
1936
296k
      output_data[ data_offset++ ] ^= internal_initialization_vector[ 14 ];
1937
296k
      output_data[ data_offset++ ] ^= internal_initialization_vector[ 15 ];
1938
#else
1939
      for( block_index = 0;
1940
           block_index < 16;
1941
           block_index++ )
1942
      {
1943
        output_data[ data_offset++ ] ^= internal_initialization_vector[ block_index ];
1944
      }
1945
#endif
1946
296k
      data_offset -= 16;
1947
1948
296k
      if( memory_copy(
1949
296k
           internal_initialization_vector,
1950
296k
           &( input_data[ data_offset ] ),
1951
296k
           16 ) == NULL )
1952
0
      {
1953
0
        libcerror_error_set(
1954
0
         error,
1955
0
         LIBCERROR_ERROR_DOMAIN_MEMORY,
1956
0
         LIBCERROR_MEMORY_ERROR_COPY_FAILED,
1957
0
         "%s: unable to copy enrypted input data to initialization vector.",
1958
0
         function );
1959
1960
0
        goto on_error;
1961
0
      }
1962
296k
    }
1963
296k
    data_offset += 16;
1964
296k
    }
1965
9.86k
  if( memory_set(
1966
9.86k
       internal_initialization_vector,
1967
9.86k
       0,
1968
9.86k
       16 ) == NULL )
1969
0
  {
1970
0
    libcerror_error_set(
1971
0
     error,
1972
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
1973
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
1974
0
     "%s: unable to clear initialization vector.",
1975
0
     function );
1976
1977
0
    goto on_error;
1978
0
  }
1979
9.86k
  return( 1 );
1980
1981
0
on_error:
1982
0
  memory_set(
1983
0
   internal_initialization_vector,
1984
0
   0,
1985
0
   16 );
1986
1987
0
  return( -1 );
1988
9.86k
}
1989
1990
#endif /* defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_AES_H ) && defined( HAVE_AES_CBC_ENCRYPT ) */
1991
1992
/* De- or encrypts a block of data using AES-CCM (Counter with CBC-MAC)
1993
 * Note that the key must be set in encryption mode (LIBCAES_CRYPT_MODE_ENCRYPT) for both de- and encryption.
1994
 *
1995
 * WARNING: this function does not implement RFC 3610 compliant AES-CCM
1996
 * This function is deprecated use libcaes_crypt_ccm_ctr_only instead.
1997
 *
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
72
{
2011
72
  uint8_t block_data[ 16 ];
2012
72
  uint8_t internal_initialization_vector[ 16 ];
2013
2014
72
  static char *function      = "libcaes_crypt_ccm";
2015
72
  size_t data_offset         = 0;
2016
72
  size_t remaining_data_size = 0;
2017
72
  uint8_t block_index        = 0;
2018
2019
72
  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
72
  if( ( mode != LIBCAES_CRYPT_MODE_DECRYPT )
2031
72
   && ( 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
72
  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
72
  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
72
  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
72
  if( ( input_data_size < 16 )
2076
65
   || ( input_data_size > (size_t) SSIZE_MAX ) )
2077
7
  {
2078
7
    libcerror_error_set(
2079
7
     error,
2080
7
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2081
7
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
2082
7
     "%s: invalid input data size value out of bounds.",
2083
7
     function );
2084
2085
7
    return( -1 );
2086
7
  }
2087
65
  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
65
  if( ( output_data_size < input_data_size )
2099
18
   || ( output_data_size > (size_t) SSIZE_MAX ) )
2100
47
  {
2101
47
    libcerror_error_set(
2102
47
     error,
2103
47
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2104
47
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
2105
47
     "%s: invalid output data size value out of bounds.",
2106
47
     function );
2107
2108
47
    return( -1 );
2109
47
  }
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
18
  if( memory_set(
2116
18
       internal_initialization_vector,
2117
18
       0,
2118
18
       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
18
  if( memory_copy(
2130
18
       &( internal_initialization_vector[ 1 ] ),
2131
18
       nonce,
2132
18
       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
18
  internal_initialization_vector[ 0 ] = 15 - (uint8_t) nonce_size - 1;
2144
2145
18
  if( memory_copy(
2146
18
       output_data,
2147
18
       input_data,
2148
18
       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
52
  while( data_offset <= ( input_data_size - 16 ) )
2160
34
  {
2161
34
    if( libcaes_crypt_ecb(
2162
34
         context,
2163
34
         LIBCAES_CRYPT_MODE_ENCRYPT,
2164
34
         internal_initialization_vector,
2165
34
         16,
2166
34
         block_data,
2167
34
         16,
2168
34
         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
34
#if defined( LIBCAES_UNFOLLED_LOOPS )
2180
34
    output_data[ data_offset++ ] ^= block_data[ 0 ];
2181
34
    output_data[ data_offset++ ] ^= block_data[ 1 ];
2182
34
    output_data[ data_offset++ ] ^= block_data[ 2 ];
2183
34
    output_data[ data_offset++ ] ^= block_data[ 3 ];
2184
34
    output_data[ data_offset++ ] ^= block_data[ 4 ];
2185
34
    output_data[ data_offset++ ] ^= block_data[ 5 ];
2186
34
    output_data[ data_offset++ ] ^= block_data[ 6 ];
2187
34
    output_data[ data_offset++ ] ^= block_data[ 7 ];
2188
34
    output_data[ data_offset++ ] ^= block_data[ 8 ];
2189
34
    output_data[ data_offset++ ] ^= block_data[ 9 ];
2190
34
    output_data[ data_offset++ ] ^= block_data[ 10 ];
2191
34
    output_data[ data_offset++ ] ^= block_data[ 11 ];
2192
34
    output_data[ data_offset++ ] ^= block_data[ 12 ];
2193
34
    output_data[ data_offset++ ] ^= block_data[ 13 ];
2194
34
    output_data[ data_offset++ ] ^= block_data[ 14 ];
2195
34
    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
34
    internal_initialization_vector[ 15 ] += 1;
2205
34
  }
2206
18
  if( data_offset < input_data_size )
2207
14
  {
2208
14
    remaining_data_size = input_data_size - data_offset;
2209
2210
14
    if( libcaes_crypt_ecb(
2211
14
         context,
2212
14
         LIBCAES_CRYPT_MODE_ENCRYPT,
2213
14
         internal_initialization_vector,
2214
14
         16,
2215
14
         block_data,
2216
14
         16,
2217
14
         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
14
    for( block_index = 0;
2229
114
         block_index < (uint8_t) remaining_data_size;
2230
100
         block_index++ )
2231
100
    {
2232
100
      output_data[ data_offset++ ] ^= block_data[ block_index ];
2233
100
    }
2234
14
  }
2235
18
  if( memory_set(
2236
18
       block_data,
2237
18
       0,
2238
18
       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
18
  if( memory_set(
2250
18
       internal_initialization_vector,
2251
18
       0,
2252
18
       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
18
  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
18
}
2278
2279
/* De- or encrypts a block of data using only the Counter (CTR) mode of AES-CCM (Counter with CBC-MAC)
2280
 * Note that the key must be set in encryption mode (LIBCAES_CRYPT_MODE_ENCRYPT) for both de- and encryption.
2281
 * Returns 1 if successful or -1 on error
2282
 */
2283
int libcaes_crypt_ccm_ctr_only(
2284
     libcaes_context_t *context,
2285
     int mode,
2286
     const uint8_t *nonce,
2287
     size_t nonce_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
1.33k
{
2294
1.33k
  uint8_t block_data[ 16 ];
2295
1.33k
  uint8_t internal_initialization_vector[ 16 ];
2296
2297
1.33k
  static char *function      = "libcaes_crypt_ccm_ctr_only";
2298
1.33k
  size_t data_offset         = 0;
2299
1.33k
  size_t remaining_data_size = 0;
2300
1.33k
  uint8_t block_index        = 0;
2301
1.33k
  uint8_t l_prime            = 0;
2302
2303
1.33k
  if( context == NULL )
2304
0
  {
2305
0
    libcerror_error_set(
2306
0
     error,
2307
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2308
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2309
0
     "%s: invalid context.",
2310
0
     function );
2311
2312
0
    return( -1 );
2313
0
  }
2314
1.33k
  if( ( mode != LIBCAES_CRYPT_MODE_DECRYPT )
2315
0
   && ( mode != LIBCAES_CRYPT_MODE_ENCRYPT ) )
2316
0
  {
2317
0
    libcerror_error_set(
2318
0
     error,
2319
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2320
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
2321
0
     "%s: unsupported mode.",
2322
0
     function );
2323
2324
0
    return( -1 );
2325
0
  }
2326
1.33k
  if( nonce == NULL )
2327
0
  {
2328
0
    libcerror_error_set(
2329
0
     error,
2330
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2331
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2332
0
     "%s: invalid nonce.",
2333
0
     function );
2334
2335
0
    return( -1 );
2336
0
  }
2337
1.33k
  if( nonce_size >= (size_t) 15 )
2338
0
  {
2339
0
    libcerror_error_set(
2340
0
     error,
2341
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2342
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
2343
0
     "%s: invalid nonce size value out of bounds.",
2344
0
     function );
2345
2346
0
    return( -1 );
2347
0
  }
2348
1.33k
  if( input_data == NULL )
2349
0
  {
2350
0
    libcerror_error_set(
2351
0
     error,
2352
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2353
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2354
0
     "%s: invalid input data.",
2355
0
     function );
2356
2357
0
    return( -1 );
2358
0
  }
2359
1.33k
  if( ( input_data_size < 16 )
2360
1.32k
   || ( input_data_size > (size_t) SSIZE_MAX ) )
2361
5
  {
2362
5
    libcerror_error_set(
2363
5
     error,
2364
5
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2365
5
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
2366
5
     "%s: invalid input data size value out of bounds.",
2367
5
     function );
2368
2369
5
    return( -1 );
2370
5
  }
2371
1.32k
  if( output_data == NULL )
2372
0
  {
2373
0
    libcerror_error_set(
2374
0
     error,
2375
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2376
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2377
0
     "%s: invalid output data.",
2378
0
     function );
2379
2380
0
    return( -1 );
2381
0
  }
2382
1.32k
  if( ( output_data_size < input_data_size )
2383
1.32k
   || ( output_data_size > (size_t) SSIZE_MAX ) )
2384
0
  {
2385
0
    libcerror_error_set(
2386
0
     error,
2387
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2388
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
2389
0
     "%s: invalid output data size value out of bounds.",
2390
0
     function );
2391
2392
0
    return( -1 );
2393
0
  }
2394
1.32k
  l_prime = 15 - (uint8_t) nonce_size - 1;
2395
2396
  /* The IV consists of:
2397
   * 1 byte size value formatted as: 15 - nonce size - 1
2398
   * a maximum of 14 bytes containing nonce bytes
2399
   * 1 byte counter
2400
   */
2401
1.32k
  if( memory_set(
2402
1.32k
       internal_initialization_vector,
2403
1.32k
       0,
2404
1.32k
       16 ) == NULL )
2405
0
  {
2406
0
    libcerror_error_set(
2407
0
     error,
2408
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
2409
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
2410
0
     "%s: unable to clear initialization vector.",
2411
0
     function );
2412
2413
0
    goto on_error;
2414
0
  }
2415
1.32k
  internal_initialization_vector[ 0 ] = l_prime;
2416
2417
1.32k
  if( memory_copy(
2418
1.32k
       &( internal_initialization_vector[ 1 ] ),
2419
1.32k
       nonce,
2420
1.32k
       nonce_size ) == NULL )
2421
0
  {
2422
0
    libcerror_error_set(
2423
0
     error,
2424
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
2425
0
     LIBCERROR_MEMORY_ERROR_COPY_FAILED,
2426
0
     "%s: unable to copy nonce to initialization vector.",
2427
0
     function );
2428
2429
0
    goto on_error;
2430
0
  }
2431
1.32k
  if( memory_copy(
2432
1.32k
       output_data,
2433
1.32k
       input_data,
2434
1.32k
       input_data_size ) == NULL )
2435
0
  {
2436
0
    libcerror_error_set(
2437
0
     error,
2438
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
2439
0
     LIBCERROR_MEMORY_ERROR_COPY_FAILED,
2440
0
     "%s: unable to copy input data to output data.",
2441
0
     function );
2442
2443
0
    goto on_error;
2444
0
  }
2445
13.9k
  while( data_offset <= ( input_data_size - 16 ) )
2446
12.6k
  {
2447
12.6k
    internal_initialization_vector[ 15 ] += 1;
2448
2449
12.6k
    if( libcaes_crypt_ecb(
2450
12.6k
         context,
2451
12.6k
         LIBCAES_CRYPT_MODE_ENCRYPT,
2452
12.6k
         internal_initialization_vector,
2453
12.6k
         16,
2454
12.6k
         block_data,
2455
12.6k
         16,
2456
12.6k
         error ) != 1 )
2457
0
    {
2458
0
      libcerror_error_set(
2459
0
       error,
2460
0
       LIBCERROR_ERROR_DOMAIN_ENCRYPTION,
2461
0
       LIBCERROR_ENCRYPTION_ERROR_ENCRYPT_FAILED,
2462
0
       "%s: unable to encrypt initialization vector.",
2463
0
       function );
2464
2465
0
      goto on_error;
2466
0
    }
2467
12.6k
#if defined( LIBCAES_UNFOLLED_LOOPS )
2468
12.6k
    output_data[ data_offset++ ] ^= block_data[ 0 ];
2469
12.6k
    output_data[ data_offset++ ] ^= block_data[ 1 ];
2470
12.6k
    output_data[ data_offset++ ] ^= block_data[ 2 ];
2471
12.6k
    output_data[ data_offset++ ] ^= block_data[ 3 ];
2472
12.6k
    output_data[ data_offset++ ] ^= block_data[ 4 ];
2473
12.6k
    output_data[ data_offset++ ] ^= block_data[ 5 ];
2474
12.6k
    output_data[ data_offset++ ] ^= block_data[ 6 ];
2475
12.6k
    output_data[ data_offset++ ] ^= block_data[ 7 ];
2476
12.6k
    output_data[ data_offset++ ] ^= block_data[ 8 ];
2477
12.6k
    output_data[ data_offset++ ] ^= block_data[ 9 ];
2478
12.6k
    output_data[ data_offset++ ] ^= block_data[ 10 ];
2479
12.6k
    output_data[ data_offset++ ] ^= block_data[ 11 ];
2480
12.6k
    output_data[ data_offset++ ] ^= block_data[ 12 ];
2481
12.6k
    output_data[ data_offset++ ] ^= block_data[ 13 ];
2482
12.6k
    output_data[ data_offset++ ] ^= block_data[ 14 ];
2483
12.6k
    output_data[ data_offset++ ] ^= block_data[ 15 ];
2484
#else
2485
    for( block_index = 0;
2486
         block_index < 16;
2487
         block_index++ )
2488
    {
2489
      output_data[ data_offset++ ] ^= block_data[ block_index ];
2490
    }
2491
#endif
2492
12.6k
  }
2493
1.32k
  if( data_offset < input_data_size )
2494
1.14k
  {
2495
1.14k
    remaining_data_size = input_data_size - data_offset;
2496
2497
1.14k
    internal_initialization_vector[ 15 ] += 1;
2498
2499
1.14k
    if( libcaes_crypt_ecb(
2500
1.14k
         context,
2501
1.14k
         LIBCAES_CRYPT_MODE_ENCRYPT,
2502
1.14k
         internal_initialization_vector,
2503
1.14k
         16,
2504
1.14k
         block_data,
2505
1.14k
         16,
2506
1.14k
         error ) != 1 )
2507
0
    {
2508
0
      libcerror_error_set(
2509
0
       error,
2510
0
       LIBCERROR_ERROR_DOMAIN_ENCRYPTION,
2511
0
       LIBCERROR_ENCRYPTION_ERROR_ENCRYPT_FAILED,
2512
0
       "%s: unable to encrypt initialization vector.",
2513
0
       function );
2514
2515
0
      goto on_error;
2516
0
    }
2517
1.14k
    for( block_index = 0;
2518
8.33k
         block_index < (uint8_t) remaining_data_size;
2519
7.18k
         block_index++ )
2520
7.18k
    {
2521
7.18k
      output_data[ data_offset++ ] ^= block_data[ block_index ];
2522
7.18k
    }
2523
1.14k
  }
2524
1.32k
  if( memory_set(
2525
1.32k
       block_data,
2526
1.32k
       0,
2527
1.32k
       16 ) == NULL )
2528
0
  {
2529
0
    libcerror_error_set(
2530
0
     error,
2531
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
2532
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
2533
0
     "%s: unable to clear block data.",
2534
0
     function );
2535
2536
0
    goto on_error;
2537
0
  }
2538
1.32k
  if( memory_set(
2539
1.32k
       internal_initialization_vector,
2540
1.32k
       0,
2541
1.32k
       16 ) == NULL )
2542
0
  {
2543
0
    libcerror_error_set(
2544
0
     error,
2545
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
2546
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
2547
0
     "%s: unable to clear initialization vector.",
2548
0
     function );
2549
2550
0
    goto on_error;
2551
0
  }
2552
1.32k
  return( 1 );
2553
2554
0
on_error:
2555
0
  memory_set(
2556
0
   block_data,
2557
0
   0,
2558
0
   16 );
2559
2560
0
  memory_set(
2561
0
   internal_initialization_vector,
2562
0
   0,
2563
0
   16 );
2564
2565
0
  return( -1 );
2566
1.32k
}
2567
2568
/* De- or encrypts a block of data using AES-CFB (Cipher Feedback Mode)
2569
 * Note that the key must be set with mode LIBCAES_CRYPT_MODE_ENCRYPT
2570
 * Returns 1 if successful or -1 on error
2571
 */
2572
int libcaes_crypt_cfb(
2573
     libcaes_context_t *context,
2574
     int mode,
2575
     const uint8_t *initialization_vector,
2576
     size_t initialization_vector_size,
2577
     const uint8_t *input_data,
2578
     size_t input_data_size,
2579
     uint8_t *output_data,
2580
     size_t output_data_size,
2581
     libcerror_error_t **error )
2582
0
{
2583
0
  uint8_t internal_initialization_vector[ 16 ];
2584
2585
0
  static char *function              = "libcaes_crypt_cfb";
2586
0
  size_t data_offset                 = 0;
2587
0
  size_t initialization_vector_index = 0;
2588
0
  uint8_t byte_value                 = 0;
2589
2590
0
  if( ( mode != LIBCAES_CRYPT_MODE_DECRYPT )
2591
0
   && ( mode != LIBCAES_CRYPT_MODE_ENCRYPT ) )
2592
0
  {
2593
0
    libcerror_error_set(
2594
0
     error,
2595
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2596
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
2597
0
     "%s: unsupported mode.",
2598
0
     function );
2599
2600
0
    return( -1 );
2601
0
  }
2602
0
  if( initialization_vector == NULL )
2603
0
  {
2604
0
    libcerror_error_set(
2605
0
     error,
2606
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2607
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2608
0
     "%s: invalid initialization vector.",
2609
0
     function );
2610
2611
0
    return( -1 );
2612
0
  }
2613
0
  if( initialization_vector_size != 16 )
2614
0
  {
2615
0
    libcerror_error_set(
2616
0
     error,
2617
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2618
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
2619
0
     "%s: invalid initialization vector size value out of bounds.",
2620
0
     function );
2621
2622
0
    return( -1 );
2623
0
  }
2624
0
  if( input_data == NULL )
2625
0
  {
2626
0
    libcerror_error_set(
2627
0
     error,
2628
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2629
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2630
0
     "%s: invalid input data.",
2631
0
     function );
2632
2633
0
    return( -1 );
2634
0
  }
2635
  /* Check if the input data size is a multitude of 16-byte
2636
   */
2637
0
  if( ( ( input_data_size & (size_t) 0x0f ) != 0 )
2638
0
   || ( input_data_size < 16 )
2639
0
   || ( input_data_size > (size_t) SSIZE_MAX ) )
2640
0
  {
2641
0
    libcerror_error_set(
2642
0
     error,
2643
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2644
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
2645
0
     "%s: invalid input data size value out of bounds.",
2646
0
     function );
2647
2648
0
    return( -1 );
2649
0
  }
2650
0
  if( output_data == NULL )
2651
0
  {
2652
0
    libcerror_error_set(
2653
0
     error,
2654
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2655
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2656
0
     "%s: invalid output data.",
2657
0
     function );
2658
2659
0
    return( -1 );
2660
0
  }
2661
0
  if( ( output_data_size < input_data_size )
2662
0
   || ( output_data_size > (size_t) SSIZE_MAX ) )
2663
0
  {
2664
0
    libcerror_error_set(
2665
0
     error,
2666
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2667
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
2668
0
     "%s: invalid output data size value out of bounds.",
2669
0
     function );
2670
2671
0
    return( -1 );
2672
0
  }
2673
0
  if( memory_copy(
2674
0
       internal_initialization_vector,
2675
0
       initialization_vector,
2676
0
       16 ) == NULL )
2677
0
  {
2678
0
    libcerror_error_set(
2679
0
     error,
2680
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
2681
0
     LIBCERROR_MEMORY_ERROR_COPY_FAILED,
2682
0
     "%s: unable to copy initialization vector.",
2683
0
     function );
2684
2685
0
    goto on_error;
2686
0
  }
2687
0
  initialization_vector_index = 16;
2688
2689
0
  for( data_offset = 0;
2690
0
       data_offset < input_data_size;
2691
0
       data_offset++ )
2692
0
  {
2693
0
    if( initialization_vector_index > 15 )
2694
0
    {
2695
0
      if( libcaes_crypt_ecb(
2696
0
           context,
2697
0
           LIBCAES_CRYPT_MODE_ENCRYPT,
2698
0
           internal_initialization_vector,
2699
0
           initialization_vector_size,
2700
0
           internal_initialization_vector,
2701
0
           initialization_vector_size,
2702
0
           error ) != 1 )
2703
0
      {
2704
0
        libcerror_error_set(
2705
0
         error,
2706
0
         LIBCERROR_ERROR_DOMAIN_ENCRYPTION,
2707
0
         LIBCERROR_ENCRYPTION_ERROR_GENERIC,
2708
0
         "%s: unable to de/encrypt initialization vector.",
2709
0
         function );
2710
2711
0
        goto on_error;
2712
0
      }
2713
0
      initialization_vector_index = 0;
2714
0
    }
2715
0
    output_data[ data_offset ] = input_data[ data_offset ] ^ internal_initialization_vector[ initialization_vector_index ];
2716
2717
0
    if( mode == LIBCAES_CRYPT_MODE_ENCRYPT )
2718
0
    {
2719
0
      byte_value = output_data[ data_offset ];
2720
0
    }
2721
0
    else
2722
0
    {
2723
0
      byte_value = input_data[ data_offset ];
2724
0
    }
2725
0
    internal_initialization_vector[ initialization_vector_index++ ] = byte_value;
2726
0
  }
2727
0
  if( memory_set(
2728
0
       internal_initialization_vector,
2729
0
       0,
2730
0
       16 ) == NULL )
2731
0
  {
2732
0
    libcerror_error_set(
2733
0
     error,
2734
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
2735
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
2736
0
     "%s: unable to clear initialization vector.",
2737
0
     function );
2738
2739
0
    goto on_error;
2740
0
  }
2741
0
  return( 1 );
2742
2743
0
on_error:
2744
0
  memory_set(
2745
0
   internal_initialization_vector,
2746
0
   0,
2747
0
   16 );
2748
2749
0
  return( -1 );
2750
0
}
2751
2752
#if defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_AES_H ) && defined( HAVE_AES_ECB_ENCRYPT )
2753
2754
/* De- or encrypts a block of data using AES-ECB (Electronic CodeBook) using OpenSSL
2755
 * The size must be a multitude of the AES block size (16 byte)
2756
 * Returns 1 if successful or -1 on error
2757
 */
2758
int libcaes_crypt_ecb(
2759
     libcaes_context_t *context,
2760
     int mode,
2761
     const uint8_t *input_data,
2762
     size_t input_data_size,
2763
     uint8_t *output_data,
2764
     size_t output_data_size,
2765
     libcerror_error_t **error )
2766
{
2767
  libcaes_internal_context_t *internal_context = NULL;
2768
  static char *function                        = "libcaes_crypt_ecb";
2769
  int result                                   = 1;
2770
  int safe_mode                                = 0;
2771
2772
  if( context == NULL )
2773
  {
2774
    libcerror_error_set(
2775
     error,
2776
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2777
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2778
     "%s: invalid context.",
2779
     function );
2780
2781
    return( -1 );
2782
  }
2783
  internal_context = (libcaes_internal_context_t *) context;
2784
2785
  if( ( mode != LIBCAES_CRYPT_MODE_DECRYPT )
2786
   && ( mode != LIBCAES_CRYPT_MODE_ENCRYPT ) )
2787
  {
2788
    libcerror_error_set(
2789
     error,
2790
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2791
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
2792
     "%s: unsupported mode.",
2793
     function );
2794
2795
    return( -1 );
2796
  }
2797
  if( input_data == NULL )
2798
  {
2799
    libcerror_error_set(
2800
     error,
2801
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2802
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2803
     "%s: invalid input data.",
2804
     function );
2805
2806
    return( -1 );
2807
  }
2808
  if( ( input_data_size < 16 )
2809
   || ( input_data_size > (size_t) SSIZE_MAX ) )
2810
  {
2811
    libcerror_error_set(
2812
     error,
2813
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2814
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
2815
     "%s: invalid input data size value out of bounds.",
2816
     function );
2817
2818
    return( -1 );
2819
  }
2820
  if( output_data == NULL )
2821
  {
2822
    libcerror_error_set(
2823
     error,
2824
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2825
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2826
     "%s: invalid output data.",
2827
     function );
2828
2829
    return( -1 );
2830
  }
2831
  if( ( output_data_size < input_data_size )
2832
   || ( output_data_size > (size_t) SSIZE_MAX ) )
2833
  {
2834
    libcerror_error_set(
2835
     error,
2836
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2837
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
2838
     "%s: invalid output data size value out of bounds.",
2839
     function );
2840
2841
    return( -1 );
2842
  }
2843
  if( mode == LIBCAES_CRYPT_MODE_ENCRYPT )
2844
  {
2845
    safe_mode = AES_ENCRYPT;
2846
  }
2847
  else
2848
  {
2849
    safe_mode = AES_DECRYPT;
2850
  }
2851
  AES_ecb_encrypt(
2852
   (unsigned char *) input_data,
2853
   (unsigned char *) output_data,
2854
   &( internal_context->key ),
2855
   safe_mode );
2856
2857
  return( result );
2858
}
2859
2860
#elif defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_EVP_H ) && defined( HAVE_EVP_CRYPTO_AES_ECB )
2861
2862
/* De- or encrypts a block of data using AES-ECB (Electronic CodeBook) using OpenSSL EVP
2863
 * The size must be a multitude of the AES block size (16 byte)
2864
 * Returns 1 if successful or -1 on error
2865
 */
2866
int libcaes_crypt_ecb(
2867
     libcaes_context_t *context,
2868
     int mode,
2869
     const uint8_t *input_data,
2870
     size_t input_data_size,
2871
     uint8_t *output_data,
2872
     size_t output_data_size,
2873
     libcerror_error_t **error )
2874
{
2875
  uint8_t block_data[ EVP_MAX_BLOCK_LENGTH ];
2876
  char error_string[ 256 ];
2877
2878
#if defined( HAVE_EVP_CIPHERINIT_EX2 )
2879
  OSSL_PARAM parameters[2];
2880
2881
  EVP_CIPHER *cipher                           = NULL;
2882
  const char *cipher_string                    = NULL;
2883
  unsigned int padding                         = 0;
2884
#else
2885
  const EVP_CIPHER *cipher                     = NULL;
2886
#endif
2887
2888
  libcaes_internal_context_t *internal_context = NULL;
2889
  static char *function                        = "libcaes_crypt_ecb";
2890
  unsigned long error_code                     = 0;
2891
  int safe_output_data_size                    = 0;
2892
2893
  if( context == NULL )
2894
  {
2895
    libcerror_error_set(
2896
     error,
2897
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2898
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2899
     "%s: invalid context.",
2900
     function );
2901
2902
    return( -1 );
2903
  }
2904
  internal_context = (libcaes_internal_context_t *) context;
2905
2906
  if( ( internal_context->key_bit_size != 128 )
2907
   && ( internal_context->key_bit_size != 192 )
2908
   && ( internal_context->key_bit_size != 256 ) )
2909
  {
2910
    libcerror_error_set(
2911
     error,
2912
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2913
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
2914
     "%s: invalid context - unsupported key bit size.",
2915
     function );
2916
2917
    return( -1 );
2918
  }
2919
  if( ( mode != LIBCAES_CRYPT_MODE_DECRYPT )
2920
   && ( mode != LIBCAES_CRYPT_MODE_ENCRYPT ) )
2921
  {
2922
    libcerror_error_set(
2923
     error,
2924
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2925
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
2926
     "%s: unsupported mode.",
2927
     function );
2928
2929
    return( -1 );
2930
  }
2931
  if( input_data == NULL )
2932
  {
2933
    libcerror_error_set(
2934
     error,
2935
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2936
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2937
     "%s: invalid input data.",
2938
     function );
2939
2940
    return( -1 );
2941
  }
2942
  if( ( input_data_size < 16 )
2943
   || ( input_data_size > (size_t) INT_MAX ) )
2944
  {
2945
    libcerror_error_set(
2946
     error,
2947
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2948
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
2949
     "%s: invalid input data size value out of bounds.",
2950
     function );
2951
2952
    return( -1 );
2953
  }
2954
  if( output_data == NULL )
2955
  {
2956
    libcerror_error_set(
2957
     error,
2958
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2959
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2960
     "%s: invalid output data.",
2961
     function );
2962
2963
    return( -1 );
2964
  }
2965
  if( ( output_data_size < input_data_size )
2966
   || ( output_data_size > (size_t) INT_MAX ) )
2967
  {
2968
    libcerror_error_set(
2969
     error,
2970
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2971
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
2972
     "%s: invalid output data size value out of bounds.",
2973
     function );
2974
2975
    return( -1 );
2976
  }
2977
  if( memory_set(
2978
       block_data,
2979
       0,
2980
       EVP_MAX_BLOCK_LENGTH ) == NULL )
2981
  {
2982
    libcerror_error_set(
2983
     error,
2984
     LIBCERROR_ERROR_DOMAIN_MEMORY,
2985
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
2986
     "%s: unable to clear block data.",
2987
     function );
2988
2989
    goto on_error;
2990
  }
2991
#if defined( HAVE_EVP_CIPHERINIT_EX2 )
2992
  if( EVP_CIPHER_CTX_reset(
2993
       internal_context->evp_cipher_context ) != 1 )
2994
  {
2995
    error_code = ERR_get_error();
2996
2997
    ERR_error_string_n(
2998
     error_code,
2999
     error_string,
3000
     256 );
3001
3002
    libcerror_error_set(
3003
     error,
3004
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3005
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
3006
     "%s: unable to reset cipher context with error: %s.",
3007
     function,
3008
     error_string );
3009
3010
    goto on_error;
3011
  }
3012
  if( internal_context->key_bit_size == 128 )
3013
  {
3014
    cipher_string = "AES-128-ECB";
3015
  }
3016
  else if( internal_context->key_bit_size == 192 )
3017
  {
3018
    cipher_string = "AES-192-ECB";
3019
  }
3020
  else if( internal_context->key_bit_size == 256 )
3021
  {
3022
    cipher_string = "AES-256-ECB";
3023
  }
3024
  cipher = EVP_CIPHER_fetch(
3025
            NULL,
3026
            cipher_string,
3027
            NULL );
3028
3029
  if( cipher == NULL )
3030
  {
3031
    libcerror_error_set(
3032
     error,
3033
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3034
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
3035
     "%s: missing cipher.",
3036
     function );
3037
3038
    goto on_error;
3039
  }
3040
  parameters[0] = OSSL_PARAM_construct_uint(
3041
                   OSSL_CIPHER_PARAM_PADDING,
3042
                   &padding );
3043
3044
  parameters[1] = OSSL_PARAM_construct_end();
3045
3046
  if( EVP_CipherInit_ex2(
3047
       internal_context->evp_cipher_context,
3048
       cipher,
3049
       (unsigned char *) internal_context->key,
3050
       NULL,
3051
       mode,
3052
       parameters ) != 1 )
3053
  {
3054
    error_code = ERR_get_error();
3055
3056
    ERR_error_string_n(
3057
     error_code,
3058
     error_string,
3059
     256 );
3060
3061
    libcerror_error_set(
3062
     error,
3063
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3064
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
3065
     "%s: unable to initialize cipher with error: %s.",
3066
     function,
3067
     error_string );
3068
3069
    goto on_error;
3070
  }
3071
#else
3072
  if( internal_context->key_bit_size == 128 )
3073
  {
3074
    cipher = EVP_aes_128_ecb();
3075
  }
3076
  else if( internal_context->key_bit_size == 192 )
3077
  {
3078
    cipher = EVP_aes_192_ecb();
3079
  }
3080
  else if( internal_context->key_bit_size == 256 )
3081
  {
3082
    cipher = EVP_aes_256_ecb();
3083
  }
3084
  if( EVP_CipherInit_ex(
3085
       internal_context->evp_cipher_context,
3086
       cipher,
3087
       NULL,
3088
       (unsigned char *) internal_context->key,
3089
       NULL,
3090
       mode ) != 1 )
3091
  {
3092
    error_code = ERR_get_error();
3093
3094
    ERR_error_string_n(
3095
     error_code,
3096
     error_string,
3097
     256 );
3098
3099
    libcerror_error_set(
3100
     error,
3101
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3102
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
3103
     "%s: unable to initialize cipher with error: %s.",
3104
     function,
3105
     error_string );
3106
3107
    goto on_error;
3108
  }
3109
  if( EVP_CIPHER_CTX_set_padding(
3110
       internal_context->evp_cipher_context,
3111
       1 ) != 1 )
3112
  {
3113
    error_code = ERR_get_error();
3114
3115
    ERR_error_string_n(
3116
     error_code,
3117
     error_string,
3118
     256 );
3119
3120
    libcerror_error_set(
3121
     error,
3122
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3123
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3124
     "%s: unable to set padding in context with error: %s.",
3125
     function,
3126
     error_string );
3127
3128
    goto on_error;
3129
  }
3130
#endif /* defined( HAVE_EVP_CIPHERINIT_EX2 ) */
3131
3132
  if( EVP_CipherUpdate(
3133
       internal_context->evp_cipher_context,
3134
       (unsigned char *) output_data,
3135
       &safe_output_data_size,
3136
       (unsigned char *) input_data,
3137
       16 ) != 1 )
3138
  {
3139
    error_code = ERR_get_error();
3140
3141
    ERR_error_string_n(
3142
     error_code,
3143
     error_string,
3144
     256 );
3145
3146
    libcerror_error_set(
3147
     error,
3148
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3149
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3150
     "%s: unable to update cipher with error: %s.",
3151
     function,
3152
     error_string );
3153
3154
    goto on_error;
3155
  }
3156
  /* Just ignore the output of this function
3157
   */
3158
  EVP_CipherFinal_ex(
3159
   internal_context->evp_cipher_context,
3160
   (unsigned char *) block_data,
3161
   &safe_output_data_size );
3162
3163
#if defined( HAVE_EVP_CIPHERINIT_EX2 )
3164
  EVP_CIPHER_free(
3165
   cipher );
3166
#endif
3167
  return( 1 );
3168
3169
on_error:
3170
#if defined( HAVE_EVP_CIPHERINIT_EX2 )
3171
  if( cipher != NULL )
3172
  {
3173
    EVP_CIPHER_free(
3174
     cipher );
3175
  }
3176
#endif
3177
  return( -1 );
3178
}
3179
3180
#else
3181
3182
/* De- or encrypts a block of data using AES-ECB (Electronic CodeBook) using fallback implementation
3183
 * The size must be a multitude of the AES block size (16 byte)
3184
 * Returns 1 if successful or -1 on error
3185
 */
3186
int libcaes_crypt_ecb(
3187
     libcaes_context_t *context,
3188
     int mode,
3189
     const uint8_t *input_data,
3190
     size_t input_data_size,
3191
     uint8_t *output_data,
3192
     size_t output_data_size,
3193
     libcerror_error_t **error )
3194
172
{
3195
172
  uint32_t cipher_values_32bit[ 4 ];
3196
172
  uint32_t values_32bit[ 4 ];
3197
3198
172
  libcaes_internal_context_t *internal_context = NULL;
3199
172
  uint32_t *round_keys                         = NULL;
3200
172
  static char *function                        = "libcaes_crypt_ecb";
3201
172
  size_t data_offset                           = 0;
3202
172
  uint32_t substitution_value                  = 0;
3203
172
  uint32_t table_value                         = 0;
3204
172
  int result                                   = 1;
3205
172
  int round_key_iterator                       = 0;
3206
3207
172
  if( context == NULL )
3208
0
  {
3209
0
    libcerror_error_set(
3210
0
     error,
3211
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3212
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3213
0
     "%s: invalid context.",
3214
0
     function );
3215
3216
0
    return( -1 );
3217
0
  }
3218
172
  internal_context = (libcaes_internal_context_t *) context;
3219
3220
172
  if( internal_context->round_keys == NULL )
3221
0
  {
3222
0
    libcerror_error_set(
3223
0
     error,
3224
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3225
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
3226
0
     "%s: invalid context - missing round keys.",
3227
0
     function );
3228
3229
0
    return( -1 );
3230
0
  }
3231
172
  if( ( mode != LIBCAES_CRYPT_MODE_DECRYPT )
3232
172
   && ( mode != LIBCAES_CRYPT_MODE_ENCRYPT ) )
3233
0
  {
3234
0
    libcerror_error_set(
3235
0
     error,
3236
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3237
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
3238
0
     "%s: unsupported mode.",
3239
0
     function );
3240
3241
0
    return( -1 );
3242
0
  }
3243
172
  if( input_data == NULL )
3244
0
  {
3245
0
    libcerror_error_set(
3246
0
     error,
3247
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3248
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3249
0
     "%s: invalid input data.",
3250
0
     function );
3251
3252
0
    return( -1 );
3253
0
  }
3254
  /* Check if the input data size is a multitude of 16-byte
3255
   */
3256
172
  if( ( ( input_data_size & (size_t) 0x0f ) != 0 )
3257
167
   || ( input_data_size < 16 )
3258
167
   || ( input_data_size > (size_t) SSIZE_MAX ) )
3259
5
  {
3260
5
    libcerror_error_set(
3261
5
     error,
3262
5
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3263
5
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
3264
5
     "%s: invalid input data size value out of bounds.",
3265
5
     function );
3266
3267
5
    return( -1 );
3268
5
  }
3269
167
  if( output_data == NULL )
3270
0
  {
3271
0
    libcerror_error_set(
3272
0
     error,
3273
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3274
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3275
0
     "%s: invalid output data.",
3276
0
     function );
3277
3278
0
    return( -1 );
3279
0
  }
3280
167
  if( ( output_data_size < input_data_size )
3281
122
   || ( output_data_size > (size_t) SSIZE_MAX ) )
3282
45
  {
3283
45
    libcerror_error_set(
3284
45
     error,
3285
45
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3286
45
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
3287
45
     "%s: invalid output data size value out of bounds.",
3288
45
     function );
3289
3290
45
    return( -1 );
3291
45
  }
3292
250
  while( data_offset < input_data_size )
3293
128
  {
3294
128
    byte_stream_copy_to_uint32_little_endian(
3295
128
     &( input_data[ data_offset ] ),
3296
128
     values_32bit[ 0 ] );
3297
3298
128
    byte_stream_copy_to_uint32_little_endian(
3299
128
     &( input_data[ data_offset + 4 ] ),
3300
128
     values_32bit[ 1 ] );
3301
3302
128
    byte_stream_copy_to_uint32_little_endian(
3303
128
     &( input_data[ data_offset + 8 ] ),
3304
128
     values_32bit[ 2 ] );
3305
3306
128
    byte_stream_copy_to_uint32_little_endian(
3307
128
     &( input_data[ data_offset + 12 ] ),
3308
128
     values_32bit[ 3 ] );
3309
3310
128
    round_keys = internal_context->round_keys;
3311
3312
128
    values_32bit[ 0 ] ^= round_keys[ 0 ];
3313
128
    values_32bit[ 1 ] ^= round_keys[ 1 ];
3314
128
    values_32bit[ 2 ] ^= round_keys[ 2 ];
3315
128
    values_32bit[ 3 ] ^= round_keys[ 3 ];
3316
3317
128
    round_keys += 4;
3318
3319
128
    if( mode == LIBCAES_CRYPT_MODE_ENCRYPT )
3320
128
    {
3321
128
      for( round_key_iterator = ( internal_context->number_of_round_keys / 2 );
3322
640
           round_key_iterator > 1;
3323
512
           round_key_iterator-- )
3324
512
      {
3325
512
        libcaes_calculate_forward_table_round(
3326
512
         round_keys,
3327
512
         cipher_values_32bit,
3328
512
         values_32bit,
3329
512
         table_value );
3330
3331
512
        round_keys += 4;
3332
3333
512
        libcaes_calculate_forward_table_round(
3334
512
         round_keys,
3335
512
         values_32bit,
3336
512
         cipher_values_32bit,
3337
512
         table_value );
3338
3339
512
        round_keys += 4;
3340
512
      }
3341
128
      libcaes_calculate_forward_table_round(
3342
128
       round_keys,
3343
128
       cipher_values_32bit,
3344
128
       values_32bit,
3345
128
       table_value );
3346
3347
128
      round_keys += 4;
3348
3349
128
      libcaes_calculate_forward_substitution_round(
3350
128
       round_keys,
3351
128
       values_32bit,
3352
128
       cipher_values_32bit,
3353
128
       substitution_value );
3354
128
    }
3355
0
    else
3356
0
    {
3357
0
      for( round_key_iterator = ( internal_context->number_of_round_keys / 2 );
3358
0
           round_key_iterator > 1;
3359
0
           round_key_iterator-- )
3360
0
      {
3361
0
        libcaes_calculate_reverse_table_round(
3362
0
         round_keys,
3363
0
         cipher_values_32bit,
3364
0
         values_32bit,
3365
0
         table_value );
3366
3367
0
        round_keys += 4;
3368
3369
0
        libcaes_calculate_reverse_table_round(
3370
0
         round_keys,
3371
0
         values_32bit,
3372
0
         cipher_values_32bit,
3373
0
         table_value );
3374
3375
0
        round_keys += 4;
3376
0
      }
3377
0
      libcaes_calculate_reverse_table_round(
3378
0
       round_keys,
3379
0
       cipher_values_32bit,
3380
0
       values_32bit,
3381
0
       table_value );
3382
3383
0
      round_keys += 4;
3384
3385
0
      libcaes_calculate_reverse_substitution_round(
3386
0
       round_keys,
3387
0
       values_32bit,
3388
0
       cipher_values_32bit,
3389
0
       table_value );
3390
0
    }
3391
128
    byte_stream_copy_from_uint32_little_endian(
3392
128
     &( output_data[ data_offset ] ),
3393
128
     values_32bit[ 0 ] );
3394
3395
128
    byte_stream_copy_from_uint32_little_endian(
3396
128
     &( output_data[ data_offset + 4 ] ),
3397
128
     values_32bit[ 1 ] );
3398
3399
128
    byte_stream_copy_from_uint32_little_endian(
3400
128
     &( output_data[ data_offset + 8 ] ),
3401
128
     values_32bit[ 2 ] );
3402
3403
128
    byte_stream_copy_from_uint32_little_endian(
3404
128
     &( output_data[ data_offset + 12 ] ),
3405
128
     values_32bit[ 3 ] );
3406
3407
128
    if( memory_set(
3408
128
         values_32bit,
3409
128
         0,
3410
128
         sizeof( uint32_t ) * 4 ) == NULL )
3411
0
    {
3412
0
      libcerror_error_set(
3413
0
       error,
3414
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
3415
0
       LIBCERROR_MEMORY_ERROR_SET_FAILED,
3416
0
       "%s: unable to clear values 32-bit.",
3417
0
       function );
3418
3419
0
      result = -1;
3420
0
    }
3421
128
    if( memory_set(
3422
128
         cipher_values_32bit,
3423
128
         0,
3424
128
         sizeof( uint32_t ) * 4 ) == NULL )
3425
0
    {
3426
0
      libcerror_error_set(
3427
0
       error,
3428
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
3429
0
       LIBCERROR_MEMORY_ERROR_SET_FAILED,
3430
0
       "%s: unable to clear cipher values 32-bit.",
3431
0
       function );
3432
3433
0
      result = -1;
3434
0
    }
3435
128
    data_offset += 16;
3436
128
  }
3437
122
  return( result );
3438
167
}
3439
3440
#endif /* defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_AES_H ) && defined( HAVE_AES_ECB_ENCRYPT ) */
3441