Coverage Report

Created: 2026-10-22 07:28

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