Coverage Report

Created: 2026-05-30 07:13

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libluksde/libluksde/libluksde_volume_header.c
Line
Count
Source
1
/*
2
 * The LUKS volume header functions
3
 *
4
 * Copyright (C) 2013-2026, 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 <byte_stream.h>
24
#include <memory.h>
25
#include <types.h>
26
27
#include "libluksde_debug.h"
28
#include "libluksde_definitions.h"
29
#include "libluksde_io_handle.h"
30
#include "libluksde_key_slot.h"
31
#include "libluksde_libbfio.h"
32
#include "libluksde_libcdata.h"
33
#include "libluksde_libcerror.h"
34
#include "libluksde_libcnotify.h"
35
#include "libluksde_libfguid.h"
36
#include "libluksde_libuna.h"
37
#include "libluksde_volume_header.h"
38
39
#include "luksde_keyslot.h"
40
#include "luksde_volume.h"
41
42
const uint8_t luksde_backup_volume_header_signature[ 6 ] = { 'S', 'K', 'U', 'L', 0xba, 0xbe };
43
44
/* Creates a volume header
45
 * Make sure the value volume_header is referencing, is set to NULL
46
 * Returns 1 if successful or -1 on error
47
 */
48
int libluksde_volume_header_initialize(
49
     libluksde_volume_header_t **volume_header,
50
     libcerror_error_t **error )
51
1.30k
{
52
1.30k
  static char *function = "libluksde_volume_header_initialize";
53
54
1.30k
  if( volume_header == NULL )
55
0
  {
56
0
    libcerror_error_set(
57
0
     error,
58
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
59
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
60
0
     "%s: invalid volume header.",
61
0
     function );
62
63
0
    return( -1 );
64
0
  }
65
1.30k
  if( *volume_header != NULL )
66
0
  {
67
0
    libcerror_error_set(
68
0
     error,
69
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
70
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
71
0
     "%s: invalid volume header value already set.",
72
0
     function );
73
74
0
    return( -1 );
75
0
  }
76
1.30k
  *volume_header = memory_allocate_structure(
77
1.30k
                    libluksde_volume_header_t );
78
79
1.30k
  if( *volume_header == NULL )
80
0
  {
81
0
    libcerror_error_set(
82
0
     error,
83
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
84
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
85
0
     "%s: unable to create volume header.",
86
0
     function );
87
88
0
    goto on_error;
89
0
  }
90
1.30k
  if( memory_set(
91
1.30k
       *volume_header,
92
1.30k
       0,
93
1.30k
       sizeof( libluksde_volume_header_t ) ) == NULL )
94
0
  {
95
0
    libcerror_error_set(
96
0
     error,
97
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
98
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
99
0
     "%s: unable to clear volume header.",
100
0
     function );
101
102
0
    memory_free(
103
0
     *volume_header );
104
105
0
    *volume_header = NULL;
106
107
0
    return( -1 );
108
0
  }
109
1.30k
  if( libcdata_array_initialize(
110
1.30k
       &( ( *volume_header )->key_slots_array ),
111
1.30k
       0,
112
1.30k
       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 key slots array.",
119
0
     function );
120
121
0
    goto on_error;
122
0
  }
123
1.30k
  return( 1 );
124
125
0
on_error:
126
0
  if( *volume_header != NULL )
127
0
  {
128
0
    memory_free(
129
0
     *volume_header );
130
131
0
    *volume_header = NULL;
132
0
  }
133
0
  return( -1 );
134
1.30k
}
135
136
/* Frees a volume header
137
 * Returns 1 if successful or -1 on error
138
 */
139
int libluksde_volume_header_free(
140
     libluksde_volume_header_t **volume_header,
141
     libcerror_error_t **error )
142
1.30k
{
143
1.30k
  static char *function = "libluksde_volume_header_free";
144
1.30k
  int result            = 1;
145
146
1.30k
  if( volume_header == NULL )
147
0
  {
148
0
    libcerror_error_set(
149
0
     error,
150
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
151
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
152
0
     "%s: invalid volume header.",
153
0
     function );
154
155
0
    return( -1 );
156
0
  }
157
1.30k
  if( *volume_header != NULL )
158
1.30k
  {
159
1.30k
    if( libcdata_array_free(
160
1.30k
         &( ( *volume_header )->key_slots_array ),
161
1.30k
         (int(*)(intptr_t **, libcerror_error_t **)) &libluksde_key_slot_free,
162
1.30k
         error ) != 1 )
163
0
    {
164
0
      libcerror_error_set(
165
0
       error,
166
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
167
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
168
0
       "%s: unable to free key slots array.",
169
0
       function );
170
171
0
      result = -1;
172
0
    }
173
1.30k
    memory_free(
174
1.30k
     *volume_header );
175
176
1.30k
    *volume_header = NULL;
177
1.30k
  }
178
1.30k
  return( result );
179
1.30k
}
180
181
/* Parses the encryption method
182
 * Returns 1 if successful or -1 on error
183
 */
184
int libluksde_volume_parse_encryption_method(
185
     libluksde_volume_header_t *volume_header,
186
     const uint8_t *encryption_method,
187
     libcerror_error_t **error )
