Coverage Report

Created: 2026-07-25 07:30

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