Coverage Report

Created: 2024-10-02 06:58

/src/libfvde/libfvde/libfvde_encrypted_metadata.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Encrypted metadata functions
3
 *
4
 * Copyright (C) 2011-2024, Omar Choudary <choudary.omar@gmail.com>
5
 *                          Joachim Metz <joachim.metz@gmail.com>
6
 *
7
 * Refer to AUTHORS for acknowledgements.
8
 *
9
 * This program is free software: you can redistribute it and/or modify
10
 * it under the terms of the GNU Lesser General Public License as published by
11
 * the Free Software Foundation, either version 3 of the License, or
12
 * (at your option) any later version.
13
 *
14
 * This program is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 * GNU General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU Lesser General Public License
20
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
21
 */
22
23
#include <common.h>
24
#include <byte_stream.h>
25
#include <memory.h>
26
#include <narrow_string.h>
27
#include <system_string.h>
28
#include <types.h>
29
30
#include "libfvde_checksum.h"
31
#include "libfvde_compression.h"
32
#include "libfvde_debug.h"
33
#include "libfvde_definitions.h"
34
#include "libfvde_encrypted_metadata.h"
35
#include "libfvde_encryption_context.h"
36
#include "libfvde_encryption_context_plist.h"
37
#include "libfvde_io_handle.h"
38
#include "libfvde_keyring.h"
39
#include "libfvde_libbfio.h"
40
#include "libfvde_libcdata.h"
41
#include "libfvde_libcerror.h"
42
#include "libfvde_libcnotify.h"
43
#include "libfvde_libfguid.h"
44
#include "libfvde_libfplist.h"
45
#include "libfvde_libfvalue.h"
46
#include "libfvde_logical_volume_descriptor.h"
47
#include "libfvde_metadata_block.h"
48
#include "libfvde_password.h"
49
#include "libfvde_segment_descriptor.h"
50
51
#include "fvde_metadata.h"
52
53
/* Some constants used for FileVault medatada
54
 */
55
const uint32_t additional_offset_encrypted_volume_start = 80;
56
57
const uint8_t libfvde_encrypted_metadata_wrapped_kek_initialization_vector[ 8 ] = {
58
  0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6 };
59
60
/* Creates encrypted metadata
61
 * Make sure the value encrypted_metadata is referencing, is set to NULL
62
 * Returns 1 if successful or -1 on error
63
 */
64
int libfvde_encrypted_metadata_initialize(
65
     libfvde_encrypted_metadata_t **encrypted_metadata,
66
     libcerror_error_t **error )
67
0
{
68
0
  static char *function = "libfvde_encrypted_metadata_initialize";
69
70
0
  if( encrypted_metadata == NULL )
71
0
  {
72
0
    libcerror_error_set(
73
0
     error,
74
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
75
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
76
0
     "%s: invalid encrypted metadata.",
77
0
     function );
78
79
0
    return( -1 );
80
0
  }
81
0
  if( *encrypted_metadata != NULL )
82
0
  {
83
0
    libcerror_error_set(
84
0
     error,
85
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
86
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
87
0
     "%s: invalid encrypted metadata value already set.",
88
0
     function );
89
90
0
    return( -1 );
91
0
  }
92
0
  *encrypted_metadata = memory_allocate_structure(
93
0
                         libfvde_encrypted_metadata_t );
94
95
0
  if( *encrypted_metadata == NULL )
96
0
  {
97
0
    libcerror_error_set(
98
0
     error,
99
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
100
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
101
0
     "%s: unable to create encrypted metadata.",
102
0
     function );
103
104
0
    goto on_error;
105
0
  }
106
0
  if( memory_set(
107
0
       *encrypted_metadata,
108
0
       0,
109
0
       sizeof( libfvde_encrypted_metadata_t ) ) == NULL )
110
0
  {
111
0
    libcerror_error_set(
112
0
     error,
113
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
114
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
115
0
     "%s: unable to clear encryped metadata.",
116
0
     function );
117
118
0
    memory_free(
119
0
     *encrypted_metadata );
120
121
0
    *encrypted_metadata = NULL;
122
123
0
    return( -1 );
124
0
  }
125
0
  if( libfvde_encryption_context_plist_initialize(
126
0
       &( ( *encrypted_metadata )->encryption_context_plist ),
127
0
       error ) != 1 )
128
0
  {
129
0
    libcerror_error_set(
130
0
     error,
131
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
132
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
133
0
     "%s: unable to create encryption context plist.",
134
0
     function );
135
136
0
    goto on_error;
137
0
  }
138
0
  if( libcdata_array_initialize(
139
0
       &( ( *encrypted_metadata )->logical_volume_descriptors ),
140
0
       0,
141
0
       error ) != 1 )
142
0
  {
143
0
    libcerror_error_set(
144
0
     error,
145
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
146
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
147
0
     "%s: unable to create logical volume descriptors array.",
148
0
     function );
149
150
0
    goto on_error;
151
0
  }
152
0
  if( libcdata_array_initialize(
153
0
       &( ( *encrypted_metadata )->segment_descriptors_0x0304 ),
154
0
       0,
155
0
       error ) != 1 )
156
0
  {
157
0
    libcerror_error_set(
158
0
     error,
159
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
160
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
161
0
     "%s: unable to create segment descriptors array.",
162
0
     function );
163
164
0
    goto on_error;
165
0
  }
166
0
  return( 1 );
167
168
0
on_error:
169
0
  if( *encrypted_metadata != NULL )
170
0
  {
171
0
    if( ( *encrypted_metadata )->logical_volume_descriptors != NULL )
172
0
    {
173
0
      libcdata_array_free(
174
0
       &( ( *encrypted_metadata )->logical_volume_descriptors ),
175
0
       NULL,
176
0
       NULL );
177
0
    }
178
0
    if( ( *encrypted_metadata )->encryption_context_plist != NULL )
179
0
    {
180
0
      libfvde_encryption_context_plist_free(
181
0
       &( ( *encrypted_metadata )->encryption_context_plist ),
182
0
       NULL );
183
0
    }
184
0
    memory_free(
185
0
     *encrypted_metadata );
186
187
0
    *encrypted_metadata = NULL;
188
0
  }
189
0
  return( -1 );
190
0
}
191
192
/* Frees encrypted metadata
193
 * Returns 1 if successful or -1 on error
194
 */
195
int libfvde_encrypted_metadata_free(
196
     libfvde_encrypted_metadata_t **encrypted_metadata,
197
     libcerror_error_t **error )
198
0
{
199
0
  static char *function = "libfvde_encrypted_metadata_free";
200
0
  int result            = 1;
201
202
0
  if( encrypted_metadata == NULL )
203
0
  {
204
0
    libcerror_error_set(
205
0
     error,
206
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
207
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
208
0
     "%s: invalid encrypted metadata.",
209
0
     function );
210
211
0
    return( -1 );
212
0
  }
213
0
  if( encrypted_metadata != NULL )
214
0
  {
215
0
    if( libfvde_encryption_context_plist_free(
216
0
         &( ( *encrypted_metadata )->encryption_context_plist ),
217
0
         error ) != 1 )
218
0
    {
219
0
      libcerror_error_set(
220
0
       error,
221
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
222
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
223
0
       "%s: unable to free encryption context plist.",
224
0
       function );
225
226
0
      result = -1;
227
0
    }
228
0
    if( libcdata_array_free(
229
0
         &( ( *encrypted_metadata )->logical_volume_descriptors ),
230
0
         (int (*)(intptr_t **, libcerror_error_t **)) &libfvde_logical_volume_descriptor_free,
231
0
         error ) != 1 )
232
0
    {
233
0
      libcerror_error_set(
234
0
       error,
235
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
236
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
237
0
       "%s: unable to free logical volume descriptors array.",
238
0
       function );
239
240
0
      result = -1;
241
0
    }
242
0
    if( libcdata_array_free(
243
0
         &( ( *encrypted_metadata )->segment_descriptors_0x0304 ),
244
0
         (int (*)(intptr_t **, libcerror_error_t **)) &libfvde_segment_descriptor_free,
245
0
         error ) != 1 )
246
0
    {
247
0
      libcerror_error_set(
248
0
       error,
249
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
250
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
251
0
       "%s: unable to free segment descriptors array.",
252
0
       function );
253
254
0
      result = -1;
255
0
    }
256
0
    if( ( *encrypted_metadata )->encryption_context_plist_data != NULL )
257
0
    {
258
0
      memory_free(
259
0
       ( *encrypted_metadata )->encryption_context_plist_data );
260
0
    }
261
0
    if( ( *encrypted_metadata )->compressed_data != NULL )
262
0
    {
263
0
      memory_free(
264
0
       ( *encrypted_metadata )->compressed_data );
265
0
    }
266
0
    memory_free(
267
0
     *encrypted_metadata );
268
269
0
    *encrypted_metadata = NULL;
270
0
  }
271
0
  return( result );
272
0
}
273
274
/* Reads the encrypted metadata block type 0x0010
275
 * Returns 1 if successful or -1 on error
276
 */
277
int libfvde_encrypted_metadata_read_type_0x0010(
278
     libfvde_encrypted_metadata_t *encrypted_metadata,
279
     const uint8_t *block_data,
280
     size_t block_data_size,
281
     libcerror_error_t **error )