188
1.00k
{
189
1.00k
  static char *function = "libluksde_volume_parse_encryption_method";
190
191
1.00k
  if( volume_header == NULL )
192
0
  {
193
0
    libcerror_error_set(
194
0
     error,
195
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
196
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
197
0
     "%s: invalid volume header.",
198
0
     function );
199
200
0
    return( -1 );
201
0
  }
202
1.00k
  if( encryption_method == NULL )
203
0
  {
204
0
    libcerror_error_set(
205
0
     error,
206
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
207
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
208
0
     "%s: invalid encryption method.",
209
0
     function );
210
211
0
    return( -1 );
212
0
  }
213
1.00k
  if( ( encryption_method[ 0 ] == 'a' )
214
910
   || ( encryption_method[ 0 ] == 'A' ) )
215
155
  {
216
155
    if( ( ( encryption_method[ 1 ] == 'e' )
217
122
      ||  ( encryption_method[ 1 ] == 'E' ) )
218
49
     && ( ( encryption_method[ 2 ] == 's' )
219
39
      ||  ( encryption_method[ 2 ] == 'S' ) )
220
19
     &&   ( encryption_method[ 3 ] == 0 ) )
221
6
    {
222
6
      volume_header->encryption_method = LIBLUKSDE_ENCRYPTION_METHOD_AES;
223
6
    }
224
149
    else if( ( ( encryption_method[ 1 ] == 'r' )
225
116
           ||  ( encryption_method[ 1 ] == 'R' ) )
226
52
          && ( ( encryption_method[ 2 ] == 'c' )
227
46
           ||  ( encryption_method[ 2 ] == 'C' ) )
228
27
          &&   ( encryption_method[ 3 ] == '4' )
229
12
          &&   ( encryption_method[ 4 ] == 0 ) )
230
1
    {
231
1
      volume_header->encryption_method = LIBLUKSDE_ENCRYPTION_METHOD_ARC4;
232
1
    }
233
155
  }
234
850
  else if( ( encryption_method[ 0 ] == 'b' )
235
725
        || ( encryption_method[ 0 ] == 'B' ) )
236
210
  {
237
210
    if( ( ( encryption_method[ 1 ] == 'l' )
238
142
      ||  ( encryption_method[ 1 ] == 'L' ) )
239
156
     && ( ( encryption_method[ 2 ] == 'o' )
240
53
      ||  ( encryption_method[ 2 ] == 'O' ) )
241
121
     && ( ( encryption_method[ 3 ] == 'w' )
242
40
      ||  ( encryption_method[ 3 ] == 'W' ) )
243
95
     && ( ( encryption_method[ 4 ] == 'f' )
244
73
      ||  ( encryption_method[ 4 ] == 'F' ) )
245
65
     && ( ( encryption_method[ 5 ] == 'i' )
246
56
      ||  ( encryption_method[ 5 ] == 'I' ) )
247
48
     && ( ( encryption_method[ 6 ] == 's' )
248
29
      ||  ( encryption_method[ 6 ] == 'S' ) )
249
31
     && ( ( encryption_method[ 7 ] == 'h' )
250
27
      ||  ( encryption_method[ 7 ] == 'H' ) )
251
10
     &&   ( encryption_method[ 8 ] == 0 ) )
252
2
    {
253
2
      volume_header->encryption_method = LIBLUKSDE_ENCRYPTION_METHOD_BLOWFISH;
254
2
    }
255
210
  }
256
640
  else if( ( encryption_method[ 0 ] == 'c' )
257
535
        || ( encryption_method[ 0 ] == 'C' ) )
258
154
  {
259
154
    if( ( ( encryption_method[ 1 ] == 'a' )
260
126
      ||  ( encryption_method[ 1 ] == 'A' ) )
261
73
     && ( ( encryption_method[ 2 ] == 's' )
262
46
      ||  ( encryption_method[ 2 ] == 'S' ) )
263
47
     && ( ( encryption_method[ 3 ] == 't' )
264
32
      ||  ( encryption_method[ 3 ] == 'T' ) )
265
23
     &&   ( encryption_method[ 5 ] == 0 ) )
266
18
    {
267
18
      if( encryption_method[ 4 ] == '5' )
268
2
      {
269
2
        volume_header->encryption_method = LIBLUKSDE_ENCRYPTION_METHOD_CAST5;
270
2
      }
271
16
      else if( encryption_method[ 4 ] == '6' )
272
3
      {
273
3
        volume_header->encryption_method = LIBLUKSDE_ENCRYPTION_METHOD_CAST6;
274
3
      }
275
18
    }
276
154
  }
277
486
  else if( ( encryption_method[ 0 ] == 's' )
278
362
        || ( encryption_method[ 0 ] == 'S' ) )
279
166
  {
280
166
    if( ( ( encryption_method[ 1 ] == 'e' )
281
61
      ||  ( encryption_method[ 1 ] == 'E' ) )
282
115
     && ( ( encryption_method[ 2 ] == 'r' )
283
68
      ||  ( encryption_method[ 2 ] == 'R' ) )
284
95
     && ( ( encryption_method[ 3 ] == 'p' )
285
61
      ||  ( encryption_method[ 3 ] == 'P' ) )
286
75
     && ( ( encryption_method[ 4 ] == 'e' )
287
38
      ||  ( encryption_method[ 4 ] == 'E' ) )
288
51
     && ( ( encryption_method[ 5 ] == 'n' )
289
26
      ||  ( encryption_method[ 5 ] == 'N' ) )
290
32
     && ( ( encryption_method[ 6 ] == 't' )
291
25
      ||  ( encryption_method[ 6 ] == 'T' ) )
292
10
     &&   ( encryption_method[ 7 ] == 0 ) )
293
1
    {
294
1
      volume_header->encryption_method = LIBLUKSDE_ENCRYPTION_METHOD_SERPENT;
295
1
    }
296
166
  }
297
320
  else if( ( encryption_method[ 0 ] == 't' )
298
290
        || ( encryption_method[ 0 ] == 'T' ) )
299
158
  {
300
158
    if( ( ( encryption_method[ 1 ] == 'w' )
301
132
      ||  ( encryption_method[ 1 ] == 'W' ) )
302
112
     && ( ( encryption_method[ 2 ] == 'o' )
303
106
      ||  ( encryption_method[ 2 ] == 'O' ) )
304
81
     && ( ( encryption_method[ 3 ] == 'f' )
305
62
      ||  ( encryption_method[ 3 ] == 'F' ) )
306
58
     && ( ( encryption_method[ 4 ] == 'i' )
307
29
      ||  ( encryption_method[ 4 ] == 'I' ) )
308
39
     && ( ( encryption_method[ 5 ] == 's' )
309
25
      ||  ( encryption_method[ 5 ] == 'S' ) )
310
19
     && ( ( encryption_method[ 6 ] == 'h' )
311
17
      ||  ( encryption_method[ 6 ] == 'H' ) )
312
5
     &&   ( encryption_method[ 7 ] == 0 ) )
313
1
    {
314
1
      volume_header->encryption_method = LIBLUKSDE_ENCRYPTION_METHOD_TWOFISH;
315
1
    }
316
158
  }
317
1.00k
  return( 1 );
318
1.00k
}
319
320
/* Parses the encryption mode
321
 * Returns 1 if successful or -1 on error
322
 */
323
int libluksde_volume_parse_encryption_mode(
324
     libluksde_volume_header_t *volume_header,
325
     const uint8_t *encryption_mode,
326
     libcerror_error_t **error )
