Coverage Report

Created: 2025-10-14 07:00

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-2024, Omar Choudary <choudary.omar@gmail.com>,
5
 *                          Joachim Metz <joachim.metz@gmail.com>
6
 *
7
 * Refer to AUTHORS for acknowledgements.
8
 *
9
 * This program is free software: you can redistribute it and/or modify
10
 * it under the terms of the GNU Lesser General Public License as published by
11
 * the Free Software Foundation, either version 3 of the License, or
12
 * (at your option) any later version.
13
 *
14
 * This program is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 * GNU General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU Lesser General Public License
20
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
21
 */
22
23
#include <common.h>
24
#include <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
    result = -1;
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
  uint32_t block_size       = 0;
968
0
  uint32_t number_of_blocks = 0;
969
0
  uint16_t volume_signature = 0;
970
0
  int result                = 0;
971
972
0
  if( internal_logical_volume == NULL )
973
0
  {
974
0
    libcerror_error_set(
975
0
     error,
976
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
977
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
978
0
     "%s: invalid logical volume.",
979
0
     function );
980
981
0
    return( -1 );
982
0
  }
983
0
  if( data == NULL )
984
0
  {
985
0
    libcerror_error_set(
986
0
     error,
987
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
988
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
989
0
     "%s: invalid data.",
990
0
     function );
991
992
0
    return( -1 );
993
0
  }
994
0
  if( ( data_size < 512 )
995
0
   || ( data_size > (size_t) SSIZE_MAX ) )
996
0
  {
997
0
    libcerror_error_set(
998
0
     error,
999
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1000
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
1001
0
     "%s: invalid data size value out of bounds.",
1002
0
     function );
1003
1004
0
    return( -1 );
1005
0
  }
1006
0
  byte_stream_copy_to_uint16_big_endian(
1007
0
   data,
1008
0
   volume_signature );
1009
1010
0
  if( ( volume_signature == 0x482b )
1011
0
   || ( volume_signature == 0x4858 ) )
1012
0
  {
1013
0
    byte_stream_copy_to_uint32_big_endian(
1014
0
     &( data[ 40 ] ),
1015
0
     block_size );
1016
1017
0
    byte_stream_copy_to_uint32_big_endian(
1018
0
     &( data[ 44 ] ),
1019
0
     number_of_blocks );
1020
1021
#if defined( HAVE_DEBUG_OUTPUT )
1022
    if( libcnotify_verbose != 0 )
1023
    {
1024
      libcnotify_printf(
1025
       "%s: block size\t\t: %" PRIu32 "\n",
1026
       function,
1027
       block_size );
1028
1029
      libcnotify_printf(
1030
       "%s: number of blocks\t\t: %" PRIu32 "\n",
1031
       function,
1032
       number_of_blocks );
1033
1034
      libcnotify_printf(
1035
       "\n" );
1036
    }
1037
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
1038
1039
0
    result = 1;
1040
0
  }
1041
0
  return( result );
1042
0
}
1043
1044
/* Reads the logical volume header
1045
 * Returns 1 if successful, 0 if not or -1 on error
1046
 */
1047
int libfvde_internal_logical_volume_open_read_volume_header(
1048
     libfvde_internal_logical_volume_t *internal_logical_volume,
1049
     libbfio_pool_t *file_io_pool,
1050
     int file_io_pool_entry,
1051
     off64_t file_offset,
1052
     libcerror_error_t **error )
1053
0
{
1054
0
  libfvde_sector_data_t *sector_data = NULL;
1055
0
  static char *function              = "libfvde_internal_logical_volume_open_read_volume_header";
1056
0
  uint64_t block_number              = 0;
1057
0
  int result                         = 0;
1058
1059
0
  if( internal_logical_volume == NULL )
1060
0
  {
1061
0
    libcerror_error_set(
1062
0
     error,
1063
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1064
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1065
0
     "%s: invalid logical volume.",
1066
0
     function );
1067
1068
0
    return( -1 );
1069
0
  }
1070
0
  if( internal_logical_volume->io_handle == NULL )
1071
0
  {
1072
0
    libcerror_error_set(
1073
0
     error,
1074
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1075
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1076
0
     "%s: invalid logical volume - missing IO handle.",
1077
0
     function );
1078
1079
0
    return( -1 );
1080
0
  }
1081
0
  if( internal_logical_volume->volume_data_handle == NULL )
1082
0
  {
1083
0
    libcerror_error_set(
1084
0
     error,
1085
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1086
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1087
0
     "%s: invalid logical volume - missing volume data handle.",
1088
0
     function );
1089
1090
0
    return( -1 );
1091
0
  }
1092
#if defined( HAVE_DEBUG_OUTPUT )
1093
  if( libcnotify_verbose != 0 )
1094
  {
1095
    libcnotify_printf(
1096
     "%s: reading logical volume header at offset: %" PRIi64 " (0x%08" PRIx64 ")\n",
1097
     function,
1098
     file_offset,
1099
     file_offset );
1100
  }
1101
#endif
1102
0
  if( libfvde_sector_data_initialize(
1103
0
       &sector_data,
1104
0
       (size_t) internal_logical_volume->io_handle->bytes_per_sector,
1105
0
       error ) != 1 )
1106
0
  {
1107
0
    libcerror_error_set(
1108
0
     error,
1109
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1110
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1111
0
     "%s: unable to create sector data.",
1112
0
     function );
1113
1114
0
    goto on_error;
1115
0
  }
1116
0
  block_number = (uint64_t) ( file_offset - internal_logical_volume->volume_data_handle->logical_volume_offset ) / internal_logical_volume->io_handle->bytes_per_sector;
1117
1118
0
  if( libfvde_sector_data_read(
1119
0
       sector_data,
1120
0
       internal_logical_volume->volume_data_handle->encryption_context,
1121
0
       file_io_pool,
1122
0
       file_io_pool_entry,
1123
0
       file_offset,
1124
0
       block_number,
1125
0
       internal_logical_volume->volume_data_handle->is_encrypted,
1126
0
       error ) != 1 )
1127
0
  {
1128
0
    libcerror_error_set(
1129
0
     error,
1130
0
     LIBCERROR_ERROR_DOMAIN_IO,
1131
0
     LIBCERROR_IO_ERROR_READ_FAILED,
1132
0
     "%s: unable to read volume header sector data.",
1133
0
     function );
1134
1135
0
    goto on_error;
1136
0
  }
1137
0
  result = libfvde_internal_logical_volume_open_read_volume_header_data(
1138
0
            internal_logical_volume,
1139
0
            sector_data->data,
1140
0
            sector_data->data_size,
1141
0
            error );
1142
1143
0
  if( result == -1 )
1144
0
  {
1145
0
    libcerror_error_set(
1146
0
     error,
1147
0
     LIBCERROR_ERROR_DOMAIN_IO,
1148
0
     LIBCERROR_IO_ERROR_READ_FAILED,
1149
0
     "%s: unable to read volume header.",
1150
0
     function );
1151
1152
0
    goto on_error;
1153
0
  }
1154
0
  if( libfvde_sector_data_free(
1155
0
       &sector_data,
1156
0
       error ) != 1 )
1157
0
  {
1158
0
    libcerror_error_set(
1159
0
     error,
1160
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1161
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1162
0
     "%s: unable to free sector data.",
1163
0
     function );
1164
1165
0
    goto on_error;
1166
0
  }
1167
0
  return( result );
1168
1169
0
on_error:
1170
0
  if( sector_data != NULL )
1171
0
  {
1172
0
    libfvde_sector_data_free(
1173
0
     &sector_data,
1174
0
     NULL );
1175
0
  }
1176
0
  return( -1 );
1177
0
}
1178
1179
/* Closes a logical volume
1180
 * Returns 0 if successful or -1 on error
1181
 */
1182
int libfvde_internal_logical_volume_close(
1183
     libfvde_internal_logical_volume_t *internal_logical_volume,
1184
     libcerror_error_t **error )
