Coverage Report

Created: 2024-02-25 07:20

/src/libfsapfs/libcaes/libcaes_tweaked_context.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * AES encryption functions
3
 *
4
 * Copyright (C) 2011-2024, Joachim Metz <joachim.metz@gmail.com>
5
 *
6
 * Refer to AUTHORS for acknowledgements.
7
 *
8
 * This program is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU Lesser General Public License as published by
10
 * the Free Software Foundation, either version 3 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public License
19
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20
 */
21
22
#include <common.h>
23
#include <byte_stream.h>
24
#include <memory.h>
25
#include <types.h>
26
27
#if defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_EVP_H )
28
#include <openssl/err.h>
29
#include <openssl/evp.h>
30
#endif
31
32
#if defined( HAVE_EVP_CIPHERINIT_EX2 )
33
#include <openssl/core_names.h>
34
#endif
35
36
#include "libcaes_context.h"
37
#include "libcaes_definitions.h"
38
#include "libcaes_libcerror.h"
39
#include "libcaes_tweaked_context.h"
40
#include "libcaes_types.h"
41
42
/* Creates a tweaked context
43
 * Make sure the value context is referencing, is set to NULL
44
 * Returns 1 if successful or -1 on error
45
 */
46
int libcaes_tweaked_context_initialize(
47
     libcaes_tweaked_context_t **tweaked_context,
48
     libcerror_error_t **error )
49
709
{
50
709
  libcaes_internal_tweaked_context_t *internal_tweaked_context = NULL;
51
709
  static char *function                                        = "libcaes_tweaked_context_initialize";
52
53
#if defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_EVP_H ) && defined( HAVE_EVP_CRYPTO_AES_XTS )
54
  char error_string[ 256 ];
55
56
  unsigned long error_code                                     = 0;
57
#endif
58
59
709
  if( tweaked_context == NULL )
60
0
  {
61
0
    libcerror_error_set(
62
0
     error,
63
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
64
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
65
0
     "%s: invalid tweaked context.",
66
0
     function );
67
68
0
    return( -1 );
69
0
  }
70
709
  if( *tweaked_context != NULL )
71
0
  {
72
0
    libcerror_error_set(
73
0
     error,
74
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
75
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
76
0
     "%s: invalid tweaked context value already set.",
77
0
     function );
78
79
0
    return( -1 );
80
0
  }
81
709
  internal_tweaked_context = memory_allocate_structure(
82
709
                              libcaes_internal_tweaked_context_t );
83
84
709
  if( internal_tweaked_context == NULL )
85
0
  {
86
0
    libcerror_error_set(
87
0
     error,
88
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
89
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
90
0
     "%s: unable to create tweaked context.",
91
0
     function );
92
93
0
    goto on_error;
94
0
  }
95
709
  if( memory_set(
96
709
       internal_tweaked_context,
97
709
       0,
98
709
       sizeof( libcaes_internal_tweaked_context_t ) ) == NULL )
99
0
  {
100
0
    libcerror_error_set(
101
0
     error,
102
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
103
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
104
0
     "%s: unable to clear tweaked context.",
105
0
     function );
106
107
0
    memory_free(
108
0
     internal_tweaked_context );
109
110
0
    return( -1 );
111
0
  }
112
#if defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_EVP_H ) && defined( HAVE_EVP_CRYPTO_AES_XTS )
113
#if defined( HAVE_EVP_CIPHER_CTX_INIT )
114
  EVP_CIPHER_CTX_init(
115
   &( internal_tweaked_context->internal_evp_cipher_context ) );
116
117
  internal_tweaked_context->evp_cipher_context = &( internal_tweaked_context->internal_evp_cipher_context );
118
#else
119
  internal_tweaked_context->evp_cipher_context = EVP_CIPHER_CTX_new();
120
121
  if( internal_tweaked_context->evp_cipher_context == NULL )
122
  {
123
    error_code = ERR_get_error();
124
125
    ERR_error_string_n(
126
     error_code,
127
     error_string,
128
     256 );
129
130
    libcerror_error_set(
131
     error,
132
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
133
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
134
     "%s: unable to create EVP cipher context with error: %s.",
135
     function,
136
     error_string );
137
138
    goto on_error;
139
  }
140
#endif /* defined( HAVE_EVP_CIPHER_CTX_INIT ) */
141
#else
142
709
  if( libcaes_context_initialize(
143
709
       &( internal_tweaked_context->main_context ),
144
709
       error ) != 1)
145
0
  {
146
0
    libcerror_error_set(
147
0
     error,
148
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
149
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
150
0
     "%s: unable to initialize main context.",
151
0
     function );
152
153
0
    goto on_error;
154
0
  }
155
709
  if( libcaes_context_initialize(
156
709
       &( internal_tweaked_context->tweak_context ),
157
709
       error ) != 1)
158
0
  {
159
0
    libcerror_error_set(
160
0
     error,
161
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
162
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
163
0
     "%s: unable to initialize tweak context.",
164
0
     function );
165
166
0
    goto on_error;
167
0
  }
168
709
#endif /* defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_EVP_H ) && defined( HAVE_EVP_CRYPTO_AES_XTS ) */
169
170
709
  *tweaked_context = (libcaes_tweaked_context_t *) internal_tweaked_context;
171
172
709
  return( 1 );
173
174
0
on_error:
175
0
  if( internal_tweaked_context != NULL )
176
0
  {
177
#if defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_EVP_H ) && defined( HAVE_EVP_CRYPTO_AES_XTS )
178
    /* No additional clean up necessary */
179
180
#else
181
0
    if( internal_tweaked_context->main_context != NULL )
182
0
    {
183
0
      libcaes_context_free(
184
0
       &( internal_tweaked_context->main_context ),
185
0
       NULL );
186
0
    }
187
0
#endif /* defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_EVP_H ) && defined( HAVE_EVP_CRYPTO_AES_XTS ) */
188
189
0
    memory_free(
190
0
     internal_tweaked_context );
191
0
  }
192
0
  return( -1 );
193
709
}
194
195
/* Frees a tweaked context
196
 * Returns 1 if successful or -1 on error
197
 */
