Coverage Report

Created: 2025-06-13 07:22

/src/libbde/libbde/libbde_volume_master_key.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Volume Master Key (VMK) metadata entry functions
3
 *
4
 * Copyright (C) 2011-2024, Joachim Metz <joachim.metz@gmail.com>
5
 *
6
 * Refer to AUTHORS for acknowledgements.
7
 *
8
 * This program is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU Lesser General Public License as published by
10
 * the Free Software Foundation, either version 3 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public License
19
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20
 */
21
22
#include <common.h>
23
#include <byte_stream.h>
24
#include <memory.h>
25
#include <system_string.h>
26
#include <types.h>
27
28
#include "libbde_aes_ccm_encrypted_key.h"
29
#include "libbde_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
4.33k
{
52
4.33k
  static char *function = "libbde_volume_master_key_initialize";
53
54
4.33k
  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
4.33k
  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
4.33k
  *volume_master_key = memory_allocate_structure(
77
4.33k
                        libbde_volume_master_key_t );
78
79
4.33k
  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
4.33k
  if( memory_set(
91
4.33k
       *volume_master_key,
92
4.33k
       0,
93
4.33k
       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
4.33k
  if( libcdata_array_initialize(
110
4.33k
       &( ( *volume_master_key )->entries_array ),
111
4.33k
       0,
112
4.33k
       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
4.33k
  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
4.33k
}
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
4.33k
{
143
4.33k
  static char *function = "libbde_volume_master_key_free";
144
4.33k
  int result            = 1;
145
146
4.33k
  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
4.33k
  if( *volume_master_key != NULL )
158
4.33k
  {
159
4.33k
    if( ( *volume_master_key )->key != NULL )
160
672
    {
161
672
      if( libbde_key_free(
162
672
           &( ( *volume_master_key )->key ),
163
672
           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
672
    }
175
4.33k
    if( ( *volume_master_key )->stretch_key != NULL )
176
401
    {
177
401
      if( libbde_stretch_key_free(
178
401
           &( ( *volume_master_key )->stretch_key ),
179
401
           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
401
    }
191
4.33k
    if( ( *volume_master_key )->aes_ccm_encrypted_key != NULL )
192
890
    {
193
890
      if( libbde_aes_ccm_encrypted_key_free(
194
890
           &( ( *volume_master_key )->aes_ccm_encrypted_key ),
195
890
           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
890
    }
207
4.33k
    if( libcdata_array_free(
208
4.33k
         &( ( *volume_master_key )->entries_array ),
209
4.33k
         (int(*)(intptr_t **, libcerror_error_t **)) &libbde_metadata_entry_free,
210
4.33k
         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
4.33k
    memory_free(
222
4.33k
     *volume_master_key );
223
224
4.33k
    *volume_master_key = NULL;
225
4.33k
  }
226
4.33k
  return( result );
227
4.33k
}
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
4.33k
{
237
4.33k
  libbde_aes_ccm_encrypted_key_t *aes_ccm_encrypted_key = NULL;
238
4.33k
  libbde_key_t *key                                     = NULL;
239
4.33k
  libbde_metadata_entry_t *property_metadata_entry      = NULL;
240
4.33k
  libbde_stretch_key_t *stretch_key                     = NULL;
241
4.33k
  uint8_t *value_data                                   = NULL;
242
4.33k
  static char *function                                 = "libbde_volume_master_key_read";
243
4.33k
  size_t value_data_size                                = 0;
244
4.33k
  ssize_t read_count                                    = 0;
245
4.33k
  int property_metadata_entry_index                     = 0;
246
247
#if defined( HAVE_DEBUG_OUTPUT )
248
  uint16_t value_16bit                                  = 0;
249
#endif
250
251
4.33k
  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
4.33k
  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
4.33k
  if( metadata_entry->value_type != LIBBDE_VALUE_TYPE_VOLUME_MASTER_KEY )
274
17
  {
275
17
    libcerror_error_set(
276
17
     error,
277
17
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
278
17
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
279
17
     "%s: invalid metadata entry - unsupported value type: 0x%04" PRIx16 ".",
280
17
     function,
281
17
     metadata_entry->value_type );
282
283
17
    return( -1 );
284
17
  }
285
4.31k
  value_data      = metadata_entry->value_data;
286
4.31k
  value_data_size = metadata_entry->value_data_size;
287
288
4.31k
  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
4.30k
  if( memory_copy(
300
4.30k
       volume_master_key->identifier,
301
4.30k
       ( (bde_metadata_entry_volume_master_key_header_t *) value_data )->identifier,
302
4.30k
       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
4.30k
  byte_stream_copy_to_uint16_little_endian(
314
4.30k
   ( (bde_metadata_entry_volume_master_key_header_t *) value_data )->protection_type,
315
4.30k
   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
4.30k
  value_data      += sizeof( bde_metadata_entry_volume_master_key_header_t );
376
4.30k
  value_data_size -= sizeof( bde_metadata_entry_volume_master_key_header_t );
377
378
13.8k
  while( value_data_size >= sizeof( bde_metadata_entry_v1_t ) )
379
10.3k
  {
380
10.3k
    if( memory_compare(
381
10.3k
         value_data,
382
10.3k
         libbde_metadata_entry_empty,
383
10.3k
         sizeof( bde_metadata_entry_v1_t ) ) == 0 )
384
784
    {
385
784
      break;
386
784
    }
387
9.52k
    if( libbde_metadata_entry_initialize(
388
9.52k
         &property_metadata_entry,
389
9.52k
         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
9.52k
    read_count = libbde_metadata_entry_read(
401
9.52k
            property_metadata_entry,
402
9.52k
            value_data,
403
9.52k
            value_data_size,
404
9.52k
            error );
405
406
9.52k
    if( read_count == -1 )
407
27
    {
408
27
      libcerror_error_set(
409
27
       error,
410
27
       LIBCERROR_ERROR_DOMAIN_IO,
411
27
       LIBCERROR_IO_ERROR_READ_FAILED,
412
27
       "%s: unable to read property metadata entry.",
413
27
       function );
414
415
27
      goto on_error;
416
27
    }
417
9.50k
    value_data      += read_count;
418
9.50k
    value_data_size -= read_count;
419
420
9.50k
    if( property_metadata_entry->value_type == LIBBDE_VALUE_TYPE_KEY )
421
1.16k
    {
422
1.16k
      if( libbde_key_initialize(
423
1.16k
           &key,
424
1.16k
           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.16k
      if( libbde_key_read(
436
1.16k
           key,
437
1.16k
           property_metadata_entry,
438
1.16k
           error ) != 1 )
439
2
      {
440
2
        libcerror_error_set(
441
2
         error,
442
2
         LIBCERROR_ERROR_DOMAIN_IO,
443
2
         LIBCERROR_IO_ERROR_READ_FAILED,
444
2
         "%s: unable to read key metadata entry.",
445
2
         function );
446
447
2
        goto on_error;
448
2
      }
449
1.16k
      if( volume_master_key->key == NULL )
450
672
      {
451
672
        volume_master_key->key = key;
452
453
672
        key = NULL;
454
672
      }
455
1.16k
      if( key != NULL )
456
492
      {
457
492
        if( libbde_key_free(
458
492
             &key,
459
492
             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
492
      }
471
1.16k
    }
472
8.33k
    else if( property_metadata_entry->value_type == LIBBDE_VALUE_TYPE_UNICODE_STRING )
473
1.68k
    {
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.68k
      if( volume_master_key->string_entry == NULL )
490
923
      {
491
923
        volume_master_key->string_entry = property_metadata_entry;
492
923
      }
493
1.68k
    }
494
6.65k
    else if( property_metadata_entry->value_type == LIBBDE_VALUE_TYPE_STRETCH_KEY )
495
1.03k
    {
496
1.03k
      if( libbde_stretch_key_initialize(
497
1.03k
           &stretch_key,
498
1.03k
           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
1.03k
      if( libbde_stretch_key_read(
510
1.03k
           stretch_key,
511
1.03k
           property_metadata_entry,
512
1.03k
           error ) != 1 )
513
3
      {
514
3
        libcerror_error_set(
515
3
         error,
516
3
         LIBCERROR_ERROR_DOMAIN_IO,
517
3
         LIBCERROR_IO_ERROR_READ_FAILED,
518
3
         "%s: unable to read stretch key metadata entry.",
519
3
         function );
520
521
3
        goto on_error;
522
3
      }
523
1.02k
      if( volume_master_key->stretch_key == NULL )
524
401
      {
525
401
        volume_master_key->stretch_key = stretch_key;
526
527
401
        stretch_key = NULL;
528
401
      }
529
1.02k
      if( stretch_key != NULL )
530
627
      {
531
627
        if( libbde_stretch_key_free(
532
627
             &stretch_key,
533
627
             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
627
      }
545
1.02k
    }
546
5.62k
    else if( property_metadata_entry->value_type == LIBBDE_VALUE_TYPE_AES_CCM_ENCRYPTED_KEY )
547
2.69k
    {
548
2.69k
      if( libbde_aes_ccm_encrypted_key_initialize(
549
2.69k
           &aes_ccm_encrypted_key,
550
2.69k
           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
2.69k
      if( libbde_aes_ccm_encrypted_key_read(
562
2.69k
           aes_ccm_encrypted_key,
563
2.69k
           property_metadata_entry,
564
2.69k
           error ) != 1 )
565
4
      {
566
4
        libcerror_error_set(
567
4
         error,
568
4
         LIBCERROR_ERROR_DOMAIN_IO,
569
4
         LIBCERROR_IO_ERROR_READ_FAILED,
570
4
         "%s: unable to read AES-CCM encrypted key from property metadata entry.",
571
4
         function );
572
573
4
        goto on_error;
574
4
      }
575
2.69k
      if( volume_master_key->aes_ccm_encrypted_key == NULL )
576
890
      {
577
890
        volume_master_key->aes_ccm_encrypted_key = aes_ccm_encrypted_key;
578
579
890
        aes_ccm_encrypted_key = NULL;
580
890
      }
581
2.69k
      if( aes_ccm_encrypted_key != NULL )
582
1.80k
      {
583
1.80k
        if( libbde_aes_ccm_encrypted_key_free(
584
1.80k
             &aes_ccm_encrypted_key,
585
1.80k
             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
1.80k
      }
597
2.69k
    }
598
9.49k
    if( libcdata_array_append_entry(
599
9.49k
         volume_master_key->entries_array,
600
9.49k
         &property_metadata_entry_index,
601
9.49k
         (intptr_t *) property_metadata_entry,
602
9.49k
         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
9.49k
    property_metadata_entry = NULL;
614
9.49k
  }
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
4.27k
  return( 1 );
631
632
36
on_error:
633
36
  if( aes_ccm_encrypted_key != NULL )
634
4
  {
635
4
    libbde_aes_ccm_encrypted_key_free(
636
4
     &aes_ccm_encrypted_key,
637
4
     NULL );
638
4
  }
639
36
  if( stretch_key != NULL )
640
3
  {
641
3
    libbde_stretch_key_free(
642
3
     &stretch_key,
643
3
     NULL );
644
3
  }
645
36
  if( key != NULL )
646
2
  {
647
2
    libbde_key_free(
648
2
     &key,
649
2
     NULL );
650
2
  }
651
36
  if( property_metadata_entry != NULL )
652
36
  {
653
36
    libbde_metadata_entry_free(
654
36
     &property_metadata_entry,
655
36
     NULL );
656
36
  }
657
36
  return( -1 );
658
4.30k
}
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