Coverage Report

Created: 2026-05-30 07:13

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libfvde/libfvde/libfvde_encryption_context.c
Line
Count
Source
1
/*
2
 * Encryption functions
3
 *
4
 * Copyright (C) 2011-2026, Omar Choudary <choudary.omar@gmail.com>
5
 *                          Joachim Metz <joachim.metz@gmail.com>
6
 *
7
 * Refer to AUTHORS for acknowledgements.
8
 *
9
 * This program is free software: you can redistribute it and/or modify
10
 * it under the terms of the GNU Lesser General Public License as published by
11
 * the Free Software Foundation, either version 3 of the License, or
12
 * (at your option) any later version.
13
 *
14
 * This program is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 * GNU General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU Lesser General Public License
20
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
21
 */
22
23
#include <common.h>
24
#include <byte_stream.h>
25
#include <memory.h>
26
#include <types.h>
27
28
#include "libfvde_definitions.h"
29
#include "libfvde_encryption_context.h"
30
#include "libfvde_libcaes.h"
31
#include "libfvde_libcerror.h"
32
#include "libfvde_libcnotify.h"
33
34
/* Creates an encryption context
35
 * Make sure the value encryption context is referencing, is set to NULL
36
 * Returns 1 if successful or -1 on error
37
 */
38
int libfvde_encryption_context_initialize(
39
     libfvde_encryption_context_t **context,
40
     uint32_t method,
41
     libcerror_error_t **error )
42
0
{
43
0
  static char *function = "libfvde_encryption_context_initialize";
44
45
0
  if( context == NULL )
46
0
  {
47
0
    libcerror_error_set(
48
0
     error,
49
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
50
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
51
0
     "%s: invalid context.",
52
0
     function );
53
54
0
    return( -1 );
55
0
  }
56
0
  if( *context != NULL )
57
0
  {
58
0
    libcerror_error_set(
59
0
     error,
60
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
61
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
62
0
     "%s: invalid context value already set.",
63
0
     function );
64
65
0
    return( -1 );
66
0
  }
67
0
  if( method != LIBFVDE_ENCRYPTION_METHOD_AES_128_XTS )
68
0
  {
69
0
    libcerror_error_set(
70
0
     error,
71
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
72
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
73
0
     "%s: unsupported method.",
74
0
     function );
75
76
0
    return( -1 );
77
0
  }
78
0
  *context = memory_allocate_structure(
79
0
              libfvde_encryption_context_t );
80
81
0
  if( *context == NULL )
82
0
  {
83
0
    libcerror_error_set(
84
0
     error,
85
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
86
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
87
0
     "%s: unable to create context.",
88
0
     function );
89
90
0
    goto on_error;
91
0
  }
92
0
  if( memory_set(
93
0
       *context,
94
0
       0,
95
0
       sizeof( libfvde_encryption_context_t ) ) == NULL )
96
0
  {
97
0
    libcerror_error_set(
98
0
     error,
99
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
100
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
101
0
     "%s: unable to clear context.",
102
0
     function );
103
104
0
    memory_free(
105
0
     *context );
106
107
0
    *context = NULL;
108
109
0
    return( -1 );
110
0
  }
111
0
  if( libcaes_tweaked_context_initialize(
112
0
       &( ( *context )->decryption_context ),
113
0
       error ) != 1 )
114
0
  {
115
0
    libcerror_error_set(
116
0
     error,
117
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
118
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
119
0
     "%s: unable to initialize decryption context.",
120
0
     function );
121
122
0
    goto on_error;
123
0
  }
124
0
  ( *context )->method = method;
125
126
0
  return( 1 );
127
128
0
on_error:
129
0
  if( *context != NULL )
130
0
  {
131
0
    if( ( *context )->decryption_context != NULL )
132
0
    {
133
0
      libcaes_tweaked_context_free(
134
0
       &( ( *context )->decryption_context ),
135
0
       NULL );
136
0
    }
137
0
    memory_free(
138
0
     *context );
139
140
0
    *context = NULL;
141
0
  }
142
0
  return( -1 );
143
0
}
144
145
/* Frees an encryption context
146
 * Returns 1 if successful or -1 on error
147
 */