1185
0
{
1186
0
  static char *function = "libfvde_internal_logical_volume_close";
1187
0
  int result            = 0;
1188
1189
0
  if( internal_logical_volume == NULL )
1190
0
  {
1191
0
    libcerror_error_set(
1192
0
     error,
1193
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1194
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1195
0
     "%s: invalid logical volume.",
1196
0
     function );
1197
1198
0
    return( -1 );
1199
0
  }
1200
0
  internal_logical_volume->current_offset = 0;
1201
0
  internal_logical_volume->is_locked      = 1;
1202
1203
0
  if( internal_logical_volume->user_password != NULL )
1204
0
  {
1205
0
    if( memory_set(
1206
0
         internal_logical_volume->user_password,
1207
0
         0,
1208
0
         internal_logical_volume->user_password_size ) == NULL )
1209
0
    {
1210
0
      libcerror_error_set(
1211
0
       error,
1212
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
1213
0
       LIBCERROR_MEMORY_ERROR_SET_FAILED,
1214
0
       "%s: unable to clear user password.",
1215
0
       function );
1216
1217
0
      result = -1;
1218
0
    }
1219
0
    memory_free(
1220
0
     internal_logical_volume->user_password );
1221
1222
0
    internal_logical_volume->user_password      = NULL;
1223
0
    internal_logical_volume->user_password_size = 0;
1224
0
  }
1225
0
  if( internal_logical_volume->recovery_password != NULL )
1226
0
  {
1227
0
    if( memory_set(
1228
0
         internal_logical_volume->recovery_password,
1229
0
         0,
1230
0
         internal_logical_volume->recovery_password_size ) == NULL )
1231
0
    {
1232
0
      libcerror_error_set(
1233
0
       error,
1234
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
1235
0
       LIBCERROR_MEMORY_ERROR_SET_FAILED,
1236
0
       "%s: unable to clear recovery password.",
1237
0
       function );
1238
1239
0
      result = -1;
1240
0
    }
1241
0
    memory_free(
1242
0
     internal_logical_volume->recovery_password );
1243
1244
0
    internal_logical_volume->recovery_password      = NULL;
1245
0
    internal_logical_volume->recovery_password_size = 0;
1246
0
  }
1247
0
  if( internal_logical_volume->volume_data_handle != NULL )
1248
0
  {
1249
0
    if( libfvde_volume_data_handle_free(
1250
0
         &( internal_logical_volume->volume_data_handle ),
1251
0
         error ) != 1 )
1252
0
    {
1253
0
      libcerror_error_set(
1254
0
       error,
1255
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1256
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1257
0
       "%s: unable to free volume data handle.",
1258
0
       function );
1259
1260
0
      result = -1;
1261
0
    }
1262
0
  }
1263
0
  if( internal_logical_volume->sectors_vector != NULL )
1264
0
  {
1265
0
    if( libfdata_vector_free(
1266
0
         &( internal_logical_volume->sectors_vector ),
1267
0
         error ) != 1 )
1268
0
    {
1269
0
      libcerror_error_set(
1270
0
       error,
1271
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1272
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1273
0
       "%s: unable to free sectors vector.",
1274
0
       function );
1275
1276
0
      result = -1;
1277
0
    }
1278
0
  }
1279
0
  if( internal_logical_volume->sectors_cache != NULL )
1280
0
  {
1281
0
    if( libfcache_cache_free(
1282
0
         &( internal_logical_volume->sectors_cache ),
1283
0
         error ) != 1 )
1284
0
    {
1285
0
      libcerror_error_set(
1286
0
       error,
1287
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1288
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1289
0
       "%s: unable to free sectors cache.",
1290
0
       function );
1291
1292
0
      result = -1;
1293
0
    }
1294
0
  }
1295
0
  return( result );
1296
0
}
1297
1298
/* Unlocks the logical volume
1299
 * Returns 1 if the volume is unlocked, 0 if not or -1 on error
1300
 */
1301
int libfvde_internal_logical_volume_unlock(
1302
     libfvde_internal_logical_volume_t *internal_logical_volume,
1303
     libbfio_pool_t *file_io_pool,
1304
     libcerror_error_t **error )
1305
0
{
1306
0
  static char *function  = "libfvde_internal_logical_volume_unlock";
1307
0
  off64_t volume_offset  = 0;
1308
0
  int file_io_pool_entry = 0;
1309
0
  int result             = 0;
1310
1311
0
  if( internal_logical_volume == NULL )
1312
0
  {
1313
0
    libcerror_error_set(
1314
0
     error,
1315
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1316
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1317
0
     "%s: invalid logical volume.",
1318
0
     function );
1319
1320
0
    return( -1 );
1321
0
  }
1322
0
  if( internal_logical_volume->io_handle == NULL )
1323
0
  {
1324
0
    libcerror_error_set(
1325
0
     error,
1326
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1327
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1328
0
     "%s: invalid logical volume - missing IO handle.",
1329
0
     function );
1330
1331
0
    return( -1 );
1332
0
  }
1333
0
  result = libfvde_internal_logical_volume_open_read_keys(
1334
0
      internal_logical_volume,
1335
0
      error );
1336
1337
0
  if( result == -1 )
1338
0
  {
1339
0
    libcerror_error_set(
1340
0
     error,
1341
0
     LIBCERROR_ERROR_DOMAIN_IO,
1342
0
     LIBCERROR_IO_ERROR_READ_FAILED,
1343
0
     "%s: unable to read keys.",
1344
0
     function );
1345
1346
0
    return( -1 );
1347
0
  }
1348
0
  else if( result != 0 )
1349
0
  {
1350
0
    if( libfvde_logical_volume_descriptor_get_first_block_number(
1351
0
         internal_logical_volume->logical_volume_descriptor,
1352
0
         (uint16_t *) &file_io_pool_entry,
1353
0
         (uint64_t *) &volume_offset,
1354
0
         error ) == -1 )
1355
0
    {
1356
0
      libcerror_error_set(
1357
0
       error,
1358
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1359
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1360
0
       "%s: unable to retrieve first block number from logical volume descriptor.",
1361
0
       function );
1362
1363
0
      return( -1 );
1364
0
    }
1365
0
    volume_offset *= internal_logical_volume->io_handle->block_size;
1366
1367
#if defined( HAVE_DEBUG_OUTPUT )
1368
    if( libcnotify_verbose != 0 )
1369
    {
1370
      libcnotify_printf(
1371
       "Reading logical volume header at offset: %" PRIi64 " (0x%08" PRIx64 "):\n",
1372
       volume_offset + 1024,
1373
       volume_offset + 1024 );
1374
    }
1375
#endif
1376
0
    result = libfvde_internal_logical_volume_open_read_volume_header(
1377
0
        internal_logical_volume,
1378
0
        file_io_pool,
1379
0
        file_io_pool_entry,
1380
0
        volume_offset + 1024,
1381
0
        error );
1382
1383
0
    if( result == -1 )
1384
0
    {
1385
0
      libcerror_error_set(
1386
0
       error,
1387
0
       LIBCERROR_ERROR_DOMAIN_IO,
1388
0
       LIBCERROR_IO_ERROR_READ_FAILED,
1389
0
       "%s: unable to read logical volume header.",
1390
0
       function );
1391
1392
0
      return( -1 );
1393
0
    }
1394
0
    else if( result != 0 )
1395
0
    {
1396
0
      internal_logical_volume->is_locked = 0;
1397
0
    }
1398
0
  }
1399
0
  return( result );
1400
0
}
1401
1402
/* Unlocks the logical volume
1403
 * Returns 1 if the volume is unlocked, 0 if not or -1 on error
1404
 */
1405
int libfvde_logical_volume_unlock(
1406
     libfvde_logical_volume_t *logical_volume,
1407
     libcerror_error_t **error )
1408
0
{
1409
0
  libfvde_internal_logical_volume_t *internal_logical_volume = NULL;
1410
0
  static char *function                                      = "libfvde_logical_volume_unlock";
1411
0
  int result                                                 = 1;
1412
1413
0
  if( logical_volume == NULL )
1414
0
  {
1415
0
    libcerror_error_set(
1416
0
     error,
1417
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1418
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1419
0
     "%s: invalid logical volume.",
1420
0
     function );
1421
1422
0
    return( -1 );
1423
0
  }
1424
0
  internal_logical_volume = (libfvde_internal_logical_volume_t *) logical_volume;
1425
1426
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
1427
0
  if( libcthreads_read_write_lock_grab_for_write(
1428
0
       internal_logical_volume->read_write_lock,
1429
0
       error ) != 1 )
1430
0
  {
1431
0
    libcerror_error_set(
1432
0
     error,
1433
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1434
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1435
0
     "%s: unable to grab read/write lock for writing.",
1436
0
     function );
1437
1438
0
    return( -1 );
1439
0
  }
1440
0
#endif
1441
0
  if( internal_logical_volume->is_locked != 0 )
1442
0
  {
1443
0
    result = libfvde_internal_logical_volume_unlock(
1444
0
              internal_logical_volume,
1445
0
              internal_logical_volume->file_io_pool,
1446
0
              error );
1447
1448
0
    if( result == -1 )
1449
0
    {
1450
0
      libcerror_error_set(
1451
0
       error,
1452
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1453
0
       LIBCERROR_RUNTIME_ERROR_GENERIC,
1454
0
       "%s: unable to unlock logical volume.",
1455
0
       function );
1456
1457
0
      result = -1;
1458
0
    }
1459
0
  }
1460
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
1461
0
  if( libcthreads_read_write_lock_release_for_write(
1462
0
       internal_logical_volume->read_write_lock,
1463
0
       error ) != 1 )
1464
0
  {
1465
0
    libcerror_error_set(
1466
0
     error,
1467
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1468
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1469
0
     "%s: unable to release read/write lock for writing.",
1470
0
     function );
1471
1472
0
    return( -1 );
1473
0
  }
1474
0
#endif
1475
0
  return( result );
1476
0
}
1477
1478
/* Reads data from the last current into a buffer using a Basic File IO (bfio) pool
1479
 * This function is not multi-thread safe acquire write lock before call
1480
 * Returns the number of bytes read or -1 on error
1481
 */
1482
ssize_t libfvde_internal_logical_volume_read_buffer_from_file_io_pool(
1483
         libfvde_internal_logical_volume_t *internal_logical_volume,
1484
         libbfio_pool_t *file_io_pool,
1485
         void *buffer,
1486
         size_t buffer_size,
1487
         libcerror_error_t **error )
