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