198
int libcaes_tweaked_context_free(
199
     libcaes_tweaked_context_t **tweaked_context,
200
     libcerror_error_t **error )
201
709
{
202
709
  libcaes_internal_tweaked_context_t *internal_tweaked_context = NULL;
203
709
  static char *function                                        = "libcaes_tweaked_context_free";
204
709
  int result                                                   = 1;
205
206
#if defined( HAVE_LIBCRYPTO ) && defined( HAVE_EVP_CIPHER_CTX_CLEANUP )
207
  char error_string[ 256 ];
208
209
  unsigned long error_code                                     = 0;
210
#endif
211
212
709
  if( tweaked_context == NULL )
213
0
  {
214
0
    libcerror_error_set(
215
0
     error,
216
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
217
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
218
0
     "%s: invalid tweaked context.",
219
0
     function );
220
221
0
    return( -1 );
222
0
  }
223
709
  if( *tweaked_context != NULL )
224
709
  {
225
709
    internal_tweaked_context = (libcaes_internal_tweaked_context_t *) *tweaked_context;
226
709
    *tweaked_context         = NULL;
227
228
#if defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_EVP_H ) && defined( HAVE_EVP_CRYPTO_AES_XTS )
229
#if defined( HAVE_EVP_CIPHER_CTX_CLEANUP )
230
    if( EVP_CIPHER_CTX_cleanup(
231
         &( internal_tweaked_context->internal_evp_cipher_context ) ) != 1 )
232
    {
233
      error_code = ERR_get_error();
234
235
      ERR_error_string_n(
236
       error_code,
237
       error_string,
238
       256 );
239
240
      libcerror_error_set(
241
       error,
242
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
243
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
244
       "%s: unable to clean up EVP cipher context with error: %s.",
245
       function,
246
       error_string );
247
248
      result = -1;
249
    }
250
    /* Make sure the error state is removed otherwise OpenSSL will leak memory
251
     */
252
    ERR_remove_thread_state(
253
     NULL );
254
#else
255
    EVP_CIPHER_CTX_free(
256
     internal_tweaked_context->evp_cipher_context );
257
258
#endif /* defined( HAVE_EVP_CIPHER_CTX_CLEANUP ) */
259
260
    internal_tweaked_context->evp_cipher_context = NULL;
261
#else
262
709
    if( libcaes_context_free(
263
709
         &( internal_tweaked_context->tweak_context ),
264
709
         error ) != 1 )
265
0
    {
266
0
      libcerror_error_set(
267
0
       error,
268
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
269
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
270
0
       "%s: unable to free tweak context.",
271
0
       function );
272
273
0
      result = -1;
274
0
    }
275
709
    if( libcaes_context_free(
276
709
         &( internal_tweaked_context->main_context ),
277
709
         error ) != 1 )
278
0
    {
279
0
      libcerror_error_set(
280
0
       error,
281
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
282
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
283
0
       "%s: unable to free main context.",
284
0
       function );
285
286
0
      result = -1;
287
0
    }
288
709
#endif /* defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_EVP_H ) && defined( HAVE_EVP_CRYPTO_AES_XTS ) */
289
290
709
    memory_free(
291
709
     internal_tweaked_context );
292
709
  }
293
709
  return( result );
294
709
}
295
296
/* Sets the keys
297
 * Returns 1 if successful or -1 on error
298
 */
299
int libcaes_tweaked_context_set_keys(
300
     libcaes_tweaked_context_t *tweaked_context,
301
     int mode,
302
     const uint8_t *key,
303
     size_t key_bit_size,
304
     const uint8_t *tweak_key,
305
     size_t tweak_key_bit_size,
306
     libcerror_error_t **error )