1488
0
{
1489
0
  libfvde_sector_data_t *sector_data = NULL;
1490
0
  static char *function              = "libfvde_internal_logical_volume_read_buffer_from_file_io_pool";
1491
0
  off64_t element_data_offset        = 0;
1492
0
  size_t buffer_offset               = 0;
1493
0
  size_t read_size                   = 0;
1494
0
  size_t sector_data_offset          = 0;
1495
1496
0
  if( internal_logical_volume == NULL )
1497
0
  {
1498
0
    libcerror_error_set(
1499
0
     error,
1500
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1501
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1502
0
     "%s: invalid logical volume.",
1503
0
     function );
1504
1505
0
    return( -1 );
1506
0
  }
1507
0
  if( internal_logical_volume->io_handle == NULL )
1508
0
  {
1509
0
    libcerror_error_set(
1510
0
     error,
1511
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1512
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1513
0
     "%s: invalid logical volume - missing IO handle.",
1514
0
     function );
1515
1516
0
    return( -1 );
1517
0
  }
1518
0
  if( internal_logical_volume->logical_volume_descriptor == NULL )
1519
0
  {
1520
0
    libcerror_error_set(
1521
0
     error,
1522
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1523
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1524
0
     "%s: invalid logical volume - missing logical volume descriptor.",
1525
0
     function );
1526
1527
0
    return( -1 );
1528
0
  }
1529
0
  if( internal_logical_volume->current_offset < 0 )
1530
0
  {
1531
0
    libcerror_error_set(
1532
0
     error,
1533
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1534
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1535
0
     "%s: invalid logical volume - current offset value out of bounds.",
1536
0
     function );
1537
1538
0
    return( -1 );
1539
0
  }
1540
0
  if( internal_logical_volume->is_locked != 0 )
1541
0
  {
1542
0
    libcerror_error_set(
1543
0
     error,
1544
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1545
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1546
0
     "%s: invalid logical volume - volume is locked.",
1547
0
     function );
1548
1549
0
    return( -1 );
1550
0
  }
1551
0
  if( buffer == NULL )
1552
0
  {
1553
0
    libcerror_error_set(
1554
0
     error,
1555
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1556
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1557
0
     "%s: invalid buffer.",
1558
0
     function );
1559
1560
0
    return( -1 );
1561
0
  }
1562
0
  if( buffer_size > (size_t) SSIZE_MAX )
1563
0
  {
1564
0
    libcerror_error_set(
1565
0
     error,
1566
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1567
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
1568
0
     "%s: invalid buffer size value exceeds maximum.",
1569
0
     function );
1570
1571
0
    return( -1 );
1572
0
  }
1573
0
  internal_logical_volume->io_handle->abort = 0;
1574
1575
0
  if( (size64_t) internal_logical_volume->current_offset >= internal_logical_volume->logical_volume_descriptor->size )
1576
0
  {
1577
0
    return( 0 );
1578
0
  }
1579
0
  if( (size64_t) buffer_size > ( internal_logical_volume->logical_volume_descriptor->size - internal_logical_volume->current_offset ) )
1580
0
  {
1581
0
    buffer_size = (size_t) ( internal_logical_volume->logical_volume_descriptor->size - internal_logical_volume->current_offset );
1582
0
  }
1583
0
  sector_data_offset = (size_t) ( internal_logical_volume->current_offset % internal_logical_volume->io_handle->bytes_per_sector );
1584
1585
0
  while( buffer_offset < buffer_size )
1586
0
  {
1587
0
    if( libfdata_vector_get_element_value_at_offset(
1588
0
         internal_logical_volume->sectors_vector,
1589
0
         (intptr_t *) file_io_pool,
1590
0
         (libfdata_cache_t *) internal_logical_volume->sectors_cache,
1591
0
         internal_logical_volume->current_offset,
1592
0
         &element_data_offset,
1593
0
         (intptr_t **) &sector_data,
1594
0
         0,
1595
0
         error ) != 1 )
1596
0
    {
1597
0
      libcerror_error_set(
1598
0
       error,
1599
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1600
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1601
0
       "%s: unable to retrieve sector data at offset: %" PRIi64 " (0x%08 " PRIx64 ").",
1602
0
       function,
1603
0
       internal_logical_volume->current_offset,
1604
0
       internal_logical_volume->current_offset );
1605
1606
0
      return( -1 );
1607
0
    }
1608
0
    if( sector_data == NULL )
1609
0
    {
1610
0
      libcerror_error_set(
1611
0
       error,
1612
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1613
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1614
0
       "%s: missing sector data at offset: %" PRIi64 " (0x%08 " PRIx64 ").",
1615
0
       function,
1616
0
       internal_logical_volume->current_offset,
1617
0
       internal_logical_volume->current_offset );
1618
1619
0
      return( -1 );
1620
0
    }
1621
0
    read_size = sector_data->data_size - sector_data_offset;
1622
1623
0
    if( read_size > ( buffer_size - buffer_offset ) )
1624
0
    {
1625
0
      read_size = buffer_size - buffer_offset;
1626
0
    }
1627
0
    if( read_size == 0 )
1628
0
    {
1629
0
      break;
1630
0
    }
1631
0
    if( memory_copy(
1632
0
         &( ( (uint8_t *) buffer )[ buffer_offset ] ),
1633
0
         &( ( sector_data->data )[ sector_data_offset ] ),
1634
0
         read_size ) == NULL )
1635
0
    {
1636
0
      libcerror_error_set(
1637
0
       error,
1638
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
1639
0
       LIBCERROR_MEMORY_ERROR_COPY_FAILED,
1640
0
       "%s: unable to copy sector data to buffer.",
1641
0
       function );
1642
1643
0
      return( -1 );
1644
0
    }
1645
0
    buffer_offset     += read_size;
1646
0
    sector_data_offset = 0;
1647
1648
0
    internal_logical_volume->current_offset += (off64_t) read_size;
1649
1650
0
    if( (size64_t) internal_logical_volume->current_offset >= internal_logical_volume->logical_volume_descriptor->size )
1651
0
    {
1652
0
      break;
1653
0
    }
1654
0
    if( internal_logical_volume->io_handle->abort != 0 )
1655
0
    {
1656
0
      break;
1657
0
    }
1658
0
  }
1659
0
  return( (ssize_t) buffer_offset );
1660
0
}
1661
1662
/* Reads data at the current offset into a buffer
1663
 * Returns the number of bytes read or -1 on error
1664
 */
1665
ssize_t libfvde_logical_volume_read_buffer(
1666
         libfvde_logical_volume_t *logical_volume,
1667
         void *buffer,
1668
         size_t buffer_size,
1669
         libcerror_error_t **error )
1670
0
{
1671
0
  libfvde_internal_logical_volume_t *internal_logical_volume = NULL;
1672
0
  static char *function                                      = "libfvde_logical_volume_read_buffer";
1673
0
  ssize_t read_count                                         = 0;
1674
1675
0
  if( logical_volume == NULL )
1676
0
  {
1677
0
    libcerror_error_set(
1678
0
     error,
1679
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1680
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1681
0
     "%s: invalid logical volume.",
1682
0
     function );
1683
1684
0
    return( -1 );
1685
0
  }
1686
0
  internal_logical_volume = (libfvde_internal_logical_volume_t *) logical_volume;
1687
1688
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
1689
0
  if( libcthreads_read_write_lock_grab_for_write(
1690
0
       internal_logical_volume->read_write_lock,
1691
0
       error ) != 1 )
1692
0
  {
1693
0
    libcerror_error_set(
1694
0
     error,
1695
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1696
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1697
0
     "%s: unable to grab read/write lock for writing.",
1698
0
     function );
1699
1700
0
    return( -1 );
1701
0
  }
1702
0
#endif
1703
0
  read_count = libfvde_internal_logical_volume_read_buffer_from_file_io_pool(
1704
0
          internal_logical_volume,
1705
0
          internal_logical_volume->file_io_pool,
1706
0
          buffer,
1707
0
          buffer_size,
1708
0
          error );
1709
1710
0
  if( read_count == -1 )
1711
0
  {
1712
0
    libcerror_error_set(
1713
0
     error,
1714
0
     LIBCERROR_ERROR_DOMAIN_IO,
1715
0
     LIBCERROR_IO_ERROR_READ_FAILED,
1716
0
     "%s: unable to read buffer.",
1717
0
     function );
1718
1719
0
    read_count = -1;
1720
0
  }
1721
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
1722
0
  if( libcthreads_read_write_lock_release_for_write(
1723
0
       internal_logical_volume->read_write_lock,
1724
0
       error ) != 1 )
1725
0
  {
1726
0
    libcerror_error_set(
1727
0
     error,
1728
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1729
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1730
0
     "%s: unable to release read/write lock for writing.",
1731
0
     function );
1732
1733
0
    return( -1 );
1734
0
  }
1735
0
#endif
1736
0
  return( read_count );
1737
0
}
1738
1739
/* Reads data at a specific offset
1740
 * Returns the number of bytes read or -1 on error
1741
 */