282
0
{
283
0
  static char *function    = "libfvde_encrypted_metadata_read_type_0x0010";
284
285
#if defined( HAVE_DEBUG_OUTPUT )
286
  uint64_t value_64bit     = 0;
287
  uint32_t value_32bit     = 0;
288
  uint16_t value_16bit     = 0;
289
  int metadata_block_index = 0;
290
#endif
291
292
0
  if( encrypted_metadata == NULL )
293
0
  {
294
0
    libcerror_error_set(
295
0
     error,
296
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
297
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
298
0
     "%s: invalid encrypted metadata.",
299
0
     function );
300
301
0
    return( -1 );
302
0
  }
303
0
  if( block_data == NULL )
304
0
  {
305
0
    libcerror_error_set(
306
0
     error,
307
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
308
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
309
0
     "%s: invalid block data.",
310
0
     function );
311
312
0
    return( -1 );
313
0
  }
314
0
  if( ( block_data_size < 344 )
315
0
   || ( block_data_size > (size_t) SSIZE_MAX ) )
316
0
  {
317
0
    libcerror_error_set(
318
0
     error,
319
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
320
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
321
0
     "%s: invalid block data size value out of bounds.",
322
0
     function );
323
324
0
    return( -1 );
325
0
  }
326
#if defined( HAVE_DEBUG_OUTPUT )
327
  if( libcnotify_verbose != 0 )
328
  {
329
    byte_stream_copy_to_uint32_little_endian(
330
     &( block_data[ 0 ] ),
331
     value_32bit );
332
    libcnotify_printf(
333
     "%s: unknown1\t\t\t\t: 0x%08" PRIx32 "\n",
334
     function,
335
     value_32bit );
336
337
    byte_stream_copy_to_uint32_little_endian(
338
     &( block_data[ 8 ] ),
339
     value_32bit );
340
    libcnotify_printf(
341
     "%s: checksum\t\t\t\t: 0x%08" PRIx32 "\n",
342
     function,
343
     value_32bit );
344
345
    byte_stream_copy_to_uint32_little_endian(
346
     &( block_data[ 12 ] ),
347
     value_32bit );
348
    libcnotify_printf(
349
     "%s: initial value\t\t\t: 0x%08" PRIx32 "\n",
350
     function,
351
     value_32bit );
352
353
    byte_stream_copy_to_uint16_little_endian(
354
     &( block_data[ 16 ] ),
355
     value_16bit );
356
    libcnotify_printf(
357
     "%s: format version\t\t\t: %" PRIu16 "\n",
358
     function,
359
     value_16bit );
360
361
    byte_stream_copy_to_uint16_little_endian(
362
     &( block_data[ 18 ] ),
363
     value_16bit );
364
    libcnotify_printf(
365
     "%s: block type\t\t\t\t: 0x%04" PRIx16 "\n",
366
     function,
367
     value_16bit );
368
369
    byte_stream_copy_to_uint32_little_endian(
370
     &( block_data[ 20 ] ),
371
     value_32bit );
372
    libcnotify_printf(
373
     "%s: serial number\t\t\t: 0x%08" PRIx32 "\n",
374
     function,
375
     value_32bit );
376
377
    byte_stream_copy_to_uint64_little_endian(
378
     &( block_data[ 24 ] ),
379
     value_64bit );
380
    libcnotify_printf(
381
     "%s: unknown2\t\t\t\t: 0x%08" PRIx64 "\n",
382
     function,
383
     value_64bit );
384
385
    byte_stream_copy_to_uint64_little_endian(
386
     &( block_data[ 32 ] ),
387
     value_64bit );
388
    libcnotify_printf(
389
     "%s: unknown3a\t\t\t\t: 0x%08" PRIx64 "\n",
390
     function,
391
     value_64bit );
392
393
    byte_stream_copy_to_uint64_little_endian(
394
     &( block_data[ 40 ] ),
395
     value_64bit );
396
    libcnotify_printf(
397
     "%s: unknown3b\t\t\t\t: 0x%08" PRIx64 "\n",
398
     function,
399
     value_64bit );
400
401
    byte_stream_copy_to_uint64_little_endian(
402
     &( block_data[ 48 ] ),
403
     value_64bit );
404
    libcnotify_printf(
405
     "%s: unknown3c\t\t\t\t: 0x%08" PRIx64 "\n",
406
     function,
407
     value_64bit );
408
409
    byte_stream_copy_to_uint32_little_endian(
410
     &( block_data[ 56 ] ),
411
     value_32bit );
412
    libcnotify_printf(
413
     "%s: bytes per sector\t\t\t: %" PRIu32 "\n",
414
     function,
415
     value_32bit );
416
417
    byte_stream_copy_to_uint32_little_endian(
418
     &( block_data[ 60 ] ),
419
     value_32bit );
420
    libcnotify_printf(
421
     "%s: unknown4a\t\t\t\t: 0x%08" PRIx32 "\n",
422
     function,
423
     value_32bit );
424
425
    byte_stream_copy_to_uint64_little_endian(
426
     &( block_data[ 64 ] ),
427
     value_64bit );
428
    libcnotify_printf(
429
     "%s: unknown4b\t\t\t\t: 0x%08" PRIx64 "\n",
430
     function,
431
     value_64bit );
432
433
    byte_stream_copy_to_uint64_little_endian(
434
     &( block_data[ 72 ] ),
435
     value_64bit );
436
    libcnotify_printf(
437
     "%s: physical volume size\t\t: %" PRIu64 "\n",
438
     function,
439
     value_64bit );
440
441
    libcnotify_printf(
442
     "%s: unknown5:\n",
443
     function );
444
    libcnotify_print_data(
445
     &( block_data[ 80 ] ),
446
     16,
447
     0 );
448
449
    libcnotify_printf(
450
     "%s: core storage signature\t\t: %c%c\n",
451
     function,
452
     block_data[ 96 ],
453
     block_data[ 97 ] );
454
455
    byte_stream_copy_to_uint32_little_endian(
456
     &( block_data[ 98 ] ),
457
     value_32bit );
458
    libcnotify_printf(
459
     "%s: checksum algorithm\t\t\t: %" PRIu32 "\n",
460
     function,
461
     value_32bit );
462
463
    byte_stream_copy_to_uint16_little_endian(
464
     &( block_data[ 102 ] ),
465
     value_16bit );
466
    libcnotify_printf(
467
     "%s: unknown6\t\t\t\t: 0x%04" PRIx16 "\n",
468
     function,
469
     value_16bit );
470
471
    byte_stream_copy_to_uint32_little_endian(
472
     &( block_data[ 104 ] ),
473
     value_32bit );
474
    libcnotify_printf(
475
     "%s: block size\t\t\t\t: %" PRIu32 "\n",
476
     function,
477
     value_32bit );
478
479
    byte_stream_copy_to_uint32_little_endian(
480
     &( block_data[ 108 ] ),
481
     value_32bit );
482
    libcnotify_printf(
483
     "%s: metadata size\t\t\t: %" PRIu32 "\n",
484
     function,
485
     value_32bit );
486
487
    for( metadata_block_index = 0;
488
         metadata_block_index < 4;
489
         metadata_block_index++ )
490
    {
491
      byte_stream_copy_to_uint64_little_endian(
492
       &( block_data[ 112 + ( metadata_block_index * 8 ) ] ),
493
       value_64bit );
494
495
      libcnotify_printf(
496
       "%s: metadata: %d block number\t\t: %" PRIu64 "\n",
497
       function,
498
       metadata_block_index + 1,
499
       value_64bit );
500
    }
501
    libcnotify_printf(
502
     "%s: unknown7:\n",
503
     function );
504
    libcnotify_print_data(
505
     &( block_data[ 144 ] ),
506
     32,
507
     0 );
508
509
    byte_stream_copy_to_uint32_little_endian(
510
     &( block_data[ 176 ] ),
511
     value_32bit );
512
    libcnotify_printf(
513
     "%s: key data size\t\t\t: %" PRIu32 "\n",
514
     function,
515
     value_32bit );
516
517
    byte_stream_copy_to_uint32_little_endian(
518
     &( block_data[ 180 ] ),
519
     value_32bit );
520
    libcnotify_printf(
521
     "%s: encryption method\t\t\t: %" PRIu32 "\n",
522
     function,
523
     value_32bit );
524
525
    libcnotify_printf(
526
     "%s: key data:\n",
527
     function );
528
    libcnotify_print_data(
529
     &( block_data[ 184 ] ),
530
     128,
531
     LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
532
533
    if( libfvde_debug_print_guid_value(
534
         function,
535
         "physical volume identifier\t\t",
536
         &( block_data[ 312 ] ),
537
         16,
538
         LIBFGUID_ENDIAN_BIG,
539
         LIBFGUID_STRING_FORMAT_FLAG_USE_LOWER_CASE,
540
         error ) != 1 )
541
    {
542
      libcerror_error_set(
543
       error,
544
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
545
       LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
546
       "%s: unable to print GUID value.",
547
       function );
548
549
      return( -1 );
550
    }
551
    if( libfvde_debug_print_guid_value(
552
         function,
553
         "logical volume group identifier\t",
554
         &( block_data[ 328 ] ),
555
         16,
556
         LIBFGUID_ENDIAN_BIG,
557
         LIBFGUID_STRING_FORMAT_FLAG_USE_LOWER_CASE,
558
         error ) != 1 )
559
    {
560
      libcerror_error_set(
561
       error,
562
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
563
       LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
564
       "%s: unable to print GUID value.",
565
       function );
566
567
      return( -1 );
568
    }
569
    libcnotify_printf(
570
     "\n" );
571
  }
572
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
573
574
0
  return( 1 );
575
0
}
576
577
/* Reads the encrypted metadata block type 0x0011
578
 * Returns 1 if successful or -1 on error
579
 */
580
int libfvde_encrypted_metadata_read_type_0x0011(
581
     libfvde_encrypted_metadata_t *encrypted_metadata,
582
     const uint8_t *block_data,
583
     size_t block_data_size,
584
     libcerror_error_t **error )
585
0
{
586
0
  static char *function      = "libfvde_encrypted_metadata_read_type_0x0011";
587
0
  size_t block_data_offset   = 0;
588
0
  uint32_t entry_index       = 0;
589
0
  uint32_t number_of_entries = 0;
590
591
#if defined( HAVE_DEBUG_OUTPUT )
592
  uint64_t value_64bit       = 0;
593
  uint32_t value_32bit       = 0;
594
  uint16_t value_16bit       = 0;
595
#endif
596
597
0
  if( encrypted_metadata == NULL )
598
0
  {
599
0
    libcerror_error_set(
600
0
     error,
601
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
602
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
603
0
     "%s: invalid encrypted metadata.",
604
0
     function );
605
606
0
    return( -1 );
607
0
  }
608
0
  if( block_data == NULL )
609
0
  {
610
0
    libcerror_error_set(
611
0
     error,
612
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
613
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
614
0
     "%s: invalid block data.",
615
0
     function );
616
617
0
    return( -1 );
618
0
  }
619
0
  if( ( block_data_size < 192 )
620
0
   || ( block_data_size > (size_t) SSIZE_MAX ) )
621
0
  {
622
0
    libcerror_error_set(
623
0
     error,
624
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
625
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
626
0
     "%s: invalid block data size value out of bounds.",
627
0
     function );
628
629
0
    return( -1 );
630
0
  }
631
#if defined( HAVE_DEBUG_OUTPUT )
632
  if( libcnotify_verbose != 0 )
633
  {
634
    byte_stream_copy_to_uint32_little_endian(
635
     &( block_data[ 0 ] ),
636
     value_32bit );
637
    libcnotify_printf(
638
     "%s: metadata size\t\t\t: %" PRIu32 "\n",
639
     function,
640
     value_32bit );
641
642
    byte_stream_copy_to_uint32_little_endian(
643
     &( block_data[ 4 ] ),
644
     value_32bit );
645
    libcnotify_printf(
646
     "%s: unknown1\t\t\t\t: 0x%08" PRIx32 "\n",
647
     function,
648
     value_32bit );
649
650
    byte_stream_copy_to_uint32_little_endian(
651
     &( block_data[ 8 ] ),
652
     value_32bit );
653
    libcnotify_printf(
654
     "%s: checksum\t\t\t\t: 0x%08" PRIx32 "\n",
655
     function,
656
     value_32bit );
657
658
    byte_stream_copy_to_uint32_little_endian(
659
     &( block_data[ 12 ] ),
660
     value_32bit );
661
    libcnotify_printf(
662
     "%s: initial value\t\t\t: 0x%08" PRIx32 "\n",
663
     function,
664
     value_32bit );
665
666
    byte_stream_copy_to_uint32_little_endian(
667
     &( block_data[ 16 ] ),
668
     value_32bit );
669
    libcnotify_printf(
670
     "%s: unknown2\t\t\t\t: 0x%08" PRIx32 "\n",
671
     function,
672
     value_32bit );
673
674
    byte_stream_copy_to_uint32_little_endian(
675
     &( block_data[ 20 ] ),
676
     value_32bit );
677
    libcnotify_printf(
678
     "%s: unknown3\t\t\t\t: 0x%08" PRIx32 "\n",
679
     function,
680
     value_32bit );
681
682
    byte_stream_copy_to_uint32_little_endian(
683
     &( block_data[ 24 ] ),
684
     value_32bit );
685
    libcnotify_printf(
686
     "%s: unknown4\t\t\t\t: 0x%08" PRIx32 "\n",
687
     function,
688
     value_32bit );
689
690
    byte_stream_copy_to_uint32_little_endian(
691
     &( block_data[ 28 ] ),
692
     value_32bit );
693
    libcnotify_printf(
694
     "%s: unknown5\t\t\t\t: 0x%08" PRIx32 "\n",
695
     function,
696
     value_32bit );
697
698
    libcnotify_printf(
699
     "%s: unknown6:\n",
700
     function );
701
    libcnotify_print_data(
702
     &( block_data[ 32 ] ),
703
     40,
704
     LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
705
706
    byte_stream_copy_to_uint32_little_endian(
707
     &( block_data[ 72 ] ),
708
     value_32bit );
709
    libcnotify_printf(
710
     "%s: unknown7\t\t\t\t: 0x%08" PRIx32 "\n",
711
     function,
712
     value_32bit );
713
714
    byte_stream_copy_to_uint32_little_endian(
715
     &( block_data[ 76 ] ),
716
     value_32bit );
717
    libcnotify_printf(
718
     "%s: unknown8\t\t\t\t: 0x%08" PRIx32 "\n",
719
     function,
720
     value_32bit );
721
722
    libcnotify_printf(
723
     "%s: unknown9:\n",
724
     function );
725
    libcnotify_print_data(
726
     &( block_data[ 80 ] ),
727
     24,
728
     LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
729
730
    byte_stream_copy_to_uint32_little_endian(
731
     &( block_data[ 104 ] ),
732
     value_32bit );
733
    libcnotify_printf(
734
     "%s: unknown10\t\t\t\t: 0x%08" PRIx32 "\n",
735
     function,
736
     value_32bit );
737
738
    byte_stream_copy_to_uint32_little_endian(
739
     &( block_data[ 108 ] ),
740
     value_32bit );
741
    libcnotify_printf(
742
     "%s: unknown11\t\t\t\t: 0x%08" PRIx32 "\n",
743
     function,
744
     value_32bit );
745
746
    byte_stream_copy_to_uint32_little_endian(
747
     &( block_data[ 112 ] ),
748
     value_32bit );
749
    libcnotify_printf(
750
     "%s: unknown12\t\t\t\t: 0x%08" PRIx32 "\n",
751
     function,
752
     value_32bit );
753
754
    byte_stream_copy_to_uint16_little_endian(
755
     &( block_data[ 116 ] ),
756
     value_16bit );
757
    libcnotify_printf(
758
     "%s: unknown13a\t\t\t\t: 0x%04" PRIx16 "\n",
759
     function,
760
     value_16bit );
761
762
    byte_stream_copy_to_uint16_little_endian(
763
     &( block_data[ 118 ] ),
764
     value_16bit );
765
    libcnotify_printf(
766
     "%s: unknown13b\t\t\t\t: 0x%04" PRIx16 "\n",
767
     function,
768
     value_16bit );
769
770
    byte_stream_copy_to_uint32_little_endian(
771
     &( block_data[ 120 ] ),
772
     value_32bit );
773
    libcnotify_printf(
774
     "%s: unknown14\t\t\t\t: 0x%08" PRIx32 "\n",
775
     function,
776
     value_32bit );
777
778
    byte_stream_copy_to_uint16_little_endian(
779
     &( block_data[ 124 ] ),
780
     value_16bit );
781
    libcnotify_printf(
782
     "%s: unknown15a\t\t\t\t: 0x%04" PRIx16 "\n",
783
     function,
784
     value_16bit );
785
786
    byte_stream_copy_to_uint16_little_endian(
787
     &( block_data[ 126 ] ),
788
     value_16bit );
789
    libcnotify_printf(
790
     "%s: unknown15b\t\t\t\t: 0x%04" PRIx16 "\n",
791
     function,
792
     value_16bit );
793
794
    byte_stream_copy_to_uint32_little_endian(
795
     &( block_data[ 128 ] ),
796
     value_32bit );
797
    libcnotify_printf(
798
     "%s: unknown16\t\t\t\t: 0x%08" PRIx32 "\n",
799
     function,
800
     value_32bit );
801
802
    libcnotify_printf(
803
     "%s: unknown17:\n",
804
     function );
805
    libcnotify_print_data(
806
     &( block_data[ 132 ] ),
807
     24,
808
     LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
809
810
    byte_stream_copy_to_uint32_little_endian(
811
     &( block_data[ 156 ] ),
812
     value_32bit );
813
    libcnotify_printf(
814
     "%s: volume groups descriptor offset\t: 0x%08" PRIx32 "\n",
815
     function,
816
     value_32bit );
817
818
    byte_stream_copy_to_uint32_little_endian(
819
     &( block_data[ 160 ] ),
820
     value_32bit );
821
    libcnotify_printf(
822
     "%s: volume group XML offset\t\t: 0x%08" PRIx32 "\n",
823
     function,
824
     value_32bit );
825
826
    byte_stream_copy_to_uint32_little_endian(
827
     &( block_data[ 164 ] ),
828
     value_32bit );
829
    libcnotify_printf(
830
     "%s: volume group XML size\t\t: %" PRIu32 "\n",
831
     function,
832
     value_32bit );
833
834
    byte_stream_copy_to_uint32_little_endian(
835
     &( block_data[ 168 ] ),
836
     value_32bit );
837
    libcnotify_printf(
838
     "%s: volume group XML size copy\t\t: %" PRIu32 "\n",
839
     function,
840
     value_32bit );
841
842
    byte_stream_copy_to_uint16_little_endian(
843
     &( block_data[ 172 ] ),
844
     value_16bit );
845
    libcnotify_printf(
846
     "%s: unknown18\t\t\t\t: 0x%04" PRIx16 "\n",
847
     function,
848
     value_16bit );
849
850
    byte_stream_copy_to_uint16_little_endian(
851
     &( block_data[ 174 ] ),
852
     value_16bit );
853
    libcnotify_printf(
854
     "%s: physical volume index\t\t: %" PRIu16 "\n",
855
     function,
856
     value_16bit );
857
858
    byte_stream_copy_to_uint64_little_endian(
859
     &( block_data[ 176 ] ),
860
     value_64bit );
861
    libcnotify_printf(
862
     "%s: volume group number of blocks\t: %" PRIu64 "\n",
863
     function,
864
     value_64bit );
865
866
    libcnotify_printf(
867
     "\n" );
868
  }
869
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
870
871
0
  byte_stream_copy_to_uint32_little_endian(
872
0
   &( block_data[ 184 ] ),
873
0
   number_of_entries );
874
875
#if defined( HAVE_DEBUG_OUTPUT )
876
  if( libcnotify_verbose != 0 )
877
  {
878
    libcnotify_printf(
879
     "%s: number of entries\t\t\t: %" PRIu32 "\n",
880
     function,
881
     number_of_entries );
882
883
    byte_stream_copy_to_uint32_little_endian(
884
     &( block_data[ 188 ] ),
885
     value_32bit );
886
    libcnotify_printf(
887
     "%s: unknown19\t\t\t\t: 0x%08" PRIx32 "\n",
888
     function,
889
     value_32bit );
890
891
    libcnotify_printf(
892
     "\n" );
893
  }
894
#endif
895
0
  block_data_offset = 192;
896
897
0
  if( number_of_entries > ( ( block_data_size - block_data_offset ) / 24 ) )
898
0
  {
899
0
    libcerror_error_set(
900
0
     error,
901
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
902
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
903
0
     "%s: invalid number of entries value out of bounds.",
904
0
     function );
905
906
0
    return( -1 );
907
0
  }
908
0
  for( entry_index = 0;
909
0
       entry_index < number_of_entries;
910
0
       entry_index++ )
911
0
  {
912
#if defined( HAVE_DEBUG_OUTPUT )
913
    if( libcnotify_verbose != 0 )
914
    {
915
      byte_stream_copy_to_uint64_little_endian(
916
       &( block_data[ block_data_offset ] ),
917
       value_64bit );
918
      libcnotify_printf(
919
       "%s: entry: %03d unknown1\t\t: %" PRIu64 "\n",
920
       function,
921
       entry_index,
922
       value_64bit );
923
924
      byte_stream_copy_to_uint64_little_endian(
925
       &( block_data[ block_data_offset + 8 ] ),
926
       value_64bit );
927
      libcnotify_printf(
928
       "%s: entry: %03d unknown2\t\t: 0x%08" PRIx64 "\n",
929
       function,
930
       entry_index,
931
       value_64bit );
932
933
      byte_stream_copy_to_uint64_little_endian(
934
       &( block_data[ block_data_offset + 16 ] ),
935
       value_64bit );
936
      libcnotify_printf(
937
       "%s: entry: %03d metadata block number\t: %" PRIu64 "\n",
938
       function,
939
       entry_index,
940
       value_64bit );
941
942
      libcnotify_printf(
943
       "\n" );
944
    }
945
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
946
947
0
    block_data_offset += 24;
948
0
  }
949
0
  return( 1 );
950
0
}
951
952
/* Reads the encrypted metadata block type 0x0012
953
 * Returns 1 if successful or -1 on error
954
 */
955
int libfvde_encrypted_metadata_read_type_0x0012(
956
     libfvde_encrypted_metadata_t *encrypted_metadata,
957
     const uint8_t *block_data,
958
     size_t block_data_size,
959
     libcerror_error_t **error )
960
0
{
961
0
  const uint8_t *xml_plist_data = NULL;
962
0
  static char *function         = "libfvde_encrypted_metadata_read_type_0x0012";
963
964
0
  if( encrypted_metadata == NULL )
965
0
  {
966
0
    libcerror_error_set(
967
0
     error,
968
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
969
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
970
0
     "%s: invalid encrypted metadata.",
971
0
     function );
972
973
0
    return( -1 );
974
0
  }
975
0
  if( block_data == NULL )
976
0
  {
977
0
    libcerror_error_set(
978
0
     error,
979
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
980
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
981
0
     "%s: invalid block data.",
982
0
     function );
983
984
0
    return( -1 );
985
0
  }
986
0
  if( ( block_data_size < 54 )
987
0
   || ( block_data_size > (size_t) SSIZE_MAX ) )
988
0
  {
989
0
    libcerror_error_set(
990
0
     error,
991
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
992
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
993
0
     "%s: invalid block data size value out of bounds.",
994
0
     function );
995
996
0
    return( -1 );
997
0
  }
998
0
  xml_plist_data = &( block_data[ 48 ] );
999
1000
0
  if( ( xml_plist_data[ 0 ] == (uint8_t) '<' )
1001
0
   && ( xml_plist_data[ 1 ] == (uint8_t) 'd' )
1002
0
   && ( xml_plist_data[ 2 ] == (uint8_t) 'i' )
1003
0
   && ( xml_plist_data[ 3 ] == (uint8_t) 'c' )
1004
0
   && ( xml_plist_data[ 4 ] == (uint8_t) 't' ) )
1005
0
  {
1006
#if defined( HAVE_DEBUG_OUTPUT )
1007
    if( libcnotify_verbose != 0 )
1008
    {
1009
      libcnotify_printf(
1010
       "%s: XML:\n%s\n",
1011
       function,
1012
       (char *) &( block_data[ 48 ] ) );
1013
1014
      libcnotify_printf(
1015
       "\n" );
1016
    }
1017
#endif
1018
0
  }
1019
/* TODO get com.apple.corestorage.lvg.name */
1020
1021
0
  return( 1 );
1022
0
}
1023
1024
/* Reads the encrypted metadata block type 0x0013
1025
 * Returns 1 if successful or -1 on error
1026
 */
1027
int libfvde_encrypted_metadata_read_type_0x0013(
1028
     libfvde_encrypted_metadata_t *encrypted_metadata,
1029
     const uint8_t *block_data,
1030
     size_t block_data_size,
1031
     libcerror_error_t **error )
1032
0
{
1033
0
  static char *function                 = "libfvde_encrypted_metadata_read_type_0x0013";
1034
0
  size_t block_data_offset              = 0;
1035
0
  uint32_t entry_index                  = 0;
1036
0
  uint32_t number_of_entries2           = 0;
1037
0
  uint32_t number_of_object_identifiers = 0;
1038
0
  uint32_t object_identifier_index      = 0;
1039
1040
#if defined( HAVE_DEBUG_OUTPUT )
1041
  uint64_t value_64bit                  = 0;
1042
  uint32_t value_32bit                  = 0;
1043
  uint16_t value_16bit                  = 0;
1044
#endif
1045
1046
0
  if( encrypted_metadata == NULL )
1047
0
  {
1048
0
    libcerror_error_set(
1049
0
     error,
1050
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1051
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1052
0
     "%s: invalid encrypted metadata.",
1053
0
     function );
1054
1055
0
    return( -1 );
1056
0
  }
1057
0
  if( block_data == NULL )
1058
0
  {
1059
0
    libcerror_error_set(
1060
0
     error,
1061
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1062
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1063
0
     "%s: invalid block data.",
1064
0
     function );
1065
1066
0
    return( -1 );
1067
0
  }
1068
0
  if( ( block_data_size < 72 )
1069
0
   || ( block_data_size > (size_t) SSIZE_MAX ) )
1070
0
  {
1071
0
    libcerror_error_set(
1072
0
     error,
1073
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1074
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1075
0
     "%s: invalid block data size value out of bounds.",
1076
0
     function );
1077
1078
0
    return( -1 );
1079
0
  }
1080
0
  byte_stream_copy_to_uint32_little_endian(
1081
0
   &( block_data[ 56 ] ),
1082
0
   number_of_object_identifiers );
1083
1084
0
  byte_stream_copy_to_uint32_little_endian(
1085
0
   &( block_data[ 60 ] ),
1086
0
   number_of_entries2 );
1087
1088
#if defined( HAVE_DEBUG_OUTPUT )
1089
  if( libcnotify_verbose != 0 )
1090
  {
1091
    byte_stream_copy_to_uint32_little_endian(
1092
     &( block_data[ 0 ] ),
1093
     value_32bit );
1094
    libcnotify_printf(
1095
     "%s: checksum\t\t\t\t: 0x%08" PRIx32 "\n",
1096
     function,
1097
     value_32bit );
1098
1099
    byte_stream_copy_to_uint32_little_endian(
1100
     &( block_data[ 4 ] ),
1101
     value_32bit );
1102
    libcnotify_printf(
1103
     "%s: initial value\t\t\t: 0x%08" PRIx32 "\n",
1104
     function,
1105
     value_32bit );
1106
1107
    if( libfvde_debug_print_guid_value(
1108
         function,
1109
         "logical volume group identifier\t",
1110
         &( block_data[ 8 ] ),
1111
         16,
1112
         LIBFGUID_ENDIAN_BIG,
1113
         LIBFGUID_STRING_FORMAT_FLAG_USE_LOWER_CASE,
1114
         error ) != 1 )
1115
    {
1116
      libcerror_error_set(
1117
       error,
1118
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1119
       LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
1120
       "%s: unable to print GUID value.",
1121
       function );
1122
1123
      return( -1 );
1124
    }
1125
    byte_stream_copy_to_uint64_little_endian(
1126
     &( block_data[ 24 ] ),
1127
     value_64bit );
1128
    libcnotify_printf(
1129
     "%s: unknown1\t\t\t\t: 0x%08" PRIx64 "\n",
1130
     function,
1131
     value_64bit );
1132
1133
    byte_stream_copy_to_uint64_little_endian(
1134
     &( block_data[ 32 ] ),
1135
     value_64bit );
1136
    libcnotify_printf(
1137
     "%s: unknown2\t\t\t\t: 0x%08" PRIx64 "\n",
1138
     function,
1139
     value_64bit );
1140
1141
    byte_stream_copy_to_uint32_little_endian(
1142
     &( block_data[ 40 ] ),
1143
     value_32bit );
1144
    libcnotify_printf(
1145
     "%s: unknown3\t\t\t\t: 0x%08" PRIx32 "\n",
1146
     function,
1147
     value_32bit );
1148
1149
    byte_stream_copy_to_uint32_little_endian(
1150
     &( block_data[ 44 ] ),
1151
     value_32bit );
1152
    libcnotify_printf(
1153
     "%s: number of blocks in transaction\t: %" PRIu32 "\n",
1154
     function,
1155
     value_32bit );
1156
1157
    byte_stream_copy_to_uint32_little_endian(
1158
     &( block_data[ 48 ] ),
1159
     value_32bit );
1160
    libcnotify_printf(
1161
     "%s: unknown5\t\t\t\t: 0x%08" PRIx32 "\n",
1162
     function,
1163
     value_32bit );
1164
1165
    byte_stream_copy_to_uint32_little_endian(
1166
     &( block_data[ 52 ] ),
1167
     value_32bit );
1168
    libcnotify_printf(
1169
     "%s: unknown6\t\t\t\t: 0x%08" PRIx32 "\n",
1170
     function,
1171
     value_32bit );
1172
1173
    libcnotify_printf(
1174
     "%s: number of object identifiers\t: %" PRIu32 "\n",
1175
     function,
1176
     number_of_object_identifiers );
1177
1178
    libcnotify_printf(
1179
     "%s: number of entries2\t\t\t: %" PRIu32 "\n",
1180
     function,
1181
     number_of_entries2 );
1182
1183
    byte_stream_copy_to_uint32_little_endian(
1184
     &( block_data[ 64 ] ),
1185
     value_32bit );
1186
    libcnotify_printf(
1187
     "%s: unknown9\t\t\t\t: 0x%08" PRIx32 "\n",
1188
     function,
1189
     value_32bit );
1190
1191
    byte_stream_copy_to_uint32_little_endian(
1192
     &( block_data[ 68 ] ),
1193
     value_32bit );
1194
    libcnotify_printf(
1195
     "%s: unknown10\t\t\t\t: 0x%08" PRIx32 "\n",
1196
     function,
1197
     value_32bit );
1198
1199
    byte_stream_copy_to_uint64_little_endian(
1200
     &( block_data[ 72 ] ),
1201
     value_64bit );
1202
    libcnotify_printf(
1203
     "%s: unknown11\t\t\t\t: 0x%08" PRIx64 "\n",
1204
     function,
1205
     value_64bit );
1206
1207
    byte_stream_copy_to_uint32_little_endian(
1208
     &( block_data[ 80 ] ),
1209
     value_32bit );
1210
    libcnotify_printf(
1211
     "%s: unknown12\t\t\t\t: 0x%08" PRIx32 "\n",
1212
     function,
1213
     value_32bit );
1214
1215
    byte_stream_copy_to_uint32_little_endian(
1216
     &( block_data[ 84 ] ),
1217
     value_32bit );
1218
    libcnotify_printf(
1219
     "%s: unknown13\t\t\t\t: 0x%08" PRIx32 "\n",
1220
     function,
1221
     value_32bit );
1222
1223
    byte_stream_copy_to_uint64_little_endian(
1224
     &( block_data[ 88 ] ),
1225
     value_64bit );
1226
    libcnotify_printf(
1227
     "%s: unknown14\t\t\t\t: 0x%08" PRIx64 "\n",
1228
     function,
1229
     value_64bit );
1230
1231
    byte_stream_copy_to_uint64_little_endian(
1232
     &( block_data[ 96 ] ),
1233
     value_64bit );
1234
    libcnotify_printf(
1235
     "%s: unknown15\t\t\t\t: 0x%08" PRIx64 "\n",
1236
     function,
1237
     value_64bit );
1238
1239
    byte_stream_copy_to_uint64_little_endian(
1240
     &( block_data[ 104 ] ),
1241
     value_64bit );
1242
    libcnotify_printf(
1243
     "%s: unknown16\t\t\t\t: 0x%08" PRIx64 "\n",
1244
     function,
1245
     value_64bit );
1246
1247
    byte_stream_copy_to_uint64_little_endian(
1248
     &( block_data[ 112 ] ),
1249
     value_64bit );
1250
    libcnotify_printf(
1251
     "%s: unknown17\t\t\t\t: 0x%08" PRIx64 "\n",
1252
     function,
1253
     value_64bit );
1254
1255
    byte_stream_copy_to_uint32_little_endian(
1256
     &( block_data[ 120 ] ),
1257
     value_32bit );
1258
    libcnotify_printf(
1259
     "%s: unknown18\t\t\t\t: 0x%08" PRIx32 "\n",
1260
     function,
1261
     value_32bit );
1262
1263
    byte_stream_copy_to_uint16_little_endian(
1264
     &( block_data[ 124 ] ),
1265
     value_16bit );
1266
    libcnotify_printf(
1267
     "%s: unknown19\t\t\t\t: %" PRIu16 "\n",
1268
     function,
1269
     value_16bit );
1270
1271
    byte_stream_copy_to_uint16_little_endian(
1272
     &( block_data[ 126 ] ),
1273
     value_16bit );
1274
    libcnotify_printf(
1275
     "%s: unknown20\t\t\t\t: %" PRIu16 "\n",
1276
     function,
1277
     value_16bit );
1278
1279
    libcnotify_printf(
1280
     "\n" );
1281
  }
1282
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
1283
1284
0
  block_data_offset = 128;
1285
1286
0
  if( number_of_object_identifiers > ( ( block_data_size - block_data_offset ) / 8 ) )
1287
0
  {
1288
0
    libcerror_error_set(
1289
0
     error,
1290
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1291
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1292
0
     "%s: invalid number of object identifiers value out of bounds.",
1293
0
     function );
1294
1295
0
    return( -1 );
1296
0
  }
1297
0
  if( number_of_object_identifiers > 0 )
1298
0
  {
1299
0
    for( object_identifier_index = 0;
1300
0
         object_identifier_index < number_of_object_identifiers;
1301
0
         object_identifier_index++ )
1302
0
    {
1303
#if defined( HAVE_DEBUG_OUTPUT )
1304
      if( libcnotify_verbose != 0 )
1305
      {
1306
        byte_stream_copy_to_uint64_little_endian(
1307
         &( block_data[ block_data_offset ] ),
1308
         value_64bit );
1309
        libcnotify_printf(
1310
         "%s: object identifier: %d\t\t: %" PRIu64 "\n",
1311
         function,
1312
         object_identifier_index,
1313
         value_64bit );
1314
      }
1315
#endif
1316
0
      block_data_offset += 8;
1317
0
    }
1318
#if defined( HAVE_DEBUG_OUTPUT )
1319
    if( libcnotify_verbose != 0 )
1320
    {
1321
      libcnotify_printf(
1322
       "\n" );
1323
    }
1324
#endif
1325
0
  }
1326
0
  if( number_of_entries2 > ( ( block_data_size - block_data_offset ) / 8 ) )
1327
0
  {
1328
0
    libcerror_error_set(
1329
0
     error,
1330
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1331
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1332
0
     "%s: invalid number of entries2 value out of bounds.",
1333
0
     function );
1334
1335
0
    return( -1 );
1336
0
  }
1337
0
  if( number_of_entries2 > 0 )
1338
0
  {
1339
0
    for( entry_index = 0;
1340
0
         entry_index < number_of_entries2;
1341
0
         entry_index++ )
1342
0
    {
1343
#if defined( HAVE_DEBUG_OUTPUT )
1344
      if( libcnotify_verbose != 0 )
1345
      {
1346
        byte_stream_copy_to_uint32_little_endian(
1347
         &( block_data[ block_data_offset ] ),
1348
         value_32bit );
1349
        libcnotify_printf(
1350
         "%s: entry2: %03d unknown1\t\t: 0x%08" PRIx32 "\n",
1351
         function,
1352
         entry_index,
1353
         value_32bit );
1354
1355
        byte_stream_copy_to_uint32_little_endian(
1356
         &( block_data[ block_data_offset + 4 ] ),
1357
         value_32bit );
1358
        libcnotify_printf(
1359
         "%s: entry2: %03d unknown2\t\t: 0x%08" PRIx32 "\n",
1360
         function,
1361
         entry_index,
1362
         value_32bit );
1363
      }
1364
#endif
1365
0
      block_data_offset += 8;
1366
0
    }
1367
#if defined( HAVE_DEBUG_OUTPUT )
1368
    if( libcnotify_verbose != 0 )
1369
    {
1370
      libcnotify_printf(
1371
       "\n" );
1372
    }
1373
#endif
1374
0
  }
1375
0
  return( 1 );
1376
0
}
1377
1378
/* Reads the encrypted metadata block type 0x0014
1379
 * Returns 1 if successful or -1 on error
1380
 */
1381
int libfvde_encrypted_metadata_read_type_0x0014(
1382
     libfvde_encrypted_metadata_t *encrypted_metadata,
1383
     const uint8_t *block_data,
1384
     size_t block_data_size,
1385
     libcerror_error_t **error )
1386
0
{
1387
0
  static char *function                 = "libfvde_encrypted_metadata_read_type_0x0014";
1388
0
  size_t block_data_offset              = 0;
1389
0
  uint32_t entry_index                  = 0;
1390
0
  uint32_t number_of_entries2           = 0;
1391
0
  uint32_t number_of_object_identifiers = 0;
1392
1393
#if defined( HAVE_DEBUG_OUTPUT )
1394
  uint64_t value_64bit                  = 0;
1395
  uint32_t value_32bit                  = 0;
1396
  uint16_t value_16bit                  = 0;
1397
#endif
1398
1399
0
  if( encrypted_metadata == NULL )
1400
0
  {
1401
0
    libcerror_error_set(
1402
0
     error,
1403
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1404
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1405
0
     "%s: invalid encrypted metadata.",
1406
0
     function );
1407
1408
0
    return( -1 );
1409
0
  }
1410
0
  if( block_data == NULL )
1411
0
  {
1412
0
    libcerror_error_set(
1413
0
     error,
1414
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1415
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1416
0
     "%s: invalid block data.",
1417
0
     function );
1418
1419
0
    return( -1 );
1420
0
  }
1421
0
  if( ( block_data_size < 72 )
1422
0
   || ( block_data_size > (size_t) SSIZE_MAX ) )
1423
0
  {
1424
0
    libcerror_error_set(
1425
0
     error,
1426
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1427
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1428
0
     "%s: invalid block data size value out of bounds.",
1429
0
     function );
1430
1431
0
    return( -1 );
1432
0
  }
1433
0
  byte_stream_copy_to_uint32_little_endian(
1434
0
   &( block_data[ 56 ] ),
1435
0
   number_of_object_identifiers );
1436
1437
0
  byte_stream_copy_to_uint32_little_endian(
1438
0
   &( block_data[ 60 ] ),
1439
0
   number_of_entries2 );
1440
1441
#if defined( HAVE_DEBUG_OUTPUT )
1442
  if( libcnotify_verbose != 0 )
1443
  {
1444
    byte_stream_copy_to_uint32_little_endian(
1445
     &( block_data[ 0 ] ),
1446
     value_32bit );
1447
    libcnotify_printf(
1448
     "%s: checksum\t\t\t\t: 0x%08" PRIx32 "\n",
1449
     function,
1450
     value_32bit );
1451
1452
    byte_stream_copy_to_uint32_little_endian(
1453
     &( block_data[ 4 ] ),
1454
     value_32bit );
1455
    libcnotify_printf(
1456
     "%s: initial value\t\t\t: 0x%08" PRIx32 "\n",
1457
     function,
1458
     value_32bit );
1459
1460
    if( libfvde_debug_print_guid_value(
1461
         function,
1462
         "logical volume group identifier\t",
1463
         &( block_data[ 8 ] ),
1464
         16,
1465
         LIBFGUID_ENDIAN_BIG,
1466
         LIBFGUID_STRING_FORMAT_FLAG_USE_LOWER_CASE,
1467
         error ) != 1 )
1468
    {
1469
      libcerror_error_set(
1470
       error,
1471
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1472
       LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
1473
       "%s: unable to print GUID value.",
1474
       function );
1475
1476
      return( -1 );
1477
    }
1478
    byte_stream_copy_to_uint64_little_endian(
1479
     &( block_data[ 24 ] ),
1480
     value_64bit );
1481
    libcnotify_printf(
1482
     "%s: block number1\t\t\t: %" PRIu64 "\n",
1483
     function,
1484
     value_64bit );
1485
1486
    byte_stream_copy_to_uint64_little_endian(
1487
     &( block_data[ 32 ] ),
1488
     value_64bit );
1489
    libcnotify_printf(
1490
     "%s: unknown2\t\t\t\t: 0x%08" PRIx64 "\n",
1491
     function,
1492
     value_64bit );
1493
1494
    byte_stream_copy_to_uint32_little_endian(
1495
     &( block_data[ 40 ] ),
1496
     value_32bit );
1497
    libcnotify_printf(
1498
     "%s: unknown3\t\t\t\t: 0x%08" PRIx32 "\n",
1499
     function,
1500
     value_32bit );
1501
1502
    byte_stream_copy_to_uint32_little_endian(
1503
     &( block_data[ 44 ] ),
1504
     value_32bit );
1505
    libcnotify_printf(
1506
     "%s: number of blocks in transaction\t: %" PRIu32 "\n",
1507
     function,
1508
     value_32bit );
1509
1510
    byte_stream_copy_to_uint32_little_endian(
1511
     &( block_data[ 48 ] ),
1512
     value_32bit );
1513
    libcnotify_printf(
1514
     "%s: unknown5\t\t\t\t: 0x%08" PRIx32 "\n",
1515
     function,
1516
     value_32bit );
1517
1518
    byte_stream_copy_to_uint32_little_endian(
1519
     &( block_data[ 52 ] ),
1520
     value_32bit );
1521
    libcnotify_printf(
1522
     "%s: unknown6\t\t\t\t: 0x%08" PRIx32 "\n",
1523
     function,
1524
     value_32bit );
1525
1526
    libcnotify_printf(
1527
     "%s: number of object identifiers\t: %" PRIu32 "\n",
1528
     function,
1529
     number_of_object_identifiers );
1530
1531
    libcnotify_printf(
1532
     "%s: number of entries2\t\t\t: %" PRIu32 "\n",
1533
     function,
1534
     number_of_entries2 );
1535
1536
    byte_stream_copy_to_uint32_little_endian(
1537
     &( block_data[ 64 ] ),
1538
     value_32bit );
1539
    libcnotify_printf(
1540
     "%s: unknown9\t\t\t\t: 0x%08" PRIx32 "\n",
1541
     function,
1542
     value_32bit );
1543
1544
    byte_stream_copy_to_uint32_little_endian(
1545
     &( block_data[ 68 ] ),
1546
     value_32bit );
1547
    libcnotify_printf(
1548
     "%s: unknown10\t\t\t\t: 0x%08" PRIx32 "\n",
1549
     function,
1550
     value_32bit );
1551
1552
    byte_stream_copy_to_uint64_little_endian(
1553
     &( block_data[ 72 ] ),
1554
     value_64bit );
1555
    libcnotify_printf(
1556
     "%s: unknown11\t\t\t\t: 0x%08" PRIx64 "\n",
1557
     function,
1558
     value_64bit );
1559
1560
    byte_stream_copy_to_uint32_little_endian(
1561
     &( block_data[ 80 ] ),
1562
     value_32bit );
1563
    libcnotify_printf(
1564
     "%s: unknown12\t\t\t\t: 0x%08" PRIx32 "\n",
1565
     function,
1566
     value_32bit );
1567
1568
    byte_stream_copy_to_uint32_little_endian(
1569
     &( block_data[ 84 ] ),
1570
     value_32bit );
1571
    libcnotify_printf(
1572
     "%s: unknown13\t\t\t\t: 0x%08" PRIx32 "\n",
1573
     function,
1574
     value_32bit );
1575
1576
    byte_stream_copy_to_uint64_little_endian(
1577
     &( block_data[ 88 ] ),
1578
     value_64bit );
1579
    libcnotify_printf(
1580
     "%s: unknown14\t\t\t\t: 0x%08" PRIx64 "\n",
1581
     function,
1582
     value_64bit );
1583
1584
    byte_stream_copy_to_uint64_little_endian(
1585
     &( block_data[ 96 ] ),
1586
     value_64bit );
1587
    libcnotify_printf(
1588
     "%s: unknown15\t\t\t\t: 0x%08" PRIx64 "\n",
1589
     function,
1590
     value_64bit );
1591
1592
    byte_stream_copy_to_uint64_little_endian(
1593
     &( block_data[ 104 ] ),
1594
     value_64bit );
1595
    libcnotify_printf(
1596
     "%s: unknown16\t\t\t\t: 0x%08" PRIx64 "\n",
1597
     function,
1598
     value_64bit );
1599
1600
    byte_stream_copy_to_uint64_little_endian(
1601
     &( block_data[ 112 ] ),
1602
     value_64bit );
1603
    libcnotify_printf(
1604
     "%s: unknown17\t\t\t\t: 0x%08" PRIx64 "\n",
1605
     function,
1606
     value_64bit );
1607
1608
    byte_stream_copy_to_uint32_little_endian(
1609
     &( block_data[ 120 ] ),
1610
     value_32bit );
1611
    libcnotify_printf(
1612
     "%s: unknown18\t\t\t\t: 0x%08" PRIx32 "\n",
1613
     function,
1614
     value_32bit );
1615
1616
    byte_stream_copy_to_uint16_little_endian(
1617
     &( block_data[ 124 ] ),
1618
     value_16bit );
1619
    libcnotify_printf(
1620
     "%s: unknown19\t\t\t\t: 0x%04" PRIx16 "\n",
1621
     function,
1622
     value_16bit );
1623
1624
    byte_stream_copy_to_uint16_little_endian(
1625
     &( block_data[ 126 ] ),
1626
     value_16bit );
1627
    libcnotify_printf(
1628
     "%s: unknown20\t\t\t\t: 0x%04" PRIx16 "\n",
1629
     function,
1630
     value_16bit );
1631
1632
    libcnotify_printf(
1633
     "\n" );
1634
  }
1635
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
1636
1637
0
  block_data_offset = 128;
1638
1639
0
  if( number_of_object_identifiers > ( ( block_data_size - block_data_offset ) / 8 ) )
1640
0
  {
1641
0
    libcerror_error_set(
1642
0
     error,
1643
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1644
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1645
0
     "%s: invalid number of object identifiers value out of bounds.",
1646
0
     function );
1647
1648
0
    return( -1 );
1649
0
  }
1650
0
  if( number_of_object_identifiers > 0 )
1651
0
  {
1652
0
    for( entry_index = 0;
1653
0
         entry_index < number_of_object_identifiers;
1654
0
         entry_index++ )
1655
0
    {
1656
#if defined( HAVE_DEBUG_OUTPUT )
1657
      if( libcnotify_verbose != 0 )
1658
      {
1659
        byte_stream_copy_to_uint64_little_endian(
1660
         &( block_data[ block_data_offset ] ),
1661
         value_64bit );
1662
        libcnotify_printf(
1663
         "%s: object identifier: %d\t\t: %" PRIu64 "\n",
1664
         function,
1665
         entry_index,
1666
         value_64bit );
1667
      }
1668
#endif
1669
0
      block_data_offset += 8;
1670
0
    }
1671
#if defined( HAVE_DEBUG_OUTPUT )
1672
    if( libcnotify_verbose != 0 )
1673
    {
1674
      libcnotify_printf(
1675
       "\n" );
1676
    }
1677
#endif
1678
0
  }
1679
0
  if( number_of_entries2 > ( ( block_data_size - block_data_offset ) / 8 ) )
1680
0
  {
1681
0
    libcerror_error_set(
1682
0
     error,
1683
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1684
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1685
0
     "%s: invalid number of entries2 value out of bounds.",
1686
0
     function );
1687
1688
0
    return( -1 );
1689
0
  }
1690
0
  if( number_of_entries2 > 0 )
1691
0
  {
1692
0
    for( entry_index = 0;
1693
0
         entry_index < number_of_entries2;
1694
0
         entry_index++ )
1695
0
    {
1696
#if defined( HAVE_DEBUG_OUTPUT )
1697
      if( libcnotify_verbose != 0 )
1698
      {
1699
        byte_stream_copy_to_uint64_little_endian(
1700
         &( block_data[ block_data_offset ] ),
1701
         value_64bit );
1702
        libcnotify_printf(
1703
         "%s: entry2: %03d unknown1\t\t: 0x%08" PRIx64 "\n",
1704
         function,
1705
         entry_index,
1706
         value_64bit );
1707
      }
1708
#endif
1709
0
      block_data_offset += 8;
1710
0
    }
1711
#if defined( HAVE_DEBUG_OUTPUT )
1712
    if( libcnotify_verbose != 0 )
1713
    {
1714
      libcnotify_printf(
1715
       "\n" );
1716
    }
1717
#endif
1718
0
  }
1719
0
  return( 1 );
1720
0
}
1721
1722
/* Reads the encrypted metadata block type 0x0016
1723
 * Returns 1 if successful or -1 on error
1724
 */
1725
int libfvde_encrypted_metadata_read_type_0x0016(
1726
     libfvde_encrypted_metadata_t *encrypted_metadata,
1727
     const uint8_t *block_data,
1728
     size_t block_data_size,
1729
     libcerror_error_t **error )
1730
0
{
1731
0
  static char *function      = "libfvde_encrypted_metadata_read_type_0x0016";
1732
0
  size_t block_data_offset   = 0;
1733
0
  uint32_t entry_index       = 0;
1734
0
  uint32_t number_of_entries = 0;
1735
1736
#if defined( HAVE_DEBUG_OUTPUT )
1737
  uint64_t value_64bit       = 0;
1738
  uint32_t value_32bit       = 0;
1739
#endif
1740
1741
0
  if( encrypted_metadata == NULL )
1742
0
  {
1743
0
    libcerror_error_set(
1744
0
     error,
1745
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1746
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1747
0
     "%s: invalid encrypted metadata.",
1748
0
     function );
1749
1750
0
    return( -1 );
1751
0
  }
1752
0
  if( block_data == NULL )
1753
0
  {
1754
0
    libcerror_error_set(
1755
0
     error,
1756
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1757
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1758
0
     "%s: invalid block data.",
1759
0
     function );
1760
1761
0
    return( -1 );
1762
0
  }
1763
0
  if( ( block_data_size < 4 )
1764
0
   || ( block_data_size > (size_t) SSIZE_MAX ) )
1765
0
  {
1766
0
    libcerror_error_set(
1767
0
     error,
1768
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1769
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1770
0
     "%s: invalid block data size value out of bounds.",
1771
0
     function );
1772
1773
0
    return( -1 );
1774
0
  }
1775
0
  byte_stream_copy_to_uint32_little_endian(
1776
0
   &( block_data[ 0 ] ),
1777
0
   number_of_entries );
1778
1779
#if defined( HAVE_DEBUG_OUTPUT )
1780
  if( libcnotify_verbose != 0 )
1781
  {
1782
    libcnotify_printf(
1783
     "%s: number of entries\t\t: %" PRIu32 "\n",
1784
     function,
1785
     number_of_entries );
1786
1787
    libcnotify_printf(
1788
     "\n" );
1789
  }
1790
#endif
1791
0
  block_data_offset = 4;
1792
1793
0
  if( number_of_entries > ( ( block_data_size - block_data_offset ) / 12 ) )
1794
0
  {
1795
0
    libcerror_error_set(
1796
0
     error,
1797
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1798
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1799
0
     "%s: invalid number of entries value out of bounds.",
1800
0
     function );
1801
1802
0
    return( -1 );
1803
0
  }
1804
0
  for( entry_index = 0;
1805
0
       entry_index < number_of_entries;
1806
0
       entry_index++ )
1807
0
  {
1808
#if defined( HAVE_DEBUG_OUTPUT )
1809
    if( libcnotify_verbose != 0 )
1810
    {
1811
      byte_stream_copy_to_uint64_little_endian(
1812
       &( block_data[ block_data_offset ] ),
1813
       value_64bit );
1814
      libcnotify_printf(
1815
       "%s: entry: %03d unknown1\t: 0x%08" PRIx64 "\n",
1816
       function,
1817
       entry_index,
1818
       value_64bit );
1819
1820
      byte_stream_copy_to_uint32_little_endian(
1821
       &( block_data[ block_data_offset + 8 ] ),
1822
       value_32bit );
1823
      libcnotify_printf(
1824
       "%s: entry: %03d unknown2\t: %" PRIu32 "\n",
1825
       function,
1826
       entry_index,
1827
       value_32bit );
1828
1829
      libcnotify_printf(
1830
       "\n" );
1831
    }
1832
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
1833
1834
0
    block_data_offset += 12;
1835
0
  }
1836
0
  return( 1 );
1837
0
}
1838
1839
/* Reads the encrypted metadata block type 0x0017
1840
 * Returns 1 if successful or -1 on error
1841
 */
1842
int libfvde_encrypted_metadata_read_type_0x0017(
1843
     libfvde_encrypted_metadata_t *encrypted_metadata,
1844
     const uint8_t *block_data,
1845
     size_t block_data_size,
1846
     libcerror_error_t **error )
1847
0
{
1848
0
  static char *function      = "libfvde_encrypted_metadata_read_type_0x0017";
1849
0
  size_t block_data_offset   = 0;
1850
0
  uint64_t entry_index       = 0;
1851
0
  uint64_t number_of_entries = 0;
1852
1853
#if defined( HAVE_DEBUG_OUTPUT )
1854
  uint64_t value_64bit       = 0;
1855
  uint32_t value_32bit       = 0;
1856
#endif
1857
1858
0
  if( encrypted_metadata == NULL )
1859
0
  {
1860
0
    libcerror_error_set(
1861
0
     error,
1862
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1863
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1864
0
     "%s: invalid encrypted metadata.",
1865
0
     function );
1866
1867
0
    return( -1 );
1868
0
  }
1869
0
  if( block_data == NULL )
1870
0
  {
1871
0
    libcerror_error_set(
1872
0
     error,
1873
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1874
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1875
0
     "%s: invalid block data.",
1876
0
     function );
1877
1878
0
    return( -1 );
1879
0
  }
1880
0
  if( ( block_data_size < 8 )
1881
0
   || ( block_data_size > (size_t) SSIZE_MAX ) )
1882
0
  {
1883
0
    libcerror_error_set(
1884
0
     error,
1885
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1886
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1887
0
     "%s: invalid block data size value out of bounds.",
1888
0
     function );
1889
1890
0
    return( -1 );
1891
0
  }
1892
0
  byte_stream_copy_to_uint64_little_endian(
1893
0
   &( block_data[ 0 ] ),
1894
0
   number_of_entries );
1895
1896
#if defined( HAVE_DEBUG_OUTPUT )
1897
  if( libcnotify_verbose != 0 )
1898
  {
1899
    libcnotify_printf(
1900
     "%s: number of entries\t\t: %" PRIu64 "\n",
1901
     function,
1902
     number_of_entries );
1903
1904
    libcnotify_printf(
1905
     "\n" );
1906
  }
1907
#endif
1908
0
  block_data_offset = 8;
1909
1910
0
  if( number_of_entries > ( ( block_data_size - block_data_offset ) / 32 ) )
1911
0
  {
1912
0
    libcerror_error_set(
1913
0
     error,
1914
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1915
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1916
0
     "%s: invalid number of entries value out of bounds.",
1917
0
     function );
1918
1919
0
    return( -1 );
1920
0
  }
1921
0
  for( entry_index = 0;
1922
0
       entry_index < number_of_entries;
1923
0
       entry_index++ )
1924
0
  {
1925
#if defined( HAVE_DEBUG_OUTPUT )
1926
    if( libcnotify_verbose != 0 )
1927
    {
1928
      byte_stream_copy_to_uint64_little_endian(
1929
       &( block_data[ block_data_offset ] ),
1930
       value_64bit );
1931
      libcnotify_printf(
1932
       "%s: entry: %02d unknown1\t\t: 0x%08" PRIx64 "\n",
1933
       function,
1934
       entry_index,
1935
       value_64bit );
1936
1937
      byte_stream_copy_to_uint32_little_endian(
1938
       &( block_data[ block_data_offset + 8 ] ),
1939
       value_32bit );
1940
      libcnotify_printf(
1941
       "%s: entry: %02d unknown2\t\t: 0x%08" PRIx32 "\n",
1942
       function,
1943
       entry_index,
1944
       value_32bit );
1945
1946
      byte_stream_copy_to_uint32_little_endian(
1947
       &( block_data[ block_data_offset + 12 ] ),
1948
       value_32bit );
1949
      libcnotify_printf(
1950
       "%s: entry: %02d unknown3\t\t: 0x%08" PRIx32 "\n",
1951
       function,
1952
       entry_index,
1953
       value_32bit );
1954
1955
      byte_stream_copy_to_uint64_little_endian(
1956
       &( block_data[ block_data_offset + 16 ] ),
1957
       value_64bit );
1958
      libcnotify_printf(
1959
       "%s: entry: %02d unknown4\t\t: 0x%08" PRIx64 "\n",
1960
       function,
1961
       entry_index,
1962
       value_64bit );
1963
1964
      byte_stream_copy_to_uint64_little_endian(
1965
       &( block_data[ block_data_offset + 24 ] ),
1966
       value_64bit );
1967
      libcnotify_printf(
1968
       "%s: entry: %02d unknown5\t\t: 0x%08" PRIx64 "\n",
1969
       function,
1970
       entry_index,
1971
       value_64bit );
1972
1973
      libcnotify_printf(
1974
       "\n" );
1975
    }
1976
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
1977
1978
0
    block_data_offset += 32;
1979
0
  }
1980
0
  return( 1 );
1981
0
}
1982
1983
/* Reads the encrypted metadata block type 0x0018
1984
 * Returns 1 if successful or -1 on error
1985
 */
1986
int libfvde_encrypted_metadata_read_type_0x0018(
1987
     libfvde_encrypted_metadata_t *encrypted_metadata,
1988
     const uint8_t *block_data,
1989
     size_t block_data_size,
1990
     libcerror_error_t **error )
1991
0
{
1992
0
  static char *function = "libfvde_encrypted_metadata_read_type_0x0018";
1993
1994
#if defined( HAVE_DEBUG_OUTPUT )
1995
  uint64_t value_64bit  = 0;
1996
#endif
1997
1998
0
  if( encrypted_metadata == NULL )
1999
0
  {
2000
0
    libcerror_error_set(
2001
0
     error,
2002
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2003
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2004
0
     "%s: invalid encrypted metadata.",
2005
0
     function );
2006
2007
0
    return( -1 );
2008
0
  }
2009
0
  if( block_data == NULL )
2010
0
  {
2011
0
    libcerror_error_set(
2012
0
     error,
2013
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2014
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2015
0
     "%s: invalid block data.",
2016
0
     function );
2017
2018
0
    return( -1 );
2019
0
  }
2020
0
  if( ( block_data_size < 16 )
2021
0
   || ( block_data_size > (size_t) SSIZE_MAX ) )
2022
0
  {
2023
0
    libcerror_error_set(
2024
0
     error,
2025
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2026
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
2027
0
     "%s: invalid block data size value out of bounds.",
2028
0
     function );
2029
2030
0
    return( -1 );
2031
0
  }
2032
#if defined( HAVE_DEBUG_OUTPUT )
2033
  if( libcnotify_verbose != 0 )
2034
  {
2035
    byte_stream_copy_to_uint64_little_endian(
2036
     &( block_data[ 0 ] ),
2037
     value_64bit );
2038
    libcnotify_printf(
2039
     "%s: 0x0105 object identifier\t: %" PRIu64 "\n",
2040
     function,
2041
     value_64bit );
2042
2043
    byte_stream_copy_to_uint64_little_endian(
2044
     &( block_data[ 8 ] ),
2045
     value_64bit );
2046
    libcnotify_printf(
2047
     "%s: unknown2\t\t\t: %" PRIu64 "\n",
2048
     function,
2049
     value_64bit );
2050
2051
    libcnotify_printf(
2052
     "\n" );
2053
  }
2054
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
2055
2056
0
  return( 1 );
2057
0
}
2058
2059
/* Reads the encrypted metadata block type 0x0019
2060
 * Returns 1 if successful or -1 on error
2061
 */
2062
int libfvde_encrypted_metadata_read_type_0x0019(
2063
     libfvde_encrypted_metadata_t *encrypted_metadata,
2064
     const uint8_t *block_data,
2065
     size_t block_data_size,
2066
     libcerror_error_t **error )
2067
0
{
2068
0
  const uint8_t *xml_plist_data   = NULL;
2069
0
  static char *function           = "libfvde_encrypted_metadata_read_type_0x0019";
2070
0
  size_t block_data_offset        = 0;
2071
0
  uint64_t next_object_identifier = 0;
2072
0
  uint32_t compressed_data_size   = 0;
2073
0
  uint32_t uncompressed_data_size = 0;
2074
0
  uint32_t xml_plist_data_offset  = 0;
2075
0
  uint32_t xml_plist_data_size    = 0;
2076
0
  uint16_t entry_index            = 0;
2077
0
  uint16_t number_of_entries      = 0;
2078
2079
#if defined( HAVE_DEBUG_OUTPUT )
2080
  uint64_t value_64bit            = 0;
2081
  uint32_t value_32bit            = 0;
2082
  uint16_t value_16bit            = 0;
2083
#endif
2084
2085
0
  if( encrypted_metadata == NULL )
2086
0
  {
2087
0
    libcerror_error_set(
2088
0
     error,
2089
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2090
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2091
0
     "%s: invalid encrypted metadata.",
2092
0
     function );
2093
2094
0
    return( -1 );
2095
0
  }
2096
0
  if( block_data == NULL )
2097
0
  {
2098
0
    libcerror_error_set(
2099
0
     error,
2100
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2101
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2102
0
     "%s: invalid block data.",
2103
0
     function );
2104
2105
0
    return( -1 );
2106
0
  }
2107
0
  if( ( block_data_size < 64 )
2108
0
   || ( block_data_size > (size_t) SSIZE_MAX ) )
2109
0
  {
2110
0
    libcerror_error_set(
2111
0
     error,
2112
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2113
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
2114
0
     "%s: invalid block data size value out of bounds.",
2115
0
     function );
2116
2117
0
    return( -1 );
2118
0
  }
2119
0
  if( encrypted_metadata->compressed_data != NULL )
2120
0
  {
2121
0
    memory_free(
2122
0
     encrypted_metadata->compressed_data );
2123
2124
0
    encrypted_metadata->compressed_data = NULL;
2125
0
  }
2126
0
  byte_stream_copy_to_uint64_little_endian(
2127
0
   &( block_data[ 32 ] ),
2128
0
   next_object_identifier );
2129
2130
0
  byte_stream_copy_to_uint32_little_endian(
2131
0
   &( block_data[ 40 ] ),
2132
0
   compressed_data_size );
2133
2134
0
  byte_stream_copy_to_uint32_little_endian(
2135
0
   &( block_data[ 44 ] ),
2136
0
   uncompressed_data_size );
2137
2138
0
  byte_stream_copy_to_uint32_little_endian(
2139
0
   &( block_data[ 48 ] ),
2140
0
   xml_plist_data_offset );
2141
2142
0
  byte_stream_copy_to_uint32_little_endian(
2143
0
   &( block_data[ 52 ] ),
2144
0
   xml_plist_data_size );
2145
2146
0
  byte_stream_copy_to_uint16_little_endian(
2147
0
   &( block_data[ 62 ] ),
2148
0
   number_of_entries );
2149
2150
#if defined( HAVE_DEBUG_OUTPUT )
2151
  if( libcnotify_verbose != 0 )
2152
  {
2153
    byte_stream_copy_to_uint64_little_endian(
2154
     &( block_data[ 0 ] ),
2155
     value_64bit );
2156
    libcnotify_printf(
2157
     "%s: unknown1\t\t\t: %" PRIu64 "\n",
2158
     function,
2159
     value_64bit );
2160
2161
    byte_stream_copy_to_uint64_little_endian(
2162
     &( block_data[ 8 ] ),
2163
     value_64bit );
2164
    libcnotify_printf(
2165
     "%s: unknown2\t\t\t: %" PRIu64 "\n",
2166
     function,
2167
     value_64bit );
2168
2169
    byte_stream_copy_to_uint64_little_endian(
2170
     &( block_data[ 16 ] ),
2171
     value_64bit );
2172
    libcnotify_printf(
2173
     "%s: 0x0605 object identifier\t: %" PRIu64 "\n",
2174
     function,
2175
     value_64bit );
2176
2177
    byte_stream_copy_to_uint64_little_endian(
2178
     &( block_data[ 24 ] ),
2179
     value_64bit );
2180
    libcnotify_printf(
2181
     "%s: 0x0205 object identifier\t: %" PRIu64 "\n",
2182
     function,
2183
     value_64bit );
2184
2185
    libcnotify_printf(
2186
     "%s: next object identifier\t: %" PRIu64 "\n",
2187
     function,
2188
     next_object_identifier );
2189
2190
    libcnotify_printf(
2191
     "%s: compressed data size\t: %" PRIu32 "\n",
2192
     function,
2193
     compressed_data_size );
2194
2195
    libcnotify_printf(
2196
     "%s: uncompressed data size\t: %" PRIu32 "\n",
2197
     function,
2198
     uncompressed_data_size );
2199
2200
    libcnotify_printf(
2201
     "%s: XML plist data offset\t: 0x%08" PRIx32 "\n",
2202
     function,
2203
     xml_plist_data_offset );
2204
2205
    libcnotify_printf(
2206
     "%s: XML plist data size\t: %" PRIu32 "\n",
2207
     function,
2208
     xml_plist_data_size );
2209
2210
    byte_stream_copy_to_uint32_little_endian(
2211
     &( block_data[ 56 ] ),
2212
     value_32bit );
2213
    libcnotify_printf(
2214
     "%s: unknown3\t\t\t: 0x%08" PRIx32 "\n",
2215
     function,
2216
     value_32bit );
2217
2218
    byte_stream_copy_to_uint16_little_endian(
2219
     &( block_data[ 60 ] ),
2220
     value_16bit );
2221
    libcnotify_printf(
2222
     "%s: unknown4\t\t\t: %" PRIu16 "\n",
2223
     function,
2224
     value_16bit );
2225
2226
    libcnotify_printf(
2227
     "%s: number of entries\t\t: %" PRIu16 "\n",
2228
     function,
2229
     number_of_entries );
2230
2231
    byte_stream_copy_to_uint64_little_endian(
2232
     &( block_data[ 64 ] ),
2233
     value_64bit );
2234
    libcnotify_printf(
2235
     "%s: unknown5\t\t\t: %" PRIu64 "\n",
2236
     function,
2237
     value_64bit );
2238
2239
    byte_stream_copy_to_uint64_little_endian(
2240
     &( block_data[ 72 ] ),
2241
     value_64bit );
2242
    libcnotify_printf(
2243
     "%s: unknown6\t\t\t: %" PRIu64 "\n",
2244
     function,
2245
     value_64bit );
2246
2247
    libcnotify_printf(
2248
     "\n" );
2249
  }
2250
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
2251
2252
0
  block_data_offset = 80;
2253
2254
0
  if( ( xml_plist_data_offset < ( block_data_offset + 64 ) )
2255
0
   || ( xml_plist_data_offset >= block_data_size ) )
2256
0
  {
2257
0
    libcerror_error_set(
2258
0
     error,
2259
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2260
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
2261
0
     "%s: invalid XML plist data offset value out of bounds.",
2262
0
     function );
2263
2264
0
    goto on_error;
2265
0
  }
2266
0
  if( xml_plist_data_size > ( block_data_size - ( xml_plist_data_offset - 64 ) ) )
2267
0
  {
2268
0
    libcerror_error_set(
2269
0
     error,
2270
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2271
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
2272
0
     "%s: invalid XML plist data size value out of bounds.",
2273
0
     function );
2274
2275
0
    goto on_error;
2276
0
  }
2277
0
  if( number_of_entries > ( ( block_data_size - block_data_offset ) / 24 ) )
2278
0
  {
2279
0
    libcerror_error_set(
2280
0
     error,
2281
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2282
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
2283
0
     "%s: invalid number of entries value out of bounds.",
2284
0
     function );
2285
2286
0
    return( -1 );
2287
0
  }
2288
0
  for( entry_index = 0;
2289
0
       entry_index < number_of_entries;
2290
0
       entry_index++ )
2291
0
  {
2292
#if defined( HAVE_DEBUG_OUTPUT )
2293
    if( libcnotify_verbose != 0 )
2294
    {
2295
      byte_stream_copy_to_uint64_little_endian(
2296
       &( block_data[ block_data_offset ] ),
2297
       value_64bit );
2298
      libcnotify_printf(
2299
       "%s: entry: %03d unknown1\t: %" PRIu64 "\n",
2300
       function,
2301
       entry_index,
2302
       value_64bit );
2303
2304
      byte_stream_copy_to_uint64_little_endian(
2305
       &( block_data[ block_data_offset + 8 ] ),
2306
       value_64bit );
2307
      libcnotify_printf(
2308
       "%s: entry: %03d unknown2\t: %" PRIu64 "\n",
2309
       function,
2310
       entry_index,
2311
       value_64bit );
2312
2313
      byte_stream_copy_to_uint64_little_endian(
2314
       &( block_data[ block_data_offset + 16 ] ),
2315
       value_64bit );
2316
      libcnotify_printf(
2317
       "%s: entry: %03d unknown3\t: %" PRIu64 "\n",
2318
       function,
2319
       entry_index,
2320
       value_64bit );
2321
2322
      libcnotify_printf(
2323
       "\n" );
2324
    }
2325
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
2326
2327
0
    block_data_offset += 24;
2328
0
  }
2329
#if defined( HAVE_DEBUG_OUTPUT )
2330
  if( libcnotify_verbose != 0 )
2331
  {
2332
    if( xml_plist_data_offset > ( block_data_offset + 64 ) )
2333
    {
2334
      libcnotify_printf(
2335
       "%s: unknown7:\n",
2336
       function );
2337
      libcnotify_print_data(
2338
       &( block_data[ block_data_offset ] ),
2339
       xml_plist_data_offset - ( block_data_offset + 64 ),
2340
       LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
2341
    }
2342
  }
2343
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
2344
2345
0
  if( compressed_data_size != uncompressed_data_size )
2346
0
  {
2347
0
    if( xml_plist_data_size > compressed_data_size )
2348
0
    {
2349
0
      libcerror_error_set(
2350
0
       error,
2351
0
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2352
0
       LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
2353
0
       "%s: invalid XML plist data size value out of bounds.",
2354
0
       function );
2355
2356
0
      goto on_error;
2357
0
    }
2358
0
    if( compressed_data_size > (uint64_t) MEMORY_MAXIMUM_ALLOCATION_SIZE )
2359
0
    {
2360
0
      libcerror_error_set(
2361
0
       error,
2362
0
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2363
0
       LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
2364
0
       "%s: invalid compressed data size value out of bounds.",
2365
0
       function );
2366
2367
0
      goto on_error;
2368
0
    }
2369
0
    encrypted_metadata->compressed_data = (uint8_t *) memory_allocate(
2370
0
                                                       sizeof( uint8_t ) * (size_t) compressed_data_size );
2371
2372
0
    if( encrypted_metadata->compressed_data == NULL )
2373
0
    {
2374
0
      libcerror_error_set(
2375
0
       error,
2376
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
2377
0
       LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
2378
0
       "%s: unable to create compressed data.",
2379
0
       function );
2380
2381
0
      goto on_error;
2382
0
    }
2383
0
    encrypted_metadata->compressed_data_size = (size_t) compressed_data_size;
2384
2385
0
    if( memory_copy(
2386
0
         encrypted_metadata->compressed_data,
2387
0
         &( block_data[ xml_plist_data_offset - 64 ] ),
2388
0
         xml_plist_data_size ) == NULL )
2389
0
    {
2390
0
      libcerror_error_set(
2391
0
       error,
2392
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
2393
0
       LIBCERROR_MEMORY_ERROR_COPY_FAILED,
2394
0
       "%s: unable to copy compressed data.",
2395
0
       function );
2396
2397
0
      goto on_error;
2398
0
    }
2399
0
    encrypted_metadata->compressed_data_object_identifier = next_object_identifier;
2400
0
    encrypted_metadata->compressed_data_offset            = (size_t) xml_plist_data_size;
2401
0
    encrypted_metadata->uncompressed_data_size            = (size_t) uncompressed_data_size;
2402
0
  }
2403
0
  else
2404
0
  {
2405
0
    xml_plist_data = &( block_data[ xml_plist_data_offset - 64 ] );
2406
2407
0
    if( ( xml_plist_data_size > 5 )
2408
0
     && ( xml_plist_data[ 0 ] == (uint8_t) '<' )
2409
0
     && ( xml_plist_data[ 1 ] == (uint8_t) 'd' )
2410
0
     && ( xml_plist_data[ 2 ] == (uint8_t) 'i' )
2411
0
     && ( xml_plist_data[ 3 ] == (uint8_t) 'c' )
2412
0
     && ( xml_plist_data[ 4 ] == (uint8_t) 't' ) )
2413
0
    {
2414
#if defined( HAVE_DEBUG_OUTPUT )
2415
      if( libcnotify_verbose != 0 )
2416
      {
2417
        libcnotify_printf(
2418
         "%s: XML:\n%s\n",
2419
         function,
2420
         (char *) xml_plist_data );
2421
2422
        libcnotify_printf(
2423
         "\n" );
2424
      }
2425
#endif
2426
0
      if( encrypted_metadata->encryption_context_plist_data != NULL )
2427
0
      {
2428
0
        memory_free(
2429
0
         encrypted_metadata->encryption_context_plist_data );
2430
2431
0
        encrypted_metadata->encryption_context_plist_data = NULL;
2432
0
      }
2433
0
      encrypted_metadata->encryption_context_plist_data = (uint8_t *) memory_allocate(
2434
0
                                                                       sizeof( uint8_t ) * xml_plist_data_size );
2435
2436
0
      if( encrypted_metadata->encryption_context_plist_data == NULL )
2437
0
      {
2438
0
        libcerror_error_set(
2439
0
         error,
2440
0
         LIBCERROR_ERROR_DOMAIN_MEMORY,
2441
0
         LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
2442
0
         "%s: unable to create encryption context plist data.",
2443
0
         function );
2444
2445
0
        goto on_error;
2446
0
      }
2447
0
      if( memory_copy(
2448
0
           encrypted_metadata->encryption_context_plist_data,
2449
0
           xml_plist_data,
2450
0
           xml_plist_data_size ) == NULL )
2451
0
      {
2452
0
        libcerror_error_set(
2453
0
         error,
2454
0
         LIBCERROR_ERROR_DOMAIN_MEMORY,
2455
0
         LIBCERROR_MEMORY_ERROR_COPY_FAILED,
2456
0
         "%s: unable to copy encryption context plist data.",
2457
0
         function );
2458
2459
0
        memory_free(
2460
0
         encrypted_metadata->encryption_context_plist_data );
2461
2462
0
        encrypted_metadata->encryption_context_plist_data = NULL;
2463
2464
0
        goto on_error;
2465
0
      }
2466
0
      encrypted_metadata->encryption_context_plist_data_size = xml_plist_data_size;
2467
0
    }
2468
0
  }
2469
0
  return( 1 );
2470
2471
0
on_error:
2472
0
  if( encrypted_metadata->compressed_data != NULL )
2473
0
  {
2474
0
    memory_free(
2475
0
     encrypted_metadata->compressed_data );
2476
2477
0
    encrypted_metadata->compressed_data = NULL;
2478
0
  }
2479
0
  return( -1 );
2480
0
}
2481
2482
/* Reads the encrypted metadata block type 0x001a
2483
 * Returns 1 if successful or -1 on error
2484
 */
2485
int libfvde_encrypted_metadata_read_type_0x001a(
2486
     libfvde_encrypted_metadata_t *encrypted_metadata,
2487
     const uint8_t *block_data,
2488
     size_t block_data_size,
2489
     libcerror_error_t **error )
2490
0
{
2491
0
  libfplist_property_t *root_property                            = NULL;
2492
0
  libfplist_property_t *sub_property                             = NULL;
2493
0
  libfplist_property_list_t *property_list                       = NULL;
2494
0
  libfvde_logical_volume_descriptor_t *logical_volume_descriptor = NULL;
2495
0
  const uint8_t *xml_plist_data                                  = NULL;
2496
0
  static char *function                                          = "libfvde_encrypted_metadata_read_type_0x001a";
2497
0
  size_t block_data_offset                                       = 0;
2498
0
  size_t xml_length                                              = 0;
2499
0
  uint64_t logical_volume_size                                   = 0;
2500
0
  uint64_t object_identifier                                     = 0;
2501
0
  uint64_t object_identifier_0x0305                              = 0;
2502
0
  uint64_t object_identifier_0x0505                              = 0;
2503
0
  uint32_t compressed_data_size                                  = 0;
2504
0
  uint32_t uncompressed_data_size                                = 0;
2505
0
  uint32_t xml_plist_data_offset                                 = 0;
2506
0
  uint32_t xml_plist_data_size                                   = 0;
2507
2508
#if defined( HAVE_DEBUG_OUTPUT )
2509
  uint8_t *string                                                = NULL;
2510
  size_t string_size                                             = 0;
2511
  uint64_t value_64bit                                           = 0;
2512
#endif
2513
2514
0
  if( encrypted_metadata == NULL )
2515
0
  {
2516
0
    libcerror_error_set(
2517
0
     error,
2518
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2519
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2520
0
     "%s: invalid encrypted metadata.",
2521
0
     function );
2522
2523
0
    return( -1 );
2524
0
  }
2525
0
  if( block_data == NULL )
2526
0
  {
2527
0
    libcerror_error_set(
2528
0
     error,
2529
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2530
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2531
0
     "%s: invalid block data.",
2532
0
     function );
2533
2534
0
    return( -1 );
2535
0
  }
2536
0
  if( ( block_data_size < 72 )
2537
0
   || ( block_data_size > (size_t) SSIZE_MAX ) )
2538
0
  {
2539
0
    libcerror_error_set(
2540
0
     error,
2541
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2542
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
2543
0
     "%s: invalid block data size value out of bounds.",
2544
0
     function );
2545
2546
0
    return( -1 );
2547
0
  }
2548
0
  byte_stream_copy_to_uint64_little_endian(
2549
0
   &( block_data[ 0 ] ),
2550
0
   object_identifier );
2551
2552
0
  byte_stream_copy_to_uint64_little_endian(
2553
0
   &( block_data[ 8 ] ),
2554
0
   object_identifier_0x0305 );
2555
2556
0
  byte_stream_copy_to_uint64_little_endian(
2557
0
   &( block_data[ 40 ] ),
2558
0
   object_identifier_0x0505 );
2559
2560
0
  byte_stream_copy_to_uint32_little_endian(
2561
0
   &( block_data[ 56 ] ),
2562
0
   compressed_data_size );
2563
2564
0
  byte_stream_copy_to_uint32_little_endian(
2565
0
   &( block_data[ 60 ] ),
2566
0
   uncompressed_data_size );
2567
2568
0
  byte_stream_copy_to_uint32_little_endian(
2569
0
   &( block_data[ 64 ] ),
2570
0
   xml_plist_data_offset );
2571
2572
0
  byte_stream_copy_to_uint32_little_endian(
2573
0
   &( block_data[ 68 ] ),
2574
0
   xml_plist_data_size );
2575
2576
#if defined( HAVE_DEBUG_OUTPUT )
2577
  if( libcnotify_verbose != 0 )
2578
  {
2579
    libcnotify_printf(
2580
     "%s: object identifier\t\t\t: %" PRIu64 "\n",
2581
     function,
2582
     object_identifier );
2583
2584
    libcnotify_printf(
2585
     "%s: 0x0305 object identifier\t\t: %" PRIu64 "\n",
2586
     function,
2587
     object_identifier_0x0305 );
2588
2589
    byte_stream_copy_to_uint64_little_endian(
2590
     &( block_data[ 16 ] ),
2591
     value_64bit );
2592
    libcnotify_printf(
2593
     "%s: unknown1\t\t\t\t: %" PRIu64 "\n",
2594
     function,
2595
     value_64bit );
2596
2597
    byte_stream_copy_to_uint64_little_endian(
2598
     &( block_data[ 24 ] ),
2599
     value_64bit );
2600
    libcnotify_printf(
2601
     "%s: unknown2\t\t\t\t: %" PRIu64 "\n",
2602
     function,
2603
     value_64bit );
2604
2605
    byte_stream_copy_to_uint64_little_endian(
2606
     &( block_data[ 32 ] ),
2607
     value_64bit );
2608
    libcnotify_printf(
2609
     "%s: 0x0021 object identifier\t\t: %" PRIu64 "\n",
2610
     function,
2611
     value_64bit );
2612
2613
    libcnotify_printf(
2614
     "%s: 0x0505 object identifier\t\t: %" PRIu64 "\n",
2615
     function,
2616
     object_identifier_0x0505 );
2617
2618
    byte_stream_copy_to_uint64_little_endian(
2619
     &( block_data[ 48 ] ),
2620
     value_64bit );
2621
    libcnotify_printf(
2622
     "%s: unknown3\t\t\t\t: %" PRIu64 "\n",
2623
     function,
2624
     value_64bit );
2625
2626
    libcnotify_printf(
2627
     "%s: compressed data size\t\t: %" PRIu32 "\n",
2628
     function,
2629
     compressed_data_size );
2630
2631
    libcnotify_printf(
2632
     "%s: uncompressed data size\t\t: %" PRIu32 "\n",
2633
     function,
2634
     uncompressed_data_size );
2635
2636
    libcnotify_printf(
2637
     "%s: XML plist data offset\t\t: 0x%08" PRIx32 "\n",
2638
     function,
2639
     xml_plist_data_offset );
2640
2641
    libcnotify_printf(
2642
     "%s: XML plist data size\t\t: %" PRIu32 "\n",
2643
     function,
2644
     xml_plist_data_size );
2645
  }
2646
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
2647
2648
0
  block_data_offset = 72;
2649
2650
0
  if( ( xml_plist_data_offset < ( block_data_offset + 64 ) )
2651
0
   || ( (size_t) xml_plist_data_offset > block_data_size ) )
2652
0
  {
2653
0
    libcerror_error_set(
2654
0
     error,
2655
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2656
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
2657
0
     "%s: invalid XML plist data offset value out of bounds.",
2658
0
     function );
2659
2660
0
    goto on_error;
2661
0
  }
2662
0
  if( xml_plist_data_size > ( block_data_size - ( xml_plist_data_offset - 64 ) ) )
2663
0
  {
2664
0
    libcerror_error_set(
2665
0
     error,
2666
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2667
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
2668
0
     "%s: invalid XML plist data size value out of bounds.",
2669
0
     function );
2670
2671
0
    goto on_error;
2672
0
  }
2673
#if defined( HAVE_DEBUG_OUTPUT )
2674
  if( libcnotify_verbose != 0 )
2675
  {
2676
    if( xml_plist_data_offset > ( block_data_offset + 64 ) )
2677
    {
2678
      libcnotify_printf(
2679
       "%s: unknown4:\n",
2680
       function );
2681
      libcnotify_print_data(
2682
       &( block_data[ block_data_offset ] ),
2683
       xml_plist_data_offset - ( block_data_offset + 64 ),
2684
       LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
2685
    }
2686
  }
2687
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
2688
2689
0
  if( libfvde_encrypted_metadata_get_logical_volume_descriptor_by_object_identifier(
2690
0
       encrypted_metadata,
2691
0
       object_identifier,
2692
0
       &logical_volume_descriptor,
2693
0
       error ) != 1 )
2694
0
  {
2695
0
    libcerror_error_set(
2696
0
     error,
2697
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2698
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2699
0
     "%s: unable to retrieve logical volume descriptor with object identifier: %" PRIu64 ".",
2700
0
     function,
2701
0
     object_identifier );
2702
2703
0
    goto on_error;
2704
0
  }
2705
0
  if( logical_volume_descriptor == NULL )
2706
0
  {
2707
0
    libcerror_error_set(
2708
0
     error,
2709
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2710
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2711
0
     "%s: missing logical volume descriptor with object identifier: %" PRIu64 ".",
2712
0
     function,
2713
0
     object_identifier );
2714
2715
0
    goto on_error;
2716
0
  }
2717
0
  if( ( object_identifier_0x0305 != 0 )
2718
0
   && ( logical_volume_descriptor->object_identifier_0x0305 != 0 )
2719
0
   && ( logical_volume_descriptor->object_identifier_0x0305 != object_identifier_0x0305 ) )
2720
0
  {
2721
0
    libcerror_error_set(
2722
0
     error,
2723
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2724
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
2725
0
     "%s: mismatch in object identifier 0x0305 (stored: %" PRIu64 ", expected: %" PRIu64 ").",
2726
0
     function,
2727
0
     object_identifier_0x0305,
2728
0
     logical_volume_descriptor->object_identifier_0x0305 );
2729
2730
0
    goto on_error;
2731
0
  }
2732
0
  if( ( object_identifier_0x0505 != 0 )
2733
0
   && ( logical_volume_descriptor->object_identifier_0x0505 != 0 )
2734
0
   && ( logical_volume_descriptor->object_identifier_0x0505 != object_identifier_0x0505 ) )
2735
0
  {
2736
0
    libcerror_error_set(
2737
0
     error,
2738
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2739
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
2740
0
     "%s: mismatch in object identifier 0x0505 (stored: %" PRIu64 ", expected: %" PRIu64 ").",
2741
0
     function,
2742
0
     object_identifier_0x0505,
2743
0
     logical_volume_descriptor->object_identifier_0x0505 );
2744
2745
0
    goto on_error;
2746
0
  }
2747
0
  if( logical_volume_descriptor->name != NULL )
2748
0
  {
2749
0
    memory_free(
2750
0
     logical_volume_descriptor->name );
2751
2752
0
    logical_volume_descriptor->name      = NULL;
2753
0
    logical_volume_descriptor->name_size = 0;
2754
0
  }
2755
0
  if( compressed_data_size != uncompressed_data_size )
2756
0
  {
2757
0
    libcerror_error_set(
2758
0
     error,
2759
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2760
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
2761
0
     "%s: unsupported compressed XML plist.",
2762
0
     function );
2763
2764
0
    goto on_error;
2765
0
  }
2766
0
  xml_plist_data = &( block_data[ xml_plist_data_offset - 64 ] );
2767
2768
/* TODO handle compressed XML plist data */
2769
0
  if( ( xml_plist_data[ 0 ] == (uint8_t) '<' )
2770
0
   && ( xml_plist_data[ 1 ] == (uint8_t) 'd' )
2771
0
   && ( xml_plist_data[ 2 ] == (uint8_t) 'i' )
2772
0
   && ( xml_plist_data[ 3 ] == (uint8_t) 'c' )
2773
0
   && ( xml_plist_data[ 4 ] == (uint8_t) 't' ) )
2774
0
  {
2775
#if defined( HAVE_DEBUG_OUTPUT )
2776
    if( libcnotify_verbose != 0 )
2777
    {
2778
      libcnotify_printf(
2779
       "%s: XML:\n%s\n",
2780
       function,
2781
       (char *) xml_plist_data );
2782
2783
      libcnotify_printf(
2784
       "\n" );
2785
    }
2786
#endif
2787
/* TODO for now determine the XML string length */
2788
/* TODO refactor this to a separate function */
2789
0
    xml_length = narrow_string_length(
2790
0
            (char *) xml_plist_data );
2791
2792
0
    if( xml_length > (size_t) ( INT_MAX - 1 ) )
2793
0
    {
2794
0
      libcerror_error_set(
2795
0
       error,
2796
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2797
0
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
2798
0
       "%s: invalid XML length value out of bounds.",
2799
0
       function );
2800
2801
0
      goto on_error;
2802
0
    }
2803
0
    if( libfplist_property_list_initialize(
2804
0
         &property_list,
2805
0
         error ) != 1 )
2806
0
    {
2807
0
      libcerror_error_set(
2808
0
       error,
2809
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2810
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
2811
0
       "%s: unable to create property list.",
2812
0
       function );
2813
2814
0
      goto on_error;
2815
0
    }
2816
0
    if( libfplist_property_list_copy_from_byte_stream(
2817
0
         property_list,
2818
0
         xml_plist_data,
2819
0
         xml_length + 1,
2820
0
         error ) != 1 )
2821
0
    {
2822
0
      libcerror_error_set(
2823
0
       error,
2824
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2825
0
       LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
2826
0
       "%s: unable to copy property list from byte stream.",
2827
0
       function );
2828
2829
0
      goto on_error;
2830
0
    }
2831
0
    if( libfplist_property_list_get_root_property(
2832
0
         property_list,
2833
0
         &root_property,
2834
0
         error ) != 1 )
2835
0
    {
2836
0
      libcerror_error_set(
2837
0
       error,
2838
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2839
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2840
0
       "%s: unable to retrieve root property.",
2841
0
       function );
2842
2843
0
      goto on_error;
2844
0
    }
2845
0
    if( libfplist_property_get_sub_property_by_utf8_name(
2846
0
         root_property,
2847
0
         (uint8_t *) "com.apple.corestorage.lv.familyUUID",
2848
0
         35,
2849
0
         &sub_property,
2850
0
         error ) != 1 )
2851
0
    {
2852
0
      libcerror_error_set(
2853
0
       error,
2854
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2855
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2856
0
       "%s: unable to retrieve com.apple.corestorage.lv.familyUUID sub property.",
2857
0
       function );
2858
2859
0
      goto on_error;
2860
0
    }
2861
#if defined( HAVE_DEBUG_OUTPUT )
2862
    if( libcnotify_verbose != 0 )
2863
    {
2864
      if( libfplist_property_get_value_string(
2865
           sub_property,
2866
           &string,
2867
           &string_size,
2868
           error ) != 1 )
2869
      {
2870
        libcerror_error_set(
2871
         error,
2872
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
2873
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2874
         "%s: unable to retrieve logical volume family identifier.",
2875
         function );
2876
2877
        goto on_error;
2878
      }
2879
      libcnotify_printf(
2880
       "%s: logical volume family identifier\t: %s\n",
2881
       function,
2882
       string );
2883
2884
      memory_free(
2885
       string );
2886
2887
      string = NULL;
2888
    }
2889
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
2890
2891
0
    if( libfplist_property_value_uuid_string_copy_to_byte_stream(
2892
0
         sub_property,
2893
0
         logical_volume_descriptor->family_identifier,
2894
0
         16,
2895
0
         error ) != 1 )
2896
0
    {
2897
0
      libcerror_error_set(
2898
0
       error,
2899
0
       LIBCERROR_ERROR_DOMAIN_CONVERSION,
2900
0
       LIBCERROR_CONVERSION_ERROR_INPUT_FAILED,
2901
0
       "%s: unable to copy LVF UUID string to byte stream.",
2902
0
       function );
2903
2904
0
      goto on_error;
2905
0
    }
2906
0
    if( libfplist_property_free(
2907
0
         &sub_property,
2908
0
         error ) != 1 )
2909
0
    {
2910
0
      libcerror_error_set(
2911
0
       error,
2912
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2913
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
2914
0
       "%s: unable to free com.apple.corestorage.lv.familyUUID property.",
2915
0
       function );
2916
2917
0
      goto on_error;
2918
0
    }
2919
0
    if( libfplist_property_get_sub_property_by_utf8_name(
2920
0
         root_property,
2921
0
         (uint8_t *) "com.apple.corestorage.lv.name",
2922
0
         29,
2923
0
         &sub_property,
2924
0
         error ) != 1 )
2925
0
    {
2926
0
      libcerror_error_set(
2927
0
       error,
2928
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2929
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2930
0
       "%s: unable to retrieve com.apple.corestorage.lv.name sub property.",
2931
0
       function );
2932
2933
0
      goto on_error;
2934
0
    }
2935
0
    if( libfplist_property_get_value_string(
2936
0
         sub_property,
2937
0
         &( logical_volume_descriptor->name ),
2938
0
         &( logical_volume_descriptor->name_size ),
2939
0
         error ) != 1 )
2940
0
    {
2941
0
      libcerror_error_set(
2942
0
       error,
2943
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2944
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2945
0
       "%s: unable to retrieve logical volume name.",
2946
0
       function );
2947
2948
0
      goto on_error;
2949
0
    }
2950
#if defined( HAVE_DEBUG_OUTPUT )
2951
    if( libcnotify_verbose != 0 )
2952
    {
2953
      libcnotify_printf(
2954
       "%s: logical volume name\t\t: %s\n",
2955
       function,
2956
       logical_volume_descriptor->name );
2957
    }
2958
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
2959
2960
0
    if( libfplist_property_free(
2961
0
         &sub_property,
2962
0
         error ) != 1 )
2963
0
    {
2964
0
      libcerror_error_set(
2965
0
       error,
2966
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2967
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
2968
0
       "%s: unable to free com.apple.corestorage.lv.name property.",
2969
0
       function );
2970
2971
0
      goto on_error;
2972
0
    }
2973
0
    if( libfplist_property_get_sub_property_by_utf8_name(
2974
0
         root_property,
2975
0
         (uint8_t *) "com.apple.corestorage.lv.size",
2976
0
         29,
2977
0
         &sub_property,
2978
0
         error ) != 1 )
2979
0
    {
2980
0
      libcerror_error_set(
2981
0
       error,
2982
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2983
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2984
0
       "%s: unable to retrieve com.apple.corestorage.lv.size sub property.",
2985
0
       function );
2986
2987
0
      goto on_error;
2988
0
    }
2989
0
    if( libfplist_property_get_value_integer(
2990
0
         sub_property,
2991
0
         (uint64_t *) &logical_volume_size,
2992
0
         error ) != 1 )
2993
0
    {
2994
0
      libcerror_error_set(
2995
0
       error,
2996
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2997
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2998
0
       "%s: unable to retrieve logical volume size.",
2999
0
       function );
3000
3001
0
      goto on_error;
3002
0
    }
3003
#if defined( HAVE_DEBUG_OUTPUT )
3004
    if( libcnotify_verbose != 0 )
3005
    {
3006
      libcnotify_printf(
3007
       "%s: logical volume size\t\t: %" PRIu64 "\n",
3008
       function,
3009
       logical_volume_size );
3010
    }
3011
#endif
3012
0
    logical_volume_descriptor->size = (size64_t) logical_volume_size;
3013
3014
0
    if( libfplist_property_free(
3015
0
         &sub_property,
3016
0
         error ) != 1 )
3017
0
    {
3018
0
      libcerror_error_set(
3019
0
       error,
3020
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3021
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
3022
0
       "%s: unable to free com.apple.corestorage.lv.size property.",
3023
0
       function );
3024
3025
0
      goto on_error;
3026
0
    }
3027
0
    if( libfplist_property_get_sub_property_by_utf8_name(
3028
0
         root_property,
3029
0
         (uint8_t *) "com.apple.corestorage.lv.uuid",
3030
0
         29,
3031
0
         &sub_property,
3032
0
         error ) != 1 )
3033
0
    {
3034
0
      libcerror_error_set(
3035
0
       error,
3036
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3037
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3038
0
       "%s: unable to retrieve com.apple.corestorage.lv.uuid sub property.",
3039
0
       function );
3040
3041
0
      goto on_error;
3042
0
    }
3043
#if defined( HAVE_DEBUG_OUTPUT )
3044
    if( libcnotify_verbose != 0 )
3045
    {
3046
      if( libfplist_property_get_value_string(
3047
           sub_property,
3048
           &string,
3049
           &string_size,
3050
           error ) != 1 )
3051
      {
3052
        libcerror_error_set(
3053
         error,
3054
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
3055
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
3056
         "%s: unable to retrieve logical volume identifier.",
3057
         function );
3058
3059
        goto on_error;
3060
      }
3061
      libcnotify_printf(
3062
       "%s: logical volume identifier\t\t: %s\n",
3063
       function,
3064
       string );
3065
3066
      memory_free(
3067
       string );
3068
3069
      string = NULL;
3070
    }
3071
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
3072
3073
0
    if( libfplist_property_value_uuid_string_copy_to_byte_stream(
3074
0
         sub_property,
3075
0
         logical_volume_descriptor->identifier,
3076
0
         16,
3077
0
         error ) != 1 )
3078
0
    {
3079
0
      libcerror_error_set(
3080
0
       error,
3081
0
       LIBCERROR_ERROR_DOMAIN_CONVERSION,
3082
0
       LIBCERROR_CONVERSION_ERROR_INPUT_FAILED,
3083
0
       "%s: unable to copy LV UUID string to byte stream.",
3084
0
       function );
3085
3086
0
      goto on_error;
3087
0
    }
3088
0
    if( libfplist_property_free(
3089
0
         &sub_property,
3090
0
         error ) != 1 )
3091
0
    {
3092
0
      libcerror_error_set(
3093
0
       error,
3094
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3095
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
3096
0
       "%s: unable to free com.apple.corestorage.lv.uuid property.",
3097
0
       function );
3098
3099
0
      goto on_error;
3100
0
    }
3101
0
    if( libfplist_property_free(
3102
0
         &root_property,
3103
0
         error ) != 1 )
3104
0
    {
3105
0
      libcerror_error_set(
3106
0
       error,
3107
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3108
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
3109
0
       "%s: unable to free root property.",
3110
0
       function );
3111
3112
0
      goto on_error;
3113
0
    }
3114
0
    if( libfplist_property_list_free(
3115
0
         &property_list,
3116
0
         error ) != 1 )
3117
0
    {
3118
0
      libcerror_error_set(
3119
0
       error,
3120
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3121
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
3122
0
       "%s: unable to free property list.",
3123
0
       function );
3124
3125
0
      goto on_error;
3126
0
    }
3127
0
  }
3128
#if defined( HAVE_DEBUG_OUTPUT )
3129
  if( libcnotify_verbose != 0 )
3130
  {
3131
    libcnotify_printf(
3132
     "\n" );
3133
  }
3134
#endif
3135
0
  return( 1 );
3136
3137
0
on_error:
3138
#if defined( HAVE_DEBUG_OUTPUT )
3139
  if( string != NULL )
3140
  {
3141
    memory_free(
3142
     string );
3143
  }
3144
#endif
3145
0
  if( sub_property != NULL )
3146
0
  {
3147
0
    libfplist_property_free(
3148
0
     &sub_property,
3149
0
     NULL );
3150
0
  }
3151
0
  if( root_property != NULL )
3152
0
  {
3153
0
    libfplist_property_free(
3154
0
     &root_property,
3155
0
     NULL );
3156
0
  }
3157
0
  if( property_list != NULL )
3158
0
  {
3159
0
    libfplist_property_list_free(
3160
0
     &property_list,
3161
0
     NULL );
3162
0
  }
3163
0
  return( -1 );
3164
0
}
3165
3166
/* Reads the encrypted metadata block type 0x001c
3167
 * Returns 1 if successful or -1 on error
3168
 */
3169
int libfvde_encrypted_metadata_read_type_0x001c(
3170
     libfvde_encrypted_metadata_t *encrypted_metadata,
3171
     const uint8_t *block_data,
3172
     size_t block_data_size,
3173
     libcerror_error_t **error )
3174
0
{
3175
0
  static char *function      = "libfvde_encrypted_metadata_read_type_0x001c";
3176
0
  size_t block_data_offset   = 0;
3177
0
  uint64_t entry_index       = 0;
3178
0
  uint64_t number_of_entries = 0;
3179
3180
#if defined( HAVE_DEBUG_OUTPUT )
3181
  uint64_t value_64bit       = 0;
3182
  uint32_t value_32bit       = 0;
3183
#endif
3184
3185
0
  if( encrypted_metadata == NULL )
3186
0
  {
3187
0
    libcerror_error_set(
3188
0
     error,
3189
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3190
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3191
0
     "%s: invalid encrypted metadata.",
3192
0
     function );
3193
3194
0
    return( -1 );
3195
0
  }
3196
0
  if( block_data == NULL )
3197
0
  {
3198
0
    libcerror_error_set(
3199
0
     error,
3200
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3201
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3202
0
     "%s: invalid block data.",
3203
0
     function );
3204
3205
0
    return( -1 );
3206
0
  }
3207
0
  if( ( block_data_size < 16 )
3208
0
   || ( block_data_size > (size_t) SSIZE_MAX ) )
3209
0
  {
3210
0
    libcerror_error_set(
3211
0
     error,
3212
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3213
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
3214
0
     "%s: invalid block data size value out of bounds.",
3215
0
     function );
3216
3217
0
    return( -1 );
3218
0
  }
3219
0
  byte_stream_copy_to_uint64_little_endian(
3220
0
   &( block_data[ 8 ] ),
3221
0
   number_of_entries );
3222
3223
#if defined( HAVE_DEBUG_OUTPUT )
3224
  if( libcnotify_verbose != 0 )
3225
  {
3226
    byte_stream_copy_to_uint64_little_endian(
3227
     &( block_data[ 0 ] ),
3228
     value_64bit );
3229
    libcnotify_printf(
3230
     "%s: unknown1\t\t\t\t: 0x%08" PRIx64 "\n",
3231
     function,
3232
     value_64bit );
3233
3234
    libcnotify_printf(
3235
     "%s: number of entries\t\t\t: %" PRIu64 "\n",
3236
     function,
3237
     number_of_entries );
3238
3239
    libcnotify_printf(
3240
     "\n" );
3241
  }
3242
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
3243
3244
0
  block_data_offset = 16;
3245
3246
0
  if( number_of_entries > ( ( block_data_size - block_data_offset ) / 32 ) )
3247
0
  {
3248
0
    libcerror_error_set(
3249
0
     error,
3250
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3251
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
3252
0
     "%s: invalid number of entries value out of bounds.",
3253
0
     function );
3254
3255
0
    return( -1 );
3256
0
  }
3257
0
  for( entry_index = 0;
3258
0
       entry_index < number_of_entries;
3259
0
       entry_index++ )
3260
0
  {
3261
#if defined( HAVE_DEBUG_OUTPUT )
3262
    if( libcnotify_verbose != 0 )
3263
    {
3264
      byte_stream_copy_to_uint32_little_endian(
3265
       &( block_data[ block_data_offset ] ),
3266
       value_32bit );
3267
      libcnotify_printf(
3268
       "%s: entry: %02d unknown1\t\t\t: 0x%08" PRIx32 "\n",
3269
       function,
3270
       entry_index,
3271
       value_32bit );
3272
3273
      byte_stream_copy_to_uint32_little_endian(
3274
       &( block_data[ block_data_offset + 4 ] ),
3275
       value_32bit );
3276
      libcnotify_printf(
3277
       "%s: entry: %02d unknown2\t\t\t: %" PRIu32 "\n",
3278
       function,
3279
       entry_index,
3280
       value_32bit );
3281
3282
      byte_stream_copy_to_uint64_little_endian(
3283
       &( block_data[ block_data_offset + 8 ] ),
3284
       value_64bit );
3285
      libcnotify_printf(
3286
       "%s: entry: %02d block number\t\t: %" PRIu64 "\n",
3287
       function,
3288
       entry_index,
3289
       value_64bit );
3290
3291
      byte_stream_copy_to_uint64_little_endian(
3292
       &( block_data[ block_data_offset + 16 ] ),
3293
       value_64bit );
3294
      libcnotify_printf(
3295
       "%s: entry: %02d 0x0022 object identifier\t: %" PRIu64 "\n",
3296
       function,
3297
       entry_index,
3298
       value_64bit );
3299
3300
      byte_stream_copy_to_uint64_little_endian(
3301
       &( block_data[ block_data_offset + 24 ] ),
3302
       value_64bit );
3303
      libcnotify_printf(
3304
       "%s: entry: %02d 0x0405 object identifier\t: %" PRIu64 "\n",
3305
       function,
3306
       entry_index,
3307
       value_64bit );
3308
3309
      libcnotify_printf(
3310
       "\n" );
3311
    }
3312
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
3313
3314
0
    block_data_offset += 32;
3315
0
  }
3316
0
  return( 1 );
3317
0
}
3318
3319
/* Reads the encrypted metadata block type 0x001d
3320
 * Returns 1 if successful or -1 on error
3321
 */
3322
int libfvde_encrypted_metadata_read_type_0x001d(
3323
     libfvde_encrypted_metadata_t *encrypted_metadata,
3324
     const uint8_t *block_data,
3325
     size_t block_data_size,
3326
     libcerror_error_t **error )
3327
0
{
3328
0
  static char *function      = "libfvde_encrypted_metadata_read_type_0x001d";
3329
0
  size_t block_data_offset   = 0;
3330
0
  uint64_t entry_index       = 0;
3331
0
  uint64_t number_of_entries = 0;
3332
3333
#if defined( HAVE_DEBUG_OUTPUT )
3334
  uint64_t value_64bit       = 0;
3335
  uint32_t value_32bit       = 0;
3336
#endif
3337
3338
0
  if( encrypted_metadata == NULL )
3339
0
  {
3340
0
    libcerror_error_set(
3341
0
     error,
3342
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3343
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3344
0
     "%s: invalid encrypted metadata.",
3345
0
     function );
3346
3347
0
    return( -1 );
3348
0
  }
3349
0
  if( block_data == NULL )
3350
0
  {
3351
0
    libcerror_error_set(
3352
0
     error,
3353
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3354
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3355
0
     "%s: invalid block data.",
3356
0
     function );
3357
3358
0
    return( -1 );
3359
0
  }
3360
0
  if( ( block_data_size < 24 )
3361
0
   || ( block_data_size > (size_t) SSIZE_MAX ) )
3362
0
  {
3363
0
    libcerror_error_set(
3364
0
     error,
3365
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3366
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
3367
0
     "%s: invalid block data size value out of bounds.",
3368
0
     function );
3369
3370
0
    return( -1 );
3371
0
  }
3372
0
  byte_stream_copy_to_uint64_little_endian(
3373
0
   &( block_data[ 16 ] ),
3374
0
   number_of_entries );
3375
3376
#if defined( HAVE_DEBUG_OUTPUT )
3377
  if( libcnotify_verbose != 0 )
3378
  {
3379
    libcnotify_printf(
3380
     "%s: unknown1:\n",
3381
     function );
3382
    libcnotify_print_data(
3383
     block_data,
3384
     16,
3385
     0 );
3386
3387
    libcnotify_printf(
3388
     "%s: number of entries\t\t\t: %" PRIu64 "\n",
3389
     function,
3390
     number_of_entries );
3391
3392
    libcnotify_printf(
3393
     "\n" );
3394
  }
3395
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
3396
3397
0
  block_data_offset = 24;
3398
3399
0
  if( number_of_entries > ( ( block_data_size - block_data_offset ) / 16 ) )
3400
0
  {
3401
0
    libcerror_error_set(
3402
0
     error,
3403
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3404
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
3405
0
     "%s: invalid number of entries value out of bounds.",
3406
0
     function );
3407
3408
0
    return( -1 );
3409
0
  }
3410
0
  for( entry_index = 0;
3411
0
       entry_index < number_of_entries;
3412
0
       entry_index++ )
3413
0
  {
3414
#if defined( HAVE_DEBUG_OUTPUT )
3415
    if( libcnotify_verbose != 0 )
3416
    {
3417
      byte_stream_copy_to_uint32_little_endian(
3418
       &( block_data[ block_data_offset ] ),
3419
       value_32bit );
3420
      libcnotify_printf(
3421
       "%s: entry: %03d number of blocks\t: %" PRIu32 "\n",
3422
       function,
3423
       entry_index,
3424
       value_32bit );
3425
3426
      byte_stream_copy_to_uint32_little_endian(
3427
       &( block_data[ block_data_offset + 4 ] ),
3428
       value_32bit );
3429
      libcnotify_printf(
3430
       "%s: entry: %03d unknown1\t\t: 0x%08" PRIx32 "\n",
3431
       function,
3432
       entry_index,
3433
       value_32bit );
3434
3435
      byte_stream_copy_to_uint64_little_endian(
3436
       &( block_data[ block_data_offset + 8 ] ),
3437
       value_64bit );
3438
3439
      libcnotify_printf(
3440
       "%s: entry: %03d physical block number\t: %" PRIu64 "\n",
3441
       function,
3442
       entry_index,
3443
       value_64bit & 0x0000ffffffffffffUL );
3444
3445
      libcnotify_printf(
3446
       "%s: entry: %03d physical volume index\t: %" PRIu64 "\n",
3447
       function,
3448
       entry_index,
3449
       value_64bit >> 48 );
3450
3451
      libcnotify_printf(
3452
       "\n" );
3453
    }
3454
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
3455
3456
0
    block_data_offset += 16;
3457
0
  }
3458
0
  return( 1 );
3459
0
}
3460
3461
/* Reads the encrypted metadata block type 0x0021
3462
 * Returns 1 if successful or -1 on error
3463
 */
3464
int libfvde_encrypted_metadata_read_type_0x0021(
3465
     libfvde_encrypted_metadata_t *encrypted_metadata,
3466
     const uint8_t *block_data,
3467
     size_t block_data_size,
3468
     libcerror_error_t **error )
3469
0
{
3470
0
  static char *function      = "libfvde_encrypted_metadata_read_type_0x0021";
3471
0
  uint32_t number_of_blocks  = 0;
3472
0
  uint16_t number_of_entries = 0;
3473
3474
0
  if( encrypted_metadata == NULL )
3475
0
  {
3476
0
    libcerror_error_set(
3477
0
     error,
3478
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3479
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3480
0
     "%s: invalid encrypted metadata.",
3481
0
     function );
3482
3483
0
    return( -1 );
3484
0
  }
3485
0
  if( block_data == NULL )
3486
0
  {
3487
0
    libcerror_error_set(
3488
0
     error,
3489
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3490
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3491
0
     "%s: invalid block data.",
3492
0
     function );
3493
3494
0
    return( -1 );
3495
0
  }
3496
0
  if( ( block_data_size < 6 )
3497
0
   || ( block_data_size > (size_t) SSIZE_MAX ) )
3498
0
  {
3499
0
    libcerror_error_set(
3500
0
     error,
3501
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3502
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
3503
0
     "%s: invalid block data size value out of bounds.",
3504
0
     function );
3505
3506
0
    return( -1 );
3507
0
  }
3508
0
  byte_stream_copy_to_uint16_little_endian(
3509
0
   &( block_data[ 0 ] ),
3510
0
   number_of_entries );
3511
3512
0
  byte_stream_copy_to_uint32_little_endian(
3513
0
   &( block_data[ 2 ] ),
3514
0
   number_of_blocks );
3515
3516
#if defined( HAVE_DEBUG_OUTPUT )
3517
  if( libcnotify_verbose != 0 )
3518
  {
3519
    libcnotify_printf(
3520
     "%s: number of entries\t\t\t: %" PRIu16 "\n",
3521
     function,
3522
     number_of_entries );
3523
3524
    libcnotify_printf(
3525
     "%s: logical volume number of blocks\t: %" PRIu32 "\n",
3526
     function,
3527
     number_of_blocks );
3528
3529
    libcnotify_printf(
3530
     "\n" );
3531
  }
3532
#endif
3533
/* TODO: determine size of entry
3534
  if( number_of_entries > ( ( block_data_size - block_data_offset ) / 16 ) )
3535
  {
3536
    libcerror_error_set(
3537
     error,
3538
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3539
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
3540
     "%s: invalid number of entries value out of bounds.",
3541
     function );
3542
3543
    return( -1 );
3544
  }
3545
*/
3546
0
  return( 1 );
3547
0
}
3548
3549
/* Reads the encrypted metadata block type 0x0022
3550
 * Returns 1 if successful or -1 on error
3551
 */
3552
int libfvde_encrypted_metadata_read_type_0x0022(
3553
     libfvde_encrypted_metadata_t *encrypted_metadata,
3554
     const uint8_t *block_data,
3555
     size_t block_data_size,
3556
     libcerror_error_t **error )
3557
0
{
3558
0
  static char *function      = "libfvde_encrypted_metadata_read_type_0x0022";
3559
0
  size_t block_data_offset   = 0;
3560
0
  uint64_t entry_index       = 0;
3561
0
  uint64_t number_of_entries = 0;
3562
3563
#if defined( HAVE_DEBUG_OUTPUT )
3564
  uint64_t value_64bit       = 0;
3565
#endif
3566
3567
0
  if( encrypted_metadata == NULL )
3568
0
  {
3569
0
    libcerror_error_set(
3570
0
     error,
3571
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3572
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3573
0
     "%s: invalid encrypted metadata.",
3574
0
     function );
3575
3576
0
    return( -1 );
3577
0
  }
3578
0
  if( block_data == NULL )
3579
0
  {
3580
0
    libcerror_error_set(
3581
0
     error,
3582
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3583
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3584
0
     "%s: invalid block data.",
3585
0
     function );
3586
3587
0
    return( -1 );
3588
0
  }
3589
0
  if( ( block_data_size < 16 )
3590
0
   || ( block_data_size > (size_t) SSIZE_MAX ) )
3591
0
  {
3592
0
    libcerror_error_set(
3593
0
     error,
3594
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3595
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
3596
0
     "%s: invalid block data size value out of bounds.",
3597
0
     function );
3598
3599
0
    return( -1 );
3600
0
  }
3601
0
  byte_stream_copy_to_uint64_little_endian(
3602
0
   &( block_data[ 8 ] ),
3603
0
   number_of_entries );
3604
3605
#if defined( HAVE_DEBUG_OUTPUT )
3606
  if( libcnotify_verbose != 0 )
3607
  {
3608
    byte_stream_copy_to_uint64_little_endian(
3609
     &( block_data[ 0 ] ),
3610
     value_64bit );
3611
    libcnotify_printf(
3612
     "%s: unknown1\t\t\t\t\t: 0x%08" PRIx64 "\n",
3613
     function,
3614
     value_64bit );
3615
3616
    libcnotify_printf(
3617
     "%s: number of entries\t\t\t\t: %" PRIu64 "\n",
3618
     function,
3619
     number_of_entries );
3620
3621
    libcnotify_printf(
3622
     "\n" );
3623
  }
3624
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
3625
3626
0
  block_data_offset = 16;
3627
3628
0
  if( number_of_entries > ( ( block_data_size - block_data_offset ) / 32 ) )
3629
0
  {
3630
0
    libcerror_error_set(
3631
0
     error,
3632
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3633
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
3634
0
     "%s: invalid number of entries value out of bounds.",
3635
0
     function );
3636
3637
0
    return( -1 );
3638
0
  }
3639
0
  for( entry_index = 0;
3640
0
       entry_index < number_of_entries;
3641
0
       entry_index++ )
3642
0
  {
3643
#if defined( HAVE_DEBUG_OUTPUT )
3644
    if( libcnotify_verbose != 0 )
3645
    {
3646
      byte_stream_copy_to_uint64_little_endian(
3647
       &( block_data[ block_data_offset ] ),
3648
       value_64bit );
3649
      libcnotify_printf(
3650
       "%s: entry: %03d number of blocks\t\t: %" PRIu64 "\n",
3651
       function,
3652
       entry_index,
3653
       value_64bit );
3654
3655
      byte_stream_copy_to_uint64_little_endian(
3656
       &( block_data[ block_data_offset + 8 ] ),
3657
       value_64bit );
3658
      libcnotify_printf(
3659
       "%s: entry: %03d unknown2\t\t\t: 0x%08" PRIx64 "\n",
3660
       function,
3661
       entry_index,
3662
       value_64bit );
3663
3664
      byte_stream_copy_to_uint64_little_endian(
3665
       &( block_data[ block_data_offset + 16 ] ),
3666
       value_64bit );
3667
      libcnotify_printf(
3668
       "%s: entry: %03d 0x001d object identifier\t: %" PRIu64 "\n",
3669
       function,
3670
       entry_index,
3671
       value_64bit );
3672
3673
      byte_stream_copy_to_uint64_little_endian(
3674
       &( block_data[ block_data_offset + 24 ] ),
3675
       value_64bit );
3676
      libcnotify_printf(
3677
       "%s: entry: %03d 0x001d object identifier\t: %" PRIu64 "\n",
3678
       function,
3679
       entry_index,
3680
       value_64bit );
3681
3682
      libcnotify_printf(
3683
       "\n" );
3684
    }
3685
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
3686
3687
0
    block_data_offset += 32;
3688
0
  }
3689
0
  return( 1 );
3690
0
}
3691
3692
/* Reads the encrypted metadata block type 0x0024
3693
 * Returns 1 if successful or -1 on error
3694
 */
3695
int libfvde_encrypted_metadata_read_type_0x0024(
3696
     libfvde_encrypted_metadata_t *encrypted_metadata,
3697
     uint64_t object_identifier,
3698
     const uint8_t *block_data,
3699
     size_t block_data_size,
3700
     libcerror_error_t **error )
3701
0
{
3702
0
  uint8_t *uncompressed_data      = NULL;
3703
0
  static char *function           = "libfvde_encrypted_metadata_read_type_0x0024";
3704
0
  size_t uncompressed_data_size   = 0;
3705
0
  uint64_t next_object_identifier = 0;
3706
0
  uint32_t xml_plist_data_size    = 0;
3707
3708
#if defined( HAVE_DEBUG_OUTPUT )
3709
  uint32_t value_32bit            = 0;
3710
#endif
3711
3712
0
  if( encrypted_metadata == NULL )
3713
0
  {
3714
0
    libcerror_error_set(
3715
0
     error,
3716
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3717
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3718
0
     "%s: invalid encrypted metadata.",
3719
0
     function );
3720
3721
0
    return( -1 );
3722
0
  }
3723
0
  if( block_data == NULL )
3724
0
  {
3725
0
    libcerror_error_set(
3726
0
     error,
3727
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3728
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3729
0
     "%s: invalid block data.",
3730
0
     function );
3731
3732
0
    return( -1 );
3733
0
  }
3734
0
  if( ( block_data_size < 16 )
3735
0
   || ( block_data_size > (size_t) SSIZE_MAX ) )
3736
0
  {
3737
0
    libcerror_error_set(
3738
0
     error,
3739
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3740
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
3741
0
     "%s: invalid block data size value out of bounds.",
3742
0
     function );
3743
3744
0
    return( -1 );
3745
0
  }
3746
0
  byte_stream_copy_to_uint64_little_endian(
3747
0
   &( block_data[ 0 ] ),
3748
0
   next_object_identifier );
3749
3750
0
  byte_stream_copy_to_uint32_little_endian(
3751
0
   &( block_data[ 8 ] ),
3752
0
   xml_plist_data_size );
3753
3754
#if defined( HAVE_DEBUG_OUTPUT )
3755
  if( libcnotify_verbose != 0 )
3756
  {
3757
    libcnotify_printf(
3758
     "%s: next object identifier\t: %" PRIu64 "\n",
3759
     function,
3760
     next_object_identifier );
3761
3762
    libcnotify_printf(
3763
     "%s: XML plist data size\t: %" PRIu32 "\n",
3764
     function,
3765
     xml_plist_data_size );
3766
3767
    byte_stream_copy_to_uint32_little_endian(
3768
     &( block_data[ 12 ] ),
3769
     value_32bit );
3770
    libcnotify_printf(
3771
     "%s: unknown1\t\t\t: 0x%08" PRIx32 "\n",
3772
     function,
3773
     value_32bit );
3774
3775
    libcnotify_printf(
3776
     "\n" );
3777
  }
3778
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
3779
3780
0
  if( encrypted_metadata->compressed_data != NULL )
3781
0
  {
3782
0
    if( ( object_identifier != 0 )
3783
0
     && ( encrypted_metadata->compressed_data_object_identifier != 0 )
3784
0
     && ( encrypted_metadata->compressed_data_object_identifier != object_identifier ) )
3785
0
    {
3786
0
      libcerror_error_set(
3787
0
       error,
3788
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3789
0
       LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
3790
0
       "%s: mismatch in object identifier (stored: %" PRIu64 ", expected: %" PRIu64 ").",
3791
0
       function,
3792
0
       object_identifier,
3793
0
       encrypted_metadata->compressed_data_object_identifier );
3794
3795
0
      goto on_error;
3796
0
    }
3797
0
    if( xml_plist_data_size > ( encrypted_metadata->compressed_data_size - encrypted_metadata->compressed_data_offset ) )
3798
0
    {
3799
0
      libcerror_error_set(
3800
0
       error,
3801
0
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3802
0
       LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
3803
0
       "%s: invalid XML plist data size value out of bounds.",
3804
0
       function );
3805
3806
0
      goto on_error;
3807
0
    }
3808
0
    if( memory_copy(
3809
0
         &( encrypted_metadata->compressed_data[ encrypted_metadata->compressed_data_offset ] ),
3810
0
         &( block_data[ 16 ] ),
3811
0
         xml_plist_data_size ) == NULL )
3812
0
    {
3813
0
      libcerror_error_set(
3814
0
       error,
3815
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
3816
0
       LIBCERROR_MEMORY_ERROR_COPY_FAILED,
3817
0
       "%s: unable to copy compressed data.",
3818
0
       function );
3819
3820
0
      goto on_error;
3821
0
    }
3822
0
    encrypted_metadata->compressed_data_object_identifier = next_object_identifier;
3823
0
    encrypted_metadata->compressed_data_offset           += (size_t) xml_plist_data_size;
3824
3825
0
    if( next_object_identifier == 0 )
3826
0
    {
3827
0
      uncompressed_data_size = encrypted_metadata->uncompressed_data_size;
3828
3829
0
      if( ( uncompressed_data_size == 0 )
3830
0
       || ( uncompressed_data_size > (uint64_t) MEMORY_MAXIMUM_ALLOCATION_SIZE ) )
3831
0
      {
3832
0
        libcerror_error_set(
3833
0
         error,
3834
0
         LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3835
0
         LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
3836
0
         "%s: invalid uncompressed data size value out of bounds.",
3837
0
         function );
3838
3839
0
        goto on_error;
3840
0
      }
3841
0
      uncompressed_data = (uint8_t *) memory_allocate(
3842
0
                                       sizeof( uint8_t ) * uncompressed_data_size );
3843
3844
0
      if( uncompressed_data == NULL )
3845
0
      {
3846
0
        libcerror_error_set(
3847
0
         error,
3848
0
         LIBCERROR_ERROR_DOMAIN_MEMORY,
3849
0
         LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
3850
0
         "%s: unable to create uncompressed data.",
3851
0
         function );
3852
3853
0
        goto on_error;
3854
0
      }
3855
0
      if( libfvde_decompress_data(
3856
0
           encrypted_metadata->compressed_data,
3857
0
           encrypted_metadata->compressed_data_size,
3858
0
           LIBFVDE_COMPRESSION_METHOD_DEFLATE,
3859
0
           uncompressed_data,
3860
0
           &uncompressed_data_size,
3861
0
           error ) != 1 )
3862
0
      {
3863
0
        libcerror_error_set(
3864
0
         error,
3865
0
         LIBCERROR_ERROR_DOMAIN_ENCRYPTION,
3866
0
         LIBCERROR_ENCRYPTION_ERROR_GENERIC,
3867
0
         "%s: unable to decompress XML plist data.",
3868
0
         function );
3869
3870
0
        goto on_error;
3871
0
      }
3872
0
      if( ( uncompressed_data_size > 5 )
3873
0
       && ( uncompressed_data[ 0 ] == (uint8_t) '<' )
3874
0
       && ( uncompressed_data[ 1 ] == (uint8_t) 'd' )
3875
0
       && ( uncompressed_data[ 2 ] == (uint8_t) 'i' )
3876
0
       && ( uncompressed_data[ 3 ] == (uint8_t) 'c' )
3877
0
       && ( uncompressed_data[ 4 ] == (uint8_t) 't' ) )
3878
0
      {
3879
#if defined( HAVE_DEBUG_OUTPUT )
3880
        if( libcnotify_verbose != 0 )
3881
        {
3882
          libcnotify_printf(
3883
           "%s: XML:\n%s\n",
3884
           function,
3885
           (char *) uncompressed_data );
3886
3887
          libcnotify_printf(
3888
           "\n" );
3889
        }
3890
#endif
3891
0
        if( encrypted_metadata->encryption_context_plist_data != NULL )
3892
0
        {
3893
0
          memory_free(
3894
0
           encrypted_metadata->encryption_context_plist_data );
3895
3896
0
          encrypted_metadata->encryption_context_plist_data = NULL;
3897
0
        }
3898
0
        encrypted_metadata->encryption_context_plist_data      = uncompressed_data;
3899
0
        encrypted_metadata->encryption_context_plist_data_size = uncompressed_data_size;
3900
3901
0
        uncompressed_data = NULL;
3902
0
      }
3903
0
      else
3904
0
      {
3905
0
        memory_free(
3906
0
         uncompressed_data );
3907
3908
0
        uncompressed_data = NULL;
3909
0
      }
3910
0
      memory_free(
3911
0
       encrypted_metadata->compressed_data );
3912
3913
0
      encrypted_metadata->compressed_data = NULL;
3914
0
    }
3915
0
  }
3916
0
  return( 1 );
3917
3918
0
on_error:
3919
0
  if( uncompressed_data != NULL )
3920
0
  {
3921
0
    memory_free(
3922
0
     uncompressed_data );
3923
0
  }
3924
0
  return( -1 );
3925
0
}
3926
3927
/* Reads the encrypted metadata block type 0x0025
3928
 * Returns 1 if successful or -1 on error
3929
 */
3930
int libfvde_encrypted_metadata_read_type_0x0025(
3931
     libfvde_encrypted_metadata_t *encrypted_metadata,
3932
     const uint8_t *block_data,
3933
     size_t block_data_size,
3934
     libcerror_error_t **error )
3935
0
{
3936
0
  static char *function      = "libfvde_encrypted_metadata_read_type_0x0025";
3937
0
  size_t block_data_offset   = 0;
3938
0
  uint64_t entry_index       = 0;
3939
0
  uint64_t number_of_entries = 0;
3940
3941
#if defined( HAVE_DEBUG_OUTPUT )
3942
  uint64_t value_64bit       = 0;
3943
#endif
3944
3945
0
  if( encrypted_metadata == NULL )
3946
0
  {
3947
0
    libcerror_error_set(
3948
0
     error,
3949
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3950
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3951
0
     "%s: invalid encrypted metadata.",
3952
0
     function );
3953
3954
0
    return( -1 );
3955
0
  }
3956
0
  if( block_data == NULL )
3957
0
  {
3958
0
    libcerror_error_set(
3959
0
     error,
3960
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3961
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3962
0
     "%s: invalid block data.",
3963
0
     function );
3964
3965
0
    return( -1 );
3966
0
  }
3967
0
  if( ( block_data_size < 16 )
3968
0
   || ( block_data_size > (size_t) SSIZE_MAX ) )
3969
0
  {
3970
0
    libcerror_error_set(
3971
0
     error,
3972
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3973
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
3974
0
     "%s: invalid block data size value out of bounds.",
3975
0
     function );
3976
3977
0
    return( -1 );
3978
0
  }
3979
0
  byte_stream_copy_to_uint64_little_endian(
3980
0
   &( block_data[ 8 ] ),
3981
0
   number_of_entries );
3982
3983
#if defined( HAVE_DEBUG_OUTPUT )
3984
  if( libcnotify_verbose != 0 )
3985
  {
3986
    byte_stream_copy_to_uint64_little_endian(
3987
     &( block_data[ 0 ] ),
3988
     value_64bit );
3989
    libcnotify_printf(
3990
     "%s: unknown1\t\t\t\t: 0x%08" PRIx64 "\n",
3991
     function,
3992
     value_64bit );
3993
3994
    libcnotify_printf(
3995
     "%s: number of entries\t\t\t: %" PRIu64 "\n",
3996
     function,
3997
     number_of_entries );
3998
3999
    libcnotify_printf(
4000
     "\n" );
4001
  }
4002
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
4003
4004
0
  block_data_offset = 16;
4005
4006
0
  if( number_of_entries > ( ( block_data_size - block_data_offset ) / 24 ) )
4007
0
  {
4008
0
    libcerror_error_set(
4009
0
     error,
4010
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4011
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
4012
0
     "%s: invalid number of entries value out of bounds.",
4013
0
     function );
4014
4015
0
    return( -1 );
4016
0
  }
4017
0
  for( entry_index = 0;
4018
0
       entry_index < number_of_entries;
4019
0
       entry_index++ )
4020
0
  {
4021
#if defined( HAVE_DEBUG_OUTPUT )
4022
    if( libcnotify_verbose != 0 )
4023
    {
4024
      byte_stream_copy_to_uint64_little_endian(
4025
       &( block_data[ block_data_offset ] ),
4026
       value_64bit );
4027
      libcnotify_printf(
4028
       "%s: entry: %03d unknown1\t\t: %" PRIu64 "\n",
4029
       function,
4030
       entry_index,
4031
       value_64bit );
4032
4033
      byte_stream_copy_to_uint64_little_endian(
4034
       &( block_data[ block_data_offset + 8 ] ),
4035
       value_64bit );
4036
      libcnotify_printf(
4037
       "%s: entry: %03d unknown2\t\t: %" PRIu64 "\n",
4038
       function,
4039
       entry_index,
4040
       value_64bit );
4041
4042
      byte_stream_copy_to_uint64_little_endian(
4043
       &( block_data[ block_data_offset + 16 ] ),
4044
       value_64bit );
4045
      libcnotify_printf(
4046
       "%s: entry: %03d unknown3\t\t: %" PRIu64 "\n",
4047
       function,
4048
       entry_index,
4049
       value_64bit );
4050
4051
      libcnotify_printf(
4052
       "\n" );
4053
    }
4054
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
4055
4056
0
    block_data_offset += 24;
4057
0
  }
4058
0
  return( 1 );
4059
0
}
4060
4061
/* Reads the encrypted metadata block type 0x0105
4062
 * Returns 1 if successful or -1 on error
4063
 */
4064
int libfvde_encrypted_metadata_read_type_0x0105(
4065
     libfvde_encrypted_metadata_t *encrypted_metadata,
4066
     const uint8_t *block_data,
4067
     size_t block_data_size,
4068
     libcerror_error_t **error )
4069
0
{
4070
0
  libfvde_logical_volume_descriptor_t *existing_logical_volume_descriptor = NULL;
4071
0
  libfvde_logical_volume_descriptor_t *logical_volume_descriptor          = NULL;
4072
0
  static char *function                                                   = "libfvde_encrypted_metadata_read_type_0x0105";
4073
0
  size_t block_data_offset                                                = 0;
4074
0
  uint64_t object_identifier                                              = 0;
4075
0
  uint32_t entry_index                                                    = 0;
4076
0
  uint32_t number_of_entries                                              = 0;
4077
0
  int logical_volume_descriptor_index                                     = 0;
4078
0
  int number_of_logical_volume_descriptors                                = 0;
4079
4080
#if defined( HAVE_DEBUG_OUTPUT )
4081
  uint64_t value_64bit                                                    = 0;
4082
  uint32_t value_32bit                                                    = 0;
4083
#endif
4084
4085
0
  if( encrypted_metadata == NULL )
4086
0
  {
4087
0
    libcerror_error_set(
4088
0
     error,
4089
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4090
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4091
0
     "%s: invalid encrypted metadata.",
4092
0
     function );
4093
4094
0
    return( -1 );
4095
0
  }
4096
0
  if( block_data == NULL )
4097
0
  {
4098
0
    libcerror_error_set(
4099
0
     error,
4100
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4101
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4102
0
     "%s: invalid block data.",
4103
0
     function );
4104
4105
0
    return( -1 );
4106
0
  }
4107
0
  if( ( block_data_size < 8 )
4108
0
   || ( block_data_size > (size_t) SSIZE_MAX ) )
4109
0
  {
4110
0
    libcerror_error_set(
4111
0
     error,
4112
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4113
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
4114
0
     "%s: invalid block data size value out of bounds.",
4115
0
     function );
4116
4117
0
    return( -1 );
4118
0
  }
4119
0
  byte_stream_copy_to_uint32_little_endian(
4120
0
   &( block_data[ 0 ] ),
4121
0
   number_of_entries );
4122
4123
#if defined( HAVE_DEBUG_OUTPUT )
4124
  if( libcnotify_verbose != 0 )
4125
  {
4126
    libcnotify_printf(
4127
     "%s: number of entries\t\t: %" PRIu32 "\n",
4128
     function,
4129
     number_of_entries );
4130
4131
    byte_stream_copy_to_uint32_little_endian(
4132
     &( block_data[ 4 ] ),
4133
     value_32bit );
4134
    libcnotify_printf(
4135
     "%s: unknown1\t\t\t: 0x%08" PRIx32 "\n",
4136
     function,
4137
     value_32bit );
4138
4139
    libcnotify_printf(
4140
     "\n" );
4141
  }
4142
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
4143
4144
0
  block_data_offset = 8;
4145
4146
0
  if( number_of_entries > ( ( block_data_size - block_data_offset ) / 16 ) )
4147
0
  {
4148
0
    libcerror_error_set(
4149
0
     error,
4150
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4151
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
4152
0
     "%s: invalid number of entries value out of bounds.",
4153
0
     function );
4154
4155
0
    goto on_error;
4156
0
  }
4157
0
  if( libcdata_array_get_number_of_entries(
4158
0
       encrypted_metadata->logical_volume_descriptors,
4159
0
       &number_of_logical_volume_descriptors,
4160
0
       error ) != 1 )
4161
0
  {
4162
0
    libcerror_error_set(
4163
0
     error,
4164
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4165
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4166
0
     "%s: unable to retrieve number of logical volume descriptors.",
4167
0
     function );
4168
4169
0
    return( -1 );
4170
0
  }
4171
0
  for( entry_index = 0;
4172
0
       entry_index < number_of_entries;
4173
0
       entry_index++ )
4174
0
  {
4175
0
    byte_stream_copy_to_uint64_little_endian(
4176
0
     &( block_data[ block_data_offset ] ),
4177
0
     object_identifier );
4178
4179
#if defined( HAVE_DEBUG_OUTPUT )
4180
    if( libcnotify_verbose != 0 )
4181
    {
4182
      libcnotify_printf(
4183
       "%s: entry: %d object identifier\t: %" PRIu64 "\n",
4184
       function,
4185
       entry_index,
4186
       object_identifier );
4187
4188
      byte_stream_copy_to_uint64_little_endian(
4189
       &( block_data[ block_data_offset + 8 ] ),
4190
       value_64bit );
4191
      libcnotify_printf(
4192
       "%s: entry: %d unknown2\t\t: 0x%08" PRIx64 "\n",
4193
       function,
4194
       entry_index,
4195
       value_64bit );
4196
4197
      libcnotify_printf(
4198
       "\n" );
4199
    }
4200
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
4201
4202
0
    block_data_offset += 16;
4203
4204
0
    if( entry_index >= (uint32_t) number_of_logical_volume_descriptors )
4205
0
    {
4206
0
      if( libfvde_logical_volume_descriptor_initialize(
4207
0
           &logical_volume_descriptor,
4208
0
           error ) != 1 )
4209
0
      {
4210
0
        libcerror_error_set(
4211
0
         error,
4212
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
4213
0
         LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
4214
0
         "%s: unable to create logical volume descriptor.",
4215
0
         function );
4216
4217
0
        goto on_error;
4218
0
      }
4219
0
      logical_volume_descriptor->object_identifier = object_identifier;
4220
4221
0
      if( libcdata_array_append_entry(
4222
0
           encrypted_metadata->logical_volume_descriptors,
4223
0
           &logical_volume_descriptor_index,
4224
0
           (intptr_t *) logical_volume_descriptor,
4225
0
           error ) != 1 )
4226
0
      {
4227
0
        libcerror_error_set(
4228
0
         error,
4229
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
4230
0
         LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
4231
0
         "%s: unable to append logical volume descriptor to array.",
4232
0
         function );
4233
4234
0
        goto on_error;
4235
0
      }
4236
0
      logical_volume_descriptor = NULL;
4237
0
    }
4238
0
    else
4239
0
    {
4240
0
      if( libcdata_array_get_entry_by_index(
4241
0
           encrypted_metadata->logical_volume_descriptors,
4242
0
           entry_index,
4243
0
           (intptr_t **) &existing_logical_volume_descriptor,
4244
0
           error ) != 1 )
4245
0
      {
4246
0
        libcerror_error_set(
4247
0
         error,
4248
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
4249
0
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4250
0
         "%s: unable to retrieve logical volume descriptor: %" PRIu64 " from array.",
4251
0
         function,
4252
0
         entry_index );
4253
4254
0
        goto on_error;
4255
0
      }
4256
0
    }
4257
0
  }
4258
0
  return( 1 );
4259
4260
0
on_error:
4261
0
  if( logical_volume_descriptor != NULL )
4262
0
  {
4263
0
    libfvde_logical_volume_descriptor_free(
4264
0
     &logical_volume_descriptor,
4265
0
     NULL );
4266
0
  }
4267
0
  return( -1 );
4268
0
}
4269
4270
/* Reads the encrypted metadata block type 0x0205
4271
 * Returns 1 if successful or -1 on error
4272
 */
4273
int libfvde_encrypted_metadata_read_type_0x0205(
4274
     libfvde_encrypted_metadata_t *encrypted_metadata,
4275
     const uint8_t *block_data,
4276
     size_t block_data_size,
4277
     libcerror_error_t **error )
4278
0
{
4279
0
  static char *function = "libfvde_encrypted_metadata_read_type_0x0205";
4280
4281
0
  if( encrypted_metadata == NULL )
4282
0
  {
4283
0
    libcerror_error_set(
4284
0
     error,
4285
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4286
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4287
0
     "%s: invalid encrypted metadata.",
4288
0
     function );
4289
4290
0
    return( -1 );
4291
0
  }
4292
0
  if( block_data == NULL )
4293
0
  {
4294
0
    libcerror_error_set(
4295
0
     error,
4296
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4297
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4298
0
     "%s: invalid block data.",
4299
0
     function );
4300
4301
0
    return( -1 );
4302
0
  }
4303
0
  if( ( block_data_size < 54 )
4304
0
   || ( block_data_size > (size_t) SSIZE_MAX ) )
4305
0
  {
4306
0
    libcerror_error_set(
4307
0
     error,
4308
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4309
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
4310
0
     "%s: invalid block data size value out of bounds.",
4311
0
     function );
4312
4313
0
    return( -1 );
4314
0
  }
4315
0
  return( 1 );
4316
0
}
4317
4318
/* Reads the encrypted metadata block type 0x0304
4319
 * Returns 1 if successful or -1 on error
4320
 */
4321
int libfvde_encrypted_metadata_read_type_0x0304(
4322
     libfvde_encrypted_metadata_t *encrypted_metadata,
4323
     const uint8_t *block_data,
4324
     size_t block_data_size,
4325
     libcerror_error_t **error )
4326
0
{
4327
0
  libfvde_segment_descriptor_t *segment_descriptor = NULL;
4328
0
  static char *function                            = "libfvde_encrypted_metadata_read_type_0x0304";
4329
0
  size_t block_data_offset                         = 0;
4330
0
  uint32_t block_number                            = 0xffffffffUL;
4331
0
  uint32_t entry_index                             = 0;
4332
0
  uint32_t number_of_blocks                        = 0;
4333
0
  uint32_t number_of_entries                       = 0;
4334
0
  int result                                       = 0;
4335
0
  int segment_descriptor_index                     = 0;
4336
4337
#if defined( HAVE_DEBUG_OUTPUT )
4338
  uint64_t value_64bit                             = 0;
4339
  uint32_t value_32bit                             = 0;
4340
#endif
4341
4342
0
  if( encrypted_metadata == NULL )
4343
0
  {
4344
0
    libcerror_error_set(
4345
0
     error,
4346
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4347
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4348
0
     "%s: invalid encrypted metadata.",
4349
0
     function );
4350
4351
0
    return( -1 );
4352
0
  }
4353
0
  if( block_data == NULL )
4354
0
  {
4355
0
    libcerror_error_set(
4356
0
     error,
4357
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4358
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4359
0
     "%s: invalid block data.",
4360
0
     function );
4361
4362
0
    return( -1 );
4363
0
  }
4364
0
  if( ( block_data_size < 8 )
4365
0
   || ( block_data_size > (size_t) SSIZE_MAX ) )
4366
0
  {
4367
0
    libcerror_error_set(
4368
0
     error,
4369
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4370
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
4371
0
     "%s: invalid block data size value out of bounds.",
4372
0
     function );
4373
4374
0
    return( -1 );
4375
0
  }
4376
0
  if( libcdata_array_empty(
4377
0
       encrypted_metadata->segment_descriptors_0x0304,
4378
0
       (int (*)(intptr_t **, libcerror_error_t **)) &libfvde_segment_descriptor_free,
4379
0
       error ) != 1 )
4380
0
  {
4381
0
    libcerror_error_set(
4382
0
     error,
4383
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4384
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
4385
0
     "%s: unable to empty segment descriptors array.",
4386
0
     function );
4387
4388
0
    goto on_error;
4389
0
  }
4390
0
  byte_stream_copy_to_uint32_little_endian(
4391
0
   &( block_data[ 0 ] ),
4392
0
   number_of_entries );
4393
4394
#if defined( HAVE_DEBUG_OUTPUT )
4395
  if( libcnotify_verbose != 0 )
4396
  {
4397
    libcnotify_printf(
4398
     "%s: number of entries\t\t\t: %" PRIu32 "\n",
4399
     function,
4400
     number_of_entries );
4401
4402
    byte_stream_copy_to_uint32_little_endian(
4403
     &( block_data[ 4 ] ),
4404
     value_32bit );
4405
    libcnotify_printf(
4406
     "%s: unknown1\t\t\t\t: 0x%08" PRIx32 "\n",
4407
     function,
4408
     value_32bit );
4409
4410
    libcnotify_printf(
4411
     "\n" );
4412
  }
4413
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
4414
4415
0
  block_data_offset = 8;
4416
4417
0
  if( number_of_entries > ( ( block_data_size - block_data_offset ) / 40 ) )
4418
0
  {
4419
0
    libcerror_error_set(
4420
0
     error,
4421
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4422
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
4423
0
     "%s: invalid number of entries value out of bounds.",
4424
0
     function );
4425
4426
0
    goto on_error;
4427
0
  }
4428
0
  for( entry_index = 0;
4429
0
       entry_index < number_of_entries;
4430
0
       entry_index++ )
4431
0
  {
4432
0
    if( libfvde_segment_descriptor_initialize(
4433
0
         &segment_descriptor,
4434
0
         error ) == -1 )
4435
0
    {
4436
0
      libcerror_error_set(
4437
0
       error,
4438
0
       LIBCERROR_ERROR_DOMAIN_ENCRYPTION,
4439
0
       LIBCERROR_ENCRYPTION_ERROR_GENERIC,
4440
0
       "%s: unable to create segment descriptor.",
4441
0
       function );
4442
4443
0
      goto on_error;
4444
0
    }
4445
0
    byte_stream_copy_to_uint64_little_endian(
4446
0
     &( block_data[ block_data_offset + 8 ] ),
4447
0
     segment_descriptor->logical_block_number );
4448
4449
0
    byte_stream_copy_to_uint32_little_endian(
4450
0
     &( block_data[ block_data_offset + 16 ] ),
4451
0
     segment_descriptor->number_of_blocks );
4452
4453
0
    byte_stream_copy_to_uint64_little_endian(
4454
0
     &( block_data[ block_data_offset + 32 ] ),
4455
0
     segment_descriptor->physical_block_number );
4456
4457
0
    segment_descriptor->physical_volume_index  = (uint16_t) ( segment_descriptor->physical_block_number >> 48 );
4458
0
    segment_descriptor->physical_block_number &= 0x0000ffffffffffffUL;
4459
4460
#if defined( HAVE_DEBUG_OUTPUT )
4461
    if( libcnotify_verbose != 0 )
4462
    {
4463
      byte_stream_copy_to_uint64_little_endian(
4464
       &( block_data[ block_data_offset ] ),
4465
       value_64bit );
4466
      libcnotify_printf(
4467
       "%s: entry: %03d unknown1\t\t: 0x%08" PRIx64 "\n",
4468
       function,
4469
       entry_index,
4470
       value_64bit );
4471
4472
      libcnotify_printf(
4473
       "%s: entry: %03d logical block number\t: %" PRIi64 "\n",
4474
       function,
4475
       entry_index,
4476
       segment_descriptor->logical_block_number );
4477
4478
      libcnotify_printf(
4479
       "%s: entry: %03d number of blocks\t: %" PRIu32 "\n",
4480
       function,
4481
       entry_index,
4482
       segment_descriptor->number_of_blocks );
4483
4484
      byte_stream_copy_to_uint32_little_endian(
4485
       &( block_data[ block_data_offset + 20 ] ),
4486
       value_32bit );
4487
      libcnotify_printf(
4488
       "%s: entry: %03d unknown3\t\t: 0x%08" PRIx32 "\n",
4489
       function,
4490
       entry_index,
4491
       value_32bit );
4492
4493
      byte_stream_copy_to_uint32_little_endian(
4494
       &( block_data[ block_data_offset + 24 ] ),
4495
       value_32bit );
4496
      libcnotify_printf(
4497
       "%s: entry: %03d unknown4\t\t: 0x%08" PRIx32 "\n",
4498
       function,
4499
       entry_index,
4500
       value_32bit );
4501
4502
      byte_stream_copy_to_uint32_little_endian(
4503
       &( block_data[ block_data_offset + 28 ] ),
4504
       value_32bit );
4505
      libcnotify_printf(
4506
       "%s: entry: %03d unknown5\t\t: 0x%08" PRIx32 "\n",
4507
       function,
4508
       entry_index,
4509
       value_32bit );
4510
4511
      libcnotify_printf(
4512
       "%s: entry: %03d physical block number\t: %" PRIu64 "\n",
4513
       function,
4514
       entry_index,
4515
       segment_descriptor->physical_block_number );
4516
4517
      libcnotify_printf(
4518
       "%s: entry: %03d physical volume index\t: %" PRIu16 "\n",
4519
       function,
4520
       entry_index,
4521
       segment_descriptor->physical_volume_index );
4522
4523
      libcnotify_printf(
4524
       "\n" );
4525
    }
4526
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
4527
4528
0
    block_data_offset += 40;
4529
4530
0
    result = libcdata_array_insert_entry(
4531
0
              encrypted_metadata->segment_descriptors_0x0304,
4532
0
              &segment_descriptor_index,
4533
0
              (intptr_t *) segment_descriptor,
4534
0
              (int (*)(intptr_t *, intptr_t *, libcerror_error_t **)) &libfvde_segment_descriptor_compare,
4535
0
              LIBCDATA_INSERT_FLAG_UNIQUE_ENTRIES,
4536
0
              error );
4537
4538
0
    if( result == -1 )
4539
0
    {
4540
0
      libcerror_error_set(
4541
0
       error,
4542
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4543
0
       LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
4544
0
       "%s: unable to insert segment descriptor: %d in array.",
4545
0
       function,
4546
0
       entry_index );
4547
4548
0
      goto on_error;
4549
0
    }
4550
0
    else if( result == 0 )
4551
0
    {
4552
0
      libcerror_error_set(
4553
0
       error,
4554
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4555
0
       LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
4556
0
       "%s: unsupported overlapping segment descriptor: %d.",
4557
0
       function,
4558
0
       entry_index );
4559
4560
0
      goto on_error;
4561
0
    }
4562
0
    if( block_number > segment_descriptor->physical_block_number )
4563
0
    {
4564
0
      block_number = segment_descriptor->physical_block_number;
4565
0
    }
4566
0
    number_of_blocks  += segment_descriptor->number_of_blocks;
4567
0
    segment_descriptor = NULL;
4568
0
  }
4569
0
  return( 1 );
4570
4571
0
on_error:
4572
0
  if( segment_descriptor != NULL )
4573
0
  {
4574
0
    libfvde_segment_descriptor_free(
4575
0
     &segment_descriptor,
4576
0
     NULL );
4577
0
  }
4578
0
  return( -1 );
4579
0
}
4580
4581
/* Reads the encrypted metadata block type 0x0305
4582
 * Returns 1 if successful or -1 on error
4583
 */
4584
int libfvde_encrypted_metadata_read_type_0x0305(
4585
     libfvde_encrypted_metadata_t *encrypted_metadata,
4586
     uint64_t object_identifier,
4587
     const uint8_t *block_data,
4588
     size_t block_data_size,
4589
     libcerror_error_t **error )
4590
0
{
4591
0
  libfvde_logical_volume_descriptor_t *logical_volume_descriptor = NULL;
4592
0
  libfvde_segment_descriptor_t *segment_descriptor               = NULL;
4593
0
  static char *function                                          = "libfvde_encrypted_metadata_read_type_0x0305";
4594
0
  size_t block_data_offset                                       = 0;
4595
0
  uint32_t block_number                                          = 0xffffffffUL;
4596
0
  uint32_t entry_index                                           = 0;
4597
0
  uint32_t number_of_blocks                                      = 0;
4598
0
  uint32_t number_of_entries                                     = 0;
4599
0
  int result                                                     = 0;
4600
0
  int segment_descriptor_index                                   = 0;
4601
4602
#if defined( HAVE_DEBUG_OUTPUT )
4603
  uint64_t value_64bit                                           = 0;
4604
  uint32_t value_32bit                                           = 0;
4605
#endif
4606
4607
0
  if( encrypted_metadata == NULL )
4608
0
  {
4609
0
    libcerror_error_set(
4610
0
     error,
4611
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4612
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4613
0
     "%s: invalid encrypted metadata.",
4614
0
     function );
4615
4616
0
    return( -1 );
4617
0
  }
4618
0
  if( block_data == NULL )
4619
0
  {
4620
0
    libcerror_error_set(
4621
0
     error,
4622
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4623
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4624
0
     "%s: invalid block data.",
4625
0
     function );
4626
4627
0
    return( -1 );
4628
0
  }
4629
0
  if( ( block_data_size < 8 )
4630
0
   || ( block_data_size > (size_t) SSIZE_MAX ) )
4631
0
  {
4632
0
    libcerror_error_set(
4633
0
     error,
4634
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4635
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
4636
0
     "%s: invalid block data size value out of bounds.",
4637
0
     function );
4638
4639
0
    return( -1 );
4640
0
  }
4641
0
  if( libfvde_encrypted_metadata_get_last_logical_volume_descriptor(
4642
0
       encrypted_metadata,
4643
0
       &logical_volume_descriptor,
4644
0
       error ) != 1 )
4645
0
  {
4646
0
    libcerror_error_set(
4647
0
     error,
4648
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4649
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
4650
0
     "%s: unable to retrieve last logical volume descriptor.",
4651
0
     function );
4652
4653
0
    goto on_error;
4654
0
  }
4655
0
  if( logical_volume_descriptor == NULL )
4656
0
  {
4657
0
    libcerror_error_set(
4658
0
     error,
4659
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4660
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
4661
0
     "%s: missing logical volume descriptor.",
4662
0
     function );
4663
4664
0
    goto on_error;
4665
0
  }
4666
0
  if( libcdata_array_empty(
4667
0
       logical_volume_descriptor->segment_descriptors,
4668
0
       (int (*)(intptr_t **, libcerror_error_t **)) &libfvde_segment_descriptor_free,
4669
0
       error ) != 1 )
4670
0
  {
4671
0
    libcerror_error_set(
4672
0
     error,
4673
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4674
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
4675
0
     "%s: unable to empty segment descriptors array.",
4676
0
     function );
4677
4678
0
    goto on_error;
4679
0
  }
4680
0
  byte_stream_copy_to_uint32_little_endian(
4681
0
   &( block_data[ 0 ] ),
4682
0
   number_of_entries );
4683
4684
#if defined( HAVE_DEBUG_OUTPUT )
4685
  if( libcnotify_verbose != 0 )
4686
  {
4687
    libcnotify_printf(
4688
     "%s: number of entries\t\t\t: %" PRIu32 "\n",
4689
     function,
4690
     number_of_entries );
4691
4692
    byte_stream_copy_to_uint32_little_endian(
4693
     &( block_data[ 4 ] ),
4694
     value_32bit );
4695
    libcnotify_printf(
4696
     "%s: unknown1\t\t\t\t: 0x%08" PRIx32 "\n",
4697
     function,
4698
     value_32bit );
4699
4700
    libcnotify_printf(
4701
     "\n" );
4702
  }
4703
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
4704
4705
0
  block_data_offset = 8;
4706
4707
0
  if( number_of_entries > ( ( block_data_size - block_data_offset ) / 40 ) )
4708
0
  {
4709
0
    libcerror_error_set(
4710
0
     error,
4711
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4712
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
4713
0
     "%s: invalid number of entries value out of bounds.",
4714
0
     function );
4715
4716
0
    goto on_error;
4717
0
  }
4718
0
  for( entry_index = 0;
4719
0
       entry_index < number_of_entries;
4720
0
       entry_index++ )
4721
0
  {
4722
0
    if( libfvde_segment_descriptor_initialize(
4723
0
         &segment_descriptor,
4724
0
         error ) == -1 )
4725
0
    {
4726
0
      libcerror_error_set(
4727
0
       error,
4728
0
       LIBCERROR_ERROR_DOMAIN_ENCRYPTION,
4729
0
       LIBCERROR_ENCRYPTION_ERROR_GENERIC,
4730
0
       "%s: unable to create segment descriptor.",
4731
0
       function );
4732
4733
0
      goto on_error;
4734
0
    }
4735
0
    byte_stream_copy_to_uint64_little_endian(
4736
0
     &( block_data[ block_data_offset + 8 ] ),
4737
0
     segment_descriptor->logical_block_number );
4738
4739
0
    byte_stream_copy_to_uint32_little_endian(
4740
0
     &( block_data[ block_data_offset + 16 ] ),
4741
0
     segment_descriptor->number_of_blocks );
4742
4743
0
    byte_stream_copy_to_uint64_little_endian(
4744
0
     &( block_data[ block_data_offset + 32 ] ),
4745
0
     segment_descriptor->physical_block_number );
4746
4747
0
    segment_descriptor->physical_volume_index  = (uint16_t) ( segment_descriptor->physical_block_number >> 48 );
4748
0
    segment_descriptor->physical_block_number &= 0x0000ffffffffffffUL;
4749
4750
#if defined( HAVE_DEBUG_OUTPUT )
4751
    if( libcnotify_verbose != 0 )
4752
    {
4753
      byte_stream_copy_to_uint64_little_endian(
4754
       &( block_data[ block_data_offset ] ),
4755
       value_64bit );
4756
      libcnotify_printf(
4757
       "%s: entry: %03d unknown1\t\t: 0x%08" PRIx64 "\n",
4758
       function,
4759
       entry_index,
4760
       value_64bit );
4761
4762
      libcnotify_printf(
4763
       "%s: entry: %03d logical block number\t: %" PRIi64 "\n",
4764
       function,
4765
       entry_index,
4766
       segment_descriptor->logical_block_number );
4767
4768
      libcnotify_printf(
4769
       "%s: entry: %03d number of blocks\t: %" PRIu32 "\n",
4770
       function,
4771
       entry_index,
4772
       segment_descriptor->number_of_blocks );
4773
4774
      byte_stream_copy_to_uint32_little_endian(
4775
       &( block_data[ block_data_offset + 20 ] ),
4776
       value_32bit );
4777
      libcnotify_printf(
4778
       "%s: entry: %03d unknown3\t\t: 0x%08" PRIx32 "\n",
4779
       function,
4780
       entry_index,
4781
       value_32bit );
4782
4783
      byte_stream_copy_to_uint32_little_endian(
4784
       &( block_data[ block_data_offset + 24 ] ),
4785
       value_32bit );
4786
      libcnotify_printf(
4787
       "%s: entry: %03d unknown4\t\t: 0x%08" PRIx32 "\n",
4788
       function,
4789
       entry_index,
4790
       value_32bit );
4791
4792
      byte_stream_copy_to_uint32_little_endian(
4793
       &( block_data[ block_data_offset + 28 ] ),
4794
       value_32bit );
4795
      libcnotify_printf(
4796
       "%s: entry: %03d unknown5\t\t: 0x%08" PRIx32 "\n",
4797
       function,
4798
       entry_index,
4799
       value_32bit );
4800
4801
      libcnotify_printf(
4802
       "%s: entry: %03d physical block number\t: %" PRIu64 "\n",
4803
       function,
4804
       entry_index,
4805
       segment_descriptor->physical_block_number );
4806
4807
      libcnotify_printf(
4808
       "%s: entry: %03d physical volume index\t: %" PRIu16 "\n",
4809
       function,
4810
       entry_index,
4811
       segment_descriptor->physical_volume_index );
4812
4813
      libcnotify_printf(
4814
       "\n" );
4815
    }
4816
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
4817
4818
0
    block_data_offset += 40;
4819
4820
0
    result = libcdata_array_insert_entry(
4821
0
              logical_volume_descriptor->segment_descriptors,
4822
0
              &segment_descriptor_index,
4823
0
              (intptr_t *) segment_descriptor,
4824
0
              (int (*)(intptr_t *, intptr_t *, libcerror_error_t **)) &libfvde_segment_descriptor_compare,
4825
0
              LIBCDATA_INSERT_FLAG_UNIQUE_ENTRIES,
4826
0
              error );
4827
4828
0
    if( result == -1 )
4829
0
    {
4830
0
      libcerror_error_set(
4831
0
       error,
4832
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4833
0
       LIBCERROR_RUNTIME_ERROR_APPEND_FAILED,
4834
0
       "%s: unable to insert segment descriptor: %d in array.",
4835
0
       function,
4836
0
       entry_index );
4837
4838
0
      goto on_error;
4839
0
    }
4840
0
    else if( result == 0 )
4841
0
    {
4842
0
      libcerror_error_set(
4843
0
       error,
4844
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
4845
0
       LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
4846
0
       "%s: unsupported overlapping segment descriptor: %d.",
4847
0
       function,
4848
0
       entry_index );
4849
4850
0
      goto on_error;
4851
0
    }
4852
0
    if( block_number > segment_descriptor->physical_block_number )
4853
0
    {
4854
0
      block_number = segment_descriptor->physical_block_number;
4855
0
    }
4856
0
    number_of_blocks  += segment_descriptor->number_of_blocks;
4857
0
    segment_descriptor = NULL;
4858
0
  }
4859
0
  logical_volume_descriptor->object_identifier_0x0305 = object_identifier;
4860
4861
0
  return( 1 );
4862
4863
0
on_error:
4864
0
  if( segment_descriptor != NULL )
4865
0
  {
4866
0
    libfvde_segment_descriptor_free(
4867
0
     &segment_descriptor,
4868
0
     NULL );
4869
0
  }
4870
0
  return( -1 );
4871
0
}
4872
4873
/* Reads the encrypted metadata block type 0x00404
4874
 * Returns 1 if successful or -1 on error
4875
 */
4876
int libfvde_encrypted_metadata_read_type_0x0404(
4877
     libfvde_encrypted_metadata_t *encrypted_metadata,
4878
     libfvde_io_handle_t *io_handle,
4879
     const uint8_t *block_data,
4880
     size_t block_data_size,
4881
     libcerror_error_t **error )
4882
0
{
4883
0
  static char *function      = "libfvde_encrypted_metadata_read_type_0x0404";
4884
0
  size_t block_data_offset   = 0;
4885
0
  uint32_t entry_index       = 0;
4886
0
  uint32_t number_of_entries = 0;
4887
4888
#if defined( HAVE_DEBUG_OUTPUT )
4889
  uint64_t value_64bit       = 0;
4890
  uint32_t value_32bit       = 0;
4891
#endif
4892
4893
0
  if( encrypted_metadata == NULL )
4894
0
  {
4895
0
    libcerror_error_set(
4896
0
     error,
4897
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4898
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4899
0
     "%s: invalid encrypted metadata.",
4900
0
     function );
4901
4902
0
    return( -1 );
4903
0
  }
4904
0
  if( io_handle == NULL )
4905
0
  {
4906
0
    libcerror_error_set(
4907
0
     error,
4908
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4909
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4910
0
     "%s: invalid IO handle.",
4911
0
     function );
4912
4913
0
    return( -1 );
4914
0
  }
4915
0
  if( block_data == NULL )
4916
0
  {
4917
0
    libcerror_error_set(
4918
0
     error,
4919
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4920
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
4921
0
     "%s: invalid block data.",
4922
0
     function );
4923
4924
0
    return( -1 );
4925
0
  }
4926
0
  if( ( block_data_size < 8 )
4927
0
   || ( block_data_size > (size_t) SSIZE_MAX ) )
4928
0
  {
4929
0
    libcerror_error_set(
4930
0
     error,
4931
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
4932
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
4933
0
     "%s: invalid block data size value out of bounds.",
4934
0
     function );
4935
4936
0
    return( -1 );
4937
0
  }
4938
0
  byte_stream_copy_to_uint32_little_endian(
4939
0
   &( block_data[ 0 ] ),
4940
0
   number_of_entries );
4941
4942
#if defined( HAVE_DEBUG_OUTPUT )
4943
  if( libcnotify_verbose != 0 )
4944
  {
4945
    libcnotify_printf(
4946
     "%s: number of entries\t\t\t: %" PRIu32 "\n",
4947
     function,
4948
     number_of_entries );
4949
4950
    byte_stream_copy_to_uint32_little_endian(
4951
     &( block_data[ 4 ] ),
4952
     value_32bit );
4953
    libcnotify_printf(
4954
     "%s: unknown1\t\t\t\t: 0x%08" PRIx32 "\n",
4955
     function,
4956
     value_32bit );
4957
4958
    libcnotify_printf(
4959
     "\n" );
4960
  }
4961
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
4962
4963
0
  block_data_offset = 8;
4964
4965
0
  if( number_of_entries > ( ( block_data_size - block_data_offset ) / 48 ) )
4966
0
  {
4967
0
    libcerror_error_set(
4968
0
     error,
4969
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
4970
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
4971
0
     "%s: invalid number of entries value out of bounds.",
4972
0
     function );
4973
4974
0
    return( -1 );
4975
0
  }
4976
0
  for( entry_index = 0;
4977
0
       entry_index < number_of_entries;
4978
0
       entry_index++ )
4979
0
  {
4980
#if defined( HAVE_DEBUG_OUTPUT )
4981
    if( libcnotify_verbose != 0 )
4982
    {
4983
      byte_stream_copy_to_uint64_little_endian(
4984
       &( block_data[ block_data_offset ] ),
4985
       value_64bit );
4986
      libcnotify_printf(
4987
       "%s: entry: %03d physical block number\t: %" PRIi64 "\n",
4988
       function,
4989
       entry_index,
4990
       value_64bit );
4991
4992
      byte_stream_copy_to_uint64_little_endian(
4993
       &( block_data[ block_data_offset + 8 ] ),
4994
       value_64bit );
4995
      libcnotify_printf(
4996
       "%s: entry: %03d number of blocks\t: %" PRIu64 "\n",
4997
       function,
4998
       entry_index,
4999
       value_64bit );
5000
5001
      byte_stream_copy_to_uint64_little_endian(
5002
       &( block_data[ block_data_offset + 16 ] ),
5003
       value_64bit );
5004
      libcnotify_printf(
5005
       "%s: entry: %03d object identifier\t: %" PRIi64 " (0x%08" PRIx64 ")\n",
5006
       function,
5007
       entry_index,
5008
       (int64_t) value_64bit,
5009
       value_64bit );
5010
5011
      byte_stream_copy_to_uint64_little_endian(
5012
       &( block_data[ block_data_offset + 24 ] ),
5013
       value_64bit );
5014
      libcnotify_printf(
5015
       "%s: entry: %03d copy number\t\t: %" PRIu64 "\n",
5016
       function,
5017
       entry_index,
5018
       value_64bit );
5019
5020
      byte_stream_copy_to_uint64_little_endian(
5021
       &( block_data[ block_data_offset + 32 ] ),
5022
       value_64bit );
5023
      libcnotify_printf(
5024
       "%s: entry: %03d unknown1\t\t: 0x%08" PRIx64 "\n",
5025
       function,
5026
       entry_index,
5027
       value_64bit );
5028
5029
      byte_stream_copy_to_uint64_little_endian(
5030
       &( block_data[ block_data_offset + 40 ] ),
5031
       value_64bit );
5032
      libcnotify_printf(
5033
       "%s: entry: %03d logical block number\t: %" PRIi64 "\n",
5034
       function,
5035
       entry_index,
5036
       value_64bit );
5037
5038
      libcnotify_printf(
5039
       "\n" );
5040
    }
5041
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
5042
5043
0
    block_data_offset += 48;
5044
0
  }
5045
0
  return( 1 );
5046
0
}
5047
5048
/* Reads the encrypted metadata block type 0x0405
5049
 * Returns 1 if successful or -1 on error
5050
 */
5051
int libfvde_encrypted_metadata_read_type_0x0405(
5052
     libfvde_encrypted_metadata_t *encrypted_metadata,
5053
     libfvde_io_handle_t *io_handle,
5054
     const uint8_t *block_data,
5055
     size_t block_data_size,
5056
     libcerror_error_t **error )
5057
0
{
5058
0
  static char *function      = "libfvde_encrypted_metadata_read_type_0x0405";
5059
0
  size_t block_data_offset   = 0;
5060
0
  uint32_t entry_index       = 0;
5061
0
  uint32_t number_of_entries = 0;
5062
5063
#if defined( HAVE_DEBUG_OUTPUT )
5064
  uint64_t value_64bit       = 0;
5065
  uint32_t value_32bit       = 0;
5066
#endif
5067
5068
0
  if( encrypted_metadata == NULL )
5069
0
  {
5070
0
    libcerror_error_set(
5071
0
     error,
5072
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5073
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5074
0
     "%s: invalid encrypted metadata.",
5075
0
     function );
5076
5077
0
    return( -1 );
5078
0
  }
5079
0
  if( io_handle == NULL )
5080
0
  {
5081
0
    libcerror_error_set(
5082
0
     error,
5083
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5084
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5085
0
     "%s: invalid IO handle.",
5086
0
     function );
5087
5088
0
    return( -1 );
5089
0
  }
5090
0
  if( block_data == NULL )
5091
0
  {
5092
0
    libcerror_error_set(
5093
0
     error,
5094
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5095
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5096
0
     "%s: invalid block data.",
5097
0
     function );
5098
5099
0
    return( -1 );
5100
0
  }
5101
0
  if( ( block_data_size < 8 )
5102
0
   || ( block_data_size > (size_t) SSIZE_MAX ) )
5103
0
  {
5104
0
    libcerror_error_set(
5105
0
     error,
5106
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5107
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
5108
0
     "%s: invalid block data size value out of bounds.",
5109
0
     function );
5110
5111
0
    return( -1 );
5112
0
  }
5113
0
  byte_stream_copy_to_uint32_little_endian(
5114
0
   &( block_data[ 0 ] ),
5115
0
   number_of_entries );
5116
5117
#if defined( HAVE_DEBUG_OUTPUT )
5118
  if( libcnotify_verbose != 0 )
5119
  {
5120
    libcnotify_printf(
5121
     "%s: number of entries\t\t\t: %" PRIu32 "\n",
5122
     function,
5123
     number_of_entries );
5124
5125
    byte_stream_copy_to_uint32_little_endian(
5126
     &( block_data[ 4 ] ),
5127
     value_32bit );
5128
    libcnotify_printf(
5129
     "%s: unknown1\t\t\t\t: 0x%08" PRIx32 "\n",
5130
     function,
5131
     value_32bit );
5132
5133
    libcnotify_printf(
5134
     "\n" );
5135
  }
5136
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
5137
5138
0
  block_data_offset = 8;
5139
5140
0
  if( number_of_entries > ( ( block_data_size - block_data_offset ) / 48 ) )
5141
0
  {
5142
0
    libcerror_error_set(
5143
0
     error,
5144
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5145
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
5146
0
     "%s: invalid number of entries value out of bounds.",
5147
0
     function );
5148
5149
0
    return( -1 );
5150
0
  }
5151
0
  for( entry_index = 0;
5152
0
       entry_index < number_of_entries;
5153
0
       entry_index++ )
5154
0
  {
5155
#if defined( HAVE_DEBUG_OUTPUT )
5156
    if( libcnotify_verbose != 0 )
5157
    {
5158
      byte_stream_copy_to_uint64_little_endian(
5159
       &( block_data[ block_data_offset ] ),
5160
       value_64bit );
5161
      libcnotify_printf(
5162
       "%s: entry: %03d physical block number\t: %" PRIi64 "\n",
5163
       function,
5164
       entry_index,
5165
       value_64bit );
5166
5167
      byte_stream_copy_to_uint64_little_endian(
5168
       &( block_data[ block_data_offset + 8 ] ),
5169
       value_64bit );
5170
      libcnotify_printf(
5171
       "%s: entry: %03d number of blocks\t: %" PRIu64 "\n",
5172
       function,
5173
       entry_index,
5174
       value_64bit );
5175
5176
      byte_stream_copy_to_uint64_little_endian(
5177
       &( block_data[ block_data_offset + 16 ] ),
5178
       value_64bit );
5179
      libcnotify_printf(
5180
       "%s: entry: %03d object identifier\t: %" PRIi64 " (0x%08" PRIx64 ")\n",
5181
       function,
5182
       entry_index,
5183
       (int64_t) value_64bit,
5184
       value_64bit );
5185
5186
      byte_stream_copy_to_uint64_little_endian(
5187
       &( block_data[ block_data_offset + 24 ] ),
5188
       value_64bit );
5189
      libcnotify_printf(
5190
       "%s: entry: %03d copy number\t\t: %" PRIu64 "\n",
5191
       function,
5192
       entry_index,
5193
       value_64bit );
5194
5195
      byte_stream_copy_to_uint64_little_endian(
5196
       &( block_data[ block_data_offset + 32 ] ),
5197
       value_64bit );
5198
      libcnotify_printf(
5199
       "%s: entry: %03d unknown1\t\t: 0x%08" PRIx64 "\n",
5200
       function,
5201
       entry_index,
5202
       value_64bit );
5203
5204
      byte_stream_copy_to_uint64_little_endian(
5205
       &( block_data[ block_data_offset + 40 ] ),
5206
       value_64bit );
5207
      libcnotify_printf(
5208
       "%s: entry: %03d logical block number\t: %" PRIi64 "\n",
5209
       function,
5210
       entry_index,
5211
       value_64bit );
5212
5213
      libcnotify_printf(
5214
       "\n" );
5215
    }
5216
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
5217
5218
0
    block_data_offset += 48;
5219
0
  }
5220
0
  return( 1 );
5221
0
}
5222
5223
/* Reads the encrypted metadata block type 0x0505
5224
 * Returns 1 if successful or -1 on error
5225
 */
5226
int libfvde_encrypted_metadata_read_type_0x0505(
5227
     libfvde_encrypted_metadata_t *encrypted_metadata,
5228
     uint64_t object_identifier,
5229
     const uint8_t *block_data,
5230
     size_t block_data_size,
5231
     libcerror_error_t **error )
5232
0
{
5233
0
  libfvde_logical_volume_descriptor_t *logical_volume_descriptor = NULL;
5234
0
  static char *function                                          = "libfvde_encrypted_metadata_read_type_0x0505";
5235
0
  size_t block_data_offset                                       = 0;
5236
0
  uint64_t physical_block_number                                 = 0;
5237
0
  uint32_t entry_index                                           = 0;
5238
0
  uint32_t number_of_entries                                     = 0;
5239
5240
#if defined( HAVE_DEBUG_OUTPUT )
5241
  uint64_t value_64bit                                           = 0;
5242
  uint32_t value_32bit                                           = 0;
5243
#endif
5244
5245
0
  if( encrypted_metadata == NULL )
5246
0
  {
5247
0
    libcerror_error_set(
5248
0
     error,
5249
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5250
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5251
0
     "%s: invalid encrypted metadata.",
5252
0
     function );
5253
5254
0
    return( -1 );
5255
0
  }
5256
0
  if( block_data == NULL )
5257
0
  {
5258
0
    libcerror_error_set(
5259
0
     error,
5260
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5261
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5262
0
     "%s: invalid block data.",
5263
0
     function );
5264
5265
0
    return( -1 );
5266
0
  }
5267
0
  if( ( block_data_size < 8 )
5268
0
   || ( block_data_size > (size_t) SSIZE_MAX ) )
5269
0
  {
5270
0
    libcerror_error_set(
5271
0
     error,
5272
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5273
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
5274
0
     "%s: invalid block data size value out of bounds.",
5275
0
     function );
5276
5277
0
    return( -1 );
5278
0
  }
5279
0
  if( libfvde_encrypted_metadata_get_last_logical_volume_descriptor(
5280
0
       encrypted_metadata,
5281
0
       &logical_volume_descriptor,
5282
0
       error ) != 1 )
5283
0
  {
5284
0
    libcerror_error_set(
5285
0
     error,
5286
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5287
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5288
0
     "%s: unable to retrieve last logical volume descriptor.",
5289
0
     function );
5290
5291
0
    return( -1 );
5292
0
  }
5293
0
  if( logical_volume_descriptor == NULL )
5294
0
  {
5295
0
    libcerror_error_set(
5296
0
     error,
5297
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5298
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
5299
0
     "%s: missing logical volume descriptor.",
5300
0
     function );
5301
5302
0
    return( -1 );
5303
0
  }
5304
0
  byte_stream_copy_to_uint32_little_endian(
5305
0
   &( block_data[ 0 ] ),
5306
0
   number_of_entries );
5307
5308
#if defined( HAVE_DEBUG_OUTPUT )
5309
  if( libcnotify_verbose != 0 )
5310
  {
5311
    libcnotify_printf(
5312
     "%s: number of entries\t\t\t: %" PRIu32 "\n",
5313
     function,
5314
     number_of_entries );
5315
5316
    byte_stream_copy_to_uint32_little_endian(
5317
     &( block_data[ 4 ] ),
5318
     value_32bit );
5319
    libcnotify_printf(
5320
     "%s: unknown1\t\t\t\t: 0x%08" PRIx32 "\n",
5321
     function,
5322
     value_32bit );
5323
5324
    libcnotify_printf(
5325
     "\n" );
5326
  }
5327
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
5328
5329
0
  block_data_offset = 8;
5330
5331
0
  if( number_of_entries > ( ( block_data_size - block_data_offset ) / 16 ) )
5332
0
  {
5333
0
    libcerror_error_set(
5334
0
     error,
5335
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5336
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
5337
0
     "%s: invalid number of entries value out of bounds.",
5338
0
     function );
5339
5340
0
    return( -1 );
5341
0
  }
5342
0
  for( entry_index = 0;
5343
0
       entry_index < number_of_entries;
5344
0
       entry_index++ )
5345
0
  {
5346
0
    byte_stream_copy_to_uint64_little_endian(
5347
0
     &( block_data[ block_data_offset + 8 ] ),
5348
0
     physical_block_number );
5349
5350
#if defined( HAVE_DEBUG_OUTPUT )
5351
    if( libcnotify_verbose != 0 )
5352
    {
5353
      byte_stream_copy_to_uint64_little_endian(
5354
       &( block_data[ block_data_offset ] ),
5355
       value_64bit );
5356
5357
      libcnotify_printf(
5358
       "%s: entry: %03d number of blocks\t: %" PRIu64 "\n",
5359
       function,
5360
       entry_index,
5361
       value_64bit );
5362
5363
      libcnotify_printf(
5364
       "%s: entry: %03d physical block number\t: %" PRIu64 "\n",
5365
       function,
5366
       entry_index,
5367
       physical_block_number & 0x0000ffffffffffffUL );
5368
5369
      libcnotify_printf(
5370
       "%s: entry: %03d physical volume index\t: %" PRIu64 "\n",
5371
       function,
5372
       entry_index,
5373
       physical_block_number >> 48 );
5374
5375
      libcnotify_printf(
5376
       "\n" );
5377
    }
5378
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
5379
5380
0
    block_data_offset += 16;
5381
0
  }
5382
0
  if( number_of_entries > 1 )
5383
0
  {
5384
0
    libcerror_error_set(
5385
0
     error,
5386
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5387
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
5388
0
     "%s: unsupported number of entries.",
5389
0
     function );
5390
5391
0
    return( -1 );
5392
0
  }
5393
0
  if( ( physical_block_number >> 48 ) > 0 )
5394
0
  {
5395
0
    libcerror_error_set(
5396
0
     error,
5397
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5398
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
5399
0
     "%s: unsupported physical block number.",
5400
0
     function );
5401
5402
0
    return( -1 );
5403
0
  }
5404
0
  logical_volume_descriptor->object_identifier_0x0505   = object_identifier;
5405
0
  logical_volume_descriptor->base_physical_block_number = physical_block_number;
5406
5407
0
  return( 1 );
5408
0
}
5409
5410
/* Reads the encrypted metadata block type 0x0605
5411
 * Returns 1 if successful or -1 on error
5412
 */
5413
int libfvde_encrypted_metadata_read_type_0x0605(
5414
     libfvde_encrypted_metadata_t *encrypted_metadata,
5415
     const uint8_t *block_data,
5416
     size_t block_data_size,
5417
     libcerror_error_t **error )
5418
0
{
5419
0
  static char *function = "libfvde_encrypted_metadata_read_type_0x0605";
5420
5421
0
  if( encrypted_metadata == NULL )
5422
0
  {
5423
0
    libcerror_error_set(
5424
0
     error,
5425
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5426
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5427
0
     "%s: invalid encrypted metadata.",
5428
0
     function );
5429
5430
0
    return( -1 );
5431
0
  }
5432
0
  if( block_data == NULL )
5433
0
  {
5434
0
    libcerror_error_set(
5435
0
     error,
5436
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5437
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5438
0
     "%s: invalid block data.",
5439
0
     function );
5440
5441
0
    return( -1 );
5442
0
  }
5443
0
  if( ( block_data_size < 54 )
5444
0
   || ( block_data_size > (size_t) SSIZE_MAX ) )
5445
0
  {
5446
0
    libcerror_error_set(
5447
0
     error,
5448
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5449
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
5450
0
     "%s: invalid block data size value out of bounds.",
5451
0
     function );
5452
5453
0
    return( -1 );
5454
0
  }
5455
0
  return( 1 );
5456
0
}
5457
5458
/* Reads the encrypted metadata
5459
 * Returns 1 if successful or -1 on error
5460
 */
5461
int libfvde_encrypted_metadata_read_from_file_io_handle(
5462
     libfvde_encrypted_metadata_t *encrypted_metadata,
5463
     libfvde_io_handle_t *io_handle,
5464
     libbfio_handle_t *file_io_handle,
5465
     off64_t file_offset,
5466
     uint64_t encrypted_metadata_size,
5467
     const uint8_t *key,
5468
     size_t key_bit_size,
5469
     const uint8_t *tweak_key,
5470
     size_t tweak_key_bit_size,
5471
     libcerror_error_t **error )
5472
0
{
5473
0
  libfvde_encryption_context_t *encryption_context = NULL;
5474
0
  libfvde_metadata_block_t *metadata_block         = NULL;
5475
0
  uint8_t *encrypted_data                          = NULL;
5476
0
  uint8_t *metadata_block_data                     = NULL;
5477
0
  static char *function                            = "libfvde_encrypted_metadata_read_from_file_io_handle";
5478
0
  size_t encrypted_data_offset                     = 0;
5479
0
  ssize_t read_count                               = 0;
5480
0
  uint64_t calculated_block_number                 = 0;
5481
0
  uint8_t empty_block_found                        = 0;
5482
0
  int result                                       = 0;
5483
5484
0
  if( encrypted_metadata == NULL )
5485
0
  {
5486
0
    libcerror_error_set(
5487
0
     error,
5488
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5489
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5490
0
     "%s: invalid encrypted metadata.",
5491
0
     function );
5492
5493
0
    return( -1 );
5494
0
  }
5495
0
  if( io_handle == NULL )
5496
0
  {
5497
0
    libcerror_error_set(
5498
0
     error,
5499
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5500
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
5501
0
     "%s: invalid IO handle.",
5502
0
     function );
5503
5504
0
    return( -1 );
5505
0
  }
5506
0
  if( ( encrypted_metadata_size == 0 )
5507
0
   || ( encrypted_metadata_size > (uint64_t) MEMORY_MAXIMUM_ALLOCATION_SIZE ) )
5508
0
  {
5509
0
    libcerror_error_set(
5510
0
     error,
5511
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
5512
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
5513
0
     "%s: invalid encrypted metadata size value out of bounds.",
5514
0
     function );
5515
5516
0
    return( -1 );
5517
0
  }
5518
0
  encrypted_data = (uint8_t *) memory_allocate(
5519
0
                                sizeof( uint8_t ) * (size_t) encrypted_metadata_size );
5520
5521
0
  if( encrypted_data == NULL )
5522
0
  {
5523
0
    libcerror_error_set(
5524
0
     error,
5525
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
5526
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
5527
0
     "%s: unable to create encrypted metadata.",
5528
0
     function );
5529
5530
0
    goto on_error;
5531
0
  }
5532
#if defined( HAVE_DEBUG_OUTPUT )
5533
  if( libcnotify_verbose != 0 )
5534
  {
5535
    libcnotify_printf(
5536
     "%s: reading encrypted metadata at offset: %" PRIi64 " (0x%08" PRIx64 ")\n",
5537
     function,
5538
     file_offset,
5539
     file_offset );
5540
  }
5541
#endif
5542
0
  read_count = libbfio_handle_read_buffer_at_offset(
5543
0
                file_io_handle,
5544
0
                encrypted_data,
5545
0
                (size_t) encrypted_metadata_size,
5546
0
                file_offset,
5547
0
                error );
5548
5549
0
  if( read_count != (ssize_t) encrypted_metadata_size )
5550
0
  {
5551
0
    libcerror_error_set(
5552
0
     error,
5553
0
     LIBCERROR_ERROR_DOMAIN_IO,
5554
0
     LIBCERROR_IO_ERROR_READ_FAILED,
5555
0
     "%s: unable to read encrypted metadata at offset: %" PRIi64 " (0x%08" PRIx64 ").",
5556
0
     function,
5557
0
     file_offset,
5558
0
     file_offset );
5559
5560
0
    goto on_error;
5561
0
  }
5562
0
  if( libfvde_encryption_context_initialize(
5563
0
       &encryption_context,
5564
0
       LIBFVDE_ENCRYPTION_METHOD_AES_128_XTS,
5565
0
       error ) == -1 )
5566
0
  {
5567
0
    libcerror_error_set(
5568
0
     error,
5569
0
     LIBCERROR_ERROR_DOMAIN_ENCRYPTION,
5570
0
     LIBCERROR_ENCRYPTION_ERROR_GENERIC,
5571
0
     "%s: unable to initialize encryption context.",
5572
0
     function );
5573
5574
0
    goto on_error;
5575
0
  }
5576
0
  if( libfvde_encryption_context_set_keys(
5577
0
       encryption_context,
5578
0
       key,
5579
0
       key_bit_size,
5580
0
       tweak_key,
5581
0
       tweak_key_bit_size,
5582
0
       error ) == -1 )
5583
0
  {
5584
0
    libcerror_error_set(
5585
0
     error,
5586
0
     LIBCERROR_ERROR_DOMAIN_IO,
5587
0
     LIBCERROR_IO_ERROR_SEEK_FAILED,
5588
0
     "%s: unable to set keys in encryption context.",
5589
0
     function );
5590
5591
0
    goto on_error;
5592
0
  }
5593
0
  metadata_block_data = (uint8_t *) memory_allocate(
5594
0
                                     sizeof( uint8_t ) * 8192 );
5595
5596
0
  if( metadata_block_data == NULL )
5597
0
  {
5598
0
    libcerror_error_set(
5599
0
     error,
5600
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
5601
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
5602
0
     "%s: unable to create metadata block data.",
5603
0
     function );
5604
5605
0
    goto on_error;
5606
0
  }
5607
/* TODO move data allocation into metadata_block? */
5608
0
  if( libfvde_metadata_block_initialize(
5609
0
       &metadata_block,
5610
0
       error ) != 1 )
5611
0
  {
5612
0
    libcerror_error_set(
5613
0
     error,
5614
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5615
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
5616
0
     "%s: unable to create metadata block.",
5617
0
     function );
5618
5619
0
    goto on_error;
5620
0
  }
5621
0
  while( encrypted_data_offset < encrypted_metadata_size )
5622
0
  {
5623
0
    result = libfvde_metadata_block_check_for_empty_block(
5624
0
        &( encrypted_data[ encrypted_data_offset ] ),
5625
0
        8192,
5626
0
        error );
5627
5628
0
    if( result == -1 )
5629
0
    {
5630
0
      libcerror_error_set(
5631
0
       error,
5632
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
5633
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
5634
0
       "%s: unable to determine if encrypted medadata block data is empty.",
5635
0
       function );
5636
5637
0
      return( -1 );
5638
0
    }
5639
0
    else if( result != 0 )
5640
0
    {
5641
0
      empty_block_found = 1;
5642
0
    }
5643
0
    if( empty_block_found != 0 )
5644
0
    {
5645
#if defined( HAVE_DEBUG_OUTPUT )
5646
      if( libcnotify_verbose != 0 )
5647
      {
5648
        libcnotify_printf(
5649
         "%s: empty metadata block: %d at offset %" PRIi64 " (0x%08" PRIx64 ").\n",
5650
         function,
5651
         calculated_block_number,
5652
         file_offset + encrypted_data_offset,
5653
         file_offset + encrypted_data_offset );
5654
      }
5655
#else
5656
0
      break;
5657
0
#endif
5658
0
    }
5659
0
    else
5660
0
    {
5661
0
      if( libfvde_encryption_context_crypt(
5662
0
           encryption_context,
5663
0
           LIBFVDE_ENCRYPTION_CRYPT_MODE_DECRYPT,
5664
0
           &( encrypted_data[ encrypted_data_offset ] ),
5665
0
           8192,
5666
0
           metadata_block_data,
5667
0
           8192,
5668
0
           calculated_block_number,
5669
0
           error ) == -1 )
5670
0
      {
5671
0
        libcerror_error_set(
5672
0
         error,
5673
0
         LIBCERROR_ERROR_DOMAIN_ENCRYPTION,
5674
0
         LIBCERROR_ENCRYPTION_ERROR_DECRYPT_FAILED,
5675
0
         "%s: unable to decrypt metadata data block: %" PRIu64 " data.",
5676
0
         function,
5677
0
         calculated_block_number );
5678
5679
0
        goto on_error;
5680
0
      }
5681
#if defined( HAVE_DEBUG_OUTPUT )
5682
      if( libcnotify_verbose != 0 )
5683
      {
5684
        libcnotify_printf(
5685
         "%s: reading decrypted metadata block: %d at offset: %" PRIi64 " (0x%08" PRIx64 ")\n",
5686
         function,
5687
         calculated_block_number,
5688
         file_offset + encrypted_data_offset,
5689
         file_offset + encrypted_data_offset );
5690
      }
5691
#endif
5692
0
      if( libfvde_metadata_block_read_data(
5693
0
           metadata_block,
5694
0
           metadata_block_data,
5695
0
           8192,
5696
0
           error ) != 1 )
5697
0
      {
5698
0
        libcerror_error_set(
5699
0
         error,
5700
0
         LIBCERROR_ERROR_DOMAIN_IO,
5701
0
         LIBCERROR_IO_ERROR_READ_FAILED,
5702
0
         "%s: unable to read metadata block.",
5703
0
         function );
5704
5705
0
        goto on_error;
5706
0
      }
5707
0
      if( metadata_block->is_lvf_wiped == 0 )
5708
0
      {
5709
#if defined( HAVE_DEBUG_OUTPUT )
5710
        if( ( libcnotify_verbose != 0 )
5711
         && ( metadata_block->serial_number != io_handle->serial_number ) )
5712
        {
5713
          libcnotify_printf(
5714
           "%s: mismatch in serial number (stored: 0x%08" PRIx32 ", expected: 0x%08" PRIx32 ").\n",
5715
           function,
5716
           metadata_block->serial_number,
5717
           io_handle->serial_number );
5718
        }
5719
#endif
5720
0
        switch( metadata_block->type )
5721
0
        {
5722
0
          case 0x0010:
5723
0
            result = libfvde_encrypted_metadata_read_type_0x0010(
5724
0
                encrypted_metadata,
5725
0
                metadata_block->data,
5726
0
                metadata_block->data_size,
5727
0
                error );
5728
0
            break;
5729
5730
0
          case 0x0011:
5731
0
            result = libfvde_encrypted_metadata_read_type_0x0011(
5732
0
                encrypted_metadata,
5733
0
                metadata_block->data,
5734
0
                metadata_block->data_size,
5735
0
                error );
5736
0
            break;
5737
5738
0
          case 0x0012:
5739
0
            result = libfvde_encrypted_metadata_read_type_0x0012(
5740
0
                encrypted_metadata,
5741
0
                metadata_block->data,
5742
0
                metadata_block->data_size,
5743
0
                error );
5744
0
            break;
5745
5746
0
          case 0x0013:
5747
0
            result = libfvde_encrypted_metadata_read_type_0x0013(
5748
0
                encrypted_metadata,
5749
0
                metadata_block->data,
5750
0
                metadata_block->data_size,
5751
0
                error );
5752
0
            break;
5753
5754
0
          case 0x0014:
5755
0
            result = libfvde_encrypted_metadata_read_type_0x0014(
5756
0
                encrypted_metadata,
5757
0
                metadata_block->data,
5758
0
                metadata_block->data_size,
5759
0
                error );
5760
0
            break;
5761
5762
0
          case 0x0016:
5763
0
            result = libfvde_encrypted_metadata_read_type_0x0016(
5764
0
                encrypted_metadata,
5765
0
                metadata_block->data,
5766
0
                metadata_block->data_size,
5767
0
                error );
5768
0
            break;
5769
5770
0
          case 0x0017:
5771
0
            result = libfvde_encrypted_metadata_read_type_0x0017(
5772
0
                encrypted_metadata,
5773
0
                metadata_block->data,
5774
0
                metadata_block->data_size,
5775
0
                error );
5776
0
            break;
5777
5778
0
          case 0x0018:
5779
0
            result = libfvde_encrypted_metadata_read_type_0x0018(
5780
0
                encrypted_metadata,
5781
0
                metadata_block->data,
5782
0
                metadata_block->data_size,
5783
0
                error );
5784
0
            break;
5785
5786
0
          case 0x0019:
5787
0
            result = libfvde_encrypted_metadata_read_type_0x0019(
5788
0
                encrypted_metadata,
5789
0
                metadata_block->data,
5790
0
                metadata_block->data_size,
5791
0
                error );
5792
0
            break;
5793
5794
0
          case 0x001a:
5795
0
            result = libfvde_encrypted_metadata_read_type_0x001a(
5796
0
                encrypted_metadata,
5797
0
                metadata_block->data,
5798
0
                metadata_block->data_size,
5799
0
                error );
5800
0
            break;
5801
5802
0
          case 0x001c:
5803
0
            result = libfvde_encrypted_metadata_read_type_0x001c(
5804
0
                encrypted_metadata,
5805
0
                metadata_block->data,
5806
0
                metadata_block->data_size,
5807
0
                error );
5808
0
            break;
5809
5810
0
          case 0x001d:
5811
0
            result = libfvde_encrypted_metadata_read_type_0x001d(
5812
0
                encrypted_metadata,
5813
0
                metadata_block->data,
5814
0
                metadata_block->data_size,
5815
0
                error );
5816
0
            break;
5817
5818
0
          case 0x0021:
5819
0
            result = libfvde_encrypted_metadata_read_type_0x0021(
5820
0
                encrypted_metadata,
5821
0
                metadata_block->data,
5822
0
                metadata_block->data_size,
5823
0
                error );
5824
0
            break;
5825
5826
0
          case 0x0022:
5827
0
            result = libfvde_encrypted_metadata_read_type_0x0022(
5828
0
                encrypted_metadata,
5829
0
                metadata_block->data,
5830
0
                metadata_block->data_size,
5831
0
                error );
5832
0
            break;
5833
5834
0
          case 0x0024:
5835
0
            result = libfvde_encrypted_metadata_read_type_0x0024(
5836
0
                encrypted_metadata,
5837
0
                metadata_block->object_identifier,
5838
0
                metadata_block->data,
5839
0
                metadata_block->data_size,
5840
0
                error );
5841
0
            break;
5842
5843
0
          case 0x0025:
5844
0
            result = libfvde_encrypted_metadata_read_type_0x0025(
5845
0
                encrypted_metadata,
5846
0
                metadata_block->data,
5847
0
                metadata_block->data_size,
5848
0
                error );
5849
0
            break;
5850
5851
0
          case 0x0105:
5852
0
            result = libfvde_encrypted_metadata_read_type_0x0105(
5853
0
                encrypted_metadata,
5854
0
                metadata_block->data,
5855
0
                metadata_block->data_size,
5856
0
                error );
5857
0
            break;
5858
5859
0
          case 0x0205:
5860
0
            result = libfvde_encrypted_metadata_read_type_0x0205(
5861
0
                encrypted_metadata,
5862
0
                metadata_block->data,
5863
0
                metadata_block->data_size,
5864
0
                error );
5865
0
            break;
5866
5867
0
          case 0x0304:
5868
0
            result = libfvde_encrypted_metadata_read_type_0x0304(
5869
0
                encrypted_metadata,
5870
0
                metadata_block->data,
5871
0
                metadata_block->data_size,
5872
0
                error );
5873
0
            break;
5874
5875
0
          case 0x0305:
5876
0
            result = libfvde_encrypted_metadata_read_type_0x0305(
5877
0
                encrypted_metadata,
5878
0
                metadata_block->object_identifier,
5879
0
                metadata_block->data,
5880
0
                metadata_block->data_size,
5881
0
                error );
5882
0
            break;
5883
5884
0
          case 0x0404:
5885
0
            result = libfvde_encrypted_metadata_read_type_0x0404(
5886
0
                encrypted_metadata,
5887
0
                io_handle,
5888
0
                metadata_block->data,
5889
0
                metadata_block->data_size,
5890
0
                error );
5891
0
            break;
5892
5893
0
          case 0x0405:
5894
0
            result = libfvde_encrypted_metadata_read_type_0x0405(
5895
0
                encrypted_metadata,
5896
0
                io_handle,
5897
0
                metadata_block->data,
5898
0
                metadata_block->data_size,
5899
0
                error );
5900
0
            break;
5901
5902
0
          case 0x0505:
5903
0
            result = libfvde_encrypted_metadata_read_type_0x0505(
5904
0
                encrypted_metadata,
5905
0
                metadata_block->object_identifier,
5906
0
                metadata_block->data,
5907
0
                metadata_block->data_size,
5908
0
                error );
5909
0
            break;
5910
5911
0
          case 0x0605:
5912
0
            result = libfvde_encrypted_metadata_read_type_0x0605(
5913
0
                encrypted_metadata,
5914
0
                metadata_block->data,
5915
0
                metadata_block->data_size,
5916
0
                error );
5917
0
            break;
5918
5919
0
          default:
5920
0
            result = 0;
5921
0
            break;
5922
0
        }
5923
0
        if( result == -1 )
5924
0
        {
5925
0
          libcerror_error_set(
5926
0
           error,
5927
0
           LIBCERROR_ERROR_DOMAIN_IO,
5928
0
           LIBCERROR_IO_ERROR_READ_FAILED,
5929
0
           "%s: unable to read metadata block type 0x%04" PRIx16 ".",
5930
0
           function,
5931
0
           metadata_block->type );
5932
5933
0
          goto on_error;
5934
0
        }
5935
0
      }
5936
0
    }
5937
0
    encrypted_data_offset += 8192;
5938
5939
0
    calculated_block_number += 1;
5940
0
  }
5941
0
  if( libfvde_metadata_block_free(
5942
0
       &metadata_block,
5943
0
       error ) != 1 )
5944
0
  {
5945
0
    libcerror_error_set(
5946
0
     error,
5947
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5948
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
5949
0
     "%s: unable to free metadata block.",
5950
0
     function );
5951
5952
0
    goto on_error;
5953
0
  }
5954
0
  if( memory_set(
5955
0
       metadata_block_data,
5956
0
       0,
5957
0
       8192 ) == NULL )
5958
0
  {
5959
0
    libcerror_error_set(
5960
0
     error,
5961
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
5962
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
5963
0
     "%s: unable to clear metadata block data.",
5964
0
     function );
5965
5966
0
    goto on_error;
5967
0
  }
5968
0
  memory_free(
5969
0
   metadata_block_data );
5970
5971
0
  metadata_block_data = NULL;
5972
5973
0
  if( libfvde_encryption_context_free(
5974
0
       &encryption_context,
5975
0
       error ) != 1 )
5976
0
  {
5977
0
    libcerror_error_set(
5978
0
     error,
5979
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
5980
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
5981
0
     "%s: unable to free encryption context.",
5982
0
     function );
5983
5984
0
    goto on_error;
5985
0
  }
5986
0
  memory_free(
5987
0
   encrypted_data );
5988
5989
0
  encrypted_data = NULL;
5990
5991
0
  if( encrypted_metadata->encryption_context_plist_data != NULL )
5992
0
  {
5993
0
    result = libfvde_encryption_context_plist_set_data(
5994
0
        encrypted_metadata->encryption_context_plist,
5995
0
        encrypted_metadata->encryption_context_plist_data,
5996
0
        encrypted_metadata->encryption_context_plist_data_size,
5997
0
        error );
5998
5999
0
    if( result == -1 )
6000
0
    {
6001
0
      libcerror_error_set(
6002
0
       error,
6003
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
6004
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
6005
0
       "%s: unable to set encryption context plist data.",
6006
0
       function );
6007
6008
0
      goto on_error;
6009
0
    }
6010
0
    else if( result != 0 )
6011
0
    {
6012
0
      encrypted_metadata->encryption_context_plist_file_is_set = 1;
6013
0
    }
6014
0
  }
6015
/* TODO find com.apple.corestorage.lvf.encryption.context/WrappedVolumeKeys/?/BlockAlgorithm */
6016
0
  return( 1 );
6017
6018
0
on_error:
6019
0
  if( encrypted_metadata->compressed_data != NULL )
6020
0
  {
6021
0
    memory_free(
6022
0
     encrypted_metadata->compressed_data );
6023
6024
0
    encrypted_metadata->compressed_data = NULL;
6025
0
  }
6026
0
  if( encrypted_metadata->encryption_context_plist_data != NULL )
6027
0
  {
6028
0
    memory_free(
6029
0
     encrypted_metadata->encryption_context_plist_data );
6030
6031
0
    encrypted_metadata->encryption_context_plist_data = NULL;
6032
0
  }
6033
0
  if( encrypted_metadata->encryption_context_plist != NULL )
6034
0
  {
6035
0
    libfvde_encryption_context_plist_free(
6036
0
     &( encrypted_metadata->encryption_context_plist ),
6037
0
     NULL );
6038
6039
0
    encrypted_metadata->encryption_context_plist_file_is_set = 0;
6040
0
  }
6041
0
  if( metadata_block != NULL )
6042
0
  {
6043
0
    libfvde_metadata_block_free(
6044
0
     &metadata_block,
6045
0
     NULL );
6046
0
  }
6047
0
  if( metadata_block_data != NULL )
6048
0
  {
6049
0
    memory_set(
6050
0
     metadata_block_data,
6051
0
     0,
6052
0
     8192 );
6053
0
    memory_free(
6054
0
     metadata_block_data );
6055
0
  }
6056
0
  if( encryption_context != NULL )
6057
0
  {
6058
0
    libfvde_encryption_context_free(
6059
0
     &encryption_context,
6060
0
     NULL );
6061
0
  }
6062
0
  if( encrypted_data != NULL )
6063
0
  {
6064
0
    memory_free(
6065
0
     encrypted_data );
6066
0
  }
6067
0
  return( -1 );
6068
0
}
6069
6070
/* Retrieves the volume master key
6071
 * Returns 1 if successful, 0 in not or -1 on error
6072
 */
6073
int libfvde_encrypted_metadata_get_volume_master_key(
6074
     libfvde_encrypted_metadata_t *metadata,
6075
     libfvde_encryption_context_plist_t *encryption_context_plist,
6076
     libfvde_keyring_t *keyring,
6077
     const uint8_t *user_password,
6078
     size_t user_password_length,
6079
     const uint8_t *recovery_password,
6080
     size_t recovery_password_length,
6081
     libcerror_error_t **error )
6082
0
{
6083
0
  uint8_t passphrase_key[ 16 ];
6084
0
  uint8_t volume_key_wrapped_kek[ 24 ];
6085
0
  uint8_t volume_master_key_wrapped_kek[ 24 ];
6086
6087
0
  uint8_t *kek_wrapped_volume_key    = NULL;
6088
0
  uint8_t *passphrase_wrapped_kek    = NULL;
6089
0
  static char *function              = "libfvde_encrypted_metadata_get_volume_master_key";
6090
0
  size_t kek_wrapped_volume_key_size = 0;
6091
0
  size_t passphrase_wrapped_kek_size = 0;
6092
0
  uint32_t number_of_iterations      = 0;
6093
0
  uint32_t value_size                = 0;
6094
0
  uint32_t value_type                = 0;
6095
0
  int found_key                      = 0;
6096
0
  int passphrase_wrapped_kek_index   = 0;
6097
0
  int result                         = 0;
6098
6099
0
  if( metadata == NULL )
6100
0
  {
6101
0
    libcerror_error_set(
6102
0
     error,
6103
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6104
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6105
0
     "%s: invalid metadata.",
6106
0
     function );
6107
6108
0
    return( -1 );
6109
0
  }
6110
0
  if( encryption_context_plist == NULL )
6111
0
  {
6112
0
    libcerror_error_set(
6113
0
     error,
6114
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6115
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6116
0
     "%s: invalid encryption context plist.",
6117
0
     function );
6118
6119
0
    return( -1 );
6120
0
  }
6121
0
  if( keyring == NULL )
6122
0
  {
6123
0
    libcerror_error_set(
6124
0
     error,
6125
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6126
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6127
0
     "%s: invalid keyring.",
6128
0
     function );
6129
6130
0
    return( -1 );
6131
0
  }
6132
0
  if( ( user_password != NULL )
6133
0
   || ( recovery_password != NULL ) )
6134
0
  {
6135
0
    do
6136
0
    {
6137
0
      result = libfvde_encryption_context_plist_get_passphrase_wrapped_kek(
6138
0
                encryption_context_plist,
6139
0
                passphrase_wrapped_kek_index,
6140
0
                &passphrase_wrapped_kek,
6141
0
                &passphrase_wrapped_kek_size,
6142
0
                error );
6143
6144
0
      if( result == -1 )
6145
0
      {
6146
0
        libcerror_error_set(
6147
0
         error,
6148
0
         LIBCERROR_ERROR_DOMAIN_IO,
6149
0
         LIBCERROR_IO_ERROR_GENERIC,
6150
0
         "%s: unable to retrieve passphrase wrapped KEK: %d from encryption context plist.",
6151
0
         function,
6152
0
         passphrase_wrapped_kek_index );
6153
6154
0
        goto on_error;
6155
0
      }
6156
0
      else if( result == 0 )
6157
0
      {
6158
0
        break;
6159
0
      }
6160
0
      if( passphrase_wrapped_kek == NULL )
6161
0
      {
6162
0
        libcerror_error_set(
6163
0
         error,
6164
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
6165
0
         LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
6166
0
         "%s: missing passphrase wrapped KEK: %d.",
6167
0
         function,
6168
0
         passphrase_wrapped_kek_index );
6169
6170
0
        goto on_error;
6171
0
      }
6172
0
      if( passphrase_wrapped_kek_size != 284 )
6173
0
      {
6174
0
        libcerror_error_set(
6175
0
         error,
6176
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
6177
0
         LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
6178
0
         "%s: invalid passphrase wrapped KEK: %d size value out of bounds.",
6179
0
         function,
6180
0
         passphrase_wrapped_kek_index );
6181
6182
0
        goto on_error;
6183
0
      }
6184
0
      byte_stream_copy_to_uint32_little_endian(
6185
0
       &( passphrase_wrapped_kek[ 0 ] ),
6186
0
       value_type );
6187
6188
0
      byte_stream_copy_to_uint32_little_endian(
6189
0
       &( passphrase_wrapped_kek[ 4 ] ),
6190
0
       value_size );
6191
6192
#if defined( HAVE_DEBUG_OUTPUT )
6193
      if( libcnotify_verbose != 0 )
6194
      {
6195
        libcnotify_printf(
6196
         "%s: value type\t\t: 0x%08" PRIx32 "\n",
6197
         function,
6198
         value_type );
6199
6200
        libcnotify_printf(
6201
         "%s: value size\t\t: %" PRIu32 "\n",
6202
         function,
6203
         value_size );
6204
      }
6205
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
6206
6207
0
      if( value_type != 0x00000003UL )
6208
0
      {
6209
0
        libcerror_error_set(
6210
0
         error,
6211
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
6212
0
         LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
6213
0
         "%s: unsupported value type.",
6214
0
         function );
6215
6216
0
        goto on_error;
6217
0
      }
6218
0
      if( value_size != 16 )
6219
0
      {
6220
0
        libcerror_error_set(
6221
0
         error,
6222
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
6223
0
         LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
6224
0
         "%s: unsupported value size.",
6225
0
         function );
6226
6227
0
        goto on_error;
6228
0
      }
6229
#if defined( HAVE_DEBUG_OUTPUT )
6230
      if( libcnotify_verbose != 0 )
6231
      {
6232
        libcnotify_printf(
6233
         "%s: salt:\n",
6234
         function );
6235
        libcnotify_print_data(
6236
         &( passphrase_wrapped_kek[ 8 ] ),
6237
         value_size,
6238
         0 );
6239
      }
6240
#endif
6241
0
      byte_stream_copy_to_uint32_little_endian(
6242
0
       &( passphrase_wrapped_kek[ 168 ] ),
6243
0
       number_of_iterations );
6244
6245
#if defined( HAVE_DEBUG_OUTPUT )
6246
      if( libcnotify_verbose != 0 )
6247
      {
6248
        libcnotify_printf(
6249
         "%s: number of iterations\t: %" PRIu32 "\n",
6250
         function,
6251
         number_of_iterations );
6252
      }
6253
#endif
6254
0
      if( user_password != NULL )
6255
0
      {
6256
0
        if( libfvde_password_pbkdf2(
6257
0
             user_password,
6258
0
             user_password_length,
6259
0
             &( passphrase_wrapped_kek[ 8 ] ),
6260
0
             value_size,
6261
0
             number_of_iterations,
6262
0
             passphrase_key,
6263
0
             16,
6264
0
             error ) == -1 )
6265
0
        {
6266
0
          libcerror_error_set(
6267
0
           error,
6268
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
6269
0
           LIBCERROR_RUNTIME_ERROR_GET_FAILED,
6270
0
           "%s: unable to determine password key.",
6271
0
           function );
6272
6273
0
          goto on_error;
6274
0
        }
6275
0
      }
6276
0
      else if( recovery_password != NULL )
6277
0
      {
6278
0
        if( libfvde_password_pbkdf2(
6279
0
             recovery_password,
6280
0
             recovery_password_length,
6281
0
             &( passphrase_wrapped_kek[ 8 ] ),
6282
0
             value_size,
6283
0
             number_of_iterations,
6284
0
             passphrase_key,
6285
0
             16,
6286
0
             error ) == -1 )
6287
0
        {
6288
0
          libcerror_error_set(
6289
0
           error,
6290
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
6291
0
           LIBCERROR_RUNTIME_ERROR_GET_FAILED,
6292
0
           "%s: unable to determine recovery password key.",
6293
0
           function );
6294
6295
0
          goto on_error;
6296
0
        }
6297
0
      }
6298
#if defined( HAVE_DEBUG_OUTPUT )
6299
      if( libcnotify_verbose != 0 )
6300
      {
6301
        libcnotify_printf(
6302
         "%s: passphrase key:\n",
6303
         function );
6304
        libcnotify_print_data(
6305
         passphrase_key,
6306
         16,
6307
         0 );
6308
      }
6309
#endif
6310
0
      byte_stream_copy_to_uint32_little_endian(
6311
0
       &( passphrase_wrapped_kek[ 24 ] ),
6312
0
       value_type );
6313
6314
0
      byte_stream_copy_to_uint32_little_endian(
6315
0
       &( passphrase_wrapped_kek[ 28 ] ),
6316
0
       value_size );
6317
6318
#if defined( HAVE_DEBUG_OUTPUT )
6319
      if( libcnotify_verbose != 0 )
6320
      {
6321
        libcnotify_printf(
6322
         "%s: value type\t\t: 0x%08" PRIx32 "\n",
6323
         function,
6324
         value_type );
6325
6326
        libcnotify_printf(
6327
         "%s: value size\t\t: %" PRIu32 "\n",
6328
         function,
6329
         value_size );
6330
      }
6331
#endif
6332
0
      if( value_type != 0x00000010UL )
6333
0
      {
6334
0
        libcerror_error_set(
6335
0
         error,
6336
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
6337
0
         LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
6338
0
         "%s: unsupported value type.",
6339
0
         function );
6340
6341
0
        goto on_error;
6342
0
      }
6343
0
      if( value_size != 24 )
6344
0
      {
6345
0
        libcerror_error_set(
6346
0
         error,
6347
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
6348
0
         LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
6349
0
         "%s: unsupported value size.",
6350
0
         function );
6351
6352
0
        goto on_error;
6353
0
      }
6354
#if defined( HAVE_DEBUG_OUTPUT )
6355
      if( libcnotify_verbose != 0 )
6356
      {
6357
        libcnotify_printf(
6358
         "%s: encrypted volume key wrapped KEK:\n",
6359
         function );
6360
        libcnotify_print_data(
6361
         &( passphrase_wrapped_kek[ 32 ] ),
6362
         value_size,
6363
         0 );
6364
      }
6365
#endif
6366
0
      if( libfvde_encryption_aes_key_unwrap(
6367
0
           passphrase_key,
6368
0
           16 * 8,
6369
0
           &( passphrase_wrapped_kek[ 32 ] ),
6370
0
           value_size,
6371
0
           volume_key_wrapped_kek,
6372
0
           24,
6373
0
           error ) == -1 )
6374
0
      {
6375
0
        libcerror_error_set(
6376
0
         error,
6377
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
6378
0
         LIBCERROR_RUNTIME_ERROR_GENERIC,
6379
0
         "%s: unable to retrieve volume key wrapped KEK.",
6380
0
         function );
6381
6382
0
        goto on_error;
6383
0
      }
6384
0
      if( memory_set(
6385
0
           passphrase_key,
6386
0
           0,
6387
0
           16 ) == NULL )
6388
0
      {
6389
0
        libcerror_error_set(
6390
0
         error,
6391
0
         LIBCERROR_ERROR_DOMAIN_MEMORY,
6392
0
         LIBCERROR_MEMORY_ERROR_SET_FAILED,
6393
0
         "%s: unable to clear passphrase key.",
6394
0
         function );
6395
6396
0
        goto on_error;
6397
0
      }
6398
0
      memory_free(
6399
0
       passphrase_wrapped_kek );
6400
6401
0
      passphrase_wrapped_kek = NULL;
6402
6403
#if defined( HAVE_DEBUG_OUTPUT )
6404
      if( libcnotify_verbose != 0 )
6405
      {
6406
        libcnotify_printf(
6407
         "%s: volume key wrapped KEK:\n",
6408
         function );
6409
        libcnotify_print_data(
6410
         volume_key_wrapped_kek,
6411
         24,
6412
         0 );
6413
      }
6414
#endif
6415
0
                  if( memory_compare(
6416
0
           volume_key_wrapped_kek,
6417
0
           libfvde_encrypted_metadata_wrapped_kek_initialization_vector,
6418
0
           8 ) == 0 )
6419
0
      {
6420
#if defined( HAVE_DEBUG_OUTPUT )
6421
        if( libcnotify_verbose != 0 )
6422
        {
6423
          libcnotify_printf(
6424
           "%s: KEK wrapped volume key encryption key:\n",
6425
           function );
6426
          libcnotify_print_data(
6427
           &( volume_key_wrapped_kek[ 8 ] ),
6428
           16,
6429
           0 );
6430
        }
6431
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
6432
6433
0
        found_key = 1;
6434
6435
0
        break;
6436
0
      }
6437
0
      passphrase_wrapped_kek_index++;
6438
0
    }
6439
0
    while( result != 0 );
6440
6441
0
    if( found_key != 0 )
6442
0
    {
6443
0
      if( libfvde_encryption_context_plist_get_kek_wrapped_volume_key(
6444
0
           encryption_context_plist,
6445
0
           &kek_wrapped_volume_key,
6446
0
           &kek_wrapped_volume_key_size,
6447
0
           error ) != 1 )
6448
0
      {
6449
0
        libcerror_error_set(
6450
0
         error,
6451
0
         LIBCERROR_ERROR_DOMAIN_IO,
6452
0
         LIBCERROR_IO_ERROR_GENERIC,
6453
0
         "%s: unable to retrieve KEK wrapped volume key from encryption context plist data.",
6454
0
         function );
6455
6456
0
        goto on_error;
6457
0
      }
6458
0
      if( kek_wrapped_volume_key == NULL )
6459
0
      {
6460
0
        libcerror_error_set(
6461
0
         error,
6462
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
6463
0
         LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
6464
0
         "%s: missing KEK wrapped volume key.",
6465
0
         function );
6466
6467
0
        goto on_error;
6468
0
      }
6469
0
      if( kek_wrapped_volume_key_size != 256 )
6470
0
      {
6471
0
        libcerror_error_set(
6472
0
         error,
6473
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
6474
0
         LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
6475
0
         "%s: invalid KEK wrapped volume key size value out of bounds.",
6476
0
         function );
6477
6478
0
        goto on_error;
6479
0
      }
6480
/* TODO: again this could be improved to get size dynamically
6481
 * in case it uses larger keys
6482
 * the first 8 bytes of the KEK is the IV
6483
 */
6484
0
      if( libfvde_encryption_aes_key_unwrap(
6485
0
           &( volume_key_wrapped_kek[ 8 ] ),
6486
0
           16 * 8,
6487
0
           &( kek_wrapped_volume_key[ 8 ] ),
6488
0
           24,
6489
0
           volume_master_key_wrapped_kek,
6490
0
           24,
6491
0
           error ) == -1 )
6492
0
      {
6493
0
        libcerror_error_set(
6494
0
         error,
6495
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
6496
0
         LIBCERROR_RUNTIME_ERROR_GENERIC,
6497
0
         "%s: unable to retrieve volume master key.",
6498
0
         function );
6499
6500
0
        goto on_error;
6501
0
      }
6502
0
      if( memory_set(
6503
0
           volume_key_wrapped_kek,
6504
0
           0,
6505
0
           24 ) == NULL )
6506
0
      {
6507
0
        libcerror_error_set(
6508
0
         error,
6509
0
         LIBCERROR_ERROR_DOMAIN_MEMORY,
6510
0
         LIBCERROR_MEMORY_ERROR_SET_FAILED,
6511
0
         "%s: unable to clear volume key wrapped KEK.",
6512
0
         function );
6513
6514
0
        goto on_error;
6515
0
      }
6516
0
      memory_free(
6517
0
       kek_wrapped_volume_key );
6518
6519
0
      kek_wrapped_volume_key = NULL;
6520
6521
0
      if( memory_compare(
6522
0
           volume_master_key_wrapped_kek,
6523
0
           libfvde_encrypted_metadata_wrapped_kek_initialization_vector,
6524
0
           8 ) == 0 )
6525
0
      {
6526
#if defined( HAVE_DEBUG_OUTPUT )
6527
        if( libcnotify_verbose != 0 )
6528
        {
6529
          libcnotify_printf(
6530
           "%s: volume master key:\n",
6531
           function );
6532
          libcnotify_print_data(
6533
           volume_master_key_wrapped_kek,
6534
           24,
6535
           0 );
6536
        }
6537
#endif
6538
0
        if( memory_copy(
6539
0
             &( keyring->volume_master_key ),
6540
0
             &( volume_master_key_wrapped_kek[ 8 ] ),
6541
0
             16 ) == NULL )
6542
0
        {
6543
0
          libcerror_error_set(
6544
0
           error,
6545
0
           LIBCERROR_ERROR_DOMAIN_MEMORY,
6546
0
           LIBCERROR_MEMORY_ERROR_COPY_FAILED,
6547
0
           "%s: unable to copy volume master key from KEK.",
6548
0
           function );
6549
6550
0
          goto on_error;
6551
0
        }
6552
0
      }
6553
0
      if( memory_set(
6554
0
           volume_master_key_wrapped_kek,
6555
0
           0,
6556
0
           24 ) == NULL )
6557
0
      {
6558
0
        libcerror_error_set(
6559
0
         error,
6560
0
         LIBCERROR_ERROR_DOMAIN_MEMORY,
6561
0
         LIBCERROR_MEMORY_ERROR_SET_FAILED,
6562
0
         "%s: unable to clear volume master key wrapped KEK.",
6563
0
         function );
6564
6565
0
        goto on_error;
6566
0
      }
6567
0
    }
6568
0
  }
6569
0
  return( found_key );
6570
6571
0
on_error:
6572
0
  if( kek_wrapped_volume_key != NULL )
6573
0
  {
6574
0
    memory_free(
6575
0
     kek_wrapped_volume_key );
6576
0
  }
6577
0
  if( passphrase_wrapped_kek != NULL )
6578
0
  {
6579
0
    memory_free(
6580
0
     passphrase_wrapped_kek );
6581
0
  }
6582
0
  memory_set(
6583
0
   volume_master_key_wrapped_kek,
6584
0
   0,
6585
0
   24 );
6586
6587
0
  memory_set(
6588
0
   volume_key_wrapped_kek,
6589
0
   0,
6590
0
   24 );
6591
6592
0
  memory_set(
6593
0
   passphrase_key,
6594
0
   0,
6595
0
   16 );
6596
6597
0
  return( -1 );
6598
0
}
6599
6600
/* Retrieves the number of logical volume descriptors
6601
 * Returns 1 if successful or -1 on error
6602
 */
6603
int libfvde_encrypted_metadata_get_number_of_logical_volume_descriptors(
6604
     libfvde_encrypted_metadata_t *encrypted_metadata,
6605
     int *number_of_logical_volume_descriptors,
6606
     libcerror_error_t **error )
6607
0
{
6608
0
  static char *function = "libfvde_encrypted_metadata_get_number_of_logical_volume_descriptors";
6609
6610
0
  if( encrypted_metadata == NULL )
6611
0
  {
6612
0
    libcerror_error_set(
6613
0
     error,
6614
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6615
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6616
0
     "%s: invalid encrypted metadata.",
6617
0
     function );
6618
6619
0
    return( -1 );
6620
0
  }
6621
0
  if( libcdata_array_get_number_of_entries(
6622
0
       encrypted_metadata->logical_volume_descriptors,
6623
0
       number_of_logical_volume_descriptors,
6624
0
       error ) != 1 )
6625
0
  {
6626
0
    libcerror_error_set(
6627
0
     error,
6628
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6629
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
6630
0
     "%s: unable to retrieve number of logical volume descriptors.",
6631
0
     function );
6632
6633
0
    return( -1 );
6634
0
  }
6635
0
  return( 1 );
6636
0
}
6637
6638
/* Retrieves a specific logical volume descriptor
6639
 * Returns 1 if successful or -1 on error
6640
 */
6641
int libfvde_encrypted_metadata_get_logical_volume_descriptor_by_index(
6642
     libfvde_encrypted_metadata_t *encrypted_metadata,
6643
     int logical_volume_descriptor_index,
6644
     libfvde_logical_volume_descriptor_t **logical_volume_descriptor,
6645
     libcerror_error_t **error )
6646
0
{
6647
0
  static char *function = "libfvde_encrypted_metadata_get_logical_volume_descriptor_by_index";
6648
6649
0
  if( encrypted_metadata == NULL )
6650
0
  {
6651
0
    libcerror_error_set(
6652
0
     error,
6653
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6654
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6655
0
     "%s: invalid encrypted metadata.",
6656
0
     function );
6657
6658
0
    return( -1 );
6659
0
  }
6660
0
  if( libcdata_array_get_entry_by_index(
6661
0
       encrypted_metadata->logical_volume_descriptors,
6662
0
       logical_volume_descriptor_index,
6663
0
       (intptr_t **) logical_volume_descriptor,
6664
0
       error ) != 1 )
6665
0
  {
6666
0
    libcerror_error_set(
6667
0
     error,
6668
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6669
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
6670
0
     "%s: unable to retrieve logical volume descriptor: %d.",
6671
0
     function,
6672
0
     logical_volume_descriptor_index );
6673
6674
0
    return( -1 );
6675
0
  }
6676
0
  return( 1 );
6677
0
}
6678
6679
/* Retrieves the logical volume descriptor with a specific object identifier
6680
 * Returns 1 if successful, 0 if no such volume desciptor or -1 on error
6681
 */
6682
int libfvde_encrypted_metadata_get_logical_volume_descriptor_by_object_identifier(
6683
     libfvde_encrypted_metadata_t *encrypted_metadata,
6684
     uint64_t object_identifier,
6685
     libfvde_logical_volume_descriptor_t **logical_volume_descriptor,
6686
     libcerror_error_t **error )
6687
0
{
6688
0
  libfvde_logical_volume_descriptor_t *safe_logical_volume_descriptor = NULL;
6689
0
  static char *function                                               = "libfvde_encrypted_metadata_get_logical_volume_descriptor_by_object_identifier";
6690
0
  int logical_volume_descriptor_index                                 = 0;
6691
0
  int number_of_logical_volume_descriptors                            = 0;
6692
6693
0
  if( encrypted_metadata == NULL )
6694
0
  {
6695
0
    libcerror_error_set(
6696
0
     error,
6697
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6698
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6699
0
     "%s: invalid encrypted metadata.",
6700
0
     function );
6701
6702
0
    return( -1 );
6703
0
  }
6704
0
  if( logical_volume_descriptor == NULL )
6705
0
  {
6706
0
    libcerror_error_set(
6707
0
     error,
6708
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6709
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6710
0
     "%s: invalid logical volume descriptor.",
6711
0
     function );
6712
6713
0
    return( -1 );
6714
0
  }
6715
0
  if( libcdata_array_get_number_of_entries(
6716
0
       encrypted_metadata->logical_volume_descriptors,
6717
0
       &number_of_logical_volume_descriptors,
6718
0
       error ) != 1 )
6719
0
  {
6720
0
    libcerror_error_set(
6721
0
     error,
6722
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6723
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
6724
0
     "%s: unable to retrieve number of logical volume descriptors.",
6725
0
     function );
6726
6727
0
    return( -1 );
6728
0
  }
6729
  /* Start with the last logical volume descriptor since most of the time
6730
   * we want to find the most recent one
6731
   */
6732
0
  for( logical_volume_descriptor_index = number_of_logical_volume_descriptors - 1;
6733
0
       logical_volume_descriptor_index >= 0;
6734
0
       logical_volume_descriptor_index-- )
6735
0
  {
6736
0
    if( libcdata_array_get_entry_by_index(
6737
0
         encrypted_metadata->logical_volume_descriptors,
6738
0
         logical_volume_descriptor_index,
6739
0
         (intptr_t **) &safe_logical_volume_descriptor,
6740
0
         error ) != 1 )
6741
0
    {
6742
0
      libcerror_error_set(
6743
0
       error,
6744
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
6745
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
6746
0
       "%s: unable to retrieve logical volume descriptor: %d from array.",
6747
0
       function,
6748
0
       logical_volume_descriptor_index );
6749
6750
0
      return( -1 );
6751
0
    }
6752
0
    if( safe_logical_volume_descriptor == NULL )
6753
0
    {
6754
0
      libcerror_error_set(
6755
0
       error,
6756
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
6757
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
6758
0
       "%s: missing logical volume descriptor: %d.",
6759
0
       function,
6760
0
       logical_volume_descriptor_index );
6761
6762
0
      return( -1 );
6763
0
    }
6764
0
    if( safe_logical_volume_descriptor->object_identifier == object_identifier )
6765
0
    {
6766
0
      *logical_volume_descriptor = safe_logical_volume_descriptor;
6767
6768
0
      return( 1 );
6769
0
    }
6770
0
  }
6771
0
  return( 0 );
6772
0
}
6773
6774
/* Retrieves the last logical volume descriptor
6775
 * Returns 1 if successful, 0 if no such volume desciptor or -1 on error
6776
 */
6777
int libfvde_encrypted_metadata_get_last_logical_volume_descriptor(
6778
     libfvde_encrypted_metadata_t *encrypted_metadata,
6779
     libfvde_logical_volume_descriptor_t **logical_volume_descriptor,
6780
     libcerror_error_t **error )
6781
0
{
6782
0
  static char *function                    = "libfvde_encrypted_metadata_get_last_logical_volume_descriptor";
6783
0
  int number_of_logical_volume_descriptors = 0;
6784
6785
0
  if( encrypted_metadata == NULL )
6786
0
  {
6787
0
    libcerror_error_set(
6788
0
     error,
6789
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6790
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6791
0
     "%s: invalid encrypted metadata.",
6792
0
     function );
6793
6794
0
    return( -1 );
6795
0
  }
6796
0
  if( logical_volume_descriptor == NULL )
6797
0
  {
6798
0
    libcerror_error_set(
6799
0
     error,
6800
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
6801
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
6802
0
     "%s: invalid logical volume descriptor.",
6803
0
     function );
6804
6805
0
    return( -1 );
6806
0
  }
6807
0
  if( libcdata_array_get_number_of_entries(
6808
0
       encrypted_metadata->logical_volume_descriptors,
6809
0
       &number_of_logical_volume_descriptors,
6810
0
       error ) != 1 )
6811
0
  {
6812
0
    libcerror_error_set(
6813
0
     error,
6814
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6815
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
6816
0
     "%s: unable to retrieve number of logical volume descriptors.",
6817
0
     function );
6818
6819
0
    return( -1 );
6820
0
  }
6821
0
  if( number_of_logical_volume_descriptors == 0 )
6822
0
  {
6823
0
    return( 0 );
6824
0
  }
6825
0
  if( libcdata_array_get_entry_by_index(
6826
0
       encrypted_metadata->logical_volume_descriptors,
6827
0
       number_of_logical_volume_descriptors - 1,
6828
0
       (intptr_t **) logical_volume_descriptor,
6829
0
       error ) != 1 )
6830
0
  {
6831
0
    libcerror_error_set(
6832
0
     error,
6833
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
6834
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
6835
0
     "%s: unable to retrieve logical volume descriptor: %d from array.",
6836
0
     function,
6837
0
     number_of_logical_volume_descriptors - 1 );
6838
6839
0
    return( -1 );
6840
0
  }
6841
0
  return( 1 );
6842
0
}
6843