307
709
{
308
709
  libcaes_internal_tweaked_context_t *internal_tweaked_context = NULL;
309
709
  static char *function                                        = "libcaes_tweaked_context_set_key";
310
311
#if defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_EVP_H ) && defined( HAVE_EVP_CRYPTO_AES_XTS )
312
  size_t key_byte_size                                         = 0;
313
#endif
314
315
709
  if( tweaked_context == NULL )
316
0
  {
317
0
    libcerror_error_set(
318
0
     error,
319
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
320
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
321
0
     "%s: invalid tweaked context.",
322
0
     function );
323
324
0
    return( -1 );
325
0
  }
326
709
  internal_tweaked_context = (libcaes_internal_tweaked_context_t *) tweaked_context;
327
328
709
  if( ( mode != LIBCAES_CRYPT_MODE_DECRYPT )
329
709
   && ( mode != LIBCAES_CRYPT_MODE_ENCRYPT ) )
330
0
  {
331
0
    libcerror_error_set(
332
0
     error,
333
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
334
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
335
0
     "%s: unsupported mode.",
336
0
     function );
337
338
0
    return( -1 );
339
0
  }
340
709
  if( ( key_bit_size != 128 )
341
709
   && ( key_bit_size != 256 ) )
342
0
  {
343
0
    libcerror_error_set(
344
0
     error,
345
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
346
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
347
0
     "%s: unsupported key bit size.",
348
0
     function );
349
350
0
    return( -1 );
351
0
  }
352
709
  if( tweak_key_bit_size != key_bit_size )
353
0
  {
354
0
    libcerror_error_set(
355
0
     error,
356
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
357
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
358
0
     "%s: unsupported tweak key bit size.",
359
0
     function );
360
361
0
    return( -1 );
362
0
  }
363
#if defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_EVP_H ) && defined( HAVE_EVP_CRYPTO_AES_XTS )
364
  if( key == NULL )
365
  {
366
    libcerror_error_set(
367
     error,
368
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
369
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
370
     "%s: invalid key.",
371
     function );
372
373
    return( -1 );
374
  }
375
  if( tweak_key == NULL )
376
  {
377
    libcerror_error_set(
378
     error,
379
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
380
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
381
     "%s: invalid tweak key.",
382
     function );
383
384
    return( -1 );
385
  }
386
  key_byte_size = key_bit_size / 8;
387
388
  if( memory_copy(
389
       internal_tweaked_context->key,
390
       key,
391
       key_byte_size ) == NULL )
392
  {
393
    libcerror_error_set(
394
     error,
395
     LIBCERROR_ERROR_DOMAIN_MEMORY,
396
     LIBCERROR_MEMORY_ERROR_COPY_FAILED,
397
     "%s: unable to copy key.",
398
     function );
399
400
    return( -1 );
401
  }
402
  if( memory_copy(
403
       &( internal_tweaked_context->key[ key_byte_size ] ),
404
       tweak_key,
405
       key_byte_size ) == NULL )
406
  {
407
    libcerror_error_set(
408
     error,
409
     LIBCERROR_ERROR_DOMAIN_MEMORY,
410
     LIBCERROR_MEMORY_ERROR_COPY_FAILED,
411
     "%s: unable to copy tweak key.",
412
     function );
413
414
    return( -1 );
415
  }
416
  internal_tweaked_context->key_bit_size = key_bit_size;
417
418
#else
419
709
  if( libcaes_context_set_key(
420
709
       internal_tweaked_context->main_context,
421
709
       mode,
422
709
       key,
423
709
       key_bit_size,
424
709
       error ) != 1 )
425
0
  {
426
0
    libcerror_error_set(
427
0
     error,
428
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
429
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
430
0
     "%s: unable to set key in main context.",
431
0
     function );
432
433
0
    return( -1 );
434
0
  }
435
709
  if( libcaes_context_set_key(
436
709
       internal_tweaked_context->tweak_context,
437
709
       LIBCAES_CRYPT_MODE_ENCRYPT,
438
709
       tweak_key,
439
709
       tweak_key_bit_size,
440
709
       error ) != 1 )
441
0
  {
442
0
    libcerror_error_set(
443
0
     error,
444
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
445
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
446
0
     "%s: unable to set tweak key in tweak context.",
447
0
     function );
448
449
0
    return( -1 );
450
0
  }
451
709
#endif /* defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_EVP_H ) && defined( HAVE_EVP_CRYPTO_AES_XTS ) */
452
453
709
  return( 1 );
454
709
}
455
456
#if defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_EVP_H ) && defined( HAVE_EVP_CRYPTO_AES_XTS )
457
458
/* De- or encrypts a block of data using AES-XTS (XEX-based tweaked-codebook mode with ciphertext stealing) using OpenSSL EVP
459
 * The size must be a multitude of the AES block size (16 byte)
460
 * Returns 1 if successful or -1 on error
461
 */
462
int libcaes_crypt_xts(
463
     libcaes_tweaked_context_t *tweaked_context,
464
     int mode,
465
     const uint8_t *tweak_value,
466
     size_t tweak_value_size,
467
     const uint8_t *input_data,
468
     size_t input_data_size,
469
     uint8_t *output_data,
470
     size_t output_data_size,
471
     libcerror_error_t **error )