1742
ssize_t libfvde_logical_volume_read_buffer_at_offset(
1743
         libfvde_logical_volume_t *logical_volume,
1744
         void *buffer,
1745
         size_t buffer_size,
1746
         off64_t offset,
1747
         libcerror_error_t **error )
1748
0
{
1749
0
  libfvde_internal_logical_volume_t *internal_logical_volume = NULL;
1750
0
  static char *function                                      = "libfvde_logical_volume_read_buffer_at_offset";
1751
0
  ssize_t read_count                                         = 0;
1752
1753
0
  if( logical_volume == NULL )
1754
0
  {
1755
0
    libcerror_error_set(
1756
0
     error,
1757
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1758
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1759
0
     "%s: invalid logical volume.",
1760
0
     function );
1761
1762
0
    return( -1 );
1763
0
  }
1764
0
  internal_logical_volume = (libfvde_internal_logical_volume_t *) logical_volume;
1765
1766
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
1767
0
  if( libcthreads_read_write_lock_grab_for_write(
1768
0
       internal_logical_volume->read_write_lock,
1769
0
       error ) != 1 )
1770
0
  {
1771
0
    libcerror_error_set(
1772
0
     error,
1773
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1774
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1775
0
     "%s: unable to grab read/write lock for writing.",
1776
0
     function );
1777
1778
0
    return( -1 );
1779
0
  }
1780
0
#endif
1781
0
  if( libfvde_internal_logical_volume_seek_offset(
1782
0
       internal_logical_volume,
1783
0
       offset,
1784
0
       SEEK_SET,
1785
0
       error ) == -1 )
1786
0
  {
1787
0
    libcerror_error_set(
1788
0
     error,
1789
0
     LIBCERROR_ERROR_DOMAIN_IO,
1790
0
     LIBCERROR_IO_ERROR_SEEK_FAILED,
1791
0
     "%s: unable to seek offset.",
1792
0
     function );
1793
1794
0
    read_count = -1;
1795
0
  }
1796
0
  else
1797
0
  {
1798
0
    read_count = libfvde_internal_logical_volume_read_buffer_from_file_io_pool(
1799
0
            internal_logical_volume,
1800
0
            internal_logical_volume->file_io_pool,
1801
0
            buffer,
1802
0
            buffer_size,
1803
0
            error );
1804
1805
0
    if( read_count == -1 )
1806
0
    {
1807
0
      libcerror_error_set(
1808
0
       error,
1809
0
       LIBCERROR_ERROR_DOMAIN_IO,
1810
0
       LIBCERROR_IO_ERROR_READ_FAILED,
1811
0
       "%s: unable to read buffer.",
1812
0
       function );
1813
1814
0
      read_count = -1;
1815
0
    }
1816
0
  }
1817
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
1818
0
  if( libcthreads_read_write_lock_release_for_write(
1819
0
       internal_logical_volume->read_write_lock,
1820
0
       error ) != 1 )
1821
0
  {
1822
0
    libcerror_error_set(
1823
0
     error,
1824
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1825
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1826
0
     "%s: unable to release read/write lock for writing.",
1827
0
     function );
1828
1829
0
    return( -1 );
1830
0
  }
1831
0
#endif
1832
0
  return( read_count );
1833
0
}
1834
1835
/* Seeks a certain offset of the data
1836
 * This function is not multi-thread safe acquire write lock before call
1837
 * Returns the offset if seek is successful or -1 on error
1838
 */
1839
off64_t libfvde_internal_logical_volume_seek_offset(
1840
         libfvde_internal_logical_volume_t *internal_logical_volume,
1841
         off64_t offset,
1842
         int whence,
1843
         libcerror_error_t **error )
1844
0
{
1845
0
  static char *function = "libfvde_internal_logical_volume_seek_offset";
1846
1847
0
  if( internal_logical_volume == NULL )
1848
0
  {
1849
0
    libcerror_error_set(
1850
0
     error,
1851
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1852
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1853
0
     "%s: invalid logical volume.",
1854
0
     function );
1855
1856
0
    return( -1 );
1857
0
  }
1858
0
  if( internal_logical_volume->logical_volume_descriptor == NULL )
1859
0
  {
1860
0
    libcerror_error_set(
1861
0
     error,
1862
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1863
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1864
0
     "%s: invalid logical volume - missing logical volume descriptor.",
1865
0
     function );
1866
1867
0
    return( -1 );
1868
0
  }
1869
0
  if( internal_logical_volume->is_locked != 0 )
1870
0
  {
1871
0
    libcerror_error_set(
1872
0
     error,
1873
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1874
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
1875
0
     "%s: invalid logical volume - volume is locked.",
1876
0
     function );
1877
1878
0
    return( -1 );
1879
0
  }
1880
0
  if( ( whence != SEEK_CUR )
1881
0
   && ( whence != SEEK_END )
1882
0
   && ( whence != SEEK_SET ) )
1883
0
  {
1884
0
    libcerror_error_set(
1885
0
     error,
1886
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1887
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
1888
0
     "%s: unsupported whence.",
1889
0
     function );
1890
1891
0
    return( -1 );
1892
0
  }
1893
0
  if( whence == SEEK_CUR )
1894
0
  { 
1895
0
    offset += internal_logical_volume->current_offset;
1896
0
  }
1897
0
  else if( whence == SEEK_END )
1898
0
  { 
1899
0
    offset += (off64_t) internal_logical_volume->logical_volume_descriptor->size;
1900
0
  }
1901
#if defined( HAVE_DEBUG_OUTPUT )
1902
  if( libcnotify_verbose != 0 )
1903
  {
1904
    libcnotify_printf(
1905
     "%s: seeking media data offset: %" PRIi64 ".\n",
1906
     function,
1907
     offset );
1908
  }
1909
#endif
1910
0
  if( offset < 0 )
1911
0
  {
1912
0
    libcerror_error_set(
1913
0
     error,
1914
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1915
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1916
0
     "%s: invalid offset value out of bounds.",
1917
0
     function );
1918
1919
0
    return( -1 );
1920
0
  }
1921
0
  internal_logical_volume->current_offset = offset;
1922
1923
0
  return( offset );
1924
0
}
1925
1926
/* Seeks a certain offset of the data
1927
 * Returns the offset if seek is successful or -1 on error
1928
 */
1929
off64_t libfvde_logical_volume_seek_offset(
1930
         libfvde_logical_volume_t *logical_volume,
1931
         off64_t offset,
1932
         int whence,
1933
         libcerror_error_t **error )
1934
0
{
1935
0
  libfvde_internal_logical_volume_t *internal_logical_volume = NULL;
1936
0
  static char *function                                      = "libfvde_logical_volume_seek_offset";
1937
1938
0
  if( logical_volume == NULL )
1939
0
  {
1940
0
    libcerror_error_set(
1941
0
     error,
1942
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1943
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1944
0
     "%s: invalid logical volume.",
1945
0
     function );
1946
1947
0
    return( -1 );
1948
0
  }
1949
0
  internal_logical_volume = (libfvde_internal_logical_volume_t *) logical_volume;
1950
1951
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
1952
0
  if( libcthreads_read_write_lock_grab_for_write(
1953
0
       internal_logical_volume->read_write_lock,
1954
0
       error ) != 1 )
1955
0
  {
1956
0
    libcerror_error_set(
1957
0
     error,
1958
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1959
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1960
0
     "%s: unable to grab read/write lock for writing.",
1961
0
     function );
1962
1963
0
    return( -1 );
1964
0
  }
1965
0
#endif
1966
0
  offset = libfvde_internal_logical_volume_seek_offset(
1967
0
            internal_logical_volume,
1968
0
            offset,
1969
0
            whence,
1970
0
            error );
1971
1972
0
  if( offset == -1 )
1973
0
  {
1974
0
    libcerror_error_set(
1975
0
     error,
1976
0
     LIBCERROR_ERROR_DOMAIN_IO,
1977
0
     LIBCERROR_IO_ERROR_SEEK_FAILED,
1978
0
     "%s: unable to seek offset.",
1979
0
     function );
1980
1981
0
    offset = -1;
1982
0
  }
1983
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
1984
0
  if( libcthreads_read_write_lock_release_for_write(
1985
0
       internal_logical_volume->read_write_lock,
1986
0
       error ) != 1 )
1987
0
  {
1988
0
    libcerror_error_set(
1989
0
     error,
1990
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1991
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1992
0
     "%s: unable to release read/write lock for writing.",
1993
0
     function );
1994
1995
0
    return( -1 );
1996
0
  }
1997
0
#endif
1998
0
  return( offset );
1999
0
}
2000
2001
/* Retrieves the current offset of the data
2002
 * Returns 1 if successful or -1 on error
2003
 */
2004
int libfvde_logical_volume_get_offset(
2005
     libfvde_logical_volume_t *logical_volume,
2006
     off64_t *offset,
2007
     libcerror_error_t **error )
