Coverage Report

Created: 2023-06-07 06:53

/src/libluksde/libluksde/libluksde_volume.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Volume functions
3
 *
4
 * Copyright (C) 2013-2023, 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
1.11k
{
54
1.11k
  libluksde_internal_volume_t *internal_volume = NULL;
55
1.11k
  static char *function                        = "libluksde_volume_initialize";
56
57
1.11k
  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
1.11k
  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
1.11k
  internal_volume = memory_allocate_structure(
80
1.11k
                     libluksde_internal_volume_t );
81
82
1.11k
  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
1.11k
  if( memory_set(
94
1.11k
       internal_volume,
95
1.11k
       0,
96
1.11k
       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
1.11k
  if( libluksde_io_handle_initialize(
111
1.11k
       &( internal_volume->io_handle ),
112
1.11k
       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
1.11k
#if defined( HAVE_LIBLUKSDE_MULTI_THREAD_SUPPORT )
124
1.11k
  if( libcthreads_read_write_lock_initialize(
125
1.11k
       &( internal_volume->read_write_lock ),
126
1.11k
       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
1.11k
#endif
138
1.11k
  internal_volume->is_locked = 1;
139
140
1.11k
  *volume = (libluksde_volume_t *) internal_volume;
141
142
1.11k
  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
1.11k
}
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
1.11k
{
166
1.11k
  libluksde_internal_volume_t *internal_volume = NULL;
167
1.11k
  static char *function                        = "libluksde_volume_free";
168
1.11k
  int result                                   = 1;
169
170
1.11k
  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
1.11k
  if( *volume != NULL )
182
1.11k
  {
183
1.11k
    internal_volume = (libluksde_internal_volume_t *) *volume;
184
185
1.11k
    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
1.11k
    *volume = NULL;
202
203
1.11k
#if defined( HAVE_LIBLUKSDE_MULTI_THREAD_SUPPORT )
204
1.11k
    if( libcthreads_read_write_lock_free(
205
1.11k
         &( internal_volume->read_write_lock ),
206
1.11k
         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
1.11k
#endif
218
1.11k
    if( libluksde_io_handle_free(
219
1.11k
         &( internal_volume->io_handle ),
220
1.11k
         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
1.11k
    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
1.11k
    memory_free(
251
1.11k
     internal_volume );
252
1.11k
  }
253
1.11k
  return( result );
254
1.11k
}
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
1.11k
{
666
1.11k
  libluksde_internal_volume_t *internal_volume = NULL;
667
1.11k
  static char *function                        = "libluksde_volume_open_file_io_handle";
668
1.11k
  int bfio_access_flags                        = 0;
669
1.11k
  int file_io_handle_is_open                   = 0;
670
1.11k
  int file_io_handle_opened_in_library         = 0;
671
1.11k
  int result                                   = 1;
672
673
1.11k
  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
1.11k
  internal_volume = (libluksde_internal_volume_t *) volume;
685
686
1.11k
  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
1.11k
  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
1.11k
  if( ( ( access_flags & LIBLUKSDE_ACCESS_FLAG_READ ) == 0 )
709
1.11k
   && ( ( 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
1.11k
  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
1.11k
  if( ( access_flags & LIBLUKSDE_ACCESS_FLAG_READ ) != 0 )
732
1.11k
  {
733
1.11k
    bfio_access_flags = LIBBFIO_ACCESS_FLAG_READ;
734
1.11k
  }
735
1.11k
  file_io_handle_is_open = libbfio_handle_is_open(
736
1.11k
                            file_io_handle,
737
1.11k
                            error );
738
739
1.11k
  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
1.11k
  else if( file_io_handle_is_open == 0 )
751
1.11k
  {
752
1.11k
    if( libbfio_handle_open(
753
1.11k
         file_io_handle,
754
1.11k
         bfio_access_flags,
755
1.11k
         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
1.11k
    file_io_handle_opened_in_library = 1;
767
1.11k
  }
768
1.11k
#if defined( HAVE_LIBLUKSDE_MULTI_THREAD_SUPPORT )
769
1.11k
  if( libcthreads_read_write_lock_grab_for_write(
770
1.11k
       internal_volume->read_write_lock,
771
1.11k
       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
1.11k
#endif
783
1.11k
  if( libluksde_internal_volume_open_read(
784
1.11k
       internal_volume,
785
1.11k
       file_io_handle,
786
1.11k
       error ) != 1 )
787
1.08k
  {
788
1.08k
    libcerror_error_set(
789
1.08k
     error,
790
1.08k
     LIBCERROR_ERROR_DOMAIN_IO,
791
1.08k
     LIBCERROR_IO_ERROR_READ_FAILED,
792
1.08k
     "%s: unable to read from volume handle.",
793
1.08k
     function );
794
795
1.08k
    result = -1;
796
1.08k
  }
797
21
  else
798
21
  {
799
21
    internal_volume->file_io_handle                   = file_io_handle;
800
21
    internal_volume->file_io_handle_opened_in_library = file_io_handle_opened_in_library;
801
21
  }
802
1.11k
#if defined( HAVE_LIBLUKSDE_MULTI_THREAD_SUPPORT )
803
1.11k
  if( libcthreads_read_write_lock_release_for_write(
804
1.11k
       internal_volume->read_write_lock,
805
1.11k
       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
1.11k
#endif
817
1.11k
  if( result == -1 )
818
1.08k
  {
819
1.08k
    goto on_error;
820
1.08k
  }
821
21
  return( 1 );
822
823
1.08k
on_error:
824
1.08k
  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
1.08k
  return( -1 );
831
1.11k
}
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
21
{
840
21
  libluksde_internal_volume_t *internal_volume = NULL;
841
21
  static char *function                        = "libluksde_volume_close";
842
21
  int result                                   = 0;
843
844
21
  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
21
  internal_volume = (libluksde_internal_volume_t *) volume;
856
857
21
  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
21
  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
21
#if defined( HAVE_LIBLUKSDE_MULTI_THREAD_SUPPORT )
880
21
  if( libcthreads_read_write_lock_grab_for_write(
881
21
       internal_volume->read_write_lock,
882
21
       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
21
#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
21
  if( internal_volume->file_io_handle_opened_in_library != 0 )
914
21
  {
915
21
    if( libbfio_handle_close(
916
21
         internal_volume->file_io_handle,
917
21
         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
21
    internal_volume->file_io_handle_opened_in_library = 0;
929
21
  }
930
21
  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
21
  internal_volume->file_io_handle = NULL;
948
21
  internal_volume->current_offset = 0;
949
21
  internal_volume->is_locked      = 1;
950
951
21
  if( libluksde_io_handle_clear(
952
21
       internal_volume->io_handle,
953
21
       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
21
  if( libluksde_volume_header_free(
965
21
       &( internal_volume->volume_header ),
966
21
       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
21
  if( memory_set(
978
21
       internal_volume->master_key,
979
21
       0,
980
21
       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
21
  if( libluksde_sector_data_vector_free(
992
21
       &( internal_volume->sector_data_vector ),
993
21
       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
21
  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
21
#if defined( HAVE_LIBLUKSDE_MULTI_THREAD_SUPPORT )
1021
21
  if( libcthreads_read_write_lock_release_for_write(
1022
21
       internal_volume->read_write_lock,
1023
21
       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
21
#endif
1035
21
  return( result );
1036
21
}
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
1.11k
{
1046
1.11k
  static char *function = "libluksde_internal_volume_open_read";
1047
1.11k
  int result            = 0;
1048
1049
1.11k
  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
1.11k
  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
1.11k
  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
1.11k
  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
1.11k
  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
1.11k
  if( libbfio_handle_get_size(
1105
1.11k
       file_io_handle,
1106
1.11k
       &( internal_volume->io_handle->volume_size ),
1107
1.11k
       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
1.11k
  if( libluksde_volume_header_initialize(
1126
1.11k
       &( internal_volume->volume_header ),
1127
1.11k
       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
1.11k
  if( libluksde_volume_header_read_file_io_handle(
1139
1.11k
       internal_volume->volume_header,
1140
1.11k
       file_io_handle,
1141
1.11k
       0,
1142
1.11k
       error ) != 1 )
1143
253
  {
1144
253
    libcerror_error_set(
1145
253
     error,
1146
253
     LIBCERROR_ERROR_DOMAIN_IO,
1147
253
     LIBCERROR_IO_ERROR_READ_FAILED,
1148
253
     "%s: unable to read volume header.",
1149
253
     function );
1150
1151
253
    goto on_error;
1152
253
  }
1153
857
  if( ( internal_volume->volume_header->master_key_size == 0 )
1154
857
   || ( internal_volume->volume_header->master_key_size > 64 ) )
1155
675
  {
1156
675
    libcerror_error_set(
1157
675
     error,
1158
675
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1159
675
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1160
675
     "%s: invalid master key size value out of bounds.",
1161
675
     function );
1162
1163
675
    goto on_error;
1164
675
  }
1165
182
  internal_volume->master_key_size = internal_volume->volume_header->master_key_size;
1166
1167
182
  if( internal_volume->volume_header->encrypted_volume_start_sector >= ( internal_volume->io_handle->volume_size / internal_volume->io_handle->bytes_per_sector ) )
1168
161
  {
1169
161
    libcerror_error_set(
1170
161
     error,
1171
161
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1172
161
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
1173
161
     "%s: invalid encrypted volume start sector value out of bounds.",
1174
161
     function );
1175
1176
161
    goto on_error;
1177
161
  }
1178
21
  internal_volume->io_handle->encrypted_volume_offset = internal_volume->volume_header->encrypted_volume_start_sector
1179
21
                                                      * internal_volume->io_handle->bytes_per_sector;
1180
1181
21
  internal_volume->io_handle->encrypted_volume_size = internal_volume->io_handle->volume_size
1182
21
                                                    - internal_volume->io_handle->encrypted_volume_offset;
1183
1184
21
  result = libluksde_internal_volume_unlock(
1185
21
            internal_volume,
1186
21
            file_io_handle,
1187
21
            error );
1188
1189
21
  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
21
  if( libluksde_sector_data_vector_initialize(
1201
21
       &( internal_volume->sector_data_vector ),
1202
21
       (size64_t) internal_volume->io_handle->bytes_per_sector,
1203
21
       internal_volume->io_handle->encrypted_volume_offset,
1204
21
       internal_volume->io_handle->volume_size,
1205
21
       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
21
  return( 1 );
1217
1218
1.08k
on_error:
1219
1.08k
  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
1.08k
  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
1.08k
  if( internal_volume->volume_header != NULL )
1232
1.08k
  {
1233
1.08k
    libluksde_volume_header_free(
1234
1.08k
     &( internal_volume->volume_header ),
1235
1.08k
     NULL );
1236
1.08k
  }
1237
1.08k
  return( -1 );
1238
21
}
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
21
{
1248
21
  uint8_t master_key_validation_hash[ 20 ];
1249
21
  uint8_t user_key[ 32 ];
1250
1251
21
  libluksde_encryption_context_t *user_key_encryption_context = NULL;
1252
21
  libluksde_key_slot_t *key_slot                              = NULL;
1253
21
  uint8_t *key_material_data                                  = NULL;
1254
21
  uint8_t *split_master_key_data                              = NULL;
1255
21
  static char *function                                       = "libluksde_internal_volume_open_read_keys";
1256
21
  size_t key_material_data_offset                             = 0;
1257
21
  size_t key_material_size                                    = 0;
1258
21
  ssize_t read_count                                          = 0;
1259
21
  uint64_t key_material_block_key                             = 0;
1260
21
  int key_slot_index                                          = 0;
1261
1262
21
  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
21
  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
21
  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
21
  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
21
  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
21
  if( ( internal_volume->volume_master_key_is_set == 0 )
1353
21
   && ( 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
21
  if( ( internal_volume->volume_master_key_is_set != 0 )
1732
21
   && ( 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
21
  if( internal_volume->encryption_context != NULL )
1772
0
  {
1773
0
    return( 1 );
1774
0
  }
1775
21
  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
21
}
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
21
{
1874
21
  static char *function = "libluksde_internal_volume_unlock";
1875
21
  int result            = 0;
1876
1877
21
  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
21
  result = libluksde_internal_volume_open_read_keys(
1889
21
            internal_volume,
1890
21
            file_io_handle,
1891
21
            error );
1892
1893
21
  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
21
  else if( result != 0 )
1905
0
  {
1906
0
    internal_volume->is_locked = 0;
1907
0
  }
1908
21
  return( result );
1909
21
}
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( internal_volume->is_locked != 0 )
2062
0
  {
2063
0
    libcerror_error_set(
2064
0
     error,
2065
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2066
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2067
0
     "%s: invalid volume - volume is locked.",
2068
0
     function );
2069
2070
0
    return( -1 );
2071
0
  }
2072
0
  if( buffer == NULL )
2073
0
  {
2074
0
    libcerror_error_set(
2075
0
     error,
2076
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2077
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2078
0
     "%s: invalid buffer.",
2079
0
     function );
2080
2081
0
    return( -1 );
2082
0
  }
2083
0
  if( buffer_size > (size_t) SSIZE_MAX )
2084
0
  {
2085
0
    libcerror_error_set(
2086
0
     error,
2087
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2088
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
2089
0
     "%s: invalid buffer size value exceeds maximum.",
2090
0
     function );
2091
2092
0
    return( -1 );
2093
0
  }
2094
0
  internal_volume->io_handle->abort = 0;
2095
2096
0
  if( (size64_t) internal_volume->current_offset >= internal_volume->io_handle->encrypted_volume_size )
2097
0
  {
2098
0
    return( 0 );
2099
0
  }
2100
0
  if( (size64_t) buffer_size > ( internal_volume->io_handle->encrypted_volume_size - internal_volume->current_offset ) )
2101
0
  {
2102
0
    buffer_size = (size_t) ( internal_volume->io_handle->encrypted_volume_size - internal_volume->current_offset );
2103
0
  }
2104
0
  remaining_buffer_size = buffer_size;
2105
2106
0
  sector_file_offset = ( internal_volume->current_offset / internal_volume->io_handle->bytes_per_sector ) * internal_volume->io_handle->bytes_per_sector;
2107
0
  sector_data_offset = (size_t) ( internal_volume->current_offset - sector_file_offset );
2108
2109
0
  while( remaining_buffer_size > 0 )
2110
0
  {
2111
0
    read_size = internal_volume->io_handle->bytes_per_sector - sector_data_offset;
2112
2113
0
    if( read_size > remaining_buffer_size )
2114
0
    {
2115
0
      read_size = remaining_buffer_size;
2116
0
    }
2117
0
    if( read_size == 0 )
2118
0
    {
2119
0
      break;
2120
0
    }
2121
0
    if( libluksde_sector_data_vector_get_sector_data_at_offset(
2122
0
         internal_volume->sector_data_vector,
2123
0
         file_io_handle,
2124
0
         internal_volume->encryption_context,
2125
0
         sector_file_offset,
2126
0
         &sector_data,
2127
0
         error ) != 1 )
2128
0
    {
2129
0
      libcerror_error_set(
2130
0
       error,
2131
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2132
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2133
0
       "%s: unable to retrieve sector data at offset: %" PRIi64 " (0x%08" PRIx64 ").",
2134
0
       function,
2135
0
       sector_file_offset,
2136
0
       sector_file_offset );
2137
2138
0
      return( -1 );
2139
0
    }
2140
0
    if( sector_data == NULL )
2141
0
    {
2142
0
      libcerror_error_set(
2143
0
       error,
2144
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2145
0
       LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2146
0
       "%s: missing sector data at offset: %" PRIi64 " (0x%08" PRIx64 ").",
2147
0
       function,
2148
0
       sector_file_offset,
2149
0
       sector_file_offset );
2150
2151
0
      return( -1 );
2152
0
    }
2153
0
    if( memory_copy(
2154
0
         &( ( (uint8_t *) buffer )[ buffer_offset ] ),
2155
0
         &( ( sector_data->data )[ sector_data_offset ] ),
2156
0
         read_size ) == NULL )
2157
0
    {
2158
0
      libcerror_error_set(
2159
0
       error,
2160
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
2161
0
       LIBCERROR_MEMORY_ERROR_COPY_FAILED,
2162
0
       "%s: unable to copy sector data to buffer.",
2163
0
       function );
2164
2165
0
      return( -1 );
2166
0
    }
2167
0
                buffer_offset         += read_size;
2168
0
                remaining_buffer_size -= read_size;
2169
0
    sector_file_offset    += read_size;
2170
0
    sector_data_offset     = 0;
2171
2172
0
    if( internal_volume->io_handle->abort != 0 )
2173
0
    {
2174
0
      break;
2175
0
    }
2176
0
  }
2177
0
  internal_volume->current_offset += (off64_t) buffer_offset;
2178
2179
0
  return( (ssize_t) buffer_offset );
2180
0
}
2181
2182
/* Reads data at the current offset into a buffer
2183
 * Returns the number of bytes read or -1 on error
2184
 */
2185
ssize_t libluksde_volume_read_buffer(
2186
         libluksde_volume_t *volume,
2187
         void *buffer,
2188
         size_t buffer_size,
2189
         libcerror_error_t **error )
2190
0
{
2191
0
  libluksde_internal_volume_t *internal_volume = NULL;
2192
0
  static char *function                        = "libluksde_volume_read_buffer";
2193
0
  ssize_t read_count                           = 0;
2194
2195
0
  if( volume == NULL )
2196
0
  {
2197
0
    libcerror_error_set(
2198
0
     error,
2199
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2200
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2201
0
     "%s: invalid volume.",
2202
0
     function );
2203
2204
0
    return( -1 );
2205
0
  }
2206
0
  internal_volume = (libluksde_internal_volume_t *) volume;
2207
2208
0
  if( internal_volume->file_io_handle == NULL )
2209
0
  {
2210
0
    libcerror_error_set(
2211
0
     error,
2212
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2213
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2214
0
     "%s: invalid volume - missing file IO handle.",
2215
0
     function );
2216
2217
0
    return( -1 );
2218
0
  }
2219
0
#if defined( HAVE_LIBLUKSDE_MULTI_THREAD_SUPPORT )
2220
0
  if( libcthreads_read_write_lock_grab_for_write(
2221
0
       internal_volume->read_write_lock,
2222
0
       error ) != 1 )
2223
0
  {
2224
0
    libcerror_error_set(
2225
0
     error,
2226
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2227
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2228
0
     "%s: unable to grab read/write lock for writing.",
2229
0
     function );
2230
2231
0
    return( -1 );
2232
0
  }
2233
0
#endif
2234
0
  read_count = libluksde_internal_volume_read_buffer_from_file_io_handle(
2235
0
          internal_volume,
2236
0
          internal_volume->file_io_handle,
2237
0
          buffer,
2238
0
          buffer_size,
2239
0
          error );
2240
2241
0
  if( read_count == -1 )
2242
0
  {
2243
0
    libcerror_error_set(
2244
0
     error,
2245
0
     LIBCERROR_ERROR_DOMAIN_IO,
2246
0
     LIBCERROR_IO_ERROR_READ_FAILED,
2247
0
     "%s: unable to read buffer.",
2248
0
     function );
2249
2250
0
    read_count = -1;
2251
0
  }
2252
0
#if defined( HAVE_LIBLUKSDE_MULTI_THREAD_SUPPORT )
2253
0
  if( libcthreads_read_write_lock_release_for_write(
2254
0
       internal_volume->read_write_lock,
2255
0
       error ) != 1 )
2256
0
  {
2257
0
    libcerror_error_set(
2258
0
     error,
2259
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2260
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2261
0
     "%s: unable to release read/write lock for writing.",
2262
0
     function );
2263
2264
0
    return( -1 );
2265
0
  }
2266
0
#endif
2267
0
  return( read_count );
2268
0
}
2269
2270
/* Reads (volume) data at a specific offset
2271
 * Returns the number of bytes read or -1 on error
2272
 */
2273
ssize_t libluksde_volume_read_buffer_at_offset(
2274
         libluksde_volume_t *volume,
2275
         void *buffer,
2276
         size_t buffer_size,
2277
         off64_t offset,
2278
         libcerror_error_t **error )
2279
0
{
2280
0
  libluksde_internal_volume_t *internal_volume = NULL;
2281
0
  static char *function                        = "libluksde_volume_read_buffer_at_offset";
2282
0
  ssize_t read_count                           = 0;
2283
2284
0
  if( volume == NULL )
2285
0
  {
2286
0
    libcerror_error_set(
2287
0
     error,
2288
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2289
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2290
0
     "%s: invalid volume.",
2291
0
     function );
2292
2293
0
    return( -1 );
2294
0
  }
2295
0
  internal_volume = (libluksde_internal_volume_t *) volume;
2296
2297
0
  if( internal_volume->file_io_handle == NULL )
2298
0
  {
2299
0
    libcerror_error_set(
2300
0
     error,
2301
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2302
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2303
0
     "%s: invalid volume - missing file IO handle.",
2304
0
     function );
2305
2306
0
    return( -1 );
2307
0
  }
2308
0
#if defined( HAVE_LIBLUKSDE_MULTI_THREAD_SUPPORT )
2309
0
  if( libcthreads_read_write_lock_grab_for_write(
2310
0
       internal_volume->read_write_lock,
2311
0
       error ) != 1 )
2312
0
  {
2313
0
    libcerror_error_set(
2314
0
     error,
2315
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2316
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2317
0
     "%s: unable to grab read/write lock for writing.",
2318
0
     function );
2319
2320
0
    return( -1 );
2321
0
  }
2322
0
#endif
2323
0
  if( libluksde_internal_volume_seek_offset(
2324
0
       internal_volume,
2325
0
       offset,
2326
0
       SEEK_SET,
2327
0
       error ) == -1 )
2328
0
  {
2329
0
    libcerror_error_set(
2330
0
     error,
2331
0
     LIBCERROR_ERROR_DOMAIN_IO,
2332
0
     LIBCERROR_IO_ERROR_SEEK_FAILED,
2333
0
     "%s: unable to seek offset.",
2334
0
     function );
2335
2336
0
    goto on_error;
2337
0
  }
2338
0
  read_count = libluksde_internal_volume_read_buffer_from_file_io_handle(
2339
0
          internal_volume,
2340
0
          internal_volume->file_io_handle,
2341
0
          buffer,
2342
0
          buffer_size,
2343
0
          error );
2344
2345
0
  if( read_count == -1 )
2346
0
  {
2347
0
    libcerror_error_set(
2348
0
     error,
2349
0
     LIBCERROR_ERROR_DOMAIN_IO,
2350
0
     LIBCERROR_IO_ERROR_READ_FAILED,
2351
0
     "%s: unable to read buffer.",
2352
0
     function );
2353
2354
0
    goto on_error;
2355
0
  }
2356
0
#if defined( HAVE_LIBLUKSDE_MULTI_THREAD_SUPPORT )
2357
0
  if( libcthreads_read_write_lock_release_for_write(
2358
0
       internal_volume->read_write_lock,
2359
0
       error ) != 1 )
2360
0
  {
2361
0
    libcerror_error_set(
2362
0
     error,
2363
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2364
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2365
0
     "%s: unable to release read/write lock for writing.",
2366
0
     function );
2367
2368
0
    return( -1 );
2369
0
  }
2370
0
#endif
2371
0
  return( read_count );
2372
2373
0
on_error:
2374
0
#if defined( HAVE_LIBLUKSDE_MULTI_THREAD_SUPPORT )
2375
0
  libcthreads_read_write_lock_release_for_write(
2376
0
   internal_volume->read_write_lock,
2377
0
   NULL );
2378
0
#endif
2379
0
  return( -1 );
2380
0
}
2381
2382
/* Seeks a certain offset of the (volume) data
2383
 * This function is not multi-thread safe acquire write lock before call
2384
 * Returns the offset if seek is successful or -1 on error
2385
 */
2386
off64_t libluksde_internal_volume_seek_offset(
2387
         libluksde_internal_volume_t *internal_volume,
2388
         off64_t offset,
2389
         int whence,
2390
         libcerror_error_t **error )
2391
0
{
2392
0
  static char *function = "libluksde_internal_volume_seek_offset";
2393
2394
0
  if( internal_volume == NULL )
2395
0
  {
2396
0
    libcerror_error_set(
2397
0
     error,
2398
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2399
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2400
0
     "%s: invalid volume.",
2401
0
     function );
2402
2403
0
    return( -1 );
2404
0
  }
2405
0
  if( internal_volume->is_locked != 0 )
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 - volume is locked.",
2412
0
     function );
2413
2414
0
    return( -1 );
2415
0
  }
2416
0
  if( internal_volume->io_handle == NULL )
2417
0
  {
2418
0
    libcerror_error_set(
2419
0
     error,
2420
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2421
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2422
0
     "%s: invalid volume - missing IO handle.",
2423
0
     function );
2424
2425
0
    return( -1 );
2426
0
  }
2427
0
  if( ( whence != SEEK_CUR )
2428
0
   && ( whence != SEEK_END )
2429
0
   && ( whence != SEEK_SET ) )
2430
0
  {
2431
0
    libcerror_error_set(
2432
0
     error,
2433
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2434
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
2435
0
     "%s: unsupported whence.",
2436
0
     function );
2437
2438
0
    return( -1 );
2439
0
  }
2440
0
  if( whence == SEEK_CUR )
2441
0
  { 
2442
0
    offset += internal_volume->current_offset;
2443
0
  }
2444
0
  else if( whence == SEEK_END )
2445
0
  { 
2446
0
    offset += (off64_t) internal_volume->io_handle->encrypted_volume_size;
2447
0
  }
2448
#if defined( HAVE_DEBUG_OUTPUT )
2449
  if( libcnotify_verbose != 0 )
2450
  {
2451
    libcnotify_printf(
2452
     "%s: seeking volume data offset: %" PRIi64 ".\n",
2453
     function,
2454
     offset );
2455
  }
2456
#endif
2457
0
  if( offset < 0 )
2458
0
  {
2459
0
    libcerror_error_set(
2460
0
     error,
2461
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2462
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
2463
0
     "%s: invalid offset value out of bounds.",
2464
0
     function );
2465
2466
0
    return( -1 );
2467
0
  }
2468
0
  internal_volume->current_offset = offset;
2469
2470
0
  return( offset );
2471
0
}
2472
2473
/* Seeks a certain offset of the data
2474
 * Returns the offset if seek is successful or -1 on error
2475
 */
2476
off64_t libluksde_volume_seek_offset(
2477
         libluksde_volume_t *volume,
2478
         off64_t offset,
2479
         int whence,
2480
         libcerror_error_t **error )
2481
0
{
2482
0
  libluksde_internal_volume_t *internal_volume = NULL;
2483
0
  static char *function                        = "libluksde_volume_seek_offset";
2484
2485
0
  if( volume == NULL )
2486
0
  {
2487
0
    libcerror_error_set(
2488
0
     error,
2489
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2490
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2491
0
     "%s: invalid volume.",
2492
0
     function );
2493
2494
0
    return( -1 );
2495
0
  }
2496
0
  internal_volume = (libluksde_internal_volume_t *) volume;
2497
2498
0
  if( internal_volume->file_io_handle == NULL )
2499
0
  {
2500
0
    libcerror_error_set(
2501
0
     error,
2502
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2503
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2504
0
     "%s: invalid volume - missing file IO handle.",
2505
0
     function );
2506
2507
0
    return( -1 );
2508
0
  }
2509
0
#if defined( HAVE_LIBLUKSDE_MULTI_THREAD_SUPPORT )
2510
0
  if( libcthreads_read_write_lock_grab_for_write(
2511
0
       internal_volume->read_write_lock,
2512
0
       error ) != 1 )
2513
0
  {
2514
0
    libcerror_error_set(
2515
0
     error,
2516
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2517
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2518
0
     "%s: unable to grab read/write lock for writing.",
2519
0
     function );
2520
2521
0
    return( -1 );
2522
0
  }
2523
0
#endif
2524
0
  offset = libluksde_internal_volume_seek_offset(
2525
0
            internal_volume,
2526
0
            offset,
2527
0
            whence,
2528
0
            error );
2529
2530
0
  if( offset == -1 )
2531
0
  {
2532
0
    libcerror_error_set(
2533
0
     error,
2534
0
     LIBCERROR_ERROR_DOMAIN_IO,
2535
0
     LIBCERROR_IO_ERROR_SEEK_FAILED,
2536
0
     "%s: unable to seek offset.",
2537
0
     function );
2538
2539
0
    offset = -1;
2540
0
  }
2541
0
#if defined( HAVE_LIBLUKSDE_MULTI_THREAD_SUPPORT )
2542
0
  if( libcthreads_read_write_lock_release_for_write(
2543
0
       internal_volume->read_write_lock,
2544
0
       error ) != 1 )
2545
0
  {
2546
0
    libcerror_error_set(
2547
0
     error,
2548
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2549
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2550
0
     "%s: unable to release read/write lock for writing.",
2551
0
     function );
2552
2553
0
    return( -1 );
2554
0
  }
2555
0
#endif
2556
0
  return( offset );
2557
0
}
2558
2559
/* Retrieves the current offset of the (volume) data
2560
 * Returns 1 if successful or -1 on error
2561
 */
2562
int libluksde_volume_get_offset(
2563
     libluksde_volume_t *volume,
2564
     off64_t *offset,
2565
     libcerror_error_t **error )
2566
0
{
2567
0
  libluksde_internal_volume_t *internal_volume = NULL;
2568
0
  static char *function                        = "libluksde_volume_get_offset";
2569
2570
0
  if( volume == NULL )
2571
0
  {
2572
0
    libcerror_error_set(
2573
0
     error,
2574
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2575
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2576
0
     "%s: invalid volume.",
2577
0
     function );
2578
2579
0
    return( -1 );
2580
0
  }
2581
0
  internal_volume = (libluksde_internal_volume_t *) volume;
2582
2583
0
  if( offset == NULL )
2584
0
  {
2585
0
    libcerror_error_set(
2586
0
     error,
2587
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2588
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2589
0
     "%s: invalid offset.",
2590
0
     function );
2591
2592
0
    return( -1 );
2593
0
  }
2594
0
#if defined( HAVE_LIBLUKSDE_MULTI_THREAD_SUPPORT )
2595
0
  if( libcthreads_read_write_lock_grab_for_read(
2596
0
       internal_volume->read_write_lock,
2597
0
       error ) != 1 )
2598
0
  {
2599
0
    libcerror_error_set(
2600
0
     error,
2601
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2602
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2603
0
     "%s: unable to grab read/write lock for reading.",
2604
0
     function );
2605
2606
0
    return( -1 );
2607
0
  }
2608
0
#endif
2609
0
  *offset = internal_volume->current_offset;
2610
2611
0
#if defined( HAVE_LIBLUKSDE_MULTI_THREAD_SUPPORT )
2612
0
  if( libcthreads_read_write_lock_release_for_read(
2613
0
       internal_volume->read_write_lock,
2614
0
       error ) != 1 )
2615
0
  {
2616
0
    libcerror_error_set(
2617
0
     error,
2618
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2619
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2620
0
     "%s: unable to release read/write lock for reading.",
2621
0
     function );
2622
2623
0
    return( -1 );
2624
0
  }
2625
0
#endif
2626
0
  return( 1 );
2627
0
}
2628
2629
/* Retrieves the size
2630
 * Returns 1 if successful or -1 on error
2631
 */
2632
int libluksde_volume_get_size(
2633
     libluksde_volume_t *volume,
2634
     size64_t *size,
2635
     libcerror_error_t **error )
2636
0
{
2637
0
  libluksde_internal_volume_t *internal_volume = NULL;
2638
0
  static char *function                        = "libluksde_volume_get_size";
2639
2640
0
  if( volume == NULL )
2641
0
  {
2642
0
    libcerror_error_set(
2643
0
     error,
2644
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2645
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2646
0
     "%s: invalid volume.",
2647
0
     function );
2648
2649
0
    return( -1 );
2650
0
  }
2651
0
  internal_volume = (libluksde_internal_volume_t *) volume;
2652
2653
0
  if( internal_volume->io_handle == NULL )
2654
0
  {
2655
0
    libcerror_error_set(
2656
0
     error,
2657
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2658
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2659
0
     "%s: invalid volume - missing IO handle.",
2660
0
     function );
2661
2662
0
    return( -1 );
2663
0
  }
2664
0
  if( size == NULL )
2665
0
  {
2666
0
    libcerror_error_set(
2667
0
     error,
2668
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2669
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2670
0
     "%s: invalid size.",
2671
0
     function );
2672
2673
0
    return( -1 );
2674
0
  }
2675
0
#if defined( HAVE_LIBLUKSDE_MULTI_THREAD_SUPPORT )
2676
0
  if( libcthreads_read_write_lock_grab_for_read(
2677
0
       internal_volume->read_write_lock,
2678
0
       error ) != 1 )
2679
0
  {
2680
0
    libcerror_error_set(
2681
0
     error,
2682
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2683
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2684
0
     "%s: unable to grab read/write lock for reading.",
2685
0
     function );
2686
2687
0
    return( -1 );
2688
0
  }
2689
0
#endif
2690
0
  *size = internal_volume->io_handle->encrypted_volume_size;
2691
2692
0
#if defined( HAVE_LIBLUKSDE_MULTI_THREAD_SUPPORT )
2693
0
  if( libcthreads_read_write_lock_release_for_read(
2694
0
       internal_volume->read_write_lock,
2695
0
       error ) != 1 )
2696
0
  {
2697
0
    libcerror_error_set(
2698
0
     error,
2699
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2700
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2701
0
     "%s: unable to release read/write lock for reading.",
2702
0
     function );
2703
2704
0
    return( -1 );
2705
0
  }
2706
0
#endif
2707
0
  return( 1 );
2708
0
}
2709
2710
/* Retrieves the encryption method
2711
 * Returns 1 if successful or -1 on error
2712
 */
2713
int libluksde_volume_get_encryption_method(
2714
     libluksde_volume_t *volume,
2715
     int *encryption_method,
2716
     int *encryption_chaining_mode,
2717
     libcerror_error_t **error )
2718
0
{
2719
0
  libluksde_internal_volume_t *internal_volume = NULL;
2720
0
  static char *function                        = "libluksde_volume_get_encryption_method";
2721
2722
0
  if( volume == NULL )
2723
0
  {
2724
0
    libcerror_error_set(
2725
0
     error,
2726
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2727
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2728
0
     "%s: invalid volume.",
2729
0
     function );
2730
2731
0
    return( -1 );
2732
0
  }
2733
0
  internal_volume = (libluksde_internal_volume_t *) volume;
2734
2735
0
  if( internal_volume->volume_header == NULL )
2736
0
  {
2737
0
    libcerror_error_set(
2738
0
     error,
2739
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2740
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
2741
0
     "%s: invalid volume - missing volume header.",
2742
0
     function );
2743
2744
0
    return( -1 );
2745
0
  }
2746
0
  if( encryption_method == 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 method.",
2753
0
     function );
2754
2755
0
    return( -1 );
2756
0
  }
2757
0
  if( encryption_chaining_mode == NULL )
2758
0
  {
2759
0
    libcerror_error_set(
2760
0
     error,
2761
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2762
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2763
0
     "%s: invalid encryption chaining mode.",
2764
0
     function );
2765
2766
0
    return( -1 );
2767
0
  }
2768
0
#if defined( HAVE_LIBLUKSDE_MULTI_THREAD_SUPPORT )
2769
0
  if( libcthreads_read_write_lock_grab_for_read(
2770
0
       internal_volume->read_write_lock,
2771
0
       error ) != 1 )
2772
0
  {
2773
0
    libcerror_error_set(
2774
0
     error,
2775
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2776
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2777
0
     "%s: unable to grab read/write lock for reading.",
2778
0
     function );
2779
2780
0
    return( -1 );
2781
0
  }
2782
0
#endif
2783
0
  *encryption_method        = internal_volume->volume_header->encryption_method;
2784
0
  *encryption_chaining_mode = internal_volume->volume_header->encryption_chaining_mode;
2785
2786
0
#if defined( HAVE_LIBLUKSDE_MULTI_THREAD_SUPPORT )
2787
0
  if( libcthreads_read_write_lock_release_for_read(
2788
0
       internal_volume->read_write_lock,
2789
0
       error ) != 1 )
2790
0
  {
2791
0
    libcerror_error_set(
2792
0
     error,
2793
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2794
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2795
0
     "%s: unable to release read/write lock for reading.",
2796
0
     function );
2797
2798
0
    return( -1 );
2799
0
  }
2800
0
#endif
2801
0
  return( 1 );
2802
0
}
2803
2804
/* Retrieves the volume identifier
2805
 * The identifier is an UUID and is 16 bytes of size
2806
 * Returns 1 if successful, 0 if not or or -1 on error
2807
 */
2808
int libluksde_volume_get_volume_identifier(
2809
     libluksde_volume_t *volume,
2810
     uint8_t *uuid_data,
2811
     size_t uuid_data_size,
2812
     libcerror_error_t **error )
2813
0
{
2814
0
  libluksde_internal_volume_t *internal_volume = NULL;
2815
0
  static char *function                        = "libluksde_volume_get_volume_identifier";
2816
0
  int result                                   = 0;
2817
2818
0
  if( volume == NULL )
2819
0
  {
2820
0
    libcerror_error_set(
2821
0
     error,
2822
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2823
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2824
0
     "%s: invalid volume.",
2825
0
     function );
2826
2827
0
    return( -1 );
2828
0
  }
2829
0
  internal_volume = (libluksde_internal_volume_t *) volume;
2830
2831
#if defined( HAVE_LIBBDE_MULTI_THREAD_SUPPORT )
2832
  if( libcthreads_read_write_lock_grab_for_read(
2833
       internal_volume->read_write_lock,
2834
       error ) != 1 )
2835
  {
2836
    libcerror_error_set(
2837
     error,
2838
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2839
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2840
     "%s: unable to grab read/write lock for reading.",
2841
     function );
2842
2843
    return( -1 );
2844
  }
2845
#endif
2846
0
  if( internal_volume->volume_header != NULL )
2847
0
  {
2848
0
    result = libluksde_volume_header_get_volume_identifier(
2849
0
              internal_volume->volume_header,
2850
0
              uuid_data,
2851
0
              uuid_data_size,
2852
0
              error );
2853
2854
0
    if( result != 1 )
2855
0
    {
2856
0
      libcerror_error_set(
2857
0
       error,
2858
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
2859
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
2860
0
       "%s: unable to retrieve volume identifier.",
2861
0
       function );
2862
2863
0
      result = -1;
2864
0
    }
2865
0
  }
2866
#if defined( HAVE_LIBBDE_MULTI_THREAD_SUPPORT )
2867
  if( libcthreads_read_write_lock_release_for_read(
2868
       internal_volume->read_write_lock,
2869
       error ) != 1 )
2870
  {
2871
    libcerror_error_set(
2872
     error,
2873
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2874
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2875
     "%s: unable to release read/write lock for reading.",
2876
     function );
2877
2878
    return( -1 );
2879
  }
2880
#endif
2881
0
  return( result );
2882
0
}
2883
2884
/* Sets the key
2885
 * This function needs to be used before one of the open functions
2886
 * Returns 1 if successful or -1 on error
2887
 */
2888
int libluksde_volume_set_key(
2889
     libluksde_volume_t *volume,
2890
     const uint8_t *master_key,
2891
     size_t master_key_size,
2892
     libcerror_error_t **error )
2893
0
{
2894
0
  libluksde_internal_volume_t *internal_volume = NULL;
2895
0
  static char *function                        = "libluksde_volume_set_key";
2896
2897
0
  if( volume == NULL )
2898
0
  {
2899
0
    libcerror_error_set(
2900
0
     error,
2901
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2902
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2903
0
     "%s: invalid volume.",
2904
0
     function );
2905
2906
0
    return( -1 );
2907
0
  }
2908
0
  internal_volume = (libluksde_internal_volume_t *) volume;
2909
2910
0
  if( master_key == NULL )
2911
0
  {
2912
0
    libcerror_error_set(
2913
0
     error,
2914
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2915
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
2916
0
     "%s: invalid master key.",
2917
0
     function );
2918
2919
0
    return( -1 );
2920
0
  }
2921
0
  if( ( master_key_size != 16 )
2922
0
   && ( master_key_size != 32 )
2923
0
   && ( master_key_size != 64 ) )
2924
0
  {
2925
0
    libcerror_error_set(
2926
0
     error,
2927
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
2928
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
2929
0
     "%s: unsupported master key size.",
2930
0
     function );
2931
2932
0
    return( -1 );
2933
0
  }
2934
0
#if defined( HAVE_LIBLUKSDE_MULTI_THREAD_SUPPORT )
2935
0
  if( libcthreads_read_write_lock_grab_for_write(
2936
0
       internal_volume->read_write_lock,
2937
0
       error ) != 1 )
2938
0
  {
2939
0
    libcerror_error_set(
2940
0
     error,
2941
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2942
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2943
0
     "%s: unable to grab read/write lock for writing.",
2944
0
     function );
2945
2946
0
    return( -1 );
2947
0
  }
2948
0
#endif
2949
0
  if( memory_set(
2950
0
       internal_volume->master_key,
2951
0
       0,
2952
0
       64  ) == NULL )
2953
0
  {
2954
0
    libcerror_error_set(
2955
0
     error,
2956
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
2957
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
2958
0
     "%s: unable to clear master key.",
2959
0
     function );
2960
2961
0
    goto on_error;
2962
0
  }
2963
0
  if( memory_copy(
2964
0
       internal_volume->master_key,
2965
0
       master_key,
2966
0
       master_key_size ) == NULL )
2967
0
  {
2968
0
    libcerror_error_set(
2969
0
     error,
2970
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
2971
0
     LIBCERROR_MEMORY_ERROR_COPY_FAILED,
2972
0
     "%s: unable to copy master key.",
2973
0
     function );
2974
2975
0
    goto on_error;
2976
0
  }
2977
0
  internal_volume->master_key_size = (uint32_t) master_key_size;
2978
2979
0
  internal_volume->volume_master_key_is_set = 1;
2980
2981
0
#if defined( HAVE_LIBLUKSDE_MULTI_THREAD_SUPPORT )
2982
0
  if( libcthreads_read_write_lock_release_for_write(
2983
0
       internal_volume->read_write_lock,
2984
0
       error ) != 1 )
2985
0
  {
2986
0
    libcerror_error_set(
2987
0
     error,
2988
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2989
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
2990
0
     "%s: unable to release read/write lock for writing.",
2991
0
     function );
2992
2993
0
    return( -1 );
2994
0
  }
2995
0
#endif
2996
0
  return( 1 );
2997
2998
0
on_error:
2999
0
  memory_set(
3000
0
   internal_volume->master_key,
3001
0
   0,
3002
0
   32 );
3003
3004
0
#if defined( HAVE_LIBLUKSDE_MULTI_THREAD_SUPPORT )
3005
0
  libcthreads_read_write_lock_release_for_write(
3006
0
   internal_volume->read_write_lock,
3007
0
   NULL );
3008
0
#endif
3009
0
  return( -1 );
3010
0
}
3011
3012
/* Sets the keys
3013
 * This function needs to be used before one of the open functions
3014
 * Returns 1 if successful or -1 on error
3015
 */
3016
int libluksde_volume_set_keys(
3017
     libluksde_volume_t *volume,
3018
     const uint8_t *master_key,
3019
     size_t master_key_size,
3020
     libcerror_error_t **error )
3021
0
{
3022
0
  libluksde_internal_volume_t *internal_volume = NULL;
3023
0
  static char *function                        = "libluksde_volume_set_keys";
3024
3025
0
  if( volume == NULL )
3026
0
  {
3027
0
    libcerror_error_set(
3028
0
     error,
3029
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3030
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3031
0
     "%s: invalid volume.",
3032
0
     function );
3033
3034
0
    return( -1 );
3035
0
  }
3036
0
  internal_volume = (libluksde_internal_volume_t *) volume;
3037
3038
0
  if( master_key == NULL )
3039
0
  {
3040
0
    libcerror_error_set(
3041
0
     error,
3042
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3043
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3044
0
     "%s: invalid master key.",
3045
0
     function );
3046
3047
0
    return( -1 );
3048
0
  }
3049
0
  if( ( master_key_size != 16 )
3050
0
   && ( master_key_size != 32 ) )
3051
0
  {
3052
0
    libcerror_error_set(
3053
0
     error,
3054
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3055
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
3056
0
     "%s: unsupported master key size.",
3057
0
     function );
3058
3059
0
    return( -1 );
3060
0
  }
3061
0
#if defined( HAVE_LIBLUKSDE_MULTI_THREAD_SUPPORT )
3062
0
  if( libcthreads_read_write_lock_grab_for_write(
3063
0
       internal_volume->read_write_lock,
3064
0
       error ) != 1 )
3065
0
  {
3066
0
    libcerror_error_set(
3067
0
     error,
3068
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3069
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3070
0
     "%s: unable to grab read/write lock for writing.",
3071
0
     function );
3072
3073
0
    return( -1 );
3074
0
  }
3075
0
#endif
3076
0
  if( master_key_size < 32 )
3077
0
  {
3078
0
    if( memory_set(
3079
0
         internal_volume->master_key,
3080
0
         0,
3081
0
         32  ) == NULL )
3082
0
    {
3083
0
      libcerror_error_set(
3084
0
       error,
3085
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
3086
0
       LIBCERROR_MEMORY_ERROR_SET_FAILED,
3087
0
       "%s: unable to clear master key.",
3088
0
       function );
3089
3090
0
      goto on_error;
3091
0
    }
3092
0
  }
3093
0
  if( memory_copy(
3094
0
       internal_volume->master_key,
3095
0
       master_key,
3096
0
       master_key_size ) == NULL )
3097
0
  {
3098
0
    libcerror_error_set(
3099
0
     error,
3100
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
3101
0
     LIBCERROR_MEMORY_ERROR_COPY_FAILED,
3102
0
     "%s: unable to copy master key.",
3103
0
     function );
3104
3105
0
    goto on_error;
3106
0
  }
3107
0
  internal_volume->master_key_size = (uint32_t) master_key_size;
3108
3109
0
  internal_volume->volume_master_key_is_set = 1;
3110
3111
0
#if defined( HAVE_LIBLUKSDE_MULTI_THREAD_SUPPORT )
3112
0
  if( libcthreads_read_write_lock_release_for_write(
3113
0
       internal_volume->read_write_lock,
3114
0
       error ) != 1 )
3115
0
  {
3116
0
    libcerror_error_set(
3117
0
     error,
3118
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3119
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3120
0
     "%s: unable to release read/write lock for writing.",
3121
0
     function );
3122
3123
0
    return( -1 );
3124
0
  }
3125
0
#endif
3126
0
  return( 1 );
3127
3128
0
on_error:
3129
0
  memory_set(
3130
0
   internal_volume->master_key,
3131
0
   0,
3132
0
   32 );
3133
3134
0
#if defined( HAVE_LIBLUKSDE_MULTI_THREAD_SUPPORT )
3135
0
  libcthreads_read_write_lock_release_for_write(
3136
0
   internal_volume->read_write_lock,
3137
0
   NULL );
3138
0
#endif
3139
0
  return( -1 );
3140
0
}
3141
3142
/* Sets an UTF-8 formatted password
3143
 * This function needs to be used before one of the open functions
3144
 * Returns 1 if successful, 0 if password is invalid or -1 on error
3145
 */
3146
int libluksde_volume_set_utf8_password(
3147
     libluksde_volume_t *volume,
3148
     const uint8_t *utf8_string,
3149
     size_t utf8_string_length,
3150
     libcerror_error_t **error )
3151
0
{
3152
0
  libluksde_internal_volume_t *internal_volume = NULL;
3153
0
  static char *function                        = "libluksde_volume_set_utf8_password";
3154
3155
0
  if( volume == NULL )
3156
0
  {
3157
0
    libcerror_error_set(
3158
0
     error,
3159
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3160
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3161
0
     "%s: invalid volume.",
3162
0
     function );
3163
3164
0
    return( -1 );
3165
0
  }
3166
0
  internal_volume = (libluksde_internal_volume_t *) volume;
3167
3168
0
#if defined( HAVE_LIBLUKSDE_MULTI_THREAD_SUPPORT )
3169
0
  if( libcthreads_read_write_lock_grab_for_write(
3170
0
       internal_volume->read_write_lock,
3171
0
       error ) != 1 )
3172
0
  {
3173
0
    libcerror_error_set(
3174
0
     error,
3175
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3176
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3177
0
     "%s: unable to grab read/write lock for writing.",
3178
0
     function );
3179
3180
0
    return( -1 );
3181
0
  }
3182
0
#endif
3183
0
  if( internal_volume->user_password != NULL )
3184
0
  {
3185
0
    if( memory_set(
3186
0
         internal_volume->user_password,
3187
0
         0,
3188
0
         internal_volume->user_password_size ) == NULL )
3189
0
    {
3190
0
      libcerror_error_set(
3191
0
       error,
3192
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
3193
0
       LIBCERROR_MEMORY_ERROR_SET_FAILED,
3194
0
       "%s: unable to user password.",
3195
0
       function );
3196
3197
0
#if defined( HAVE_LIBLUKSDE_MULTI_THREAD_SUPPORT )
3198
0
      libcthreads_read_write_lock_release_for_write(
3199
0
       internal_volume->read_write_lock,
3200
0
       NULL );
3201
0
#endif
3202
0
      return( -1 );
3203
0
    }
3204
0
    memory_free(
3205
0
     internal_volume->user_password );
3206
3207
0
    internal_volume->user_password      = NULL;
3208
0
    internal_volume->user_password_size = 0;
3209
0
  }
3210
0
  if( libuna_byte_stream_size_from_utf8(
3211
0
       utf8_string,
3212
0
       utf8_string_length,
3213
0
       LIBLUKSDE_CODEPAGE_US_ASCII,
3214
0
       &( internal_volume->user_password_size ),
3215
0
       error ) != 1 )
3216
0
  {
3217
0
    libcerror_error_set(
3218
0
     error,
3219
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3220
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3221
0
     "%s: unable to set password size.",
3222
0
     function );
3223
3224
0
    goto on_error;
3225
0
  }
3226
0
  internal_volume->user_password_size += 1;
3227
3228
0
  if( internal_volume->user_password_size > (size_t) MEMORY_MAXIMUM_ALLOCATION_SIZE )
3229
0
  {
3230
0
    libcerror_error_set(
3231
0
     error,
3232
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3233
0
     LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
3234
0
     "%s: invalid volume - user password size value exceeds maximum allocation size.",
3235
0
     function );
3236
3237
0
    goto on_error;
3238
0
  }
3239
0
  internal_volume->user_password = (uint8_t *) memory_allocate(
3240
0
                                                sizeof( uint8_t ) * internal_volume->user_password_size );
3241
3242
0
  if( internal_volume->user_password == NULL )
3243
0
  {
3244
0
    libcerror_error_set(
3245
0
     error,
3246
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3247
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3248
0
     "%s: unable to create user password.",
3249
0
     function );
3250
3251
0
    goto on_error;
3252
0
  }
3253
0
  if( libuna_byte_stream_copy_from_utf8(
3254
0
       internal_volume->user_password,
3255
0
       internal_volume->user_password_size,
3256
0
       LIBLUKSDE_CODEPAGE_US_ASCII,
3257
0
       utf8_string,
3258
0
       utf8_string_length,
3259
0
       error ) != 1 )
3260
0
  {
3261
0
    libcerror_error_set(
3262
0
     error,
3263
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3264
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3265
0
     "%s: unable to copy user password.",
3266
0
     function );
3267
3268
0
    goto on_error;
3269
0
  }
3270
0
  internal_volume->user_password[ internal_volume->user_password_size - 1 ] = 0;
3271
3272
0
  internal_volume->user_password_is_set = 1;
3273
3274
#if defined( HAVE_DEBUG_OUTPUT )
3275
  if( libcnotify_verbose != 0 )
3276
  {
3277
    libcnotify_printf(
3278
     "%s: user password: %s\n",
3279
     function,
3280
     internal_volume->user_password );
3281
  }
3282
#endif
3283
0
#if defined( HAVE_LIBLUKSDE_MULTI_THREAD_SUPPORT )
3284
0
  if( libcthreads_read_write_lock_release_for_write(
3285
0
       internal_volume->read_write_lock,
3286
0
       error ) != 1 )
3287
0
  {
3288
0
    libcerror_error_set(
3289
0
     error,
3290
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3291
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3292
0
     "%s: unable to release read/write lock for writing.",
3293
0
     function );
3294
3295
0
    return( -1 );
3296
0
  }
3297
0
#endif
3298
0
  return( 1 );
3299
3300
0
on_error:
3301
0
  if( internal_volume->user_password != NULL )
3302
0
  {
3303
0
    memory_set(
3304
0
     internal_volume->user_password,
3305
0
     0,
3306
0
     internal_volume->user_password_size );
3307
0
    memory_free(
3308
0
     internal_volume->user_password );
3309
3310
0
    internal_volume->user_password = NULL;
3311
0
  }
3312
0
  internal_volume->user_password_size = 0;
3313
3314
0
#if defined( HAVE_LIBLUKSDE_MULTI_THREAD_SUPPORT )
3315
0
  libcthreads_read_write_lock_release_for_write(
3316
0
   internal_volume->read_write_lock,
3317
0
   NULL );
3318
0
#endif
3319
0
  return( -1 );
3320
0
}
3321
3322
/* Sets an UTF-16 formatted password
3323
 * This function needs to be used before one of the open functions
3324
 * Returns 1 if successful, 0 if password is invalid or -1 on error
3325
 */
3326
int libluksde_volume_set_utf16_password(
3327
     libluksde_volume_t *volume,
3328
     const uint16_t *utf16_string,
3329
     size_t utf16_string_length,
3330
     libcerror_error_t **error )
3331
0
{
3332
0
  libluksde_internal_volume_t *internal_volume = NULL;
3333
0
  static char *function                        = "libluksde_volume_set_utf16_password";
3334
3335
0
  if( volume == NULL )
3336
0
  {
3337
0
    libcerror_error_set(
3338
0
     error,
3339
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
3340
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
3341
0
     "%s: invalid volume.",
3342
0
     function );
3343
3344
0
    return( -1 );
3345
0
  }
3346
0
  internal_volume = (libluksde_internal_volume_t *) volume;
3347
3348
0
#if defined( HAVE_LIBLUKSDE_MULTI_THREAD_SUPPORT )
3349
0
  if( libcthreads_read_write_lock_grab_for_write(
3350
0
       internal_volume->read_write_lock,
3351
0
       error ) != 1 )
3352
0
  {
3353
0
    libcerror_error_set(
3354
0
     error,
3355
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3356
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3357
0
     "%s: unable to grab read/write lock for writing.",
3358
0
     function );
3359
3360
0
    return( -1 );
3361
0
  }
3362
0
#endif
3363
0
  if( internal_volume->user_password != NULL )
3364
0
  {
3365
0
    if( memory_set(
3366
0
         internal_volume->user_password,
3367
0
         0,
3368
0
         internal_volume->user_password_size ) == NULL )
3369
0
    {
3370
0
      libcerror_error_set(
3371
0
       error,
3372
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
3373
0
       LIBCERROR_MEMORY_ERROR_SET_FAILED,
3374
0
       "%s: unable to user password.",
3375
0
       function );
3376
3377
0
#if defined( HAVE_LIBLUKSDE_MULTI_THREAD_SUPPORT )
3378
0
      libcthreads_read_write_lock_release_for_write(
3379
0
       internal_volume->read_write_lock,
3380
0
       NULL );
3381
0
#endif
3382
0
      return( -1 );
3383
0
    }
3384
0
    memory_free(
3385
0
     internal_volume->user_password );
3386
3387
0
    internal_volume->user_password      = NULL;
3388
0
    internal_volume->user_password_size = 0;
3389
0
  }
3390
0
  if( libuna_byte_stream_size_from_utf16(
3391
0
       utf16_string,
3392
0
       utf16_string_length,
3393
0
       LIBLUKSDE_CODEPAGE_US_ASCII,
3394
0
       &( internal_volume->user_password_size ),
3395
0
       error ) != 1 )
3396
0
  {
3397
0
    libcerror_error_set(
3398
0
     error,
3399
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3400
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3401
0
     "%s: unable to set password length.",
3402
0
     function );
3403
3404
0
    goto on_error;
3405
0
  }
3406
0
  internal_volume->user_password_size += 1;
3407
3408
0
  if( internal_volume->user_password_size > (size_t) MEMORY_MAXIMUM_ALLOCATION_SIZE )
3409
0
  {
3410
0
    libcerror_error_set(
3411
0
     error,
3412
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3413
0
     LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM,
3414
0
     "%s: invalid volume - user password size value exceeds maximum allocation size.",
3415
0
     function );
3416
3417
0
    goto on_error;
3418
0
  }
3419
0
  internal_volume->user_password = (uint8_t *) memory_allocate(
3420
0
                                                sizeof( uint8_t ) * internal_volume->user_password_size );
3421
3422
0
  if( internal_volume->user_password == NULL )
3423
0
  {
3424
0
    libcerror_error_set(
3425
0
     error,
3426
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3427
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3428
0
     "%s: unable to create user password.",
3429
0
     function );
3430
3431
0
    goto on_error;
3432
0
  }
3433
0
  if( libuna_byte_stream_copy_from_utf16(
3434
0
       internal_volume->user_password,
3435
0
       internal_volume->user_password_size,
3436
0
       LIBLUKSDE_CODEPAGE_US_ASCII,
3437
0
       utf16_string,
3438
0
       utf16_string_length,
3439
0
       error ) != 1 )
3440
0
  {
3441
0
    libcerror_error_set(
3442
0
     error,
3443
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3444
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3445
0
     "%s: unable to copy user password.",
3446
0
     function );
3447
3448
0
    goto on_error;
3449
0
  }
3450
0
  internal_volume->user_password[ internal_volume->user_password_size - 1 ] = 0;
3451
3452
0
  internal_volume->user_password_is_set = 1;
3453
3454
#if defined( HAVE_DEBUG_OUTPUT )
3455
  if( libcnotify_verbose != 0 )
3456
  {
3457
    libcnotify_printf(
3458
     "%s: user password: %s\n",
3459
     function,
3460
     internal_volume->user_password );
3461
  }
3462
#endif
3463
0
#if defined( HAVE_LIBLUKSDE_MULTI_THREAD_SUPPORT )
3464
0
  if( libcthreads_read_write_lock_release_for_write(
3465
0
       internal_volume->read_write_lock,
3466
0
       error ) != 1 )
3467
0
  {
3468
0
    libcerror_error_set(
3469
0
     error,
3470
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
3471
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
3472
0
     "%s: unable to release read/write lock for writing.",
3473
0
     function );
3474
3475
0
    return( -1 );
3476
0
  }
3477
0
#endif
3478
0
  return( 1 );
3479
3480
0
on_error:
3481
0
  if( internal_volume->user_password != NULL )
3482
0
  {
3483
0
    memory_set(
3484
0
     internal_volume->user_password,
3485
0
     0,
3486
0
     internal_volume->user_password_size );
3487
0
    memory_free(
3488
0
     internal_volume->user_password );
3489
3490
0
    internal_volume->user_password = NULL;
3491
0
  }
3492
0
  internal_volume->user_password_size = 0;
3493
3494
0
#if defined( HAVE_LIBLUKSDE_MULTI_THREAD_SUPPORT )
3495
0
  libcthreads_read_write_lock_release_for_write(
3496
0
   internal_volume->read_write_lock,
3497
0
   NULL );
3498
0
#endif
3499
0
  return( -1 );
3500
0
}
3501