472
{
473
  uint8_t block_data[ EVP_MAX_BLOCK_LENGTH ];
474
  char error_string[ 256 ];
475
476
#if defined( HAVE_EVP_CIPHERINIT_EX2 )
477
  OSSL_PARAM parameters[2];
478
479
  EVP_CIPHER *cipher                                           = NULL;
480
  const char *cipher_string                                    = NULL;
481
  unsigned int padding                                         = 0;
482
#else
483
  const EVP_CIPHER *cipher                                     = NULL;
484
#endif
485
486
  libcaes_internal_tweaked_context_t *internal_tweaked_context = NULL;
487
  static char *function                                        = "libcaes_crypt_xts";
488
  unsigned long error_code                                     = 0;
489
  int safe_output_data_size                                    = 0;
490
491
  if( tweaked_context == NULL )
492
  {
493
    libcerror_error_set(
494
     error,
495
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
496
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
497
     "%s: invalid tweaked context.",
498
     function );
499
500
    return( -1 );
501
  }
502
  internal_tweaked_context = (libcaes_internal_tweaked_context_t *) tweaked_context;
503
504
  if( ( mode != LIBCAES_CRYPT_MODE_DECRYPT )
505
   && ( mode != LIBCAES_CRYPT_MODE_ENCRYPT ) )
506
  {
507
    libcerror_error_set(
508
     error,
509
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
510
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
511
     "%s: unsupported mode.",
512
     function );
513
514
    return( -1 );
515
  }
516
  if( tweak_value == NULL )
517
  {
518
    libcerror_error_set(
519
     error,
520
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
521
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
522
     "%s: invalid tweak value.",
523
     function );
524
525
    return( -1 );
526
  }
527
  if( tweak_value_size != 16 )
528
  {
529
    libcerror_error_set(
530
     error,
531
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
532
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
533
     "%s: invalid tweak value size value out of bounds.",
534
     function );
535
536
    return( -1 );
537
  }
538
  if( input_data == NULL )
539
  {
540
    libcerror_error_set(
541
     error,
542
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
543
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
544
     "%s: invalid input data.",
545
     function );
546
547
    return( -1 );
548
  }
549
  if( input_data_size > (size_t) INT_MAX )
550
  {
551
    libcerror_error_set(
552
     error,
553
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
554
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
555
     "%s: invalid input data size value exceeds maximum.",
556
     function );
557
558
    return( -1 );
559
  }
560
  if( input_data_size < 16 )
561
  {
562
    libcerror_error_set(
563
     error,
564
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
565
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
566
     "%s: invalid input data size value too small.",
567
     function );
568
569
    return( -1 );
570
  }
571
  if( output_data == NULL )
572
  {
573
    libcerror_error_set(
574
     error,
575
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
576
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
577
     "%s: invalid output data.",
578
     function );
579
580
    return( -1 );
581
  }
582
  if( output_data_size > (size_t) INT_MAX )
583
  {
584
    libcerror_error_set(
585
     error,
586
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
587
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
588
     "%s: invalid output data size value exceeds maximum.",
589
     function );
590
591
    return( -1 );
592
  }
593
  if( output_data_size < input_data_size )
594
  {
595
    libcerror_error_set(
596
     error,
597
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
598
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
599
     "%s: invalid ouput data size smaller than input data size.",
600
     function );
601
602
    return( -1 );
603
  }
604
  if( memory_set(
605
       block_data,
606
       0,
607
       EVP_MAX_BLOCK_LENGTH ) == NULL )
608
  {
609
    libcerror_error_set(
610
     error,
611
     LIBCERROR_ERROR_DOMAIN_MEMORY,
612
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
613
     "%s: unable to clear input block data.",
614
     function );
615
616
    goto on_error;
617
  }
618
#if defined( HAVE_EVP_CIPHERINIT_EX2 )
619
  if( EVP_CIPHER_CTX_reset(
620
       internal_tweaked_context->evp_cipher_context ) != 1 )
621
  {
622
    error_code = ERR_get_error();
623
624
    ERR_error_string_n(
625
     error_code,
626
     error_string,
627
     256 );
628
629
    libcerror_error_set(
630
     error,
631
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
632
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
633
     "%s: unable to reset cipher context with error: %s.",
634
     function,
635
     error_string );
636
637
    goto on_error;
638
  }
639
  if( internal_tweaked_context->key_bit_size == 128 )
640
  {
641
    cipher_string = "AES-128-XTS";
642
  }
643
  else if( internal_tweaked_context->key_bit_size == 256 )
644
  {
645
    cipher_string = "AES-256-XTS";
646
  }
647
  cipher = EVP_CIPHER_fetch(
648
            NULL,
649
            cipher_string,
650
            NULL );
651
652
  if( cipher == NULL )
653
  {
654
    libcerror_error_set(
655
     error,
656
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
657
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
658
     "%s: missing cipher.",
659
     function );
660
661
    goto on_error;
662
  }
663
  parameters[0] = OSSL_PARAM_construct_uint(
664
                   OSSL_CIPHER_PARAM_PADDING,
665
                   &padding );
666
667
  parameters[1] = OSSL_PARAM_construct_end();
668
669
  if( EVP_CipherInit_ex2(
670
       internal_tweaked_context->evp_cipher_context,
671
       cipher,
672
       (unsigned char *) internal_tweaked_context->key,
673
       (unsigned char *) tweak_value,
674
       mode,
675
       parameters ) != 1 )
676
  {
677
    error_code = ERR_get_error();
678
679
    ERR_error_string_n(
680
     error_code,
681
     error_string,
682
     256 );
683
684
    libcerror_error_set(
685
     error,
686
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
687
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
688
     "%s: unable to initialize cipher with error: %s.",
689
     function,
690
     error_string );
691
692
    goto on_error;
693
  }
694
#else
695
  if( internal_tweaked_context->key_bit_size == 128 )
696
  {
697
    cipher = EVP_aes_128_xts();
698
  }
699
  else if( internal_tweaked_context->key_bit_size == 256 )
700
  {
701
    cipher = EVP_aes_256_xts();
702
  }
703
  if( EVP_CipherInit_ex(
704
       internal_tweaked_context->evp_cipher_context,
705
       cipher,
706
       NULL,
707
       (unsigned char *) internal_tweaked_context->key,
708
       (unsigned char *) tweak_value,
709
       mode ) != 1 )
710
  {
711
    error_code = ERR_get_error();
712
713
    ERR_error_string_n(
714
     error_code,
715
     error_string,
716
     256 );
717
718
    libcerror_error_set(
719
     error,
720
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
721
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
722
     "%s: unable to initialize cipher with error: %s.",
723
     function,
724
     error_string );
725
726
    goto on_error;
727
  }
728
  if( EVP_CIPHER_CTX_set_padding(
729
       internal_tweaked_context->evp_cipher_context,
730
       1 ) != 1 )
731
  {
732
    error_code = ERR_get_error();
733
734
    ERR_error_string_n(
735
     error_code,
736
     error_string,
737
     256 );
738
739
    libcerror_error_set(
740
     error,
741
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
742
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
743
     "%s: unable to set padding in context with error: %s.",
744
     function,
745
     error_string );
746
747
    goto on_error;
748
  }
749
#endif /* defined( HAVE_EVP_CIPHERINIT_EX2 ) */
750
751
  if( EVP_CipherUpdate(
752
       internal_tweaked_context->evp_cipher_context,
753
       (unsigned char *) output_data,
754
       &safe_output_data_size,
755
       (unsigned char *) input_data,
756
       input_data_size ) != 1 )
757
  {
758
    error_code = ERR_get_error();
759
760
    ERR_error_string_n(
761
     error_code,
762
     error_string,
763
     256 );
764
765
    libcerror_error_set(
766
     error,
767
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
768
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
769
     "%s: unable to update cipher with error: %s.",
770
     function,
771
     error_string );
772
773
    goto on_error;
774
  }
775
  /* Just ignore the output of this function
776
   */
777
  EVP_CipherFinal_ex(
778
   internal_tweaked_context->evp_cipher_context,
779
   (unsigned char *) block_data,
780
   &safe_output_data_size );
781
782
#if defined( HAVE_EVP_CIPHERINIT_EX2 )
783
  EVP_CIPHER_free(
784
   cipher );
785
#endif
786
  return( 1 );
787
788
on_error:
789
#if defined( HAVE_EVP_CIPHERINIT_EX2 )
790
  if( cipher != NULL )
791
  {
792
    EVP_CIPHER_free(
793
     cipher );
794
  }
795
#endif
796
  return( -1 );
797
}
798
799
#else
800
801
/* De- or encrypts a block of data using AES-XTS (XEX-based tweaked-codebook mode with ciphertext stealing) using fallback implementation
802
 * The size must be a multitude of the AES block size (16 byte)
803
 * Returns 1 if successful or -1 on error
804
 */