2008
0
{
2009
0
  libfvde_internal_logical_volume_t *internal_logical_volume = NULL;
2010
0
  static char *function                                      = "libfvde_logical_volume_get_offset";
2011
2012
0
  if( logical_volume == NULL )
2013
0
  {
2014
0
    libcerror_error_set(
2015
0
     error,
2016
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2017
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2018
0
     "%s: invalid logical volume.",
2019
0
     function );
2020
2021
0
    return( -1 );
2022
0
  }
2023
0
  internal_logical_volume = (libfvde_internal_logical_volume_t *) logical_volume;
2024
2025
0
  if( offset == NULL )
2026
0
  {
2027
0
    libcerror_error_set(
2028
0
     error,
2029
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2030
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2031
0
     "%s: invalid offset.",
2032
0
     function );
2033
2034
0
    return( -1 );
2035
0
  }
2036
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
2037
0
  if( libcthreads_read_write_lock_grab_for_read(
2038
0
       internal_logical_volume->read_write_lock,
2039
0
       error ) != 1 )
2040
0
  {
2041
0
    libcerror_error_set(
2042
0
     error,
2043
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2044
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2045
0
     "%s: unable to grab read/write lock for reading.",
2046
0
     function );
2047
2048
0
    return( -1 );
2049
0
  }
2050
0
#endif
2051
0
  *offset = internal_logical_volume->current_offset;
2052
2053
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
2054
0
  if( libcthreads_read_write_lock_release_for_read(
2055
0
       internal_logical_volume->read_write_lock,
2056
0
       error ) != 1 )
2057
0
  {
2058
0
    libcerror_error_set(
2059
0
     error,
2060
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2061
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2062
0
     "%s: unable to release read/write lock for reading.",
2063
0
     function );
2064
2065
0
    return( -1 );
2066
0
  }
2067
0
#endif
2068
0
  return( 1 );
2069
0
}
2070
2071
/* Retrieves the logical volume identifier
2072
 * The identifier is a UUID and is 16 bytes of size
2073
 * Returns 1 if successful or -1 on error
2074
 */
2075
int libfvde_logical_volume_get_identifier(
2076
     libfvde_logical_volume_t *logical_volume,
2077
     uint8_t *uuid_data,
2078
     size_t uuid_data_size,
2079
     libcerror_error_t **error )
2080
0
{
2081
0
  libfvde_internal_logical_volume_t *internal_logical_volume = NULL;
2082
0
  static char *function                                      = "libfvde_logical_volume_get_identifier";
2083
0
  int result                                                 = 1;
2084
2085
0
  if( logical_volume == NULL )
2086
0
  {
2087
0
    libcerror_error_set(
2088
0
     error,
2089
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2090
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2091
0
     "%s: invalid logical volume.",
2092
0
     function );
2093
2094
0
    return( -1 );
2095
0
  }
2096
0
  internal_logical_volume = (libfvde_internal_logical_volume_t *) logical_volume;
2097
2098
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
2099
0
  if( libcthreads_read_write_lock_grab_for_read(
2100
0
       internal_logical_volume->read_write_lock,
2101
0
       error ) != 1 )
2102
0
  {
2103
0
    libcerror_error_set(
2104
0
     error,
2105
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2106
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2107
0
     "%s: unable to grab read/write lock for reading.",
2108
0
     function );
2109
2110
0
    return( -1 );
2111
0
  }
2112
0
#endif
2113
0
  if( libfvde_logical_volume_descriptor_get_identifier(
2114
0
       internal_logical_volume->logical_volume_descriptor,
2115
0
       uuid_data,
2116
0
       uuid_data_size,
2117
0
       error ) != 1 )
2118
0
  {
2119
0
    libcerror_error_set(
2120
0
     error,
2121
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2122
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2123
0
     "%s: unable to retrieve logical volume identifier from descriptor.",
2124
0
     function );
2125
2126
0
    result = -1;
2127
0
  }
2128
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
2129
0
  if( libcthreads_read_write_lock_release_for_read(
2130
0
       internal_logical_volume->read_write_lock,
2131
0
       error ) != 1 )
2132
0
  {
2133
0
    libcerror_error_set(
2134
0
     error,
2135
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2136
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2137
0
     "%s: unable to release read/write lock for reading.",
2138
0
     function );
2139
2140
0
    return( -1 );
2141
0
  }
2142
0
#endif
2143
0
  return( result );
2144
0
}
2145
2146
/* Retrieves the size of the UTF-8 encoded name
2147
 * The returned size includes the end of string character
2148
 * Returns 1 if successful, 0 if not available or -1 on error
2149
 */
2150
int libfvde_logical_volume_get_utf8_name_size(
2151
     libfvde_logical_volume_t *logical_volume,
2152
     size_t *utf8_string_size,
2153
     libcerror_error_t **error )
2154
0
{
2155
0
  libfvde_internal_logical_volume_t *internal_logical_volume = NULL;
2156
0
  static char *function                                      = "libfvde_logical_volume_get_utf8_name_size";
2157
0
  int result                                                 = 0;
2158
2159
0
  if( logical_volume == NULL )
2160
0
  {
2161
0
    libcerror_error_set(
2162
0
     error,
2163
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2164
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2165
0
     "%s: invalid logical volume.",
2166
0
     function );
2167
2168
0
    return( -1 );
2169
0
  }
2170
0
  internal_logical_volume = (libfvde_internal_logical_volume_t *) logical_volume;
2171
2172
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
2173
0
  if( libcthreads_read_write_lock_grab_for_write(
2174
0
       internal_logical_volume->read_write_lock,
2175
0
       error ) != 1 )
2176
0
  {
2177
0
    libcerror_error_set(
2178
0
     error,
2179
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2180
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2181
0
     "%s: unable to grab read/write lock for writing.",
2182
0
     function );
2183
2184
0
    return( -1 );
2185
0
  }
2186
0
#endif
2187
0
  result = libfvde_logical_volume_descriptor_get_utf8_name_size(
2188
0
            internal_logical_volume->logical_volume_descriptor,
2189
0
            utf8_string_size,
2190
0
            error );
2191
2192
0
  if( result == -1 )
2193
0
  {
2194
0
    libcerror_error_set(
2195
0
     error,
2196
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2197
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2198
0
     "%s: unable to retrieve size of UTF-8 volume group name from descriptor.",
2199
0
     function );
2200
2201
0
    result = -1;
2202
0
  }
2203
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
2204
0
  if( libcthreads_read_write_lock_release_for_write(
2205
0
       internal_logical_volume->read_write_lock,
2206
0
       error ) != 1 )
2207
0
  {
2208
0
    libcerror_error_set(
2209
0
     error,
2210
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2211
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2212
0
     "%s: unable to release read/write lock for writing.",
2213
0
     function );
2214
2215
0
    return( -1 );
2216
0
  }
2217
0
#endif
2218
0
  return( result );
2219
0
}
2220
2221
/* Retrieves the UTF-8 encoded name
2222
 * The size should include the end of string character
2223
 * Returns 1 if successful, 0 if not available or -1 on error
2224
 */
2225
int libfvde_logical_volume_get_utf8_name(
2226
     libfvde_logical_volume_t *logical_volume,
2227
     uint8_t *utf8_string,
2228
     size_t utf8_string_size,
2229
     libcerror_error_t **error )
2230
0
{
2231
0
  libfvde_internal_logical_volume_t *internal_logical_volume = NULL;
2232
0
  static char *function                                      = "libfvde_logical_volume_get_utf8_name";
2233
0
  int result                                                 = 0;
2234
2235
0
  if( logical_volume == NULL )
2236
0
  {
2237
0
    libcerror_error_set(
2238
0
     error,
2239
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2240
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2241
0
     "%s: invalid logical volume.",
2242
0
     function );
2243
2244
0
    return( -1 );
2245
0
  }
2246
0
  internal_logical_volume = (libfvde_internal_logical_volume_t *) logical_volume;
2247
2248
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
2249
0
  if( libcthreads_read_write_lock_grab_for_write(
2250
0
       internal_logical_volume->read_write_lock,
2251
0
       error ) != 1 )
2252
0
  {
2253
0
    libcerror_error_set(
2254
0
     error,
2255
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2256
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2257
0
     "%s: unable to grab read/write lock for writing.",
2258
0
     function );
2259
2260
0
    return( -1 );
2261
0
  }
2262
0
#endif
2263
0
  result = libfvde_logical_volume_descriptor_get_utf8_name(
2264
0
            internal_logical_volume->logical_volume_descriptor,
2265
0
            utf8_string,
2266
0
            utf8_string_size,
2267
0
            error );
2268
2269
0
  if( result == -1 )
2270
0
  {
2271
0
    libcerror_error_set(
2272
0
     error,
2273
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2274
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2275
0
     "%s: unable to retrieve UTF-8 volume group name from descriptor.",
2276
0
     function );
2277
2278
0
    result = -1;
2279
0
  }
2280
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
2281
0
  if( libcthreads_read_write_lock_release_for_write(
2282
0
       internal_logical_volume->read_write_lock,
2283
0
       error ) != 1 )
2284
0
  {
2285
0
    libcerror_error_set(
2286
0
     error,
2287
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2288
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2289
0
     "%s: unable to release read/write lock for writing.",
2290
0
     function );
2291
2292
0
    return( -1 );
2293
0
  }
2294
0
#endif
2295
0
  return( result );
2296
0
}
2297
2298
/* Retrieves the size of the UTF-16 encoded name
2299
 * The returned size includes the end of string character
2300
 * Returns 1 if successful, 0 if not available or -1 on error
2301
 */