327
1.00k
{
328
1.00k
  static char *function = "libluksde_volume_parse_encryption_mode";
329
1.00k
  int separator_index   = 0;
330
331
1.00k
  if( volume_header == NULL )
332
0
  {
333
0
    libcerror_error_set(
334
0
     error,
335
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
336
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
337
0
     "%s: invalid volume header.",
338
0
     function );
339
340
0
    return( -1 );
341
0
  }
342
1.00k
  if( encryption_mode == NULL )
343
0
  {
344
0
    libcerror_error_set(
345
0
     error,
346
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
347
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
348
0
     "%s: invalid encryption mode.",
349
0
     function );
350
351
0
    return( -1 );
352
0
  }
353
1.00k
  if( ( encryption_mode[ 0 ] == 'c' )
354
790
   || ( encryption_mode[ 0 ] == 'C' ) )
355
595
  {
356
595
    if( ( ( encryption_mode[ 1 ] == 'b' )
357
341
      ||  ( encryption_mode[ 1 ] == 'B' ) )
358
540
     && ( ( encryption_mode[ 2 ] == 'c' )
359
166
      ||  ( encryption_mode[ 2 ] == 'C' ) )
360
510
     &&   ( encryption_mode[ 3 ] == '-' ) )
361
489
    {
362
489
      volume_header->encryption_chaining_mode = LIBLUKSDE_ENCRYPTION_CHAINING_MODE_CBC;
363
364
489
      separator_index = 3;
365
489
    }
366
595
  }
367
410
  else if( ( encryption_mode[ 0 ] == 'e' )
368
358
        || ( encryption_mode[ 0 ] == 'E' ) )
369
118
  {
370
118
    if( ( ( encryption_mode[ 1 ] == 'c' )
371
67
      ||  ( encryption_mode[ 1 ] == 'C' ) )
372
64
     && ( ( encryption_mode[ 2 ] == 'b' )
373
44
      ||  ( encryption_mode[ 2 ] == 'B' ) )
374
44
     &&   ( encryption_mode[ 3 ] == 0 ) )
375
35
    {
376
35
      volume_header->encryption_chaining_mode = LIBLUKSDE_ENCRYPTION_CHAINING_MODE_ECB;
377
378
35
      separator_index = 3;
379
35
    }
380
118
  }
381
292
  else if( ( encryption_mode[ 0 ] == 'x' )
382
272
        || ( encryption_mode[ 0 ] == 'X' ) )
383
77
  {
384
77
    if( ( ( encryption_mode[ 1 ] == 't' )
385
67
      ||  ( encryption_mode[ 1 ] == 'T' ) )
386
44
     && ( ( encryption_mode[ 2 ] == 's' )
387
30
      ||  ( encryption_mode[ 2 ] == 'S' ) )
388
22
     &&   ( encryption_mode[ 3 ] == '-' ) )
389
8
    {
390
8
      volume_header->encryption_chaining_mode = LIBLUKSDE_ENCRYPTION_CHAINING_MODE_XTS;
391
392
8
      separator_index = 3;
393
8
    }
394
77
  }
395
1.00k
  if( ( separator_index > 0 )
396
532
   && ( separator_index < 31 ) )
397
532
  {
398
532
    volume_header->initialization_vector_mode = LIBLUKSDE_INITIALIZATION_VECTOR_MODE_NONE;
399
400
532
    if( ( encryption_mode[ separator_index + 1 ] == 'b' )
401
518
     || ( encryption_mode[ separator_index + 1 ] == 'B' ) )
402
75
    {
403
75
      if( ( ( encryption_mode[ separator_index + 2 ] == 'e' )
404
43
        ||  ( encryption_mode[ separator_index + 2 ] == 'E' ) )
405
61
       && ( ( encryption_mode[ separator_index + 3 ] == 'n' )
406
41
        ||  ( encryption_mode[ separator_index + 3 ] == 'N' ) )
407
48
       && ( ( encryption_mode[ separator_index + 4 ] == 'b' )
408
33
        ||  ( encryption_mode[ separator_index + 4 ] == 'B' ) )
409
27
       && ( ( encryption_mode[ separator_index + 5 ] == 'i' )
410
20
        ||  ( encryption_mode[ separator_index + 5 ] == 'I' ) )
411
9
       &&   ( encryption_mode[ separator_index + 6 ] == 0 ) )
412
1
      {
413
1
        volume_header->initialization_vector_mode = LIBLUKSDE_INITIALIZATION_VECTOR_MODE_BENBI;
414
1
      }
415
75
    }
416
457
    else if( ( encryption_mode[ separator_index + 1 ] == 'e' )
417
403
          || ( encryption_mode[ separator_index + 1 ] == 'E' ) )
418
183
    {
419
183
      if( ( ( encryption_mode[ separator_index + 2 ] == 's' )
420
152
        ||  ( encryption_mode[ separator_index + 2 ] == 'S' ) )
421
162
       && ( ( encryption_mode[ separator_index + 3 ] == 's' )
422
124
        ||  ( encryption_mode[ separator_index + 3 ] == 'S' ) )
423
142
       && ( ( encryption_mode[ separator_index + 4 ] == 'i' )
424
59
        ||  ( encryption_mode[ separator_index + 4 ] == 'I' ) )
425
121
       && ( ( encryption_mode[ separator_index + 5 ] == 'v' )
426
103
        ||  ( encryption_mode[ separator_index + 5 ] == 'V' ) )
427
101
       &&   ( encryption_mode[ separator_index + 6 ] == ':' ) )
428
90
      {
429
90
        if( ( ( encryption_mode[ separator_index + 7 ] == 's' )
430
75
          ||  ( encryption_mode[ separator_index + 7 ] == 'S' ) )
431
78
         && ( ( encryption_mode[ separator_index + 8 ] == 'h' )
432
48
          ||  ( encryption_mode[ separator_index + 8 ] == 'H' ) )
433
61
         && ( ( encryption_mode[ separator_index + 9 ] == 'a' )
434
23
          ||  ( encryption_mode[ separator_index + 9 ] == 'A' ) ) )
435
48
        {
436
48
          if( ( encryption_mode[ separator_index + 10 ] == '1' )
437
9
           && ( encryption_mode[ separator_index + 11 ] == 0 ) )
438
1
          {
439
1
            volume_header->initialization_vector_mode = LIBLUKSDE_INITIALIZATION_VECTOR_MODE_ESSIV;
440
1
            volume_header->essiv_hashing_method       = LIBLUKSDE_HASHING_METHOD_SHA1;
441
1
          }
442
47
          else if( ( encryption_mode[ separator_index + 10 ] == '2' )
443
25
                && ( encryption_mode[ separator_index + 11 ] == '5' )
444
14
                && ( encryption_mode[ separator_index + 12 ] == '6' )
445
2
                && ( encryption_mode[ separator_index + 13 ] == 0 ) )
446
1
          {
447
1
            volume_header->initialization_vector_mode = LIBLUKSDE_INITIALIZATION_VECTOR_MODE_ESSIV;
448
1
            volume_header->essiv_hashing_method       = LIBLUKSDE_HASHING_METHOD_SHA256;
449
1
          }
450
48
        }
451
/* TODO IV options */
452
90
      }
453
183
    }
454
274
    else if( ( encryption_mode[ separator_index + 1 ] == 'l' )
455
242
          || ( encryption_mode[ separator_index + 1 ] == 'L' ) )
456
48
    {
457
48
      if( ( ( encryption_mode[ separator_index + 2 ] == 'm' )
458
29
        ||  ( encryption_mode[ separator_index + 2 ] == 'M' ) )
459
30
       && ( ( encryption_mode[ separator_index + 3 ] == 'k' )
460
23
        ||  ( encryption_mode[ separator_index + 3 ] == 'K' ) )
461
11
       &&   ( encryption_mode[ separator_index + 4 ] == 0 ) )
462
2
      {
463
2
        volume_header->initialization_vector_mode = LIBLUKSDE_INITIALIZATION_VECTOR_MODE_LMK;
464
2
      }
465
48
    }
466
226
    else if( ( encryption_mode[ separator_index + 1 ] == 'n' )
467
199
          || ( encryption_mode[ separator_index + 1 ] == 'N' ) )
468
62
    {
469
62
      if( ( ( encryption_mode[ separator_index + 2 ] == 'u' )
470
36
        ||  ( encryption_mode[ separator_index + 2 ] == 'U' ) )
471
46
       && ( ( encryption_mode[ separator_index + 3 ] == 'l' )
472
34
        ||  ( encryption_mode[ separator_index + 3 ] == 'L' ) )
473
31
       && ( ( encryption_mode[ separator_index + 4 ] == 'l' )
474
24
        ||  ( encryption_mode[ separator_index + 4 ] == 'L' ) )
475
13
       &&   ( encryption_mode[ separator_index + 5 ] == 0 ) )
476
2
      {
477
2
        volume_header->initialization_vector_mode = LIBLUKSDE_INITIALIZATION_VECTOR_MODE_NULL;
478
2
      }
479
62
    }
480
164
    else if( ( encryption_mode[ separator_index + 1 ] == 'p' )
481
73
          || ( encryption_mode[ separator_index + 1 ] == 'P' ) )
482
115
    {
483
115
      if( ( ( encryption_mode[ separator_index + 2 ] == 'l' )
484
94
        ||  ( encryption_mode[ separator_index + 2 ] == 'L' ) )
485
90
       && ( ( encryption_mode[ separator_index + 3 ] == 'a' )
486
36
        ||  ( encryption_mode[ separator_index + 3 ] == 'A' ) )
487
73
       && ( ( encryption_mode[ separator_index + 4 ] == 'i' )
488
52
        ||  ( encryption_mode[ separator_index + 4 ] == 'I' ) )
489
51
       && ( ( encryption_mode[ separator_index + 5 ] == 'n' )
490
29
        ||  ( encryption_mode[ separator_index + 5 ] == 'N' ) ) )
491
31
      {
492
31
        if( encryption_mode[ separator_index + 6 ] == 0 )
493
1
        {
494
1
          volume_header->initialization_vector_mode = LIBLUKSDE_INITIALIZATION_VECTOR_MODE_PLAIN32;
495
1
        }
496
30
        else if( ( encryption_mode[ separator_index + 6 ] == '6' )
497
18
              && ( encryption_mode[ separator_index + 7 ] == '4' )
498
8
              && ( encryption_mode[ separator_index + 8 ] == 0 ) )
499
2
        {
500
2
          volume_header->initialization_vector_mode = LIBLUKSDE_INITIALIZATION_VECTOR_MODE_PLAIN64;
501
2
        }
502
31
      }
503
115
    }
504
532
  }
505
1.00k
  return( 1 );
506
1.00k
}
507
508
/* Parses the hashing method
509
 * Returns 1 if successful or -1 on error
510
 */
