Coverage Report

Created: 2024-10-02 06:58

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