Coverage Report

Created: 2026-04-04 07:47

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libbde/libbde/libbde_volume_master_key.c
Line
Count
Source
1
/*
2
 * Volume Master Key (VMK) metadata entry functions
3
 *
4
 * Copyright (C) 2011-2025, 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_debug.h"
30
#include "libbde_definitions.h"
31
#include "libbde_io_handle.h"
32
#include "libbde_key.h"
33
#include "libbde_libcdata.h"
34
#include "libbde_libcerror.h"
35
#include "libbde_libcnotify.h"
36
#include "libbde_libfdatetime.h"
37
#include "libbde_libfguid.h"
38
#include "libbde_metadata_entry.h"
39
#include "libbde_stretch_key.h"
40
#include "libbde_volume_master_key.h"
41
42
#include "bde_metadata.h"
43
44
/* Creates a volume master key
45
 * Make sure the value volume master key is referencing, is set to NULL
46
 * Returns 1 if successful or -1 on error
47
 */
48
int libbde_volume_master_key_initialize(
49
     libbde_volume_master_key_t **volume_master_key,
50
     libcerror_error_t **error )
51
5.24k
{
52
5.24k
  static char *function = "libbde_volume_master_key_initialize";
53
54
5.24k
  if( volume_master_key == NULL )
55
0
  {
56
0
    libcerror_error_set(
57
0
     error,
58
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
59
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
60
0
     "%s: invalid volume master key.",
61
0
     function );
62
63
0
    return( -1 );
64
0
  }
65
5.24k
  if( *volume_master_key != NULL )
66
0
  {
67
0
    libcerror_error_set(
68
0
     error,
69
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
70
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
71
0
     "%s: invalid volume master key value already set.",
72
0
     function );
73
74
0
    return( -1 );
75
0
  }
76
5.24k
  *volume_master_key = memory_allocate_structure(
77
5.24k
                        libbde_volume_master_key_t );
78
79
5.24k
  if( *volume_master_key == NULL )
80
0
  {
81
0
    libcerror_error_set(
82
0
     error,
83
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
84
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
85
0
     "%s: unable to create volume master key.",
86
0
     function );
87
88
0
    goto on_error;
89
0
  }
90
5.24k
  if( memory_set(
91
5.24k
       *volume_master_key,
92
5.24k
       0,
93
5.24k
       sizeof( libbde_volume_master_key_t ) ) == NULL )
94
0
  {
95
0
    libcerror_error_set(
96
0
     error,
97
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
98
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
99
0
     "%s: unable to clear volume master key.",
100
0
     function );
101
102
0
    memory_free(
103
0
     *volume_master_key );
104
105
0
    *volume_master_key = NULL;
106
107
0
    return( -1 );
108
0
  }
109
5.24k
  if( libcdata_array_initialize(
110
5.24k
       &( ( *volume_master_key )->entries_array ),
111
5.24k
       0,
112
5.24k
       error ) != 1 )
113
0
  {
114
0
    libcerror_error_set(
115
0
     error,
116
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
117
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
118
0
     "%s: unable to create entries array.",
119
0
     function );
120
121
0
    goto on_error;
122
0
  }
123
5.24k
  return( 1 );
124
125
0
on_error:
126
0
  if( *volume_master_key != NULL )
127
0
  {
128
0
    memory_free(
129
0
     *volume_master_key );
130
131
0
    *volume_master_key = NULL;
132
0
  }
133
0
  return( -1 );
134
5.24k
}
135
136
/* Frees a volume master key
137
 * Returns 1 if successful or -1 on error
138
 */
139
int libbde_volume_master_key_free(
140
     libbde_volume_master_key_t **volume_master_key,
141
     libcerror_error_t **error )