2302
int libfvde_logical_volume_get_utf16_name_size(
2303
     libfvde_logical_volume_t *logical_volume,
2304
     size_t *utf16_string_size,
2305
     libcerror_error_t **error )
2306
0
{
2307
0
  libfvde_internal_logical_volume_t *internal_logical_volume = NULL;
2308
0
  static char *function                                      = "libfvde_logical_volume_get_utf16_name_size";
2309
0
  int result                                                 = 0;
2310
2311
0
  if( logical_volume == NULL )
2312
0
  {
2313
0
    libcerror_error_set(
2314
0
     error,
2315
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2316
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2317
0
     "%s: invalid logical volume.",
2318
0
     function );
2319
2320
0
    return( -1 );
2321
0
  }
2322
0
  internal_logical_volume = (libfvde_internal_logical_volume_t *) logical_volume;
2323
2324
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
2325
0
  if( libcthreads_read_write_lock_grab_for_write(
2326
0
       internal_logical_volume->read_write_lock,
2327
0
       error ) != 1 )
2328
0
  {
2329
0
    libcerror_error_set(
2330
0
     error,
2331
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2332
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2333
0
     "%s: unable to grab read/write lock for writing.",
2334
0
     function );
2335
2336
0
    return( -1 );
2337
0
  }
2338
0
#endif
2339
0
  result = libfvde_logical_volume_descriptor_get_utf16_name_size(
2340
0
            internal_logical_volume->logical_volume_descriptor,
2341
0
            utf16_string_size,
2342
0
            error );
2343
2344
0
  if( result == -1 )
2345
0
  {
2346
0
    libcerror_error_set(
2347
0
     error,
2348
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2349
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2350
0
     "%s: unable to retrieve size of UTF-16 volume group name from descriptor.",
2351
0
     function );
2352
2353
0
    result = -1;
2354
0
  }
2355
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
2356
0
  if( libcthreads_read_write_lock_release_for_write(
2357
0
       internal_logical_volume->read_write_lock,
2358
0
       error ) != 1 )
2359
0
  {
2360
0
    libcerror_error_set(
2361
0
     error,
2362
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2363
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2364
0
     "%s: unable to release read/write lock for writing.",
2365
0
     function );
2366
2367
0
    return( -1 );
2368
0
  }
2369
0
#endif
2370
0
  return( result );
2371
0
}
2372
2373
/* Retrieves the UTF-16 encoded name
2374
 * The size should include the end of string character
2375
 * Returns 1 if successful, 0 if not available or -1 on error
2376
 */
2377
int libfvde_logical_volume_get_utf16_name(
2378
     libfvde_logical_volume_t *logical_volume,
2379
     uint16_t *utf16_string,
2380
     size_t utf16_string_size,
2381
     libcerror_error_t **error )
2382
0
{
2383
0
  libfvde_internal_logical_volume_t *internal_logical_volume = NULL;
2384
0
  static char *function                                      = "libfvde_logical_volume_get_utf16_name";
2385
0
  int result                                                 = 0;
2386
2387
0
  if( logical_volume == NULL )
2388
0
  {
2389
0
    libcerror_error_set(
2390
0
     error,
2391
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2392
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2393
0
     "%s: invalid logical volume.",
2394
0
     function );
2395
2396
0
    return( -1 );
2397
0
  }
2398
0
  internal_logical_volume = (libfvde_internal_logical_volume_t *) logical_volume;
2399
2400
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
2401
0
  if( libcthreads_read_write_lock_grab_for_write(
2402
0
       internal_logical_volume->read_write_lock,
2403
0
       error ) != 1 )
2404
0
  {
2405
0
    libcerror_error_set(
2406
0
     error,
2407
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2408
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2409
0
     "%s: unable to grab read/write lock for writing.",
2410
0
     function );
2411
2412
0
    return( -1 );
2413
0
  }
2414
0
#endif
2415
0
  result = libfvde_logical_volume_descriptor_get_utf16_name(
2416
0
            internal_logical_volume->logical_volume_descriptor,
2417
0
            utf16_string,
2418
0
            utf16_string_size,
2419
0
            error );
2420
2421
0
  if( result == -1 )
2422
0
  {
2423
0
    libcerror_error_set(
2424
0
     error,
2425
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2426
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2427
0
     "%s: unable to retrieve UTF-16 volume group name from descriptor.",
2428
0
     function );
2429
2430
0
    result = -1;
2431
0
  }
2432
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
2433
0
  if( libcthreads_read_write_lock_release_for_write(
2434
0
       internal_logical_volume->read_write_lock,
2435
0
       error ) != 1 )
2436
0
  {
2437
0
    libcerror_error_set(
2438
0
     error,
2439
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2440
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2441
0
     "%s: unable to release read/write lock for writing.",
2442
0
     function );
2443
2444
0
    return( -1 );
2445
0
  }
2446
0
#endif
2447
0
  return( result );
2448
0
}
2449
2450
/* Retrieves the volume size
2451
 * Returns 1 if successful or -1 on error
2452
 */
2453
int libfvde_logical_volume_get_size(
2454
     libfvde_logical_volume_t *logical_volume,
2455
     size64_t *size,
2456
     libcerror_error_t **error )
2457
0
{
2458
0
  libfvde_internal_logical_volume_t *internal_logical_volume = NULL;
2459
0
  static char *function                                      = "libfvde_logical_volume_get_size";
2460
2461
0
  if( logical_volume == NULL )
2462
0
  {
2463
0
    libcerror_error_set(
2464
0
     error,
2465
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2466
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2467
0
     "%s: invalid logical volume.",
2468
0
     function );
2469
2470
0
    return( -1 );
2471
0
  }
2472
0
  if( size == NULL )
2473
0
  {
2474
0
    libcerror_error_set(
2475
0
     error,
2476
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2477
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2478
0
     "%s: invalid size.",
2479
0
     function );
2480
2481
0
    return( -1 );
2482
0
  }
2483
0
  internal_logical_volume = (libfvde_internal_logical_volume_t *) logical_volume;
2484
2485
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
2486
0
  if( libcthreads_read_write_lock_grab_for_read(
2487
0
       internal_logical_volume->read_write_lock,
2488
0
       error ) != 1 )
2489
0
  {
2490
0
    libcerror_error_set(
2491
0
     error,
2492
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2493
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2494
0
     "%s: unable to grab read/write lock for reading.",
2495
0
     function );
2496
2497
0
    return( -1 );
2498
0
  }
2499
0
#endif
2500
0
  *size = internal_logical_volume->volume_size;
2501
2502
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
2503
0
  if( libcthreads_read_write_lock_release_for_read(
2504
0
       internal_logical_volume->read_write_lock,
2505
0
       error ) != 1 )
2506
0
  {
2507
0
    libcerror_error_set(
2508
0
     error,
2509
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2510
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2511
0
     "%s: unable to release read/write lock for reading.",
2512
0
     function );
2513
2514
0
    return( -1 );
2515
0
  }
2516
0
#endif
2517
0
  return( 1 );
2518
0
}
2519
2520
/* Determines if the logical volume is locked
2521
 * Returns 1 if locked, 0 if not or -1 on error
2522
 */
2523
int libfvde_logical_volume_is_locked(
2524
     libfvde_logical_volume_t *logical_volume,
2525
     libcerror_error_t **error )
2526
0
{
2527
0
  libfvde_internal_logical_volume_t *internal_logical_volume = NULL;
2528
0
  static char *function                                      = "libfvde_logical_volume_is_locked";
2529
0
  uint8_t is_locked                                          = 0;
2530
2531
0
  if( logical_volume == NULL )
2532
0
  {
2533
0
    libcerror_error_set(
2534
0
     error,
2535
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2536
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2537
0
     "%s: invalid logical volume.",
2538
0
     function );
2539
2540
0
    return( -1 );
2541
0
  }
2542
0
  internal_logical_volume = (libfvde_internal_logical_volume_t *) logical_volume;
2543
2544
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
2545
0
  if( libcthreads_read_write_lock_grab_for_read(
2546
0
       internal_logical_volume->read_write_lock,
2547
0
       error ) != 1 )
2548
0
  {
2549
0
    libcerror_error_set(
2550
0
     error,
2551
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2552
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2553
0
     "%s: unable to grab read/write lock for reading.",
2554
0
     function );
2555
2556
0
    return( -1 );
2557
0
  }
2558
0
#endif
2559
0
  is_locked = internal_logical_volume->is_locked;
2560
2561
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
2562
0
  if( libcthreads_read_write_lock_release_for_read(
2563
0
       internal_logical_volume->read_write_lock,
2564
0
       error ) != 1 )
2565
0
  {
2566
0
    libcerror_error_set(
2567
0
     error,
2568
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2569
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2570
0
     "%s: unable to release read/write lock for reading.",
2571
0
     function );
2572
2573
0
    return( -1 );
2574
0
  }
2575
0
#endif
2576
0
  return( is_locked );
2577
0
}
2578
2579
/* Sets the key
2580
 * This function needs to be used before the unlock function
2581
 * Returns 1 if successful or -1 on error
2582
 */