148
int libfvde_encryption_context_free(
149
     libfvde_encryption_context_t **context,
150
     libcerror_error_t **error )
151
0
{
152
0
  static char *function = "libfvde_encryption_context_free";
153
0
  int result            = 1;
154
155
0
  if( context == NULL )
156
0
  {
157
0
    libcerror_error_set(
158
0
     error,
159
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
160
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
161
0
     "%s: invalid context.",
162
0
     function );
163
164
0
    return( -1 );
165
0
  }
166
0
  if( *context != NULL )
167
0
  {
168
0
    if( libcaes_tweaked_context_free(
169
0
         &( ( *context )->decryption_context ),
170
0
         error ) != 1 )
171
0
    {
172
0
      libcerror_error_set(
173
0
       error,
174
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
175
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
176
0
       "%s: unable free decryption context.",
177
0
       function );
178
179
0
      result = -1;
180
0
    }
181
0
    memory_free(
182
0
     *context );
183
184
0
    *context = NULL;
185
0
  }
186
0
  return( result );
187
0
}
188
189
/* Sets the de- and encryption keys
190
 * Returns 1 if successful or -1 on error
191
 */
192
int libfvde_encryption_context_set_keys(
193
     libfvde_encryption_context_t *context,
194
     const uint8_t *key,
195
     size_t key_size,
196
     const uint8_t *tweak_key,
197
     size_t tweak_key_size,
198
     libcerror_error_t **error )
199
0
{
200
0
  static char *function = "libfvde_encryption_context_set_keys";
201
0
  size_t key_bit_size   = 0;
202
0
  size_t key_byte_size  = 0;
203
204
0
  if( context == NULL )
205
0
  {
206
0
    libcerror_error_set(
207
0
     error,
208
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
209
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
210
0
     "%s: invalid context.",
211
0
     function );
212
213
0
    return( -1 );
214
0
  }
215
0
  if( key == NULL )
216
0
  {
217
0
    libcerror_error_set(
218
0
     error,
219
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
220
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
221
0
     "%s: invalid key.",
222
0
     function );
223
224
0
    return( -1 );
225
0
  }
226
0
  if( key_size > (size_t) SSIZE_MAX )
227
0
  {
228
0
    libcerror_error_set(
229
0
     error,
230
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
231
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
232
0
     "%s: invalid key size value exceeds maximum.",
233
0
     function );
234
235
0
    return( -1 );
236
0
  }
237
0
  if( tweak_key == NULL )
238
0
  {
239
0
    libcerror_error_set(
240
0
     error,
241
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
242
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
243
0
     "%s: invalid tweak key.",
244
0
     function );
245
246
0
    return( -1 );
247
0
  }
248
0
  if( tweak_key_size > (size_t) SSIZE_MAX )
249
0
  {
250
0
    libcerror_error_set(
251
0
     error,
252
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
253
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
254
0
     "%s: invalid tweak key size value exceeds maximum.",
255
0
     function );
256
257
0
    return( -1 );
258
0
  }
259
0
  if( context->method == LIBFVDE_ENCRYPTION_METHOD_AES_128_XTS )
260
0
  {
261
0
    key_byte_size = 16;
262
0
  }
263
0
  if( key_size < key_byte_size )
264
0
  {
265
0
    libcerror_error_set(
266
0
     error,
267
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
268
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
269
0
     "%s: invalid key value too small.",
270
0
     function );
271
272
0
    return( -1 );
273
0
  }
274
0
  if( tweak_key_size < key_byte_size )
275
0
  {
276
0
    libcerror_error_set(
277
0
     error,
278
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
279
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
280
0
     "%s: invalid tweak key value too small.",
281
0
     function );
282
283
0
    return( -1 );
284
0
  }
285
0
  key_bit_size = key_byte_size * 8;
286
287
0
  if( libcaes_tweaked_context_set_keys(
288
0
       context->decryption_context,
289
0
       LIBCAES_CRYPT_MODE_DECRYPT,
290
0
       key,
291
0
       key_bit_size,
292
0
       tweak_key,
293
0
       key_bit_size,
294
0
       error ) != 1 )
295
0
  {
296
0
    libcerror_error_set(
297
0
     error,
298
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
299
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
300
0
     "%s: unable to set keys in decryption context.",
301
0
     function );
302
303
0
    return( -1 );
304
0
  }
305
0
  return( 1 );
306
0
}
307
308
/* De- or encrypts a block of data
309
 * Returns 1 if successful or -1 on error
310
 */