142
5.24k
{
143
5.24k
  static char *function = "libbde_volume_master_key_free";
144
5.24k
  int result            = 1;
145
146
5.24k
  if( volume_master_key == NULL )
147
0
  {
148
0
    libcerror_error_set(
149
0
     error,
150
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
151
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
152
0
     "%s: invalid volume master key.",
153
0
     function );
154
155
0
    return( -1 );
156
0
  }
157
5.24k
  if( *volume_master_key != NULL )
158
5.24k
  {
159
5.24k
    if( ( *volume_master_key )->key != NULL )
160
830
    {
161
830
      if( libbde_key_free(
162
830
           &( ( *volume_master_key )->key ),
163
830
           error ) != 1 )
164
0
      {
165
0
        libcerror_error_set(
166
0
         error,
167
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
168
0
         LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
169
0
         "%s: unable to free key.",
170
0
         function );
171
172
0
        result = -1;
173
0
      }
174
830
    }
175
5.24k
    if( ( *volume_master_key )->stretch_key != NULL )
176
507
    {
177
507
      if( libbde_stretch_key_free(
178
507
           &( ( *volume_master_key )->stretch_key ),
179
507
           error ) != 1 )
180
0
      {
181
0
        libcerror_error_set(
182
0
         error,
183
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
184
0
         LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
185
0
         "%s: unable to free stretch key.",
186
0
         function );
187
188
0
        result = -1;
189
0
      }
190
507
    }
191
5.24k
    if( ( *volume_master_key )->aes_ccm_encrypted_key != NULL )
192
974
    {
193
974
      if( libbde_aes_ccm_encrypted_key_free(
194
974
           &( ( *volume_master_key )->aes_ccm_encrypted_key ),
195
974
           error ) != 1 )
196
0
      {
197
0
        libcerror_error_set(
198
0
         error,
199
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
200
0
         LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
201
0
         "%s: unable to free AES-CCM encrypted key.",
202
0
         function );
203
204
0
        result = -1;
205
0
      }
206
974
    }
207
5.24k
    if( libcdata_array_free(
208
5.24k
         &( ( *volume_master_key )->entries_array ),
209
5.24k
         (int(*)(intptr_t **, libcerror_error_t **)) &libbde_metadata_entry_free,
210
5.24k
         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 entries array.",
217
0
       function );
218
219
0
      result = -1;
220
0
    }
221
5.24k
    memory_free(
222
5.24k
     *volume_master_key );
223
224
5.24k
    *volume_master_key = NULL;
225
5.24k
  }
226
5.24k
  return( result );
227
5.24k
}
228
229
/* Reads a volume master key from the metadata entry
230
 * Returns 1 if successful or -1 on error
231
 */
232
int libbde_volume_master_key_read(
233
     libbde_volume_master_key_t *volume_master_key,
234
     libbde_metadata_entry_t *metadata_entry,
235
     libcerror_error_t **error )