2583
int libfvde_logical_volume_set_key(
2584
     libfvde_logical_volume_t *logical_volume,
2585
     const uint8_t *volume_master_key,
2586
     size_t volume_master_key_size,
2587
     libcerror_error_t **error )
2588
0
{
2589
0
  libfvde_internal_logical_volume_t *internal_logical_volume = NULL;
2590
0
  static char *function                                      = "libfvde_logical_volume_set_key";
2591
0
  int result                                                 = 1;
2592
2593
0
  if( logical_volume == NULL )
2594
0
  {
2595
0
    libcerror_error_set(
2596
0
     error,
2597
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2598
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2599
0
     "%s: invalid logical volume.",
2600
0
     function );
2601
2602
0
    return( -1 );
2603
0
  }
2604
0
  internal_logical_volume = (libfvde_internal_logical_volume_t *) logical_volume;
2605
2606
0
  if( internal_logical_volume->keyring == NULL )
2607
0
  {
2608
0
    libcerror_error_set(
2609
0
     error,
2610
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2611
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2612
0
     "%s: invalid logical volume - missing keyring handle.",
2613
0
     function );
2614
2615
0
    return( -1 );
2616
0
  }
2617
0
  if( volume_master_key == NULL )
2618
0
  {
2619
0
    libcerror_error_set(
2620
0
     error,
2621
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2622
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2623
0
     "%s: invalid volume master key.",
2624
0
     function );
2625
2626
0
    return( -1 );
2627
0
  }
2628
0
  if( volume_master_key_size != 16 )
2629
0
  {
2630
0
    libcerror_error_set(
2631
0
     error,
2632
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2633
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
2634
0
     "%s: unsupported volume master key size.",
2635
0
     function );
2636
2637
0
    return( -1 );
2638
0
  }
2639
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
2640
0
  if( libcthreads_read_write_lock_grab_for_write(
2641
0
       internal_logical_volume->read_write_lock,
2642
0
       error ) != 1 )
2643
0
  {
2644
0
    libcerror_error_set(
2645
0
     error,
2646
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2647
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2648
0
     "%s: unable to grab read/write lock for writing.",
2649
0
     function );
2650
2651
0
    return( -1 );
2652
0
  }
2653
0
#endif
2654
0
  if( memory_copy(
2655
0
       internal_logical_volume->keyring->volume_master_key,
2656
0
       volume_master_key,
2657
0
       16 ) == NULL )
2658
0
  {
2659
0
    libcerror_error_set(
2660
0
     error,
2661
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
2662
0
     LIBCERROR_MEMORY_ERROR_COPY_FAILED,
2663
0
     "%s: unable to copy volume master key to keyring.",
2664
0
     function );
2665
2666
0
    result = -1;
2667
0
  }
2668
0
  else
2669
0
  {
2670
0
    internal_logical_volume->volume_master_key_is_set = 1;
2671
0
  }
2672
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
2673
0
  if( libcthreads_read_write_lock_release_for_write(
2674
0
       internal_logical_volume->read_write_lock,
2675
0
       error ) != 1 )
2676
0
  {
2677
0
    libcerror_error_set(
2678
0
     error,
2679
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2680
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2681
0
     "%s: unable to release read/write lock for writing.",
2682
0
     function );
2683
2684
0
    return( -1 );
2685
0
  }
2686
0
#endif
2687
0
  return( result );
2688
0
}
2689
2690
/* Sets an UTF-8 formatted password
2691
 * This function needs to be used before the unlock function
2692
 * Returns 1 if successful, 0 if password is invalid or -1 on error
2693
 */
2694
int libfvde_logical_volume_set_utf8_password(
2695
     libfvde_logical_volume_t *logical_volume,
2696
     const uint8_t *utf8_string,
2697
     size_t utf8_string_length,
2698
     libcerror_error_t **error )
2699
0
{
2700
0
  libfvde_internal_logical_volume_t *internal_logical_volume = NULL;
2701
0
  static char *function                                      = "libfvde_logical_volume_set_utf8_password";
2702
0
  int result                                                 = 1;
2703
2704
0
  if( logical_volume == NULL )
2705
0
  {
2706
0
    libcerror_error_set(
2707
0
     error,
2708
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2709
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2710
0
     "%s: invalid logical volume.",
2711
0
     function );
2712
2713
0
    return( -1 );
2714
0
  }
2715
0
  internal_logical_volume = (libfvde_internal_logical_volume_t *) logical_volume;
2716
2717
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
2718
0
  if( libcthreads_read_write_lock_grab_for_write(
2719
0
       internal_logical_volume->read_write_lock,
2720
0
       error ) != 1 )
2721
0
  {
2722
0
    libcerror_error_set(
2723
0
     error,
2724
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2725
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2726
0
     "%s: unable to grab read/write lock for writing.",
2727
0
     function );
2728
2729
0
    return( -1 );
2730
0
  }
2731
0
#endif
2732
0
  if( internal_logical_volume->user_password != NULL )
2733
0
  {
2734
0
    if( memory_set(
2735
0
         internal_logical_volume->user_password,
2736
0
         0,
2737
0
         internal_logical_volume->user_password_size ) == NULL )
2738
0
    {
2739
0
      libcerror_error_set(
2740
0
       error,
2741
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
2742
0
       LIBCERROR_MEMORY_ERROR_SET_FAILED,
2743
0
       "%s: unable to clear user password.",
2744
0
       function );
2745
2746
0
      result = -1;
2747
0
    }
2748
0
    memory_free(
2749
0
     internal_logical_volume->user_password );
2750
2751
0
    internal_logical_volume->user_password      = NULL;
2752
0
    internal_logical_volume->user_password_size = 0;
2753
0
  }
2754
0
  if( result == 1 )
2755
0
  {
2756
0
    if( libfvde_password_copy_from_utf8_string(
2757
0
         &( internal_logical_volume->user_password ),
2758
0
         &( internal_logical_volume->user_password_size ),
2759
0
         utf8_string,
2760
0
         utf8_string_length,
2761
0
         error ) != 1 )
2762
0
    {
2763
0
      libcerror_error_set(
2764
0
       error,
2765
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2766
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2767
0
       "%s: unable to set user password.",
2768
0
       function );
2769
2770
0
      result = -1;
2771
0
    }
2772
#if defined( HAVE_DEBUG_OUTPUT )
2773
    else if( libcnotify_verbose != 0 )
2774
    {
2775
      libcnotify_printf(
2776
       "%s: user password: %s\n",
2777
       function,
2778
       internal_logical_volume->user_password );
2779
    }
2780
#endif
2781
0
  }
2782
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
2783
0
  if( libcthreads_read_write_lock_release_for_write(
2784
0
       internal_logical_volume->read_write_lock,
2785
0
       error ) != 1 )
2786
0
  {
2787
0
    libcerror_error_set(
2788
0
     error,
2789
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2790
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2791
0
     "%s: unable to release read/write lock for writing.",
2792
0
     function );
2793
2794
0
    return( -1 );
2795
0
  }
2796
0
#endif
2797
0
  return( result );
2798
0
}
2799
2800
/* Sets an UTF-16 formatted password
2801
 * This function needs to be used before the unlock function
2802
 * Returns 1 if successful, 0 if password is invalid or -1 on error
2803
 */
2804
int libfvde_logical_volume_set_utf16_password(
2805
     libfvde_logical_volume_t *logical_volume,
2806
     const uint16_t *utf16_string,
2807
     size_t utf16_string_length,
2808
     libcerror_error_t **error )
2809
0
{
2810
0
  libfvde_internal_logical_volume_t *internal_logical_volume = NULL;
2811
0
  static char *function                                      = "libfvde_logical_volume_set_utf16_password";
2812
0
  int result                                                 = 1;
2813
2814
0
  if( logical_volume == NULL )
2815
0
  {
2816
0
    libcerror_error_set(
2817
0
     error,
2818
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2819
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2820
0
     "%s: invalid logical volume.",
2821
0
     function );
2822
2823
0
    return( -1 );
2824
0
  }
2825
0
  internal_logical_volume = (libfvde_internal_logical_volume_t *) logical_volume;
2826
2827
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
2828
0
  if( libcthreads_read_write_lock_grab_for_write(
2829
0
       internal_logical_volume->read_write_lock,
2830
0
       error ) != 1 )
2831
0
  {
2832
0
    libcerror_error_set(
2833
0
     error,
2834
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2835
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2836
0
     "%s: unable to grab read/write lock for writing.",
2837
0
     function );
2838
2839
0
    return( -1 );
2840
0
  }
2841
0
#endif
2842
0
  if( internal_logical_volume->user_password != NULL )
2843
0
  {
2844
0
    if( memory_set(
2845
0
         internal_logical_volume->user_password,
2846
0
         0,
2847
0
         internal_logical_volume->user_password_size ) == NULL )
2848
0
    {
2849
0
      libcerror_error_set(
2850
0
       error,
2851
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
2852
0
       LIBCERROR_MEMORY_ERROR_SET_FAILED,
2853
0
       "%s: unable to clear user password.",
2854
0
       function );
2855
2856
0
      result = -1;
2857
0
    }
2858
0
    memory_free(
2859
0
     internal_logical_volume->user_password );
2860
2861
0
    internal_logical_volume->user_password      = NULL;
2862
0
    internal_logical_volume->user_password_size = 0;
2863
0
  }
2864
0
  if( result == 1 )
2865
0
  {
2866
0
    if( libfvde_password_copy_from_utf16_string(
2867
0
         &( internal_logical_volume->user_password ),
2868
0
         &( internal_logical_volume->user_password_size ),
2869
0
         utf16_string,
2870
0
         utf16_string_length,
2871
0
         error ) != 1 )
2872
0
    {
2873
0
      libcerror_error_set(
2874
0
       error,
2875
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2876
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2877
0
       "%s: unable to set user password.",
2878
0
       function );
2879
2880
0
      result = -1;
2881
0
    }
2882
#if defined( HAVE_DEBUG_OUTPUT )
2883
    else if( libcnotify_verbose != 0 )
2884
    {
2885
      libcnotify_printf(
2886
       "%s: user password: %s\n",
2887
       function,
2888
       internal_logical_volume->user_password );
2889
    }
2890
#endif
2891
0
  }
2892
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
2893
0
  if( libcthreads_read_write_lock_release_for_write(
2894
0
       internal_logical_volume->read_write_lock,
2895
0
       error ) != 1 )
2896
0
  {
2897
0
    libcerror_error_set(
2898
0
     error,
2899
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2900
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2901
0
     "%s: unable to release read/write lock for writing.",
2902
0
     function );
2903
2904
0
    return( -1 );
2905
0
  }
2906
0
#endif
2907
0
  return( result );
2908
0
}
2909
2910
/* Sets an UTF-8 formatted recovery password
2911
 * This function needs to be used before the unlock function
2912
 * Returns 1 if successful, 0 if recovery password is invalid or -1 on error
2913
 */
