Coverage Report

Created: 2025-06-24 07:14

/src/libfsapfs/libfsapfs/libfsapfs_encryption_context.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Encryption context functions
3
 *
4
 * Copyright (C) 2018-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
#include "libfsapfs_definitions.h"
28
#include "libfsapfs_encryption_context.h"
29
#include "libfsapfs_libcaes.h"
30
#include "libfsapfs_libcerror.h"
31
#include "libfsapfs_libcnotify.h"
32
33
/* Creates an encryption context
34
 * Make sure the value encryption context is referencing, is set to NULL
35
 * Returns 1 if successful or -1 on error
36
 */
37
int libfsapfs_encryption_context_initialize(
38
     libfsapfs_encryption_context_t **context,
39
     uint32_t method,
40
     libcerror_error_t **error )
41
932
{
42
932
  static char *function = "libfsapfs_encryption_context_initialize";
43
44
932
  if( context == NULL )
45
0
  {
46
0
    libcerror_error_set(
47
0
     error,
48
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
49
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
50
0
     "%s: invalid context.",
51
0
     function );
52
53
0
    return( -1 );
54
0
  }
55
932
  if( *context != NULL )
56
0
  {
57
0
    libcerror_error_set(
58
0
     error,
59
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
60
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
61
0
     "%s: invalid context value already set.",
62
0
     function );
63
64
0
    return( -1 );
65
0
  }
66
932
  if( method != LIBFSAPFS_ENCRYPTION_METHOD_AES_128_XTS )
67
0
  {
68
0
    libcerror_error_set(
69
0
     error,
70
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
71
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
72
0
     "%s: unsupported method.",
73
0
     function );
74
75
0
    return( -1 );
76
0
  }
77
932
  *context = memory_allocate_structure(
78
932
              libfsapfs_encryption_context_t );
79
80
932
  if( *context == NULL )
81
0
  {
82
0
    libcerror_error_set(
83
0
     error,
84
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
85
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
86
0
     "%s: unable to create context.",
87
0
     function );
88
89
0
    goto on_error;
90
0
  }
91
932
  if( memory_set(
92
932
       *context,
93
932
       0,
94
932
       sizeof( libfsapfs_encryption_context_t ) ) == NULL )
95
0
  {
96
0
    libcerror_error_set(
97
0
     error,
98
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
99
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
100
0
     "%s: unable to clear context.",
101
0
     function );
102
103
0
    memory_free(
104
0
     *context );
105
106
0
    *context = NULL;
107
108
0
    return( -1 );
109
0
  }
110
932
  if( libcaes_tweaked_context_initialize(
111
932
       &( ( *context )->decryption_context ),
112
932
       error ) != 1 )
113
0
  {
114
0
    libcerror_error_set(
115
0
     error,
116
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
117
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
118
0
     "%s: unable to initialize decryption context.",
119
0
     function );
120
121
0
    goto on_error;
122
0
  }
123
932
  ( *context )->method = method;
124
125
932
  return( 1 );
126
127
0
on_error:
128
0
  if( *context != NULL )
129
0
  {
130
0
    if( ( *context )->decryption_context != NULL )
131
0
    {
132
0
      libcaes_tweaked_context_free(
133
0
       &( ( *context )->decryption_context ),
134
0
       NULL );
135
0
    }
136
0
    memory_free(
137
0
     *context );
138
139
0
    *context = NULL;
140
0
  }
141
0
  return( -1 );
142
932
}
143
144
/* Frees an encryption context
145
 * Returns 1 if successful or -1 on error
146
 */
147
int libfsapfs_encryption_context_free(
148
     libfsapfs_encryption_context_t **context,
149
     libcerror_error_t **error )
150
932
{
151
932
  static char *function = "libfsapfs_encryption_context_free";
152
932
  int result            = 1;
153
154
932
  if( context == NULL )
155
0
  {
156
0
    libcerror_error_set(
157
0
     error,
158
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
159
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
160
0
     "%s: invalid context.",
161
0
     function );
162
163
0
    return( -1 );
164
0
  }
165
932
  if( *context != NULL )
166
932
  {
167
932
    if( libcaes_tweaked_context_free(
168
932
         &( ( *context )->decryption_context ),
169
932
         error ) != 1 )
170
0
    {
171
0
      libcerror_error_set(
172
0
       error,
173
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
174
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
175
0
       "%s: unable free decryption context.",
176
0
       function );
177
178
0
      result = -1;
179
0
    }
180
932
    memory_free(
181
932
     *context );
182
183
932
    *context = NULL;
184
932
  }
185
932
  return( result );
186
932
}
187
188
/* Sets the de- and encryption keys
189
 * Returns 1 if successful or -1 on error
190
 */