236
5.24k
{
237
5.24k
  libbde_aes_ccm_encrypted_key_t *aes_ccm_encrypted_key = NULL;
238
5.24k
  libbde_key_t *key                                     = NULL;
239
5.24k
  libbde_metadata_entry_t *property_metadata_entry      = NULL;
240
5.24k
  libbde_stretch_key_t *stretch_key                     = NULL;
241
5.24k
  uint8_t *value_data                                   = NULL;
242
5.24k
  static char *function                                 = "libbde_volume_master_key_read";
243
5.24k
  size_t value_data_size                                = 0;
244
5.24k
  ssize_t read_count                                    = 0;
245
5.24k
  int property_metadata_entry_index                     = 0;
246
247
#if defined( HAVE_DEBUG_OUTPUT )
248
  uint16_t value_16bit                                  = 0;
249
#endif
250
251
5.24k
  if( volume_master_key == NULL )
252
0
  {
253
0
    libcerror_error_set(
254
0
     error,
255
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
256
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
257
0
     "%s: invalid volume master key.",
258
0
     function );
259
260
0
    return( -1 );
261
0
  }
262
5.24k
  if( metadata_entry == NULL )
263
0
  {
264
0
    libcerror_error_set(
265
0
     error,
266
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
267
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
268
0
     "%s: invalid metadata entry.",
269
0
     function );
270
271
0
    return( -1 );
272
0
  }
273
5.24k
  if( metadata_entry->value_type != LIBBDE_VALUE_TYPE_VOLUME_MASTER_KEY )
274
19
  {
275
19
    libcerror_error_set(
276
19
     error,
277
19
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
278
19
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
279
19
     "%s: invalid metadata entry - unsupported value type: 0x%04" PRIx16 ".",
280
19
     function,
281
19
     metadata_entry->value_type );
282
283
19
    return( -1 );
284
19
  }
285
5.22k
  value_data      = metadata_entry->value_data;
286
5.22k
  value_data_size = metadata_entry->value_data_size;
287
288
5.22k
  if( value_data_size < sizeof( bde_metadata_entry_volume_master_key_header_t ) )
289
4
  {
290
4
    libcerror_error_set(
291
4
     error,
292
4
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
293
4
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
294
4
     "%s: value data size value out of bounds.",
295
4
     function );
296
297
4
    return( -1 );
298
4
  }
299
5.22k
  if( memory_copy(
300
5.22k
       volume_master_key->identifier,
301
5.22k
       ( (bde_metadata_entry_volume_master_key_header_t *) value_data )->identifier,
302
5.22k
       16 ) == NULL )
303
0
  {
304
0
    libcerror_error_set(
305
0
     error,
306
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
307
0
     LIBCERROR_MEMORY_ERROR_COPY_FAILED,
308
0
     "%s: unable to copy volume identifier.",
309
0
     function );
310
311
0
    goto on_error;
312
0
  }
313
5.22k
  byte_stream_copy_to_uint16_little_endian(
314
5.22k
   ( (bde_metadata_entry_volume_master_key_header_t *) value_data )->protection_type,
315
5.22k
   volume_master_key->protection_type );
316
317
#if defined( HAVE_DEBUG_OUTPUT )
318
  if( libcnotify_verbose != 0 )
319
  {
320
    if( libbde_debug_print_guid_value(
321
         function,
322
         "identifier\t\t\t\t",
323
         ( (bde_metadata_entry_volume_master_key_header_t *) value_data )->identifier,
324
         16,
325
         LIBFGUID_ENDIAN_LITTLE,
326
         LIBFGUID_STRING_FORMAT_FLAG_USE_LOWER_CASE,
327
         error ) != 1 )
328
    {
329
      libcerror_error_set(
330
       error,
331
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
332
       LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
333
       "%s: unable to print GUID value.",
334
       function );
335
336
      goto on_error;
337
    }
338
    if( libbde_debug_print_filetime_value(
339
         function,
340
         "modification time\t\t\t",
341
         ( (bde_metadata_entry_volume_master_key_header_t *) value_data )->modification_time,
342
         8,
343
         LIBFDATETIME_ENDIAN_LITTLE,
344
         LIBFDATETIME_STRING_FORMAT_TYPE_CTIME | LIBFDATETIME_STRING_FORMAT_FLAG_DATE_TIME_NANO_SECONDS,
345
         error ) != 1 )
346
    {
347
      libcerror_error_set(
348
       error,
349
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
350
       LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
351
       "%s: unable to print FILETIME value.",
352
       function );
353
354
      goto on_error;
355
    }
356
    byte_stream_copy_to_uint16_little_endian(
357
     ( (bde_metadata_entry_volume_master_key_header_t *) value_data )->unknown1,
358
     value_16bit );
359
    libcnotify_printf(
360
     "%s: unknown1\t\t\t\t\t: %" PRIu16 "\n",
361
     function,
362
     value_16bit );
363
364
    libcnotify_printf(
365
     "%s: protection type\t\t\t\t: 0x%04" PRIx16 " (%s)\n",
366
     function,
367
     volume_master_key->protection_type,
368
     libbde_debug_print_key_protection_type(
369
      volume_master_key->protection_type ) );
370
371
    libcnotify_printf(
372
     "\n" );
373
  }
374
#endif
375
5.22k
  value_data      += sizeof( bde_metadata_entry_volume_master_key_header_t );
376
5.22k
  value_data_size -= sizeof( bde_metadata_entry_volume_master_key_header_t );
377
378
12.4k
  while( value_data_size >= sizeof( bde_metadata_entry_v1_t ) )
379
8.25k
  {
380
8.25k
    if( memory_compare(
381
8.25k
         value_data,
382
8.25k
         libbde_metadata_entry_empty,
383
8.25k
         sizeof( bde_metadata_entry_v1_t ) ) == 0 )
384
987
    {
385
987
      break;
386
987
    }
387
7.26k
    if( libbde_metadata_entry_initialize(
388
7.26k
         &property_metadata_entry,
389
7.26k
         error ) != 1 )
390
0
    {
391
0
      libcerror_error_set(
392
0
       error,
393
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
394
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
395
0
       "%s: unable to create property metadata entry.",
396
0
       function );
397
398
0
      goto on_error;
399
0
    }
400
7.26k
    read_count = libbde_metadata_entry_read(
401
7.26k
            property_metadata_entry,
402
7.26k
            value_data,
403
7.26k
            value_data_size,
404
7.26k
            error );
405
406
7.26k
    if( read_count == -1 )
407
35
    {
408
35
      libcerror_error_set(
409
35
       error,
410
35
       LIBCERROR_ERROR_DOMAIN_IO,
411
35
       LIBCERROR_IO_ERROR_READ_FAILED,
412
35
       "%s: unable to read property metadata entry.",
413
35
       function );
414
415
35
      goto on_error;
416
35
    }
417
7.23k
    value_data      += read_count;
418
7.23k
    value_data_size -= read_count;
419
420
7.23k
    if( property_metadata_entry->value_type == LIBBDE_VALUE_TYPE_KEY )
421
1.33k
    {
422
1.33k
      if( libbde_key_initialize(
423
1.33k
           &key,
424
1.33k
           error ) != 1 )
425
0
      {
426
0
        libcerror_error_set(
427
0
         error,
428
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
429
0
         LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
430
0
         "%s: unable to create key.",
431
0
         function );
432
433
0
        goto on_error;
434
0
      }
435
1.33k
      if( libbde_key_read(
436
1.33k
           key,
437
1.33k
           property_metadata_entry,
438
1.33k
           error ) != 1 )
439
1
      {
440
1
        libcerror_error_set(
441
1
         error,
442
1
         LIBCERROR_ERROR_DOMAIN_IO,
443
1
         LIBCERROR_IO_ERROR_READ_FAILED,
444
1
         "%s: unable to read key metadata entry.",
445
1
         function );
446
447
1
        goto on_error;
448
1
      }
449
1.33k
      if( volume_master_key->key == NULL )
450
830
      {
451
830
        volume_master_key->key = key;
452
453
830
        key = NULL;
454
830
      }
455
1.33k
      if( key != NULL )
456
500
      {
457
500
        if( libbde_key_free(
458
500
             &key,
459
500
             error ) != 1 )
460
0
        {
461
0
          libcerror_error_set(
462
0
           error,
463
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
464
0
           LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
465
0
           "%s: unable to free key.",
466
0
           function );
467
468
0
          goto on_error;
469
0
        }
470
500
      }
471
1.33k
    }
472
5.90k
    else if( property_metadata_entry->value_type == LIBBDE_VALUE_TYPE_UNICODE_STRING )
473
1.62k
    {
474
#if defined( HAVE_DEBUG_OUTPUT )
475
      if( libbde_metadata_entry_read_string(
476
           property_metadata_entry,
477
           error ) != 1 )
478
      {
479
        libcerror_error_set(
480
         error,
481
         LIBCERROR_ERROR_DOMAIN_IO,
482
         LIBCERROR_IO_ERROR_READ_FAILED,
483
         "%s: unable to read string from property metadata entry.",
484
         function );
485
486
        goto on_error;
487
      }
488
#endif
489
1.62k
      if( volume_master_key->string_entry == NULL )
490
1.09k
      {
491
1.09k
        volume_master_key->string_entry = property_metadata_entry;
492
1.09k
      }
493
1.62k
    }
494
4.28k
    else if( property_metadata_entry->value_type == LIBBDE_VALUE_TYPE_STRETCH_KEY )
495
761
    {
496
761
      if( libbde_stretch_key_initialize(
497
761
           &stretch_key,
498
761
           error ) != 1 )
499
0
      {
500
0
        libcerror_error_set(
501
0
         error,
502
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
503
0
         LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
504
0
         "%s: unable to create stretch key.",
505
0
         function );
506
507
0
        goto on_error;
508
0
      }
509
761
      if( libbde_stretch_key_read(
510
761
           stretch_key,
511
761
           property_metadata_entry,
512
761
           error ) != 1 )
513
6
      {
514
6
        libcerror_error_set(
515
6
         error,
516
6
         LIBCERROR_ERROR_DOMAIN_IO,
517
6
         LIBCERROR_IO_ERROR_READ_FAILED,
518
6
         "%s: unable to read stretch key metadata entry.",
519
6
         function );
520
521
6
        goto on_error;
522
6
      }
523
755
      if( volume_master_key->stretch_key == NULL )
524
507
      {
525
507
        volume_master_key->stretch_key = stretch_key;
526
527
507
        stretch_key = NULL;
528
507
      }
529
755
      if( stretch_key != NULL )
530
248
      {
531
248
        if( libbde_stretch_key_free(
532
248
             &stretch_key,
533
248
             error ) != 1 )
534
0
        {
535
0
          libcerror_error_set(
536
0
           error,
537
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
538
0
           LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
539
0
           "%s: unable to free stretch key.",
540
0
           function );
541
542
0
          goto on_error;
543
0
        }
544
248
      }
545
755
    }
546
3.52k
    else if( property_metadata_entry->value_type == LIBBDE_VALUE_TYPE_AES_CCM_ENCRYPTED_KEY )
547
1.45k
    {
548
1.45k
      if( libbde_aes_ccm_encrypted_key_initialize(
549
1.45k
           &aes_ccm_encrypted_key,
550
1.45k
           error ) != 1 )
551
0
      {
552
0
        libcerror_error_set(
553
0
         error,
554
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
555
0
         LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
556
0
         "%s: unable to create AES-CCM encrypted key.",
557
0
         function );
558
559
0
        goto on_error;
560
0
      }
561
1.45k
      if( libbde_aes_ccm_encrypted_key_read(
562
1.45k
           aes_ccm_encrypted_key,
563
1.45k
           property_metadata_entry,
564
1.45k
           error ) != 1 )
565
3
      {
566
3
        libcerror_error_set(
567
3
         error,
568
3
         LIBCERROR_ERROR_DOMAIN_IO,
569
3
         LIBCERROR_IO_ERROR_READ_FAILED,
570
3
         "%s: unable to read AES-CCM encrypted key from property metadata entry.",
571
3
         function );
572
573
3
        goto on_error;
574
3
      }
575
1.45k
      if( volume_master_key->aes_ccm_encrypted_key == NULL )
576
974
      {
577
974
        volume_master_key->aes_ccm_encrypted_key = aes_ccm_encrypted_key;
578
579
974
        aes_ccm_encrypted_key = NULL;
580
974
      }
581
1.45k
      if( aes_ccm_encrypted_key != NULL )
582
477
      {
583
477
        if( libbde_aes_ccm_encrypted_key_free(
584
477
             &aes_ccm_encrypted_key,
585
477
             error ) != 1 )
586
0
        {
587
0
          libcerror_error_set(
588
0
           error,
589
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
590
0
           LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
591
0
           "%s: unable to free AES-CCM encrypted key.",
592
0
           function );
593
594
0
          goto on_error;
595
0
        }
596
477
      }
597
1.45k
    }
598
7.22k
    if( libcdata_array_append_entry(
599
7.22k
         volume_master_key->entries_array,
600
7.22k
         &property_metadata_entry_index,
601
7.22k
         (intptr_t *) property_metadata_entry,
602
7.22k
         error ) != 1 )
603
0
    {
604
0
      libcerror_error_set(
605
0
       error,
606
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
607
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
608
0
       "%s: unable to append property metadata entry to entries array.",
609
0
       function );
610
611
0
      goto on_error;
612
0
    }
613
7.22k
    property_metadata_entry = NULL;
614
7.22k
  }
615
#if defined( HAVE_DEBUG_OUTPUT )
616
  if( libcnotify_verbose != 0 )
617
  {
618
    if( value_data_size > 0 )
619
    {
620
      libcnotify_printf(
621
       "%s: trailing data:\n",
622
       function );
623
      libcnotify_print_data(
624
       value_data,
625
       value_data_size,
626
       LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
627
    }
628
  }
629
#endif
630
5.17k
  return( 1 );
631
632
45
on_error:
633
45
  if( aes_ccm_encrypted_key != NULL )
634
3
  {
635
3
    libbde_aes_ccm_encrypted_key_free(
636
3
     &aes_ccm_encrypted_key,
637
3
     NULL );
638
3
  }
639
45
  if( stretch_key != NULL )
640
6
  {
641
6
    libbde_stretch_key_free(
642
6
     &stretch_key,
643
6
     NULL );
644
6
  }
645
45
  if( key != NULL )
646
1
  {
647
1
    libbde_key_free(
648
1
     &key,
649
1
     NULL );
650
1
  }
651
45
  if( property_metadata_entry != NULL )
652
45
  {
653
45
    libbde_metadata_entry_free(
654
45
     &property_metadata_entry,
655
45
     NULL );
656
45
  }
657
45
  return( -1 );
658
5.22k
}
659
660
/* Retrieves the identifier
661
 * The identifier is a GUID and is 16 bytes of size
662
 * Returns 1 if successful or -1 on error
663
 */
664
int libbde_volume_master_key_get_identifier(
665
     libbde_volume_master_key_t *volume_master_key,
666
     uint8_t *guid_data,
667
     size_t guid_data_size,
668
     libcerror_error_t **error )
669
0
{
670
0
  static char *function = "libbde_volume_master_key_get_identifier";
671
672
0
  if( volume_master_key == NULL )
673
0
  {
674
0
    libcerror_error_set(
675
0
     error,
676
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
677
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
678
0
     "%s: invalid volume master key.",
679
0
     function );
680
681
0
    return( -1 );
682
0
  }
683
0
  if( guid_data == NULL )
684
0
  {
685
0
    libcerror_error_set(
686
0
     error,
687
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
688
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
689
0
     "%s: invalid GUID data.",
690
0
     function );
691
692
0
    return( -1 );
693
0
  }
694
0
  if( guid_data_size < 16 )
695
0
  {
696
0
    libcerror_error_set(
697
0
     error,
698
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
699
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
700
0
     "%s: invalid GUID data size value too small.",
701
0
     function );
702
703
0
    return( -1 );
704
0
  }
705
0
  if( memory_copy(
706
0
       guid_data,
707
0
       volume_master_key->identifier,
708
0
       16 ) == NULL )
709
0
  {
710
0
    libcerror_error_set(
711
0
     error,
712
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
713
0
     LIBCERROR_MEMORY_ERROR_COPY_FAILED,
714
0
     "%s: unable to copy GUID data.",
715
0
     function );
716
717
0
    return( -1 );
718
0
  }
719
0
  return( 1 );
720
0
}
721
722
/* Retrieves the protection type
723
 * Returns 1 if successful or -1 on error
724
 */
725
int libbde_volume_master_key_get_protection_type(
726
     libbde_volume_master_key_t *volume_master_key,
727
     uint16_t *protection_type,
728
     libcerror_error_t **error )
729
0
{
730
0
  static char *function = "libbde_volume_master_key_get_protection_type";
731
732
0
  if( volume_master_key == NULL )
733
0
  {
734
0
    libcerror_error_set(
735
0
     error,
736
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
737
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
738
0
     "%s: invalid volume master key.",
739
0
     function );
740
741
0
    return( -1 );
742
0
  }
743
0
  if( protection_type == NULL )
744
0
  {
745
0
    libcerror_error_set(
746
0
     error,
747
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
748
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
749
0
     "%s: invalid protection type.",
750
0
     function );
751
752
0
    return( -1 );
753
0
  }
754
0
  *protection_type = volume_master_key->protection_type;
755
756
0
  return( 1 );
757
0
}
758