2914
int libfvde_logical_volume_set_utf8_recovery_password(
2915
     libfvde_logical_volume_t *logical_volume,
2916
     const uint8_t *utf8_string,
2917
     size_t utf8_string_length,
2918
     libcerror_error_t **error )
2919
0
{
2920
0
  libfvde_internal_logical_volume_t *internal_logical_volume = NULL;
2921
0
  static char *function                                      = "libfvde_logical_volume_set_utf8_recovery_password";
2922
0
  int result                                                 = 1;
2923
2924
0
  if( logical_volume == NULL )
2925
0
  {
2926
0
    libcerror_error_set(
2927
0
     error,
2928
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2929
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2930
0
     "%s: invalid logical volume.",
2931
0
     function );
2932
2933
0
    return( -1 );
2934
0
  }
2935
0
  internal_logical_volume = (libfvde_internal_logical_volume_t *) logical_volume;
2936
2937
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
2938
0
  if( libcthreads_read_write_lock_grab_for_write(
2939
0
       internal_logical_volume->read_write_lock,
2940
0
       error ) != 1 )
2941
0
  {
2942
0
    libcerror_error_set(
2943
0
     error,
2944
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2945
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2946
0
     "%s: unable to grab read/write lock for writing.",
2947
0
     function );
2948
2949
0
    return( -1 );
2950
0
  }
2951
0
#endif
2952
0
  if( internal_logical_volume->recovery_password != NULL )
2953
0
  {
2954
0
    if( memory_set(
2955
0
         internal_logical_volume->recovery_password,
2956
0
         0,
2957
0
         internal_logical_volume->recovery_password_size ) == NULL )
2958
0
    {
2959
0
      libcerror_error_set(
2960
0
       error,
2961
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
2962
0
       LIBCERROR_MEMORY_ERROR_SET_FAILED,
2963
0
       "%s: unable to clear recovery password.",
2964
0
       function );
2965
2966
0
      result = -1;
2967
0
    }
2968
0
    memory_free(
2969
0
     internal_logical_volume->recovery_password );
2970
2971
0
    internal_logical_volume->recovery_password      = NULL;
2972
0
    internal_logical_volume->recovery_password_size = 0;
2973
0
  }
2974
0
  if( result == 1 )
2975
0
  {
2976
0
    if( libfvde_password_copy_from_utf8_string(
2977
0
         &( internal_logical_volume->recovery_password ),
2978
0
         &( internal_logical_volume->recovery_password_size ),
2979
0
         utf8_string,
2980
0
         utf8_string_length,
2981
0
         error ) != 1 )
2982
0
    {
2983
0
      libcerror_error_set(
2984
0
       error,
2985
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2986
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2987
0
       "%s: unable to set recovery password.",
2988
0
       function );
2989
2990
0
      result = -1;
2991
0
    }
2992
#if defined( HAVE_DEBUG_OUTPUT )
2993
    else if( libcnotify_verbose != 0 )
2994
    {
2995
      libcnotify_printf(
2996
       "%s: recovery password: %s\n",
2997
       function,
2998
       internal_logical_volume->recovery_password );
2999
    }
3000
#endif
3001
0
  }
3002
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
3003
0
  if( libcthreads_read_write_lock_release_for_write(
3004
0
       internal_logical_volume->read_write_lock,
3005
0
       error ) != 1 )
3006
0
  {
3007
0
    libcerror_error_set(
3008
0
     error,
3009
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3010
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3011
0
     "%s: unable to release read/write lock for writing.",
3012
0
     function );
3013
3014
0
    return( -1 );
3015
0
  }
3016
0
#endif
3017
0
  return( result );
3018
0
}
3019
3020
/* Sets an UTF-16 formatted recovery password
3021
 * This function needs to be used before the unlock function
3022
 * Returns 1 if successful, 0 if recovery password is invalid or -1 on error
3023
 */
3024
int libfvde_logical_volume_set_utf16_recovery_password(
3025
     libfvde_logical_volume_t *logical_volume,
3026
     const uint16_t *utf16_string,
3027
     size_t utf16_string_length,
3028
     libcerror_error_t **error )
3029
0
{
3030
0
  libfvde_internal_logical_volume_t *internal_logical_volume = NULL;
3031
0
  static char *function                                      = "libfvde_logical_volume_set_utf16_recovery_password";
3032
0
  int result                                                 = 1;
3033
3034
0
  if( logical_volume == NULL )
3035
0
  {
3036
0
    libcerror_error_set(
3037
0
     error,
3038
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3039
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3040
0
     "%s: invalid logical volume.",
3041
0
     function );
3042
3043
0
    return( -1 );
3044
0
  }
3045
0
  internal_logical_volume = (libfvde_internal_logical_volume_t *) logical_volume;
3046
3047
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
3048
0
  if( libcthreads_read_write_lock_grab_for_write(
3049
0
       internal_logical_volume->read_write_lock,
3050
0
       error ) != 1 )
3051
0
  {
3052
0
    libcerror_error_set(
3053
0
     error,
3054
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3055
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3056
0
     "%s: unable to grab read/write lock for writing.",
3057
0
     function );
3058
3059
0
    return( -1 );
3060
0
  }
3061
0
#endif
3062
0
  if( internal_logical_volume->recovery_password != NULL )
3063
0
  {
3064
0
    if( memory_set(
3065
0
         internal_logical_volume->recovery_password,
3066
0
         0,
3067
0
         internal_logical_volume->recovery_password_size ) == NULL )
3068
0
    {
3069
0
      libcerror_error_set(
3070
0
       error,
3071
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
3072
0
       LIBCERROR_MEMORY_ERROR_SET_FAILED,
3073
0
       "%s: unable to clear recovery password.",
3074
0
       function );
3075
3076
0
      result = -1;
3077
0
    }
3078
0
    memory_free(
3079
0
     internal_logical_volume->recovery_password );
3080
3081
0
    internal_logical_volume->recovery_password      = NULL;
3082
0
    internal_logical_volume->recovery_password_size = 0;
3083
0
  }
3084
0
  if( result == 1 )
3085
0
  {
3086
0
    if( libfvde_password_copy_from_utf16_string(
3087
0
         &( internal_logical_volume->recovery_password ),
3088
0
         &( internal_logical_volume->recovery_password_size ),
3089
0
         utf16_string,
3090
0
         utf16_string_length,
3091
0
         error ) != 1 )
3092
0
    {
3093
0
      libcerror_error_set(
3094
0
       error,
3095
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
3096
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3097
0
       "%s: unable to set recovery password.",
3098
0
       function );
3099
3100
0
      result = -1;
3101
0
    }
3102
#if defined( HAVE_DEBUG_OUTPUT )
3103
    else if( libcnotify_verbose != 0 )
3104
    {
3105
      libcnotify_printf(
3106
       "%s: recovery password: %s\n",
3107
       function,
3108
       internal_logical_volume->recovery_password );
3109
    }
3110
#endif
3111
0
  }
3112
0
#if defined( HAVE_LIBFVDE_MULTI_THREAD_SUPPORT )
3113
0
  if( libcthreads_read_write_lock_release_for_write(
3114
0
       internal_logical_volume->read_write_lock,
3115
0
       error ) != 1 )
3116
0
  {
3117
0
    libcerror_error_set(
3118
0
     error,
3119
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3120
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3121
0
     "%s: unable to release read/write lock for writing.",
3122
0
     function );
3123
3124
0
    return( -1 );
3125
0
  }
3126
0
#endif
3127
0
  return( result );
3128
0
}
3129