311
int libfvde_encryption_context_crypt(
312
     libfvde_encryption_context_t *context,
313
     int mode,
314
     const uint8_t *input_data,
315
     size_t input_data_size,
316
     uint8_t *output_data,
317
     size_t output_data_size,
318
     uint64_t block_number,
319
     libcerror_error_t **error )
320
0
{
321
0
  uint8_t tweak_value[ 16 ];
322
323
0
  static char *function = "libfvde_encryption_context_crypt";
324
0
  size_t data_offset    = 0;
325
326
0
  if( context == NULL )
327
0
  {
328
0
    libcerror_error_set(
329
0
     error,
330
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
331
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
332
0
     "%s: invalid context.",
333
0
     function );
334
335
0
    return( -1 );
336
0
  }
337
0
  if( mode != LIBFVDE_ENCRYPTION_CRYPT_MODE_DECRYPT )
338
0
  {
339
0
    libcerror_error_set(
340
0
     error,
341
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
342
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
343
0
     "%s: unsupported mode.",
344
0
     function );
345
346
0
    return( -1 );
347
0
  }
348
0
  if( input_data == NULL )
349
0
  {
350
0
    libcerror_error_set(
351
0
     error,
352
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
353
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
354
0
     "%s: invalid input data.",
355
0
     function );
356
357
0
    return( -1 );
358
0
  }
359
0
  if( input_data_size > (size_t) SSIZE_MAX )
360
0
  {
361
0
    libcerror_error_set(
362
0
     error,
363
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
364
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
365
0
     "%s: invalid input data size value exceeds maximum.",
366
0
     function );
367
368
0
    return( -1 );
369
0
  }
370
0
  if( output_data == NULL )
371
0
  {
372
0
    libcerror_error_set(
373
0
     error,
374
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
375
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
376
0
     "%s: invalid output data.",
377
0
     function );
378
379
0
    return( -1 );
380
0
  }
381
0
  if( output_data_size > (size_t) SSIZE_MAX )
382
0
  {
383
0
    libcerror_error_set(
384
0
     error,
385
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
386
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
387
0
     "%s: invalid output data size value exceeds maximum.",
388
0
     function );
389
390
0
    return( -1 );
391
0
  }
392
0
  if( output_data_size < input_data_size )
393
0
  {
394
0
    libcerror_error_set(
395
0
     error,
396
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
397
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
398
0
     "%s: invalid output data size value smaller than input data size.",
399
0
     function );
400
401
0
    return( -1 );
402
0
  }
403
0
  if( memory_set(
404
0
       tweak_value,
405
0
       0,
406
0
       16 ) == NULL )
407
0
  {
408
0
    libcerror_error_set(
409
0
     error,
410
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
411
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
412
0
     "%s: unable to clear tweak value.",
413
0
     function );
414
415
0
    goto on_error;
416
0
  }
417
0
  byte_stream_copy_from_uint64_little_endian(
418
0
   tweak_value,
419
0
   block_number );
420
421
0
  if( libcaes_crypt_xts(
422
0
       context->decryption_context,
423
0
       LIBCAES_CRYPT_MODE_DECRYPT,
424
0
       tweak_value,
425
0
       16,
426
0
       &( input_data[ data_offset ] ),
427
0
       input_data_size,
428
0
       &( output_data[ data_offset ] ),
429
0
       output_data_size,
430
0
       error ) != 1 )
431
0
  {
432
0
    libcerror_error_set(
433
0
     error,
434
0
     LIBCERROR_ERROR_DOMAIN_ENCRYPTION,
435
0
     LIBCERROR_ENCRYPTION_ERROR_DECRYPT_FAILED,
436
0
     "%s: unable to decrypt data.",
437
0
     function );
438
439
0
    goto on_error;
440
0
  }
441
0
  return( 1 );
442
443
0
on_error:
444
0
  memory_set(
445
0
   tweak_value,
446
0
   0,
447
0
   16 );
448
449
0
  return( -1 );
450
0
}
451
452
/* Unwrap data using AES Key Wrap (RFC3394)
453
 * Returns 1 if successful or -1 on error
454
 */