511
int libluksde_volume_parse_hashing_method(
512
     libluksde_volume_header_t *volume_header,
513
     const uint8_t *hashing_method,
514
     libcerror_error_t **error )
515
1.00k
{
516
1.00k
  static char *function = "libluksde_volume_parse_hashing_method";
517
518
1.00k
  if( volume_header == NULL )
519
0
  {
520
0
    libcerror_error_set(
521
0
     error,
522
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
523
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
524
0
     "%s: invalid volume header.",
525
0
     function );
526
527
0
    return( -1 );
528
0
  }
529
1.00k
  if( hashing_method == NULL )
530
0
  {
531
0
    libcerror_error_set(
532
0
     error,
533
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
534
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
535
0
     "%s: invalid hashing method.",
536
0
     function );
537
538
0
    return( -1 );
539
0
  }
540
1.00k
  if( ( hashing_method[ 0 ] == 'r' )
541
861
   || ( hashing_method[ 0 ] == 'R' ) )
542
175
  {
543
175
    if( ( ( hashing_method[ 1 ] == 'i' )
544
62
      ||  ( hashing_method[ 1 ] == 'I' ) )
545
125
     && ( ( hashing_method[ 2 ] == 'p' )
546
78
      ||  ( hashing_method[ 2 ] == 'P' ) )
547
95
     && ( ( hashing_method[ 3 ] == 'e' )
548
55
      ||  ( hashing_method[ 3 ] == 'E' ) )
549
78
     && ( ( hashing_method[ 4 ] == 'm' )
550
27
      ||  ( hashing_method[ 4 ] == 'M' ) )
551
57
     && ( ( hashing_method[ 5 ] == 'd' )
552
32
      ||  ( hashing_method[ 5 ] == 'D' ) )
553
41
     &&   ( hashing_method[ 6 ] == '1' )
554
34
     &&   ( hashing_method[ 7 ] == '6' )
555
19
     &&   ( hashing_method[ 8 ] == '0' )
556
12
     &&   ( hashing_method[ 9 ] == 0 ) )
557
3
    {
558
3
      volume_header->hashing_method = LIBLUKSDE_HASHING_METHOD_RIPEMD160;
559
3
    }
560
175
  }
561
830
  else if( ( hashing_method[ 0 ] == 's' )
562
759
        || ( hashing_method[ 0 ] == 'S' ) )
563
304
  {
564
304
    if( ( ( hashing_method[ 1 ] == 'h' )
565
165
      ||  ( hashing_method[ 1 ] == 'H' ) )
566
231
     && ( ( hashing_method[ 2 ] == 'a' )
567
185
      ||  ( hashing_method[ 2 ] == 'A' ) ) )
568
191
    {
569
191
      if( ( hashing_method[ 3 ] == '1' )
570
24
       && ( hashing_method[ 4 ] == 0 ) )
571
4
      {
572
4
        volume_header->hashing_method = LIBLUKSDE_HASHING_METHOD_SHA1;
573
4
      }
574
187
      else if( ( hashing_method[ 3 ] == '2' )
575
86
            && ( hashing_method[ 4 ] == '2' )
576
28
            && ( hashing_method[ 5 ] == '4' )
577
6
            && ( hashing_method[ 6 ] == 0 ) )
578
3
      {
579
3
        volume_header->hashing_method = LIBLUKSDE_HASHING_METHOD_SHA224;
580
3
      }
581
184
      else if( ( hashing_method[ 3 ] == '2' )
582
83
            && ( hashing_method[ 4 ] == '5' )
583
29
            && ( hashing_method[ 5 ] == '6' )
584
15
            && ( hashing_method[ 6 ] == 0 ) )
585
4
      {
586
4
        volume_header->hashing_method = LIBLUKSDE_HASHING_METHOD_SHA256;
587
4
      }
588
180
      else if( ( hashing_method[ 3 ] == '5' )
589
46
            && ( hashing_method[ 4 ] == '1' )
590
26
            && ( hashing_method[ 5 ] == '2' )
591
14
            && ( hashing_method[ 6 ] == 0 ) )
592
1
      {
593
1
        volume_header->hashing_method = LIBLUKSDE_HASHING_METHOD_SHA512;
594
1
      }
595
191
    }
596
304
  }
597
1.00k
  return( 1 );
598
1.00k
}
599
600
/* Reads the volume header
601
 * Returns 1 if successful or -1 on error
602
 */