805
int libcaes_crypt_xts(
806
     libcaes_tweaked_context_t *tweaked_context,
807
     int mode,
808
     const uint8_t *tweak_value,
809
     size_t tweak_value_size,
810
     const uint8_t *input_data,
811
     size_t input_data_size,
812
     uint8_t *output_data,
813
     size_t output_data_size,
814
     libcerror_error_t **error )
815
27.5k
{
816
27.5k
  uint8_t encrypted_tweak_value[ 16 ];
817
27.5k
  uint8_t encrypted_tweak_value_copy[ 16 ];
818
819
27.5k
  libcaes_internal_tweaked_context_t *internal_tweaked_context = NULL;
820
27.5k
  static char *function                                        = "libcaes_crypt_xts";
821
27.5k
  size_t data_offset                                           = 0;
822
27.5k
  size_t remaining_data_size                                   = 0;
823
27.5k
  uint8_t block_index                                          = 0;
824
27.5k
  uint8_t byte_value                                           = 0;
825
27.5k
  uint8_t carry_bit                                            = 0;
826
827
27.5k
  if( tweaked_context == NULL )
828
0
  {
829
0
    libcerror_error_set(
830
0
     error,
831
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
832
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
833
0
     "%s: invalid tweaked context.",
834
0
     function );
835
836
0
    return( -1 );
837
0
  }
838
27.5k
  internal_tweaked_context = (libcaes_internal_tweaked_context_t *) tweaked_context;
839
840
27.5k
  if( ( mode != LIBCAES_CRYPT_MODE_DECRYPT )
841
27.5k
   && ( mode != LIBCAES_CRYPT_MODE_ENCRYPT ) )
842
0
  {
843
0
    libcerror_error_set(
844
0
     error,
845
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
846
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
847
0
     "%s: unsupported mode.",
848
0
     function );
849
850
0
    return( -1 );
851
0
  }
852
27.5k
  if( tweak_value == NULL )
853
0
  {
854
0
    libcerror_error_set(
855
0
     error,
856
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
857
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
858
0
     "%s: invalid tweak value.",
859
0
     function );
860
861
0
    return( -1 );
862
0
  }
863
27.5k
  if( tweak_value_size != 16 )
864
0
  {
865
0
    libcerror_error_set(
866
0
     error,
867
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
868
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
869
0
     "%s: invalid tweak value size value out of bounds.",
870
0
     function );
871
872
0
    return( -1 );
873
0
  }
874
27.5k
  if( input_data == NULL )
875
0
  {
876
0
    libcerror_error_set(
877
0
     error,
878
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
879
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
880
0
     "%s: invalid input data.",
881
0
     function );
882
883
0
    return( -1 );
884
0
  }
885
27.5k
  if( input_data_size < 16 )
886
7
  {
887
7
    libcerror_error_set(
888
7
     error,
889
7
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
890
7
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
891
7
     "%s: invalid input data size value too small.",
892
7
     function );
893
894
7
    return( -1 );
895
7
  }
896
27.5k
  if( input_data_size > (size_t) SSIZE_MAX )
897
0
  {
898
0
    libcerror_error_set(
899
0
     error,
900
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
901
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
902
0
     "%s: invalid input data size value exceeds maximum.",
903
0
     function );
904
905
0
    return( -1 );
906
0
  }
907
27.5k
  if( output_data == NULL )
908
0
  {
909
0
    libcerror_error_set(
910
0
     error,
911
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
912
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
913
0
     "%s: invalid output data.",
914
0
     function );
915
916
0
    return( -1 );
917
0
  }
918
27.5k
  if( output_data_size > (size_t) SSIZE_MAX )
919
0
  {
920
0
    libcerror_error_set(
921
0
     error,
922
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
923
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
924
0
     "%s: invalid output data size value exceeds maximum.",
925
0
     function );
926
927
0
    return( -1 );
928
0
  }
929
27.5k
  if( output_data_size < input_data_size )
930
46
  {
931
46
    libcerror_error_set(
932
46
     error,
933
46
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
934
46
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
935
46
     "%s: invalid ouput data size smaller than input data size.",
936
46
     function );
937
938
46
    return( -1 );
939
46
  }
940
27.5k
  if( libcaes_crypt_ecb(
941
27.5k
       internal_tweaked_context->tweak_context,
942
27.5k
       LIBCAES_CRYPT_MODE_ENCRYPT,
943
27.5k
       tweak_value,
944
27.5k
       16,
945
27.5k
       encrypted_tweak_value,
946
27.5k
       16,
947
27.5k
       error ) != 1 )
948
0
  {
949
0
    libcerror_error_set(
950
0
     error,
951
0
     LIBCERROR_ERROR_DOMAIN_ENCRYPTION,
952
0
     LIBCERROR_ENCRYPTION_ERROR_GENERIC,
953
0
     "%s: unable to encrypt tweak value.",
954
0
     function );
955
956
0
    goto on_error;
957
0
  }
958
27.5k
  if( memory_copy(
959
27.5k
       output_data,
960
27.5k
       input_data,
961
27.5k
       input_data_size ) == NULL )
962
0
  {
963
0
    libcerror_error_set(
964
0
     error,
965
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
966
0
     LIBCERROR_MEMORY_ERROR_COPY_FAILED,
967
0
     "%s: unable to copy input data to output data.",
968
0
     function );
969
970
0
    return( -1 );
971
0
  }
972
27.5k
  remaining_data_size = input_data_size;
973
974
907k
  while( data_offset <= ( input_data_size - 16 ) )
975
880k
  {
976
880k
    if( ( remaining_data_size < 32 )
977
880k
     && ( remaining_data_size != 16 ) )
978
12
    {
979
      /* If the input data size is not a multitude of 16 the remaining data needs to be handled differently
980
       */
981
12
      if( mode == LIBCAES_CRYPT_MODE_DECRYPT )
982
0
      {
983
0
        if( memory_copy(
984
0
             encrypted_tweak_value_copy,
985
0
             encrypted_tweak_value,
986
0
             16 ) == NULL )
987
0
        {
988
0
          libcerror_error_set(
989
0
           error,
990
0
           LIBCERROR_ERROR_DOMAIN_MEMORY,
991
0
           LIBCERROR_MEMORY_ERROR_COPY_FAILED,
992
0
           "%s: unable to copy encrypted tweak value.",
993
0
           function );
994
        
995
0
          goto on_error;
996
0
        }
997
        /* Update the encrypted tweak value for the next 16-byte block
998
         */
999
0
        carry_bit = 0;
1000
1001
0
        for( block_index = 0;
1002
0
             block_index < 16;
1003
0
             block_index++ )
1004
0
        {
1005
0
          byte_value = ( encrypted_tweak_value[ block_index ] << 1 ) | carry_bit;
1006
0
          carry_bit  = encrypted_tweak_value[ block_index ] >> 7;
1007
1008
0
          encrypted_tweak_value[ block_index ] = byte_value;
1009
0
        }
1010
0
        if( carry_bit > 0 )
1011
0
        {
1012
0
          encrypted_tweak_value[ 0 ] ^= 0x87;
1013
0
        }
1014
0
      }
1015
12
    }
1016
880k
#if defined( LIBCAES_UNFOLLED_LOOPS )
1017
880k
    output_data[ data_offset++ ] ^= encrypted_tweak_value[ 0 ];
1018
880k
    output_data[ data_offset++ ] ^= encrypted_tweak_value[ 1 ];
1019
880k
    output_data[ data_offset++ ] ^= encrypted_tweak_value[ 2 ];
1020
880k
    output_data[ data_offset++ ] ^= encrypted_tweak_value[ 3 ];
1021
880k
    output_data[ data_offset++ ] ^= encrypted_tweak_value[ 4 ];
1022
880k
    output_data[ data_offset++ ] ^= encrypted_tweak_value[ 5 ];
1023
880k
    output_data[ data_offset++ ] ^= encrypted_tweak_value[ 6 ];
1024
880k
    output_data[ data_offset++ ] ^= encrypted_tweak_value[ 7 ];
1025
880k
    output_data[ data_offset++ ] ^= encrypted_tweak_value[ 8 ];
1026
880k
    output_data[ data_offset++ ] ^= encrypted_tweak_value[ 9 ];
1027
880k
    output_data[ data_offset++ ] ^= encrypted_tweak_value[ 10 ];
1028
880k
    output_data[ data_offset++ ] ^= encrypted_tweak_value[ 11 ];
1029
880k
    output_data[ data_offset++ ] ^= encrypted_tweak_value[ 12 ];
1030
880k
    output_data[ data_offset++ ] ^= encrypted_tweak_value[ 13 ];
1031
880k
    output_data[ data_offset++ ] ^= encrypted_tweak_value[ 14 ];
1032
880k
    output_data[ data_offset++ ] ^= encrypted_tweak_value[ 15 ];
1033
#else
1034
    for( block_index = 0;
1035
         block_index < 16;
1036
         block_index++ )
1037
    {
1038
      output_data[ data_offset++ ] ^= encrypted_tweak_value[ block_index ];
1039
    }
1040
#endif
1041
880k
    data_offset -= 16;
1042
1043
880k
    if( libcaes_crypt_ecb(
1044
880k
         internal_tweaked_context->main_context,
1045
880k
         mode,
1046
880k
         &( output_data[ data_offset ] ),
1047
880k
         16,
1048
880k
         &( output_data[ data_offset ] ),
1049
880k
         16,
1050
880k
         error ) != 1 )
1051
0
    {
1052
0
      libcerror_error_set(
1053
0
       error,
1054
0
       LIBCERROR_ERROR_DOMAIN_ENCRYPTION,
1055
0
       LIBCERROR_ENCRYPTION_ERROR_GENERIC,
1056
0
       "%s: unable to de/encrypt data.",
1057
0
       function );
1058
1059
0
      goto on_error;
1060
0
    }
1061
880k
#if defined( LIBCAES_UNFOLLED_LOOPS )
1062
880k
    output_data[ data_offset++ ] ^= encrypted_tweak_value[ 0 ];
1063
880k
    output_data[ data_offset++ ] ^= encrypted_tweak_value[ 1 ];
1064
880k
    output_data[ data_offset++ ] ^= encrypted_tweak_value[ 2 ];
1065
880k
    output_data[ data_offset++ ] ^= encrypted_tweak_value[ 3 ];
1066
880k
    output_data[ data_offset++ ] ^= encrypted_tweak_value[ 4 ];
1067
880k
    output_data[ data_offset++ ] ^= encrypted_tweak_value[ 5 ];
1068
880k
    output_data[ data_offset++ ] ^= encrypted_tweak_value[ 6 ];
1069
880k
    output_data[ data_offset++ ] ^= encrypted_tweak_value[ 7 ];
1070
880k
    output_data[ data_offset++ ] ^= encrypted_tweak_value[ 8 ];
1071
880k
    output_data[ data_offset++ ] ^= encrypted_tweak_value[ 9 ];
1072
880k
    output_data[ data_offset++ ] ^= encrypted_tweak_value[ 10 ];
1073
880k
    output_data[ data_offset++ ] ^= encrypted_tweak_value[ 11 ];
1074
880k
    output_data[ data_offset++ ] ^= encrypted_tweak_value[ 12 ];
1075
880k
    output_data[ data_offset++ ] ^= encrypted_tweak_value[ 13 ];
1076
880k
    output_data[ data_offset++ ] ^= encrypted_tweak_value[ 14 ];
1077
880k
    output_data[ data_offset++ ] ^= encrypted_tweak_value[ 15 ];
1078
#else
1079
    for( block_index = 0;
1080
         block_index < 16;
1081
         block_index++ )
1082
    {
1083
      output_data[ data_offset++ ] ^= encrypted_tweak_value[ block_index ];
1084
    }
1085
#endif
1086
880k
    remaining_data_size -= 16;
1087
1088
    /* Update the encrypted tweak value for the next 16-byte block
1089
     */
1090
880k
    carry_bit = 0;
1091
1092
880k
    for( block_index = 0;
1093
14.9M
         block_index < 16;
1094
14.0M
         block_index++ )
1095
14.0M
    {
1096
14.0M
      byte_value = ( encrypted_tweak_value[ block_index ] << 1 ) | carry_bit;
1097
14.0M
      carry_bit  = encrypted_tweak_value[ block_index ] >> 7;
1098
1099
14.0M
      encrypted_tweak_value[ block_index ] = byte_value;
1100
14.0M
    }
1101
880k
    if( carry_bit > 0 )
1102
448k
    {
1103
448k
      encrypted_tweak_value[ 0 ] ^= 0x87;
1104
448k
    }
1105
880k
  }
1106
  /* Any remaining data needs to be handled differently
1107
   */
1108
27.5k
  if( remaining_data_size > 0 )
1109
12
  {
1110
12
    if( mode == LIBCAES_CRYPT_MODE_DECRYPT )
1111
0
    {
1112
0
      if( memory_copy(
1113
0
           encrypted_tweak_value,
1114
0
           encrypted_tweak_value_copy,
1115
0
           16 ) == NULL )
1116
0
      {
1117
0
        libcerror_error_set(
1118
0
         error,
1119
0
         LIBCERROR_ERROR_DOMAIN_MEMORY,
1120
0
         LIBCERROR_MEMORY_ERROR_COPY_FAILED,
1121
0
         "%s: unable to copy encrypted tweak value.",
1122
0
         function );
1123
      
1124
0
        goto on_error;
1125
0
      }
1126
0
      if( memory_set(
1127
0
           encrypted_tweak_value_copy,
1128
0
           0,
1129
0
           16 ) == NULL )
1130
0
      {
1131
0
        libcerror_error_set(
1132
0
         error,
1133
0
         LIBCERROR_ERROR_DOMAIN_MEMORY,
1134
0
         LIBCERROR_MEMORY_ERROR_SET_FAILED,
1135
0
         "%s: unable to clear encrypted tweak value copy.",
1136
0
         function );
1137
1138
0
        goto on_error;
1139
0
      }
1140
0
    }
1141
    /* Swap the data of the last 16-byte block with the remaining data
1142
     */
1143
12
    data_offset -= 16;
1144
1145
12
    if( memory_copy(
1146
12
         &( output_data[ data_offset + 16 ] ),
1147
12
         &( output_data[ data_offset ] ),
1148
12
         remaining_data_size ) == NULL )
1149
0
    {
1150
0
      libcerror_error_set(
1151
0
       error,
1152
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
1153
0
       LIBCERROR_MEMORY_ERROR_COPY_FAILED,
1154
0
       "%s: unable to copy remaining output data.",
1155
0
       function );
1156
1157
0
      goto on_error;
1158
0
    }
1159
12
    if( memory_copy(
1160
12
         &( output_data[ data_offset ] ),
1161
12
         &( input_data[ data_offset + 16 ] ),
1162
12
         remaining_data_size ) == NULL )
1163
0
    {
1164
0
      libcerror_error_set(
1165
0
       error,
1166
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
1167
0
       LIBCERROR_MEMORY_ERROR_COPY_FAILED,
1168
0
       "%s: unable to copy input data to block data.",
1169
0
       function );
1170
1171
0
      goto on_error;
1172
0
    }
1173
12
#if defined( LIBCAES_UNFOLLED_LOOPS )
1174
12
    output_data[ data_offset++ ] ^= encrypted_tweak_value[ 0 ];
1175
12
    output_data[ data_offset++ ] ^= encrypted_tweak_value[ 1 ];
1176
12
    output_data[ data_offset++ ] ^= encrypted_tweak_value[ 2 ];
1177
12
    output_data[ data_offset++ ] ^= encrypted_tweak_value[ 3 ];
1178
12
    output_data[ data_offset++ ] ^= encrypted_tweak_value[ 4 ];
1179
12
    output_data[ data_offset++ ] ^= encrypted_tweak_value[ 5 ];
1180
12
    output_data[ data_offset++ ] ^= encrypted_tweak_value[ 6 ];
1181
12
    output_data[ data_offset++ ] ^= encrypted_tweak_value[ 7 ];
1182
12
    output_data[ data_offset++ ] ^= encrypted_tweak_value[ 8 ];
1183
12
    output_data[ data_offset++ ] ^= encrypted_tweak_value[ 9 ];
1184
12
    output_data[ data_offset++ ] ^= encrypted_tweak_value[ 10 ];
1185
12
    output_data[ data_offset++ ] ^= encrypted_tweak_value[ 11 ];
1186
12
    output_data[ data_offset++ ] ^= encrypted_tweak_value[ 12 ];
1187
12
    output_data[ data_offset++ ] ^= encrypted_tweak_value[ 13 ];
1188
12
    output_data[ data_offset++ ] ^= encrypted_tweak_value[ 14 ];
1189
12
    output_data[ data_offset++ ] ^= encrypted_tweak_value[ 15 ];
1190
#else
1191
    for( block_index = 0;
1192
         block_index < 16;
1193
         block_index++ )
1194
    {
1195
      output_data[ data_offset++ ] ^= encrypted_tweak_value[ block_index ];
1196
    }
1197
#endif
1198
12
    data_offset -= 16;
1199
1200
12
    if( libcaes_crypt_ecb(
1201
12
         internal_tweaked_context->main_context,
1202
12
         mode,
1203
12
         &( output_data[ data_offset ] ),
1204
12
         16,
1205
12
         &( output_data[ data_offset ] ),
1206
12
         16,
1207
12
         error ) != 1 )
1208
0
    {
1209
0
      libcerror_error_set(
1210
0
       error,
1211
0
       LIBCERROR_ERROR_DOMAIN_ENCRYPTION,
1212
0
       LIBCERROR_ENCRYPTION_ERROR_GENERIC,
1213
0
       "%s: unable to de/encrypt data.",
1214
0
       function );
1215
1216
0
      goto on_error;
1217
0
    }
1218
12
#if defined( LIBCAES_UNFOLLED_LOOPS )
1219
12
    output_data[ data_offset++ ] ^= encrypted_tweak_value[ 0 ];
1220
12
    output_data[ data_offset++ ] ^= encrypted_tweak_value[ 1 ];
1221
12
    output_data[ data_offset++ ] ^= encrypted_tweak_value[ 2 ];
1222
12
    output_data[ data_offset++ ] ^= encrypted_tweak_value[ 3 ];
1223
12
    output_data[ data_offset++ ] ^= encrypted_tweak_value[ 4 ];
1224
12
    output_data[ data_offset++ ] ^= encrypted_tweak_value[ 5 ];
1225
12
    output_data[ data_offset++ ] ^= encrypted_tweak_value[ 6 ];
1226
12
    output_data[ data_offset++ ] ^= encrypted_tweak_value[ 7 ];
1227
12
    output_data[ data_offset++ ] ^= encrypted_tweak_value[ 8 ];
1228
12
    output_data[ data_offset++ ] ^= encrypted_tweak_value[ 9 ];
1229
12
    output_data[ data_offset++ ] ^= encrypted_tweak_value[ 10 ];
1230
12
    output_data[ data_offset++ ] ^= encrypted_tweak_value[ 11 ];
1231
12
    output_data[ data_offset++ ] ^= encrypted_tweak_value[ 12 ];
1232
12
    output_data[ data_offset++ ] ^= encrypted_tweak_value[ 13 ];
1233
12
    output_data[ data_offset++ ] ^= encrypted_tweak_value[ 14 ];
1234
12
    output_data[ data_offset++ ] ^= encrypted_tweak_value[ 15 ];
1235
#else
1236
    for( block_index = 0;
1237
         block_index < 16;
1238
         block_index++ )
1239
    {
1240
      output_data[ data_offset++ ] ^= encrypted_tweak_value[ block_index ];
1241
    }
1242
#endif
1243
12
  }
1244
27.5k
  if( memory_set(
1245
27.5k
       encrypted_tweak_value,
1246
27.5k
       0,
1247
27.5k
       16 ) == NULL )
1248
0
  {
1249
0
    libcerror_error_set(
1250
0
     error,
1251
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
1252
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
1253
0
     "%s: unable to clear encrypted tweak value.",
1254
0
     function );
1255
1256
0
    goto on_error;
1257
0
  }
1258
27.5k
  return( 1 );
1259
1260
0
on_error:
1261
0
  memory_set(
1262
0
   encrypted_tweak_value_copy,
1263
0
   0,
1264
0
   16 );
1265
1266
0
  memory_set(
1267
0
   encrypted_tweak_value,
1268
0
   0,
1269
0
   16 );
1270
1271
0
  return( -1 );
1272
27.5k
}
1273
1274
#endif /* defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_EVP_H ) && defined( HAVE_EVP_CRYPTO_AES_XTS ) */
1275