455
int libfvde_encryption_aes_key_unwrap(
456
     const uint8_t *key,
457
     size_t key_bit_size,
458
     const uint8_t *wrapped_data,
459
     size_t wrapped_data_size,
460
     uint8_t *unwrapped_data,
461
     size_t unwrapped_data_size,
462
     libcerror_error_t **error )
463
0
{
464
0
  uint8_t block_data[ 16 ];
465
0
  uint8_t vector_data[ 8 ];
466
467
0
  libcaes_context_t *aes_context = NULL;
468
0
  uint8_t *initialization_vector = NULL;
469
0
  static char *function          = "libfvde_encryption_aes_key_unwrap";
470
0
  size_t block_offset            = 0;
471
0
  size_t number_of_blocks        = 0;
472
0
  size_t block_index             = 0;
473
0
  int8_t round_index             = 0;
474
475
0
  if( key == NULL )
476
0
  {
477
0
    libcerror_error_set(
478
0
     error,
479
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
480
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
481
0
     "%s: invalid AES key.",
482
0
     function);
483
484
0
    return( -1 );
485
0
  }
486
0
  if( ( key_bit_size != 128 )
487
0
   && ( key_bit_size != 192 )
488
0
   && ( key_bit_size != 256 ) )
489
0
  {
490
0
    libcerror_error_set(
491
0
     error,
492
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
493
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
494
0
     "%s: invalid AES key length value out of bounds.",
495
0
     function);
496
497
0
    return( -1 );
498
0
  }
499
0
  if( wrapped_data == NULL )
500
0
  {
501
0
    libcerror_error_set(
502
0
     error,
503
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
504
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
505
0
     "%s: invalid wrapped data.",
506
0
     function);
507
508
0
    return( -1 );
509
0
  }
510
0
  if( wrapped_data_size > (size_t) SSIZE_MAX )
511
0
  {
512
0
    libcerror_error_set(
513
0
     error,
514
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
515
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
516
0
     "%s: invalid wrapped data size value exceeds maximum.",
517
0
     function );
518
519
0
    return( -1 );
520
0
  }
521
0
  if( wrapped_data_size <= 8 )
522
0
  {
523
0
    libcerror_error_set(
524
0
     error,
525
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
526
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
527
0
     "%s: invalid wrapped data size value too small.",
528
0
     function);
529
530
0
    return( -1 );
531
0
  }
532
0
  if( ( wrapped_data_size % 8 ) != 0 )
533
0
  {
534
0
    libcerror_error_set(
535
0
     error,
536
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
537
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
538
0
     "%s: invalid wrapped data size value not a multitude of 8.",
539
0
     function);
540
541
0
    return( -1 );
542
0
  }
543
0
  if( unwrapped_data == NULL )
544
0
  {
545
0
    libcerror_error_set(
546
0
     error,
547
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
548
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
549
0
     "%s: invalid unwrapped data.",
550
0
     function);
551
552
0
    return( -1 );
553
0
  }
554
0
  if( unwrapped_data_size > (size_t) SSIZE_MAX )
555
0
  {
556
0
    libcerror_error_set(
557
0
     error,
558
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
559
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
560
0
     "%s: invalid unwrapped data size value exceeds maximum.",
561
0
     function );
562
563
0
    return( -1 );
564
0
  }
565
0
  if( unwrapped_data_size < wrapped_data_size )
566
0
  {
567
0
    libcerror_error_set(
568
0
     error,
569
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
570
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
571
0
     "%s: invalid unwrapped data size value too small.",
572
0
     function);
573
574
0
    return( -1 );
575
0
  }
576
0
  if( libcaes_context_initialize(
577
0
       &aes_context,
578
0
       error ) != 1 )
579
0
  {
580
0
    libcerror_error_set(
581
0
     error,
582
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
583
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
584
0
     "%s: unable to initialize AES context.",
585
0
     function );
586
587
0
    goto on_error;
588
0
  }
589
0
  if( libcaes_context_set_key(
590
0
       aes_context,
591
0
       LIBCAES_CRYPT_MODE_DECRYPT,
592
0
       key,
593
0
       key_bit_size,
594
0
       error ) != 1 )
595
0
  {
596
0
    libcerror_error_set(
597
0
     error,
598
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
599
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
600
0
     "%s: unable to set key in AES context.",
601
0
     function );
602
603
0
    goto on_error;
604
0
  }
605
0
  if( memory_copy(
606
0
       unwrapped_data,
607
0
       wrapped_data,
608
0
       wrapped_data_size ) == NULL )
609
0
  {
610
0
    libcerror_error_set(
611
0
     error,
612
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
613
0
     LIBCERROR_MEMORY_ERROR_COPY_FAILED,
614
0
     "%s: unable to copy wrapped data.",
615
0
     function );
616
617
0
    goto on_error;
618
0
  }
619
0
  number_of_blocks = wrapped_data_size / 8;
620
621
#if defined( HAVE_DEBUG_OUTPUT )
622
  if( libcnotify_verbose != 0 )
623
  {
624
    libcnotify_printf(
625
     "%s: number of blocks\t\t\t: %" PRIzd "\n",
626
     function,
627
     number_of_blocks );
628
629
    libcnotify_printf(
630
     "%s: wrapped data:\n",
631
     function );
632
    libcnotify_print_data(
633
     wrapped_data,
634
     wrapped_data_size,
635
     0 );
636
  }
637
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
638
639
/* TODO make this code more readable */
640
0
  initialization_vector = unwrapped_data;
641
642
0
  for( round_index = 5;
643
0
       round_index >= 0;
644
0
       round_index-- )
645
0
  {
646
0
    for( block_index = number_of_blocks - 1;
647
0
         block_index > 0;
648
0
         block_index-- )
649
0
    {
650
0
      block_offset = block_index * 8;
651
652
0
      byte_stream_copy_from_uint64_big_endian(
653
0
       vector_data,
654
0
       (uint64_t) ( round_index * ( number_of_blocks - 1 ) + block_index ) );
655
656
0
      vector_data[ 0 ] ^= initialization_vector[ 0 ];
657
0
      vector_data[ 1 ] ^= initialization_vector[ 1 ];
658
0
      vector_data[ 2 ] ^= initialization_vector[ 2 ];
659
0
      vector_data[ 3 ] ^= initialization_vector[ 3 ];
660
0
      vector_data[ 4 ] ^= initialization_vector[ 4 ];
661
0
      vector_data[ 5 ] ^= initialization_vector[ 5 ];
662
0
      vector_data[ 6 ] ^= initialization_vector[ 6 ];
663
0
      vector_data[ 7 ] ^= initialization_vector[ 7 ];
664
665
0
      if( memory_copy(
666
0
           &( block_data[ 0 ] ),
667
0
           vector_data,
668
0
           8 ) == NULL )
669
0
      {
670
0
        libcerror_error_set(
671
0
         error,
672
0
         LIBCERROR_ERROR_DOMAIN_MEMORY,
673
0
         LIBCERROR_MEMORY_ERROR_COPY_FAILED,
674
0
         "%s: unable to copy vector data to block data.",
675
0
         function );
676
677
0
        goto on_error;
678
0
      }
679
0
      if( memory_copy(
680
0
           &( block_data[ 8 ] ),
681
0
           &( unwrapped_data[ block_offset ] ),
682
0
           8 ) == NULL )
683
0
      {
684
0
        libcerror_error_set(
685
0
         error,
686
0
         LIBCERROR_ERROR_DOMAIN_MEMORY,
687
0
         LIBCERROR_MEMORY_ERROR_COPY_FAILED,
688
0
         "%s: unable to copy unwrapped data to block data.",
689
0
         function );
690
691
0
        goto on_error;
692
0
      }
693
0
      if( libcaes_crypt_ecb(
694
0
           aes_context,
695
0
           LIBCAES_CRYPT_MODE_DECRYPT,
696
0
           block_data,
697
0
           16,
698
0
           block_data,
699
0
           16,
700
0
           error ) != 1 )
701
0
      {
702
0
        libcerror_error_set(
703
0
         error,
704
0
         LIBCERROR_ERROR_DOMAIN_ENCRYPTION,
705
0
         LIBCERROR_ENCRYPTION_ERROR_DECRYPT_FAILED,
706
0
         "%s: unable to decrypt block data.",
707
0
         function );
708
709
0
        goto on_error;
710
0
      }
711
0
      if( memory_copy(
712
0
           initialization_vector,
713
0
           &( block_data[ 0 ] ),
714
0
           8 ) == NULL )
715
0
      {
716
0
        libcerror_error_set(
717
0
         error,
718
0
         LIBCERROR_ERROR_DOMAIN_MEMORY,
719
0
         LIBCERROR_MEMORY_ERROR_COPY_FAILED,
720
0
         "%s: unable to decrypted block data to initialization vector.",
721
0
         function );
722
723
0
        goto on_error;
724
0
      }
725
0
      if( memory_copy(
726
0
           &( unwrapped_data[ block_offset ] ),
727
0
           &( block_data[ 8 ] ),
728
0
           8 ) == NULL )
729
0
      {
730
0
        libcerror_error_set(
731
0
         error,
732
0
         LIBCERROR_ERROR_DOMAIN_MEMORY,
733
0
         LIBCERROR_MEMORY_ERROR_COPY_FAILED,
734
0
         "%s: unable to copy decrypted block data to unwrapped data.",
735
0
         function );
736
737
0
        goto on_error;
738
0
      }
739
0
    }
740
0
  }
741
0
  if( libcaes_context_free(
742
0
       &aes_context,
743
0
       error ) != 1 )
744
0
  {
745
0
    libcerror_error_set(
746
0
     error,
747
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
748
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
749
0
     "%s: unable to free AES context.",
750
0
     function );
751
752
0
    goto on_error;
753
0
  }
754
#if defined( HAVE_DEBUG_OUTPUT )
755
  if( libcnotify_verbose != 0 )
756
  {
757
    libcnotify_printf(
758
     "%s: unwrapped data:\n",
759
     function );
760
    libcnotify_print_data(
761
     unwrapped_data,
762
     wrapped_data_size,
763
     0 );
764
  }
765
#endif
766
0
  return( 1 );
767
768
0
on_error:
769
0
  if( aes_context != NULL )
770
0
  {
771
0
    libcaes_context_free(
772
0
     &aes_context,
773
     NULL);
774
0
  }
775
0
  return( -1 );
776
0
}
777