603
int libluksde_volume_header_read_data(
604
     libluksde_volume_header_t *volume_header,
605
     const uint8_t *data,
606
     size_t data_size,
607
     libcerror_error_t **error )
608
1.27k
{
609
1.27k
  libfguid_identifier_t *guid    = NULL;
610
1.27k
  libluksde_key_slot_t *key_slot = NULL;
611
1.27k
  static char *function          = "libluksde_volume_header_read_data";
612
1.27k
  size_t data_offset             = 0;
613
1.27k
  int entry_index                = 0;
614
1.27k
  int key_slot_index             = 0;
615
1.27k
  int result                     = 0;
616
617
#if defined( HAVE_DEBUG_OUTPUT )
618
  uint64_t value_64bit           = 0;
619
#endif
620
621
1.27k
  if( volume_header == NULL )
622
0
  {
623
0
    libcerror_error_set(
624
0
     error,
625
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
626
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
627
0
     "%s: invalid volume header.",
628
0
     function );
629
630
0
    return( -1 );
631
0
  }
632
1.27k
  if( data == NULL )
633
0
  {
634
0
    libcerror_error_set(
635
0
     error,
636
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
637
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
638
0
     "%s: invalid data.",
639
0
     function );
640
641
0
    return( -1 );
642
0
  }
643
1.27k
  if( ( data_size < sizeof( luksde_volume_header_v1_t ) )
644
1.27k
   || ( data_size > (size_t) SSIZE_MAX ) )
645
0
  {
646
0
    libcerror_error_set(
647
0
     error,
648
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
649
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
650
0
     "%s: invalid data size value out of bounds.",
651
0
     function );
652
653
0
    return( -1 );
654
0
  }
655
#if defined( HAVE_DEBUG_OUTPUT )
656
  if( libcnotify_verbose != 0 )
657
  {
658
    libcnotify_printf(
659
     "%s: volume header data:\n",
660
     function );
661
    libcnotify_print_data(
662
     data,
663
     sizeof( luksde_volume_header_v1_t ),
664
     LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
665
  }
666
#endif
667
1.27k
  if( memory_compare(
668
1.27k
       ( (luksde_volume_header_v1_t *) data )->signature,
669
1.27k
       luksde_signature,
670
1.27k
       6 ) == 0 )
671
369
  {
672
369
  }
673
909
  else if( memory_compare(
674
909
            ( (luksde_volume_header_v1_t *) data )->signature,
675
909
            luksde_backup_volume_header_signature,
676
909
            6 ) == 0 )
677
850
  {
678
850
  }
679
59
  else
680
59
  {
681
59
    libcerror_error_set(
682
59
     error,
683
59
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
684
59
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
685
59
     "%s: unsupported signature.",
686
59
     function );
687
688
59
    goto on_error;
689
59
  }
690
1.21k
  byte_stream_copy_to_uint16_big_endian(
691
1.21k
   ( (luksde_volume_header_v1_t *) data )->format_version,
692
1.21k
   volume_header->format_version );
693
694
1.21k
  if( ( volume_header->format_version != 1 )
695
21
   && ( volume_header->format_version != 2 ) )
696
20
  {
697
20
    libcerror_error_set(
698
20
     error,
699
20
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
700
20
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
701
20
     "%s: unsupported format version.",
702
20
     function );
703
704
20
    goto on_error;
705
20
  }
706
1.19k
  if( volume_header->format_version == 2 )
707
1
  {
708
1
    if( data_size < sizeof( luksde_volume_header_v2_t ) )
709
0
    {
710
0
      libcerror_error_set(
711
0
       error,
712
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
713
0
       LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
714
0
       "%s: invalid data size value out of bounds.",
715
0
       function );
716
717
0
      goto on_error;
718
0
    }
719
1
  }
720
1.19k
  if( volume_header->format_version == 1 )
721
1.19k
  {
722
1.19k
    byte_stream_copy_to_uint32_big_endian(
723
1.19k
     ( (luksde_volume_header_v1_t *) data )->encrypted_volume_start_sector,
724
1.19k
     volume_header->encrypted_volume_start_sector );
725
726
1.19k
    byte_stream_copy_to_uint32_big_endian(
727
1.19k
     ( (luksde_volume_header_v1_t *) data )->master_key_size,
728
1.19k
     volume_header->master_key_size );
729
730
1.19k
    if( memory_copy(
731
1.19k
         volume_header->master_key_validation_hash,
732
1.19k
         ( (luksde_volume_header_v1_t *) data )->master_key_validation_hash,
733
1.19k
         20 ) == NULL )
734
0
    {
735
0
      libcerror_error_set(
736
0
       error,
737
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
738
0
       LIBCERROR_MEMORY_ERROR_COPY_FAILED,
739
0
       "%s: unable to copy master key validation hash.",
740
0
       function );
741
742
0
      goto on_error;
743
0
    }
744
1.19k
    if( memory_copy(
745
1.19k
         volume_header->master_key_salt,
746
1.19k
         ( (luksde_volume_header_v1_t *) data )->master_key_salt,
747
1.19k
         32 ) == NULL )
748
0
    {
749
0
      libcerror_error_set(
750
0
       error,
751
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
752
0
       LIBCERROR_MEMORY_ERROR_COPY_FAILED,
753
0
       "%s: unable to copy master key salt.",
754
0
       function );
755
756
0
      goto on_error;
757
0
    }
758
1.19k
    byte_stream_copy_to_uint32_big_endian(
759
1.19k
     ( (luksde_volume_header_v1_t *) data )->master_key_number_of_iterations,
760
1.19k
     volume_header->master_key_number_of_iterations );
761
1.19k
  }
762
1.19k
  if( libfguid_identifier_initialize(
763
1.19k
       &guid,
764
1.19k
       error ) != 1 )
765
0
  {
766
0
    libcerror_error_set(
767
0
     error,
768
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
769
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
770
0
     "%s: unable to create GUID.",
771
0
     function );
772
773
0
    goto on_error;
774
0
  }
775
1.19k
  if( volume_header->format_version == 1 )
776
1.19k
  {
777
1.19k
    result = libfguid_identifier_copy_from_utf8_string(
778
1.19k
              guid,
779
1.19k
              ( (luksde_volume_header_v1_t *) data )->volume_identifier,
780
1.19k
              40,
781
1.19k
              LIBFGUID_STRING_FORMAT_FLAG_USE_MIXED_CASE,
782
1.19k
              error );
783
1.19k
  }
784
1
  else if( volume_header->format_version == 2 )
785
1
  {
786
1
    result = libfguid_identifier_copy_from_utf8_string(
787
1
              guid,
788
1
              ( (luksde_volume_header_v2_t *) data )->volume_identifier,
789
1
              40,
790
1
              LIBFGUID_STRING_FORMAT_FLAG_USE_MIXED_CASE,
791
1
              error );
792
1
  }
793
1.19k
  if( result != 1 )
794
193
  {
795
193
    libcerror_error_set(
796
193
     error,
797
193
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
798
193
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
799
193
     "%s: unable to copy GUID from string.",
800
193
     function );
801
802
193
    goto on_error;
803
193
  }
804
1.00k
  if( libfguid_identifier_copy_to_byte_stream(
805
1.00k
       guid,
806
1.00k
       volume_header->volume_identifier,
807
1.00k
       16,
808
1.00k
       LIBFGUID_ENDIAN_BIG,
809
1.00k
       error ) != 1 )
810
0
  {
811
0
    libcerror_error_set(
812
0
     error,
813
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
814
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
815
0
     "%s: unable to copy GUID to byte stream.",
816
0
     function );
817
818
0
    goto on_error;
819
0
  }
820
1.00k
  if( libfguid_identifier_free(
821
1.00k
       &guid,
822
1.00k
       error ) != 1 )
823
0
  {
824
0
    libcerror_error_set(
825
0
     error,
826
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
827
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
828
0
     "%s: unable to free GUID.",
829
0
     function );
830
831
0
    goto on_error;
832
0
  }
833
#if defined( HAVE_DEBUG_OUTPUT )
834
  if( libcnotify_verbose != 0 )
835
  {
836
    libcnotify_printf(
837
     "%s: signature\t\t\t\t: %c%c%c%c\\x%02x\\x%02x\n",
838
     function,
839
     data[ 0 ],
840
     data[ 1 ],
841
     data[ 2 ],
842
     data[ 3 ],
843
     data[ 4 ],
844
     data[ 5 ] );
845
846
    libcnotify_printf(
847
     "%s: format version\t\t\t: %" PRIu16 "\n",
848
     function,
849
     volume_header->format_version );
850
851
    if( volume_header->format_version == 1 )
852
    {
853
      if( libluksde_debug_print_string_value(
854
           function,
855
           "encryption method\t\t\t",
856
           ( (luksde_volume_header_v1_t *) data )->encryption_method,
857
           32,
858
           LIBUNA_CODEPAGE_US_ASCII,
859
           error ) != 1 )
860
      {
861
        libcerror_error_set(
862
         error,
863
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
864
         LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
865
         "%s: unable to print string value.",
866
         function );
867
868
        goto on_error;
869
      }
870
      if( libluksde_debug_print_string_value(
871
           function,
872
           "encryption mode\t\t\t",
873
           ( (luksde_volume_header_v1_t *) data )->encryption_mode,
874
           32,
875
           LIBUNA_CODEPAGE_US_ASCII,
876
           error ) != 1 )
877
      {
878
        libcerror_error_set(
879
         error,
880
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
881
         LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
882
         "%s: unable to print string value.",
883
         function );
884
885
        goto on_error;
886
      }
887
      if( libluksde_debug_print_string_value(
888
           function,
889
           "hashing method\t\t\t",
890
           ( (luksde_volume_header_v1_t *) data )->hashing_method,
891
           32,
892
           LIBUNA_CODEPAGE_US_ASCII,
893
           error ) != 1 )
894
      {
895
        libcerror_error_set(
896
         error,
897
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
898
         LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
899
         "%s: unable to print string value.",
900
         function );
901
902
        goto on_error;
903
      }
904
      libcnotify_printf(
905
       "%s: encrypted volume start sector\t: %" PRIu64 "\n",
906
       function,
907
       volume_header->encrypted_volume_start_sector );
908
909
      libcnotify_printf(
910
       "%s: master key size\t\t\t: %" PRIu32 "\n",
911
       function,
912
       volume_header->master_key_size );
913
914
      libcnotify_printf(
915
       "%s: master key validation hash:\n",
916
       function );
917
      libcnotify_print_data(
918
       volume_header->master_key_validation_hash,
919
       20,
920
       0 );
921
922
      libcnotify_printf(
923
       "%s: master key salt:\n",
924
       function );
925
      libcnotify_print_data(
926
       volume_header->master_key_salt,
927
       32,
928
       0 );
929
930
      libcnotify_printf(
931
       "%s: master key number of iterations\t: %" PRIu32 "\n",
932
       function,
933
       volume_header->master_key_number_of_iterations );
934
935
      if( libluksde_debug_print_string_value(
936
           function,
937
           "volume identifier\t\t\t",
938
           ( (luksde_volume_header_v1_t *) data )->volume_identifier,
939
           40,
940
           LIBUNA_CODEPAGE_US_ASCII,
941
           error ) != 1 )
942
      {
943
        libcerror_error_set(
944
         error,
945
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
946
         LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
947
         "%s: unable to print string value.",
948
         function );
949
950
        goto on_error;
951
      }
952
    }
953
    else if( volume_header->format_version == 2 )
954
    {
955
      byte_stream_copy_to_uint64_big_endian(
956
       ( (luksde_volume_header_v2_t *) data )->metadata_area_size,
957
       value_64bit );
958
      libcnotify_printf(
959
       "%s: metadata area size\t\t\t: %" PRIu64 "\n",
960
       function,
961
       value_64bit );
962
963
      byte_stream_copy_to_uint64_big_endian(
964
       ( (luksde_volume_header_v2_t *) data )->sequence_identifier,
965
       value_64bit );
966
      libcnotify_printf(
967
       "%s: sequence identifier\t\t\t: %" PRIu64 "\n",
968
       function,
969
       value_64bit );
970
971
      if( libluksde_debug_print_string_value(
972
           function,
973
           "label\t\t\t\t",
974
           ( (luksde_volume_header_v2_t *) data )->label,
975
           48,
976
           LIBUNA_CODEPAGE_US_ASCII,
977
           error ) != 1 )
978
      {
979
        libcerror_error_set(
980
         error,
981
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
982
         LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
983
         "%s: unable to print string value.",
984
         function );
985
986
        goto on_error;
987
      }
988
      if( libluksde_debug_print_string_value(
989
           function,
990
           "checksum method\t\t\t",
991
           ( (luksde_volume_header_v2_t *) data )->checksum_method,
992
           32,
993
           LIBUNA_CODEPAGE_US_ASCII,
994
           error ) != 1 )
995
      {
996
        libcerror_error_set(
997
         error,
998
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
999
         LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
1000
         "%s: unable to print string value.",
1001
         function );
1002
1003
        goto on_error;
1004
      }
1005
      libcnotify_printf(
1006
       "%s: salt:\n",
1007
       function );
1008
      libcnotify_print_data(
1009
       ( (luksde_volume_header_v2_t *) data )->salt,
1010
       64,
1011
       0 );
1012
1013
      if( libluksde_debug_print_string_value(
1014
           function,
1015
           "volume identifier\t\t\t",
1016
           ( (luksde_volume_header_v2_t *) data )->volume_identifier,
1017
           40,
1018
           LIBUNA_CODEPAGE_US_ASCII,
1019
           error ) != 1 )
1020
      {
1021
        libcerror_error_set(
1022
         error,
1023
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1024
         LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
1025
         "%s: unable to print string value.",
1026
         function );
1027
1028
        goto on_error;
1029
      }
1030
      if( libluksde_debug_print_string_value(
1031
           function,
1032
           "subsystem\t\t\t\t",
1033
           ( (luksde_volume_header_v2_t *) data )->subsystem,
1034
           48,
1035
           LIBUNA_CODEPAGE_US_ASCII,
1036
           error ) != 1 )
1037
      {
1038
        libcerror_error_set(
1039
         error,
1040
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1041
         LIBCERROR_RUNTIME_ERROR_PRINT_FAILED,
1042
         "%s: unable to print string value.",
1043
         function );
1044
1045
        goto on_error;
1046
      }
1047
      byte_stream_copy_to_uint64_big_endian(
1048
       ( (luksde_volume_header_v2_t *) data )->header_offset,
1049
       value_64bit );
1050
      libcnotify_printf(
1051
       "%s: header offset\t\t\t: %" PRIu64 "\n",
1052
       function,
1053
       value_64bit );
1054
1055
      libcnotify_printf(
1056
       "%s: padding1:\n",
1057
       function );
1058
      libcnotify_print_data(
1059
       ( (luksde_volume_header_v2_t *) data )->padding1,
1060
       184,
1061
       LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
1062
1063
      libcnotify_printf(
1064
       "%s: checksum:\n",
1065
       function );
1066
      libcnotify_print_data(
1067
       ( (luksde_volume_header_v2_t *) data )->checksum,
1068
       64,
1069
       0 );
1070
1071
      libcnotify_printf(
1072
       "%s: padding2:\n",
1073
       function );
1074
      libcnotify_print_data(
1075
       ( (luksde_volume_header_v2_t *) data )->padding2,
1076
       3584,
1077
       LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
1078
    }
1079
    libcnotify_printf(
1080
     "\n" );
1081
  }
1082
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
1083
1084
1.00k
  if( volume_header->format_version == 1 )
1085
1.00k
  {
1086
1.00k
    if( libluksde_volume_parse_encryption_method(
1087
1.00k
         volume_header,
1088
1.00k
         ( (luksde_volume_header_v1_t *) data )->encryption_method,
1089
1.00k
         error ) != 1 )
1090
0
    {
1091
0
      libcerror_error_set(
1092
0
       error,
1093
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1094
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1095
0
       "%s: unable to parse encryption method.",
1096
0
       function );
1097
1098
0
      goto on_error;
1099
0
    }
1100
1.00k
    if( libluksde_volume_parse_encryption_mode(
1101
1.00k
         volume_header,
1102
1.00k
         ( (luksde_volume_header_v1_t *) data )->encryption_mode,
1103
1.00k
         error ) != 1 )
1104
0
    {
1105
0
      libcerror_error_set(
1106
0
       error,
1107
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1108
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1109
0
       "%s: unable to parse encryption mode.",
1110
0
       function );
1111
1112
0
      goto on_error;
1113
0
    }
1114
1.00k
    if( libluksde_volume_parse_hashing_method(
1115
1.00k
         volume_header,
1116
1.00k
         ( (luksde_volume_header_v1_t *) data )->hashing_method,
1117
1.00k
         error ) != 1 )
1118
0
    {
1119
0
      libcerror_error_set(
1120
0
       error,
1121
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1122
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1123
0
       "%s: unable to parse hashing method.",
1124
0
       function );
1125
1126
0
      goto on_error;
1127
0
    }
1128
1.00k
    data_offset = sizeof( luksde_volume_header_v1_t );
1129
1130
1.00k
    for( key_slot_index = 0;
1131
9.04k
         key_slot_index < 8;
1132
8.04k
         key_slot_index++ )
1133
8.04k
    {
1134
8.04k
      if( libluksde_key_slot_initialize(
1135
8.04k
           &key_slot,
1136
8.04k
           error ) != 1 )
1137
0
      {
1138
0
        libcerror_error_set(
1139
0
         error,
1140
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1141
0
         LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1142
0
         "%s: unable to create key slot.",
1143
0
         function );
1144
1145
0
        goto on_error;
1146
0
      }
1147
8.04k
      if( libluksde_key_slot_read_data(
1148
8.04k
           key_slot,
1149
8.04k
           &( data[ data_offset ] ),
1150
8.04k
           sizeof( luksde_volume_keyslot_t ),
1151
8.04k
           error ) != 1 )
1152
0
      {
1153
0
        libcerror_error_set(
1154
0
         error,
1155
0
         LIBCERROR_ERROR_DOMAIN_IO,
1156
0
         LIBCERROR_IO_ERROR_READ_FAILED,
1157
0
         "%s: unable to read key slot data.",
1158
0
         function );
1159
1160
0
        goto on_error;
1161
0
      }
1162
8.04k
      if( libcdata_array_append_entry(
1163
8.04k
           volume_header->key_slots_array,
1164
8.04k
           &entry_index,
1165
8.04k
           (intptr_t *) key_slot,
1166
8.04k
           error ) != 1 )
1167
0
      {
1168
0
        libcerror_error_set(
1169
0
         error,
1170
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1171
0
         LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1172
0
         "%s: unable to append key slot to key slots array.",
1173
0
         function );
1174
1175
0
        goto on_error;
1176
0
      }
1177
8.04k
      key_slot = NULL;
1178
1179
8.04k
      data_offset += sizeof( luksde_volume_keyslot_t );
1180
8.04k
    }
1181
1.00k
  }
1182
1.00k
  return( 1 );
1183
1184
272
on_error:
1185
272
  if( key_slot != NULL )
1186
0
  {
1187
0
    libluksde_key_slot_free(
1188
0
     &key_slot,
1189
0
     NULL );
1190
0
  }
1191
272
  if( guid != NULL )
1192
193
  {
1193
193
    libfguid_identifier_free(
1194
193
     &guid,
1195
193
     NULL );
1196
193
  }
1197
272
  libcdata_array_empty(
1198
272
   volume_header->key_slots_array,
1199
272
   (int(*)(intptr_t **, libcerror_error_t **)) &libluksde_key_slot_free,
1200
272
   NULL );
1201
1202
272
  return( -1 );
1203
1.00k
}
1204
1205
/* Reads the volume header
1206
 * Returns 1 if successful or -1 on error
1207
 */
1208
int libluksde_volume_header_read_file_io_handle(
1209
     libluksde_volume_header_t *volume_header,
1210
     libbfio_handle_t *file_io_handle,
1211
     off64_t file_offset,
1212
     libcerror_error_t **error )
1213
1.30k
{
1214
1.30k
  uint8_t volume_header_data[ 4096 ];
1215
1216
1.30k
  static char *function = "libluksde_volume_header_read_file_io_handle";
1217
1.30k
  ssize_t read_count    = 0;
1218
1219
1.30k
  if( volume_header == NULL )
1220
0
  {
1221
0
    libcerror_error_set(
1222
0
     error,
1223
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1224
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1225
0
     "%s: invalid volume header.",
1226
0
     function );
1227
1228
0
    return( -1 );
1229
0
  }
1230
#if defined( HAVE_DEBUG_OUTPUT )
1231
  if( libcnotify_verbose != 0 )
1232
  {
1233
    libcnotify_printf(
1234
     "%s: reading volume header at offset: %" PRIi64 " (0x%08" PRIx64 ")\n",
1235
     function,
1236
     file_offset,
1237
     file_offset );
1238
  }
1239
#endif
1240
1.30k
  read_count = libbfio_handle_read_buffer_at_offset(
1241
1.30k
                file_io_handle,
1242
1.30k
                volume_header_data,
1243
1.30k
                4096,
1244
1.30k
                file_offset,
1245
1.30k
                error );
1246
1247
1.30k
  if( read_count != (ssize_t) 4096 )
1248
22
  {
1249
22
    libcerror_error_set(
1250
22
     error,
1251
22
     LIBCERROR_ERROR_DOMAIN_IO,
1252
22
     LIBCERROR_IO_ERROR_READ_FAILED,
1253
22
     "%s: unable to read volume header data at offset: %" PRIi64 " (0x%08" PRIx64 ").",
1254
22
     function,
1255
22
     file_offset,
1256
22
     file_offset );
1257
1258
22
    return( -1 );
1259
22
  }
1260
1.27k
  if( libluksde_volume_header_read_data(
1261
1.27k
       volume_header,
1262
1.27k
       volume_header_data,
1263
1.27k
       4096,
1264
1.27k
       error ) != 1 )
1265
272
  {
1266
272
    libcerror_error_set(
1267
272
     error,
1268
272
     LIBCERROR_ERROR_DOMAIN_IO,
1269
272
     LIBCERROR_IO_ERROR_READ_FAILED,
1270
272
     "%s: unable to read volume header.",
1271
272
     function );
1272
1273
272
    return( -1 );
1274
272
  }
1275
1.00k
  return( 1 );
1276
1.27k
}
1277
1278
/* Retrieves the format version
1279
 * Returns 1 if successful or -1 on error
1280
 */
1281
int libluksde_volume_header_get_format_version(
1282
     libluksde_volume_header_t *volume_header,
1283
     uint16_t *format_version,
1284
     libcerror_error_t **error )
1285
0
{
1286
0
  static char *function = "libluksde_volume_header_get_format_version";
1287
1288
0
  if( volume_header == NULL )
1289
0
  {
1290
0
    libcerror_error_set(
1291
0
     error,
1292
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1293
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1294
0
     "%s: invalid volume header.",
1295
0
     function );
1296
1297
0
    return( -1 );
1298
0
  }
1299
0
  if( format_version == NULL )
1300
0
  {
1301
0
    libcerror_error_set(
1302
0
     error,
1303
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1304
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1305
0
     "%s: invalid format version.",
1306
0
     function );
1307
1308
0
    return( -1 );
1309
0
  }
1310
0
  *format_version = volume_header->format_version;
1311
1312
0
  return( 1 );
1313
0
}
1314
1315
/* Retrieves the volume identifier
1316
 * The identifier is an UUID and is 16 bytes of size
1317
 * Returns 1 if successful or -1 on error
1318
 */
1319
int libluksde_volume_header_get_volume_identifier(
1320
     libluksde_volume_header_t *volume_header,
1321
     uint8_t *uuid_data,
1322
     size_t uuid_data_size,
1323
     libcerror_error_t **error )
1324
0
{
1325
0
  static char *function = "libluksde_volume_header_get_volume_identifier";
1326
1327
0
  if( volume_header == NULL )
1328
0
  {
1329
0
    libcerror_error_set(
1330
0
     error,
1331
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1332
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1333
0
     "%s: invalid volume header.",
1334
0
     function );
1335
1336
0
    return( -1 );
1337
0
  }
1338
0
  if( uuid_data == NULL )
1339
0
  {
1340
0
    libcerror_error_set(
1341
0
     error,
1342
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1343
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1344
0
     "%s: invalid UUID data.",
1345
0
     function );
1346
1347
0
    return( -1 );
1348
0
  }
1349
0
  if( uuid_data_size < 16 )
1350
0
  {
1351
0
    libcerror_error_set(
1352
0
     error,
1353
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1354
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
1355
0
     "%s: invalid UUID data value too small.",
1356
0
     function );
1357
1358
0
    return( -1 );
1359
0
  }
1360
0
  if( memory_copy(
1361
0
       uuid_data,
1362
0
       volume_header->volume_identifier,
1363
0
       16 ) == NULL )
1364
0
  {
1365
0
    libcerror_error_set(
1366
0
     error,
1367
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
1368
0
     LIBCERROR_MEMORY_ERROR_COPY_FAILED,
1369
0
     "%s: unable to set volume identifier.",
1370
0
     function );
1371
1372
0
    return( -1 );
1373
0
  }
1374
0
  return( 1 );
1375
0
}
1376