Coverage Report

Created: 2025-08-28 07:10

/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.23k
{
57
4.23k
  static char *function = "libbde_metadata_initialize";
58
59
4.23k
  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.23k
  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.23k
  *metadata = memory_allocate_structure(
82
4.23k
               libbde_metadata_t );
83
84
4.23k
  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.23k
  if( memory_set(
96
4.23k
       *metadata,
97
4.23k
       0,
98
4.23k
       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.23k
  if( libcdata_array_initialize(
115
4.23k
       &( ( *metadata )->entries_array ),
116
4.23k
       0,
117
4.23k
       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.23k
  if( libcdata_array_initialize(
129
4.23k
       &( ( *metadata )->volume_master_keys_array ),
130
4.23k
       0,
131
4.23k
       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.23k
  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.23k
}
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.23k
{
169
4.23k
  static char *function = "libbde_metadata_free";
170
4.23k
  int result            = 1;
171
172
4.23k
  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.23k
  if( *metadata != NULL )
184
4.23k
  {
185
4.23k
    if( ( *metadata )->description != NULL )
186
229
    {
187
229
      memory_free(
188
229
       ( *metadata )->description );
189
229
    }
190
4.23k
    if( ( *metadata )->startup_key_external_key != NULL )
191
130
    {
192
130
      if( libbde_external_key_free(
193
130
           &( ( *metadata )->startup_key_external_key ),
194
130
           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
130
    }
206
4.23k
    if( ( *metadata )->full_volume_encryption_key != NULL )
207
444
    {
208
444
      if( libbde_aes_ccm_encrypted_key_free(
209
444
           &( ( *metadata )->full_volume_encryption_key ),
210
444
           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
444
    }
222
4.23k
    if( libcdata_array_free(
223
4.23k
         &( ( *metadata )->entries_array ),
224
4.23k
         (int(*)(intptr_t **, libcerror_error_t **)) &libbde_metadata_entry_free,
225
4.23k
         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.23k
    if( libcdata_array_free(
237
4.23k
         &( ( *metadata )->volume_master_keys_array ),
238
4.23k
         (int(*)(intptr_t **, libcerror_error_t **)) &libbde_volume_master_key_free,
239
4.23k
         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.23k
    memory_free(
251
4.23k
     *metadata );
252
253
4.23k
    *metadata = NULL;
254
4.23k
  }
255
4.23k
  return( result );
256
4.23k
}
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.23k
{
270
4.23k
  libbde_metadata_block_header_t *block_header = NULL;
271
4.23k
  libbde_metadata_header_t *header             = NULL;
272
4.23k
  static char *function                        = "libbde_metadata_read_block";
273
4.23k
  uint64_t volume_header_size                  = 0;
274
4.23k
  uint32_t entries_data_size                   = 0;
275
276
4.23k
  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.23k
  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.23k
  if( libbde_metadata_block_header_initialize(
299
4.23k
       &block_header,
300
4.23k
       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.23k
  if( libbde_metadata_block_header_read_file_io_handle(
322
4.23k
       block_header,
323
4.23k
       file_io_handle,
324
4.23k
       file_offset,
325
4.23k
       error ) != 1 )
326
107
  {
327
107
    libcerror_error_set(
328
107
     error,
329
107
     LIBCERROR_ERROR_DOMAIN_IO,
330
107
     LIBCERROR_IO_ERROR_READ_FAILED,
331
107
     "%s: unable to read metadata block header.",
332
107
     function );
333
334
107
    goto on_error;
335
107
  }
336
4.12k
  metadata->version               = block_header->version;
337
4.12k
  metadata->encrypted_volume_size = block_header->encrypted_volume_size;
338
4.12k
  metadata->volume_header_offset  = block_header->volume_header_offset;
339
340
4.12k
  volume_header_size = block_header->number_of_volume_header_sectors * io_handle->bytes_per_sector;
341
342
4.12k
  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.12k
  if( (uint64_t) io_handle->first_metadata_offset != block_header->first_metadata_offset )
354
74
  {
355
74
    libcerror_error_set(
356
74
     error,
357
74
     LIBCERROR_ERROR_DOMAIN_INPUT,
358
74
     LIBCERROR_INPUT_ERROR_VALUE_MISMATCH,
359
74
     "%s: value mismatch for first metadata offset.",
360
74
     function );
361
362
74
    goto on_error;
363
74
  }
364
4.05k
  if( (uint64_t) io_handle->second_metadata_offset != block_header->second_metadata_offset )
365
81
  {
366
81
    libcerror_error_set(
367
81
     error,
368
81
     LIBCERROR_ERROR_DOMAIN_INPUT,
369
81
     LIBCERROR_INPUT_ERROR_VALUE_MISMATCH,
370
81
     "%s: value mismatch for second metadata offset.",
371
81
     function );
372
373
81
    goto on_error;
374
81
  }
375
3.96k
  if( (uint64_t) io_handle->third_metadata_offset != block_header->third_metadata_offset )
376
75
  {
377
75
    libcerror_error_set(
378
75
     error,
379
75
     LIBCERROR_ERROR_DOMAIN_INPUT,
380
75
     LIBCERROR_INPUT_ERROR_VALUE_MISMATCH,
381
75
     "%s: value mismatch for third metadata offset.",
382
75
     function );
383
384
75
    goto on_error;
385
75
  }
386
3.89k
  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.89k
  if( libbde_metadata_header_initialize(
399
3.89k
       &header,
400
3.89k
       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.89k
  if( libbde_metadata_header_read_file_io_handle(
412
3.89k
       header,
413
3.89k
       file_io_handle,
414
3.89k
       file_offset,
415
3.89k
       error ) != 1 )
416
121
  {
417
121
    libcerror_error_set(
418
121
     error,
419
121
     LIBCERROR_ERROR_DOMAIN_IO,
420
121
     LIBCERROR_IO_ERROR_READ_FAILED,
421
121
     "%s: unable to read metadata header.",
422
121
     function );
423
424
121
    goto on_error;
425
121
  }
426
3.77k
  if( memory_copy(
427
3.77k
       metadata->volume_identifier,
428
3.77k
       header->volume_identifier,
429
3.77k
       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.77k
  metadata->encryption_method = header->encryption_method;
441
3.77k
  metadata->creation_time     = header->creation_time;
442
443
3.77k
  entries_data_size = header->metadata_size;
444
445
3.77k
  if( entries_data_size < sizeof( bde_metadata_header_v1_t ) )
446
6
  {
447
6
    libcerror_error_set(
448
6
     error,
449
6
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
450
6
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
451
6
     "%s: metadata size value out of bounds.",
452
6
     function );
453
454
6
    goto on_error;
455
6
  }
456
3.76k
  entries_data_size -= sizeof( bde_metadata_header_v1_t );
457
458
3.76k
  if( libbde_metadata_read_entries_file_io_handle(
459
3.76k
       metadata,
460
3.76k
       file_io_handle,
461
3.76k
       (size_t) entries_data_size,
462
3.76k
       startup_key_identifier,
463
3.76k
       startup_key_identifier_size,
464
3.76k
       error ) != 1 )
465
326
  {
466
326
    libcerror_error_set(
467
326
     error,
468
326
     LIBCERROR_ERROR_DOMAIN_IO,
469
326
     LIBCERROR_IO_ERROR_READ_FAILED,
470
326
     "%s: unable to read metadata entries.",
471
326
     function );
472
473
326
    goto on_error;
474
326
  }
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.44k
  if( metadata->volume_header_size == 0 )
485
2.99k
  {
486
2.99k
    metadata->volume_header_size = volume_header_size;
487
2.99k
  }
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.44k
  if( libbde_metadata_header_free(
503
3.44k
       &header,
504
3.44k
       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.44k
  if( libbde_metadata_block_header_free(
516
3.44k
       &block_header,
517
3.44k
       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.44k
  return( 1 );
529
530
790
on_error:
531
790
  if( header != NULL )
532
453
  {
533
453
    libbde_metadata_header_free(
534
453
     &header,
535
453
     NULL );
536
453
  }
537
790
  if( block_header != NULL )
538
790
  {
539
790
    libbde_metadata_block_header_free(
540
790
     &block_header,
541
790
     NULL );
542
790
  }
543
790
  return( -1 );
544
3.44k
}
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.76k
{
557
3.76k
  uint8_t *entries_data = NULL;
558
3.76k
  static char *function = "libbde_metadata_read_entries_file_io_handle";
559
3.76k
  ssize_t read_count    = 0;
560
561
3.76k
  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.76k
  if( ( entries_data_size == 0 )
573
3.76k
   || ( entries_data_size > (size_t) LIBBDE_MAXIMUM_FVE_METADATA_SIZE ) )
574
27
  {
575
27
    libcerror_error_set(
576
27
     error,
577
27
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
578
27
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
579
27
     "%s: invalid entries data size value out of bounds.",
580
27
     function );
581
582
27
    return( -1 );
583
27
  }
584
3.74k
  entries_data = (uint8_t *) memory_allocate(
585
3.74k
                              sizeof( uint8_t ) * entries_data_size );
586
587
3.74k
  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.74k
  read_count = libbfio_handle_read_buffer(
599
3.74k
                file_io_handle,
600
3.74k
                entries_data,
601
3.74k
                (size_t) entries_data_size,
602
3.74k
                error );
603
604
3.74k
  if( read_count != (ssize_t) entries_data_size )
605
42
  {
606
42
    libcerror_error_set(
607
42
     error,
608
42
     LIBCERROR_ERROR_DOMAIN_IO,
609
42
     LIBCERROR_IO_ERROR_READ_FAILED,
610
42
     "%s: unable to read metadata entries data.",
611
42
     function );
612
613
42
    goto on_error;
614
42
  }
615
3.69k
  if( libbde_metadata_read_entries_data(
616
3.69k
       metadata,
617
3.69k
       entries_data,
618
3.69k
       entries_data_size,
619
3.69k
       startup_key_identifier,
620
3.69k
       startup_key_identifier_size,
621
3.69k
       error ) != 1 )
622
257
  {
623
257
    libcerror_error_set(
624
257
     error,
625
257
     LIBCERROR_ERROR_DOMAIN_IO,
626
257
     LIBCERROR_IO_ERROR_READ_FAILED,
627
257
     "%s: unable to read metadata entries.",
628
257
     function );
629
630
257
    goto on_error;
631
257
  }
632
3.44k
  memory_free(
633
3.44k
   entries_data );
634
635
3.44k
  entries_data = NULL;
636
637
3.44k
  return( 1 );
638
639
299
on_error:
640
299
  if( entries_data != NULL )
641
299
  {
642
299
    memory_free(
643
299
     entries_data );
644
299
  }
645
299
  return( -1 );
646
3.69k
}
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.69k
{
659
3.69k
  libbde_aes_ccm_encrypted_key_t *aes_ccm_encrypted_key = NULL;
660
3.69k
  libbde_external_key_t *external_key                   = NULL;
661
3.69k
  libbde_metadata_entry_t *metadata_entry               = NULL;
662
3.69k
  libbde_volume_master_key_t *volume_master_key         = NULL;
663
3.69k
  static char *function                                 = "libbde_metadata_read_entries_data";
664
3.69k
  size_t entries_data_offset                            = 0;
665
3.69k
  ssize_t read_count                                    = 0;
666
3.69k
  uint64_t volume_header_offset                         = 0;
667
3.69k
  uint64_t volume_header_size                           = 0;
668
3.69k
  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.69k
  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.69k
  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.69k
  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.69k
  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
33.2k
  while( entries_data_size >= sizeof( bde_metadata_entry_v1_t ) )
723
31.0k
  {
724
31.0k
    if( memory_compare(
725
31.0k
         &( entries_data[ entries_data_offset ] ),
726
31.0k
         libbde_metadata_entry_empty,
727
31.0k
         sizeof( bde_metadata_entry_v1_t ) ) == 0 )
728
1.23k
    {
729
1.23k
      break;
730
1.23k
    }
731
29.7k
    if( libbde_metadata_entry_initialize(
732
29.7k
         &metadata_entry,
733
29.7k
         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
29.7k
    read_count = libbde_metadata_entry_read(
745
29.7k
            metadata_entry,
746
29.7k
            &( entries_data[ entries_data_offset ] ),
747
29.7k
            entries_data_size,
748
29.7k
            error );
749
750
29.7k
    if( read_count == -1 )
751
71
    {
752
71
      libcerror_error_set(
753
71
       error,
754
71
       LIBCERROR_ERROR_DOMAIN_IO,
755
71
       LIBCERROR_IO_ERROR_READ_FAILED,
756
71
       "%s: unable to read metadata entry.",
757
71
       function );
758
759
71
      goto on_error;
760
71
    }
761
29.7k
    entries_data_offset += read_count;
762
29.7k
    entries_data_size   -= read_count;
763
764
29.7k
    switch( metadata_entry->type )
765
29.7k
    {
766
4.08k
      case LIBBDE_ENTRY_TYPE_VOLUME_MASTER_KEY:
767
4.08k
        if( libbde_volume_master_key_initialize(
768
4.08k
             &volume_master_key,
769
4.08k
             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.08k
        if( libbde_volume_master_key_read(
781
4.08k
             volume_master_key,
782
4.08k
             metadata_entry,
783
4.08k
             error ) != 1 )
784
55
        {
785
55
          libcerror_error_set(
786
55
           error,
787
55
           LIBCERROR_ERROR_DOMAIN_IO,
788
55
           LIBCERROR_IO_ERROR_READ_FAILED,
789
55
           "%s: unable to read volume master key.",
790
55
           function );
791
792
55
          goto on_error;
793
55
        }
794
4.02k
        if( volume_master_key->protection_type == LIBBDE_KEY_PROTECTION_TYPE_CLEAR_KEY )
795
1.24k
        {
796
1.24k
          if( metadata->clear_key_volume_master_key == NULL )
797
588
          {
798
588
            metadata->clear_key_volume_master_key = volume_master_key;
799
588
          }
800
1.24k
        }
801
2.78k
        else if( volume_master_key->protection_type == LIBBDE_KEY_PROTECTION_TYPE_STARTUP_KEY )
802
259
        {
803
259
          if( ( metadata->startup_key_volume_master_key == NULL )
804
259
           && ( 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
259
        }
818
2.52k
        else if( volume_master_key->protection_type == LIBBDE_KEY_PROTECTION_TYPE_RECOVERY_PASSWORD )
819
754
        {
820
754
          if( metadata->recovery_password_volume_master_key == NULL )
821
75
          {
822
75
            metadata->recovery_password_volume_master_key = volume_master_key;
823
75
          }
824
754
        }
825
1.76k
        else if( volume_master_key->protection_type == LIBBDE_KEY_PROTECTION_TYPE_PASSWORD )
826
153
        {
827
153
          if( metadata->password_volume_master_key == NULL )
828
48
          {
829
48
            metadata->password_volume_master_key = volume_master_key;
830
48
          }
831
153
        }
832
4.02k
        if( libcdata_array_append_entry(
833
4.02k
             metadata->volume_master_keys_array,
834
4.02k
             &entry_index,
835
4.02k
             (intptr_t *) volume_master_key,
836
4.02k
             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.02k
        volume_master_key = NULL;
848
849
4.02k
        break;
850
851
1.05k
      case LIBBDE_ENTRY_TYPE_FULL_VOLUME_ENCRYPTION_KEY:
852
/* TODO change to name */
853
5.48k
      case 0x000b:
854
5.48k
        if( libbde_aes_ccm_encrypted_key_initialize(
855
5.48k
             &aes_ccm_encrypted_key,
856
5.48k
             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
5.48k
        if( libbde_aes_ccm_encrypted_key_read(
868
5.48k
             aes_ccm_encrypted_key,
869
5.48k
             metadata_entry,
870
5.48k
             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
5.46k
        if( ( metadata_entry->type == LIBBDE_ENTRY_TYPE_FULL_VOLUME_ENCRYPTION_KEY )
882
5.46k
         && ( metadata->full_volume_encryption_key == NULL ) )
883
444
        {
884
444
          metadata->full_volume_encryption_key = aes_ccm_encrypted_key;
885
886
444
          aes_ccm_encrypted_key = NULL;
887
444
        }
888
5.46k
        if( metadata_entry->type == 0x000b )
889
4.41k
        {
890
/* TODO store key somewhere */
891
4.41k
        }
892
5.46k
        if( aes_ccm_encrypted_key != NULL )
893
5.02k
        {
894
5.02k
          if( libbde_aes_ccm_encrypted_key_free(
895
5.02k
               &aes_ccm_encrypted_key,
896
5.02k
               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
5.02k
        }
908
5.46k
        break;
909
910
5.46k
      case LIBBDE_ENTRY_TYPE_STARTUP_KEY:
911
3.43k
        if( libbde_external_key_initialize(
912
3.43k
             &external_key,
913
3.43k
             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
3.43k
        if( libbde_external_key_read(
925
3.43k
             external_key,
926
3.43k
             metadata_entry,
927
3.43k
             error ) != 1 )
928
33
        {
929
33
          libcerror_error_set(
930
33
           error,
931
33
           LIBCERROR_ERROR_DOMAIN_IO,
932
33
           LIBCERROR_IO_ERROR_READ_FAILED,
933
33
           "%s: unable to read external key from property metadata entry.",
934
33
           function );
935
936
33
          goto on_error;
937
33
        }
938
3.39k
        if( metadata->startup_key_external_key == NULL )
939
130
        {
940
130
          metadata->startup_key_external_key = external_key;
941
942
130
          external_key = NULL;
943
130
        }
944
3.39k
        if( external_key != NULL )
945
3.26k
        {
946
3.26k
          if( libbde_external_key_free(
947
3.26k
               &external_key,
948
3.26k
               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
3.26k
        }
960
3.39k
        break;
961
962
3.39k
      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.62k
        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.62k
        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.62k
        if( ( metadata_entry->value_data != NULL )
1001
1.62k
         && ( metadata_entry->value_data_size > 0 ) )
1002
240
        {
1003
240
          metadata->description = (uint8_t *) memory_allocate(
1004
240
                                               (size_t) metadata_entry->value_data_size );
1005
1006
240
          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
240
          if( memory_copy(
1018
240
               metadata->description,
1019
240
               metadata_entry->value_data,
1020
240
               (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
240
          metadata->description_size = metadata_entry->value_data_size;
1032
240
        }
1033
1.62k
        break;
1034
1035
1.62k
      case LIBBDE_ENTRY_TYPE_VOLUME_HEADER_BLOCK:
1036
1.50k
        if( metadata_entry->value_type == LIBBDE_VALUE_TYPE_OFFSET_AND_SIZE )
1037
608
        {
1038
/* TODO move to separate function and check for the size */
1039
608
          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
603
          byte_stream_copy_to_uint64_little_endian(
1051
603
           &( metadata_entry->value_data[ 0 ] ),
1052
603
           volume_header_offset );
1053
1054
603
          byte_stream_copy_to_uint64_little_endian(
1055
603
           &( metadata_entry->value_data[ 8 ] ),
1056
603
           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
603
          if( (off64_t) volume_header_offset != metadata->volume_header_offset )
1112
74
          {
1113
74
            libcerror_error_set(
1114
74
             error,
1115
74
             LIBCERROR_ERROR_DOMAIN_INPUT,
1116
74
             LIBCERROR_INPUT_ERROR_VALUE_MISMATCH,
1117
74
             "%s: value mismatch for metadata volume header offset.",
1118
74
             function );
1119
1120
74
            goto on_error;
1121
74
          }
1122
529
          metadata->volume_header_size = (size64_t) volume_header_size;
1123
529
        }
1124
1.42k
        break;
1125
1126
13.5k
      default:
1127
13.5k
        break;
1128
29.7k
    }
1129
29.5k
    if( libcdata_array_append_entry(
1130
29.5k
         metadata->entries_array,
1131
29.5k
         &entry_index,
1132
29.5k
         (intptr_t *) metadata_entry,
1133
29.5k
         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
29.5k
    metadata_entry = NULL;
1145
29.5k
  }
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.44k
  return( 1 );
1163
1164
257
on_error:
1165
257
  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
257
  if( external_key != NULL )
1172
33
  {
1173
33
    libbde_external_key_free(
1174
33
     &external_key,
1175
33
     NULL );
1176
33
  }
1177
257
  if( volume_master_key != NULL )
1178
55
  {
1179
55
    libbde_volume_master_key_free(
1180
55
     &volume_master_key,
1181
55
     NULL );
1182
55
  }
1183
257
  if( metadata->description != NULL )
1184
11
  {
1185
11
    memory_free(
1186
11
     metadata->description );
1187
1188
11
    metadata->description      = NULL;
1189
11
    metadata->description_size = 0;
1190
11
  }
1191
257
  if( metadata_entry != NULL )
1192
257
  {
1193
257
    libbde_metadata_entry_free(
1194
257
     &metadata_entry,
1195
257
     NULL );
1196
257
  }
1197
257
  libcdata_array_empty(
1198
257
   metadata->entries_array,
1199
257
   (int(*)(intptr_t **, libcerror_error_t **)) &libbde_metadata_entry_free,
1200
257
   NULL );
1201
1202
257
  return( -1 );
1203
3.69k
}
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
907
{
1217
907
  uint8_t aes_ccm_key[ 32 ];
1218
1219
907
  libcaes_context_t *aes_context = NULL;
1220
907
  uint8_t *unencrypted_data      = NULL;
1221
907
  static char *function          = "libbde_metadata_read_volume_master_key";
1222
907
  size_t unencrypted_data_size   = 0;
1223
907
  uint32_t data_size             = 0;
1224
907
  uint32_t version               = 0;
1225
907
  int result                     = 0;
1226
1227
907
  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
907
  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
907
  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
907
  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
907
  if( metadata->clear_key_volume_master_key != NULL )
1272
313
  {
1273
313
    if( metadata->clear_key_volume_master_key->key == NULL )
1274
10
    {
1275
10
      libcerror_error_set(
1276
10
       error,
1277
10
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1278
10
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1279
10
       "%s: invalid metadata - invalid clear key volume master key - missing key.",
1280
10
       function );
1281
1282
10
      goto on_error;
1283
10
    }
1284
303
    if( metadata->clear_key_volume_master_key->aes_ccm_encrypted_key == NULL )
1285
3
    {
1286
3
      libcerror_error_set(
1287
3
       error,
1288
3
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1289
3
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1290
3
       "%s: invalid metadata - invalid clear key volume master key - missing AES-CCM encrypted key.",
1291
3
       function );
1292
1293
3
      goto on_error;
1294
3
    }
1295
300
    if( metadata->clear_key_volume_master_key->key->data_size != 32 )
1296
11
    {
1297
11
      libcerror_error_set(
1298
11
       error,
1299
11
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1300
11
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1301
11
       "%s: clear key volume master key - key data size value out of bounds.",
1302
11
       function );
1303
1304
11
      goto on_error;
1305
11
    }
1306
289
    if( memory_copy(
1307
289
         aes_ccm_key,
1308
289
         metadata->clear_key_volume_master_key->key->data,
1309
289
         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
289
    unencrypted_data_size = metadata->clear_key_volume_master_key->aes_ccm_encrypted_key->data_size;
1333
1334
289
    if( ( unencrypted_data_size < 28 )
1335
289
     || ( unencrypted_data_size > MEMORY_MAXIMUM_ALLOCATION_SIZE ) )
1336
5
    {
1337
5
      libcerror_error_set(
1338
5
       error,
1339
5
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1340
5
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1341
5
       "%s: invalid clear key volume master key - AES-CCM encrypted key data size value out of bounds.",
1342
5
       function );
1343
1344
5
      goto on_error;
1345
5
    }
1346
284
    unencrypted_data = (uint8_t *) memory_allocate(
1347
284
            unencrypted_data_size );
1348
1349
284
    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
284
    if( memory_set(
1361
284
         unencrypted_data,
1362
284
         0,
1363
284
         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
284
    if( libcaes_context_initialize(
1375
284
         &aes_context,
1376
284
         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
284
    if( libcaes_context_set_key(
1388
284
         aes_context,
1389
284
         LIBCAES_CRYPT_MODE_ENCRYPT,
1390
284
         aes_ccm_key,
1391
284
         256,
1392
284
         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
284
    if( libcaes_crypt_ccm(
1404
284
         aes_context,
1405
284
         LIBCAES_CRYPT_MODE_DECRYPT,
1406
284
         metadata->clear_key_volume_master_key->aes_ccm_encrypted_key->nonce,
1407
284
         12,
1408
284
         metadata->clear_key_volume_master_key->aes_ccm_encrypted_key->data,
1409
284
         metadata->clear_key_volume_master_key->aes_ccm_encrypted_key->data_size,
1410
284
         unencrypted_data,
1411
284
         unencrypted_data_size,
1412
284
         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
284
    byte_stream_copy_to_uint16_little_endian(
1437
284
     &( unencrypted_data[ 16 ] ),
1438
284
     data_size );
1439
1440
284
    byte_stream_copy_to_uint16_little_endian(
1441
284
     &( unencrypted_data[ 20 ] ),
1442
284
     version );
1443
1444
284
    if( version == 1 )
1445
245
    {
1446
245
      if( data_size == 0x2c )
1447
197
      {
1448
197
        if( unencrypted_data_size < ( 28 + 32 ) )
1449
4
        {
1450
4
          libcerror_error_set(
1451
4
           error,
1452
4
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
1453
4
           LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1454
4
           "%s: unencrypted volume master key data size value out of bounds.",
1455
4
           function );
1456
1457
4
          goto on_error;
1458
4
        }
1459
193
        if( memory_copy(
1460
193
             volume_master_key,
1461
193
             &( unencrypted_data[ 28 ] ),
1462
193
             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
193
        result = 1;
1474
193
      }
1475
245
    }
1476
280
    if( libcaes_context_free(
1477
280
         &aes_context,
1478
280
         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
280
    if( memory_set(
1490
280
         unencrypted_data,
1491
280
         0,
1492
280
         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
280
    memory_free(
1504
280
     unencrypted_data );
1505
1506
280
    unencrypted_data = NULL;
1507
280
  }
1508
874
  if( result == 0 )
1509
681
  {
1510
681
    if( ( external_key != NULL )
1511
681
     && ( 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
681
  }
1741
874
  if( result == 0 )
1742
681
  {
1743
681
    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
681
  }
1988
874
  if( result == 0 )
1989
681
  {
1990
681
    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
681
  }
2235
874
  return( result );
2236
2237
33
on_error:
2238
33
  if( unencrypted_data != NULL )
2239
4
  {
2240
4
    memory_set(
2241
4
     unencrypted_data,
2242
4
     0,
2243
4
     unencrypted_data_size );
2244
4
    memory_free(
2245
4
     unencrypted_data );
2246
4
  }
2247
33
  if( aes_context != NULL )
2248
4
  {
2249
4
    libcaes_context_free(
2250
4
     &aes_context,
2251
4
     NULL );
2252
4
  }
2253
33
  return( -1 );
2254
874
}
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
193
{
2270
193
  uint8_t *unencrypted_data      = NULL;
2271
193
  libcaes_context_t *aes_context = NULL;
2272
193
  static char *function          = "libbde_metadata_read_full_volume_encryption_key";
2273
193
  size_t unencrypted_data_size   = 0;
2274
193
  uint32_t data_size             = 0;
2275
193
  uint32_t version               = 0;
2276
193
  int result                     = 0;
2277
2278
193
  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
193
  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
192
  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
187
  if( ( encryption_method != LIBBDE_ENCRYPTION_METHOD_AES_128_CBC )
2312
187
   && ( encryption_method != LIBBDE_ENCRYPTION_METHOD_AES_128_CBC_DIFFUSER )
2313
187
   && ( encryption_method != LIBBDE_ENCRYPTION_METHOD_AES_256_CBC )
2314
187
   && ( encryption_method != LIBBDE_ENCRYPTION_METHOD_AES_256_CBC_DIFFUSER )
2315
187
   && ( encryption_method != LIBBDE_ENCRYPTION_METHOD_AES_128_XTS )
2316
187
   && ( encryption_method != LIBBDE_ENCRYPTION_METHOD_AES_256_XTS ) )
2317
28
  {
2318
28
    libcerror_error_set(
2319
28
     error,
2320
28
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2321
28
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
2322
28
     "%s: unsupported encryption method.",
2323
28
     function );
2324
2325
28
    return( -1 );
2326
28
  }
2327
159
  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
159
  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
159
  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
159
  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
159
  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
159
  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
159
  unencrypted_data_size = metadata->full_volume_encryption_key->data_size;
2394
2395
159
  if( ( unencrypted_data_size == 0 )
2396
159
   || ( 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
159
  unencrypted_data = (uint8_t *) memory_allocate(
2408
159
                                  unencrypted_data_size );
2409
2410
159
  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
159
  if( memory_set(
2422
159
       unencrypted_data,
2423
159
       0,
2424
159
       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
159
  if( libcaes_context_initialize(
2436
159
       &aes_context,
2437
159
       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
159
  if( libcaes_context_set_key(
2449
159
       aes_context,
2450
159
       LIBCAES_CRYPT_MODE_ENCRYPT,
2451
159
       volume_master_key,
2452
159
       256,
2453
159
       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
159
  if( libcaes_crypt_ccm(
2465
159
       aes_context,
2466
159
       LIBCAES_CRYPT_MODE_DECRYPT,
2467
159
       metadata->full_volume_encryption_key->nonce,
2468
159
       12,
2469
159
       metadata->full_volume_encryption_key->data,
2470
159
       metadata->full_volume_encryption_key->data_size,
2471
159
       unencrypted_data,
2472
159
       unencrypted_data_size,
2473
159
       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
159
  byte_stream_copy_to_uint16_little_endian(
2498
159
   &( unencrypted_data[ 16 ] ),
2499
159
   data_size );
2500
2501
159
  byte_stream_copy_to_uint16_little_endian(
2502
159
   &( unencrypted_data[ 20 ] ),
2503
159
   version );
2504
2505
159
  if( version == 1 )
2506
93
  {
2507
93
    if( encryption_method == LIBBDE_ENCRYPTION_METHOD_AES_128_CBC )
2508
24
    {
2509
24
      if( data_size != 0x1c )
2510
18
      {
2511
18
        libcerror_error_set(
2512
18
         error,
2513
18
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
2514
18
         LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
2515
18
         "%s: unsupported data size.",
2516
18
         function );
2517
2518
18
        goto on_error;
2519
18
      }
2520
6
      if( unencrypted_data_size < 44 )
2521
3
      {
2522
3
        libcerror_error_set(
2523
3
         error,
2524
3
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
2525
3
         LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
2526
3
         "%s: invalid unencrypted data size value out of bounds.",
2527
3
         function );
2528
2529
3
        goto on_error;
2530
3
      }
2531
3
      if( memory_copy(
2532
3
           full_volume_encryption_key,
2533
3
           &( unencrypted_data[ 28 ] ),
2534
3
           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
3
      result = 1;
2546
3
    }
2547
69
    else if( ( encryption_method == LIBBDE_ENCRYPTION_METHOD_AES_256_CBC )
2548
69
          || ( encryption_method == LIBBDE_ENCRYPTION_METHOD_AES_128_XTS ) )
2549
27
    {
2550
27
      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
10
      if( unencrypted_data_size < 60 )
2562
4
      {
2563
4
        libcerror_error_set(
2564
4
         error,
2565
4
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
2566
4
         LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
2567
4
         "%s: invalid unencrypted data size value out of bounds.",
2568
4
         function );
2569
2570
4
        goto on_error;
2571
4
      }
2572
6
      if( memory_copy(
2573
6
           full_volume_encryption_key,
2574
6
           &( unencrypted_data[ 28 ] ),
2575
6
           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
6
      result = 1;
2587
6
    }
2588
42
    else if( ( encryption_method == LIBBDE_ENCRYPTION_METHOD_AES_128_CBC_DIFFUSER )
2589
42
          || ( encryption_method == LIBBDE_ENCRYPTION_METHOD_AES_256_CBC_DIFFUSER ) )
2590
27
    {
2591
27
      if( data_size != 0x4c )
2592
18
      {
2593
18
        libcerror_error_set(
2594
18
         error,
2595
18
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
2596
18
         LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
2597
18
         "%s: unsupported data size.",
2598
18
         function );
2599
2600
18
        goto on_error;
2601
18
      }
2602
9
      if( unencrypted_data_size < 92 )
2603
4
      {
2604
4
        libcerror_error_set(
2605
4
         error,
2606
4
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
2607
4
         LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
2608
4
         "%s: invalid unencrypted data size value out of bounds.",
2609
4
         function );
2610
2611
4
        goto on_error;
2612
4
      }
2613
5
      if( memory_copy(
2614
5
           full_volume_encryption_key,
2615
5
           &( unencrypted_data[ 28 ] ),
2616
5
           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
5
      if( memory_copy(
2628
5
           tweak_key,
2629
5
           &( unencrypted_data[ 60 ] ),
2630
5
           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
5
      result = 1;
2642
5
    }
2643
15
    else if( encryption_method == LIBBDE_ENCRYPTION_METHOD_AES_256_XTS )
2644
15
    {
2645
15
      if( data_size != 0x4c )
2646
1
      {
2647
1
        libcerror_error_set(
2648
1
         error,
2649
1
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
2650
1
         LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
2651
1
         "%s: unsupported data size.",
2652
1
         function );
2653
2654
1
        goto on_error;
2655
1
      }
2656
14
      if( unencrypted_data_size < 92 )
2657
5
      {
2658
5
        libcerror_error_set(
2659
5
         error,
2660
5
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
2661
5
         LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
2662
5
         "%s: invalid unencrypted data size value out of bounds.",
2663
5
         function );
2664
2665
5
        goto on_error;
2666
5
      }
2667
9
      if( memory_copy(
2668
9
           full_volume_encryption_key,
2669
9
           &( unencrypted_data[ 28 ] ),
2670
9
           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
9
      result = 1;
2682
9
    }
2683
93
  }
2684
89
  if( libcaes_context_free(
2685
89
       &aes_context,
2686
89
       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
89
  if( unencrypted_data != NULL )
2698
89
  {
2699
89
    if( memory_set(
2700
89
         unencrypted_data,
2701
89
         0,
2702
89
         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
89
    memory_free(
2714
89
     unencrypted_data );
2715
89
  }
2716
89
  return( result );
2717
2718
70
on_error:
2719
70
  if( unencrypted_data != NULL )
2720
70
  {
2721
70
    memory_set(
2722
70
     unencrypted_data,
2723
70
     0,
2724
70
     unencrypted_data_size );
2725
70
    memory_free(
2726
70
     unencrypted_data );
2727
70
  }
2728
70
  if( aes_context != NULL )
2729
70
  {
2730
70
    libcaes_context_free(
2731
70
     &aes_context,
2732
70
     NULL );
2733
70
  }
2734
70
  return( -1 );
2735
89
}
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