191
int libfsapfs_encryption_context_set_keys(
192
     libfsapfs_encryption_context_t *context,
193
     const uint8_t *key,
194
     size_t key_size,
195
     const uint8_t *tweak_key,
196
     size_t tweak_key_size,
197
     libcerror_error_t **error )
198
932
{
199
932
  static char *function = "libfsapfs_encryption_context_set_keys";
200
932
  size_t key_bit_size   = 0;
201
932
  size_t key_byte_size  = 0;
202
203
932
  if( context == NULL )
204
0
  {
205
0
    libcerror_error_set(
206
0
     error,
207
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
208
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
209
0
     "%s: invalid context.",
210
0
     function );
211
212
0
    return( -1 );
213
0
  }
214
932
  if( key == NULL )
215
0
  {
216
0
    libcerror_error_set(
217
0
     error,
218
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
219
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
220
0
     "%s: invalid key.",
221
0
     function );
222
223
0
    return( -1 );
224
0
  }
225
932
  if( key_size > (size_t) SSIZE_MAX )
226
0
  {
227
0
    libcerror_error_set(
228
0
     error,
229
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
230
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
231
0
     "%s: invalid key size value exceeds maximum.",
232
0
     function );
233
234
0
    return( -1 );
235
0
  }
236
932
  if( tweak_key == NULL )
237
0
  {
238
0
    libcerror_error_set(
239
0
     error,
240
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
241
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
242
0
     "%s: invalid tweak key.",
243
0
     function );
244
245
0
    return( -1 );
246
0
  }
247
932
  if( tweak_key_size > (size_t) SSIZE_MAX )
248
0
  {
249
0
    libcerror_error_set(
250
0
     error,
251
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
252
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
253
0
     "%s: invalid tweak key size value exceeds maximum.",
254
0
     function );
255
256
0
    return( -1 );
257
0
  }
258
932
  if( context->method == LIBFSAPFS_ENCRYPTION_METHOD_AES_128_XTS )
259
932
  {
260
932
    key_byte_size = 16;
261
932
  }
262
932
  if( key_size < key_byte_size )
263
0
  {
264
0
    libcerror_error_set(
265
0
     error,
266
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
267
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
268
0
     "%s: invalid key value too small.",
269
0
     function );
270
271
0
    return( -1 );
272
0
  }
273
932
  if( tweak_key_size < key_byte_size )
274
0
  {
275
0
    libcerror_error_set(
276
0
     error,
277
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
278
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
279
0
     "%s: invalid tweak key value too small.",
280
0
     function );
281
282
0
    return( -1 );
283
0
  }
284
932
  key_bit_size = key_byte_size * 8;
285
286
932
  if( libcaes_tweaked_context_set_keys(
287
932
       context->decryption_context,
288
932
       LIBCAES_CRYPT_MODE_DECRYPT,
289
932
       key,
290
932
       key_bit_size,
291
932
       tweak_key,
292
932
       key_bit_size,
293
932
       error ) != 1 )
294
0
  {
295
0
    libcerror_error_set(
296
0
     error,
297
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
298
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
299
0
     "%s: unable to set keys in decryption context.",
300
0
     function );
301
302
0
    return( -1 );
303
0
  }
304
932
  return( 1 );
305
932
}
306
307
/* De- or encrypts a block of data
308
 * Returns 1 if successful or -1 on error
309
 */
310
int libfsapfs_encryption_context_crypt(
311
     libfsapfs_encryption_context_t *context,
312
     int mode,
313
     const uint8_t *input_data,
314
     size_t input_data_size,
315
     uint8_t *output_data,
316
     size_t output_data_size,
317
     uint64_t sector_number,
318
     uint16_t bytes_per_sector,
319
     libcerror_error_t **error )
