Coverage Report

Created: 2025-06-22 07:35

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