320
932
{
321
932
  uint8_t tweak_value[ 16 ];
322
323
932
  static char *function = "libfsapfs_encryption_context_crypt";
324
932
  size_t data_offset    = 0;
325
326
932
  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
932
  if( mode != LIBFSAPFS_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
932
  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
932
  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
932
  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
932
  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
932
  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
932
  if( memory_set(
404
932
       tweak_value,
405
932
       0,
406
932
       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
932
  for( data_offset = 0;
418
274k
       data_offset < input_data_size;
419
273k
       data_offset += bytes_per_sector )
420
273k
  {
421
273k
    byte_stream_copy_from_uint64_little_endian(
422
273k
     tweak_value,
423
273k
     sector_number );
424
425
273k
    if( libcaes_crypt_xts(
426
273k
         context->decryption_context,
427
273k
         LIBCAES_CRYPT_MODE_DECRYPT,
428
273k
         tweak_value,
429
273k
         16,
430
273k
         &( input_data[ data_offset ] ),
431
273k
         bytes_per_sector,
432
273k
         &( output_data[ data_offset ] ),
433
273k
         bytes_per_sector,
434
273k
         error ) != 1 )
435
0
    {
436
0
      libcerror_error_set(
437
0
       error,
438
0
       LIBCERROR_ERROR_DOMAIN_ENCRYPTION,
439
0
       LIBCERROR_ENCRYPTION_ERROR_DECRYPT_FAILED,
440
0
       "%s: unable to decrypt data.",
441
0
       function );
442
443
0
      goto on_error;
444
0
    }
445
273k
    sector_number += 1;
446
273k
  }
447
932
  return( 1 );
448
449
0
on_error:
450
0
  memory_set(
451
0
   tweak_value,
452
0
   0,
453
0
   16 );
454
455
0
  return( -1 );
456
932
}
457
458
/* Unwrap data using AES Key Wrap (RFC3394)
459
 * Returns 1 if successful or -1 on error
460
 */
461
int libfsapfs_encryption_aes_key_unwrap(
462
     const uint8_t *key,
463
     size_t key_bit_size,
464
     const uint8_t *wrapped_data,
465
     size_t wrapped_data_size,
466
     uint8_t *unwrapped_data,
467
     size_t unwrapped_data_size,
468
     libcerror_error_t **error )
469
0
{
470
0
  uint8_t block_data[ 16 ];
471
0
  uint8_t vector_data[ 8 ];
472
473
0
  libcaes_context_t *aes_context = NULL;
474
0
  uint8_t *initialization_vector = NULL;
475
0
  static char *function          = "libfsapfs_encryption_aes_key_unwrap";
476
0
  size_t block_offset            = 0;
477
0
  size_t number_of_blocks        = 0;
478
0
  size_t block_index             = 0;
479
0
  int8_t round_index             = 0;
480
481
0
  if( key == NULL )
482
0
  {
483
0
    libcerror_error_set(
484
0
     error,
485
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
486
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
487
0
     "%s: invalid AES key.",
488
0
     function);
489
490
0
    return( -1 );
491
0
  }
492
0
  if( ( key_bit_size != 128 )
493
0
   && ( key_bit_size != 192 )
494
0
   && ( key_bit_size != 256 ) )
495
0
  {
496
0
    libcerror_error_set(
497
0
     error,
498
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
499
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
500
0
     "%s: invalid AES key length value out of bounds.",
501
0
     function);
502
503
0
    return( -1 );
504
0
  }
505
0
  if( wrapped_data == NULL )
506
0
  {
507
0
    libcerror_error_set(
508
0
     error,
509
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
510
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
511
0
     "%s: invalid wrapped data.",
512
0
     function);
513
514
0
    return( -1 );
515
0
  }
516
0
  if( wrapped_data_size > (size_t) SSIZE_MAX )
517
0
  {
518
0
    libcerror_error_set(
519
0
     error,
520
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
521
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
522
0
     "%s: invalid wrapped data size value exceeds maximum.",
523
0
     function );
524
525
0
    return( -1 );
526
0
  }
527
0
  if( wrapped_data_size <= 8 )
528
0
  {
529
0
    libcerror_error_set(
530
0
     error,
531
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
532
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
533
0
     "%s: invalid wrapped data size value too small.",
534
0
     function);
535
536
0
    return( -1 );
537
0
  }
538
0
  if( ( wrapped_data_size % 8 ) != 0 )
539
0
  {
540
0
    libcerror_error_set(
541
0
     error,
542
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
543
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
544
0
     "%s: invalid wrapped data size value not a multitude of 8.",
545
0
     function);
546
547
0
    return( -1 );
548
0
  }
549
0
  if( unwrapped_data == NULL )
550
0
  {
551
0
    libcerror_error_set(
552
0
     error,
553
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
554
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
555
0
     "%s: invalid unwrapped data.",
556
0
     function);
557
558
0
    return( -1 );
559
0
  }
560
0
  if( unwrapped_data_size > (size_t) SSIZE_MAX )
561
0
  {
562
0
    libcerror_error_set(
563
0
     error,
564
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
565
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
566
0
     "%s: invalid unwrapped data size value exceeds maximum.",
567
0
     function );
568
569
0
    return( -1 );
570
0
  }
571
0
  if( unwrapped_data_size < wrapped_data_size )
572
0
  {
573
0
    libcerror_error_set(
574
0
     error,
575
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
576
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
577
0
     "%s: invalid unwrapped data size value too small.",
578
0
     function);
579
580
0
    return( -1 );
581
0
  }
582
0
  if( libcaes_context_initialize(
583
0
       &aes_context,
584
0
       error ) != 1 )
585
0
  {
586
0
    libcerror_error_set(
587
0
     error,
588
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
589
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
590
0
     "%s: unable to initialize AES context.",
591
0
     function );
592
593
0
    goto on_error;
594
0
  }
595
0
  if( libcaes_context_set_key(
596
0
       aes_context,
597
0
       LIBCAES_CRYPT_MODE_DECRYPT,
598
0
       key,
599
0
       key_bit_size,
600
0
       error ) != 1 )
601
0
  {
602
0
    libcerror_error_set(
603
0
     error,
604
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
605
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
606
0
     "%s: unable to set key in AES context.",
607
0
     function );
608
609
0
    goto on_error;
610
0
  }
611
0
  if( memory_copy(
612
0
       unwrapped_data,
613
0
       wrapped_data,
614
0
       wrapped_data_size ) == NULL )
615
0
  {
616
0
    libcerror_error_set(
617
0
     error,
618
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
619
0
     LIBCERROR_MEMORY_ERROR_COPY_FAILED,
620
0
     "%s: unable to copy wrapped data.",
621
0
     function );
622
623
0
    goto on_error;
624
0
  }
625
0
  number_of_blocks = wrapped_data_size / 8;
626
627
#if defined( HAVE_DEBUG_OUTPUT )
628
  if( libcnotify_verbose != 0 )
629
  {
630
    libcnotify_printf(
631
     "%s: number of blocks: %" PRIzd "\n",
632
     function,
633
     number_of_blocks );
634
635
    libcnotify_printf(
636
     "%s: wrapped data:\n",
637
     function );
638
    libcnotify_print_data(
639
     wrapped_data,
640
     wrapped_data_size,
641
     0 );
642
  }
643
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
644
645
/* TODO make this code more readable */
646
0
  initialization_vector = unwrapped_data;
647
648
0
  for( round_index = 5;
649
0
       round_index >= 0;
650
0
       round_index-- )
651
0
  {
652
0
    for( block_index = number_of_blocks - 1;
653
0
         block_index > 0;
654
0
         block_index-- )
655
0
    {
656
0
      block_offset = block_index * 8;
657
658
0
      byte_stream_copy_from_uint64_big_endian(
659
0
       vector_data,
660
0
       (uint64_t) ( round_index * ( number_of_blocks - 1 ) + block_index ) );
661
662
0
      vector_data[ 0 ] ^= initialization_vector[ 0 ];
663
0
      vector_data[ 1 ] ^= initialization_vector[ 1 ];
664
0
      vector_data[ 2 ] ^= initialization_vector[ 2 ];
665
0
      vector_data[ 3 ] ^= initialization_vector[ 3 ];
666
0
      vector_data[ 4 ] ^= initialization_vector[ 4 ];
667
0
      vector_data[ 5 ] ^= initialization_vector[ 5 ];
668
0
      vector_data[ 6 ] ^= initialization_vector[ 6 ];
669
0
      vector_data[ 7 ] ^= initialization_vector[ 7 ];
670
671
0
      if( memory_copy(
672
0
           &( block_data[ 0 ] ),
673
0
           vector_data,
674
0
           8 ) == NULL )
675
0
      {
676
0
        libcerror_error_set(
677
0
         error,
678
0
         LIBCERROR_ERROR_DOMAIN_MEMORY,
679
0
         LIBCERROR_MEMORY_ERROR_COPY_FAILED,
680
0
         "%s: unable to copy vector data to block data.",
681
0
         function );
682
683
0
        goto on_error;
684
0
      }
685
0
      if( memory_copy(
686
0
           &( block_data[ 8 ] ),
687
0
           &( unwrapped_data[ block_offset ] ),
688
0
           8 ) == NULL )
689
0
      {
690
0
        libcerror_error_set(
691
0
         error,
692
0
         LIBCERROR_ERROR_DOMAIN_MEMORY,
693
0
         LIBCERROR_MEMORY_ERROR_COPY_FAILED,
694
0
         "%s: unable to copy unwrapped data to block data.",
695
0
         function );
696
697
0
        goto on_error;
698
0
      }
699
0
      if( libcaes_crypt_ecb(
700
0
           aes_context,
701
0
           LIBCAES_CRYPT_MODE_DECRYPT,
702
0
           block_data,
703
0
           16,
704
0
           block_data,
705
0
           16,
706
0
           error ) != 1 )
707
0
      {
708
0
        libcerror_error_set(
709
0
         error,
710
0
         LIBCERROR_ERROR_DOMAIN_ENCRYPTION,
711
0
         LIBCERROR_ENCRYPTION_ERROR_DECRYPT_FAILED,
712
0
         "%s: unable to decrypt block data.",
713
0
         function );
714
715
0
        goto on_error;
716
0
      }
717
0
      if( memory_copy(
718
0
           initialization_vector,
719
0
           &( block_data[ 0 ] ),
720
0
           8 ) == NULL )
721
0
      {
722
0
        libcerror_error_set(
723
0
         error,
724
0
         LIBCERROR_ERROR_DOMAIN_MEMORY,
725
0
         LIBCERROR_MEMORY_ERROR_COPY_FAILED,
726
0
         "%s: unable to decrypted block data to initialization vector.",
727
0
         function );
728
729
0
        goto on_error;
730
0
      }
731
0
      if( memory_copy(
732
0
           &( unwrapped_data[ block_offset ] ),
733
0
           &( block_data[ 8 ] ),
734
0
           8 ) == NULL )
735
0
      {
736
0
        libcerror_error_set(
737
0
         error,
738
0
         LIBCERROR_ERROR_DOMAIN_MEMORY,
739
0
         LIBCERROR_MEMORY_ERROR_COPY_FAILED,
740
0
         "%s: unable to copy decrypted block data to unwrapped data.",
741
0
         function );
742
743
0
        goto on_error;
744
0
      }
745
0
    }
746
0
  }
747
0
  if( libcaes_context_free(
748
0
       &aes_context,
749
0
       error ) != 1 )
750
0
  {
751
0
    libcerror_error_set(
752
0
     error,
753
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
754
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
755
0
     "%s: unable to free AES context.",
756
0
     function );
757
758
0
    goto on_error;
759
0
  }
760
#if defined( HAVE_DEBUG_OUTPUT )
761
  if( libcnotify_verbose != 0 )
762
  {
763
    libcnotify_printf(
764
     "%s: unwrapped data:\n",
765
     function );
766
    libcnotify_print_data(
767
     unwrapped_data,
768
     wrapped_data_size,
769
     0 );
770
  }
771
#endif
772
0
  return( 1 );
773
774
0
on_error:
775
0
  if( aes_context != NULL )
776
0
  {
777
0
    libcaes_context_free(
778
0
     &aes_context,
779
0
     NULL);
780
0
  }
781
0
  return( -1 );
782
0
}
783