Coverage Report

Created: 2026-07-10 07:32

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.42k
{
52
1.42k
  static char *function = "libluksde_volume_header_initialize";
53
54
1.42k
  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.42k
  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.42k
  *volume_header = memory_allocate_structure(
77
1.42k
                    libluksde_volume_header_t );
78
79
1.42k
  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.42k
  if( memory_set(
91
1.42k
       *volume_header,
92
1.42k
       0,
93
1.42k
       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.42k
  if( libcdata_array_initialize(
110
1.42k
       &( ( *volume_header )->key_slots_array ),
111
1.42k
       0,
112
1.42k
       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.42k
  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.42k
}
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.42k
{
143
1.42k
  static char *function = "libluksde_volume_header_free";
144
1.42k
  int result            = 1;
145
146
1.42k
  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.42k
  if( *volume_header != NULL )
158
1.42k
  {
159
1.42k
    if( libcdata_array_free(
160
1.42k
         &( ( *volume_header )->key_slots_array ),
161
1.42k
         (int(*)(intptr_t **, libcerror_error_t **)) &libluksde_key_slot_free,
162
1.42k
         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.42k
    memory_free(
174
1.42k
     *volume_header );
175
176
1.42k
    *volume_header = NULL;
177
1.42k
  }
178
1.42k
  return( result );
179
1.42k
}
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.16k
{
189
1.16k
  static char *function = "libluksde_volume_parse_encryption_method";
190
191
1.16k
  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.16k
  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.16k
  if( ( encryption_method[ 0 ] == 'a' )
214
884
   || ( encryption_method[ 0 ] == 'A' ) )
215
342
  {
216
342
    if( ( ( encryption_method[ 1 ] == 'e' )
217
315
      ||  ( encryption_method[ 1 ] == 'E' ) )
218
213
     && ( ( encryption_method[ 2 ] == 's' )
219
205
      ||  ( encryption_method[ 2 ] == 'S' ) )
220
16
     &&   ( encryption_method[ 3 ] == 0 ) )
221
9
    {
222
9
      volume_header->encryption_method = LIBLUKSDE_ENCRYPTION_METHOD_AES;
223
9
    }
224
333
    else if( ( ( encryption_method[ 1 ] == 'r' )
225
291
           ||  ( encryption_method[ 1 ] == 'R' ) )
226
54
          && ( ( encryption_method[ 2 ] == 'c' )
227
47
           ||  ( encryption_method[ 2 ] == 'C' ) )
228
26
          &&   ( encryption_method[ 3 ] == '4' )
229
15
          &&   ( encryption_method[ 4 ] == 0 ) )
230
4
    {
231
4
      volume_header->encryption_method = LIBLUKSDE_ENCRYPTION_METHOD_ARC4;
232
4
    }
233
342
  }
234
827
  else if( ( encryption_method[ 0 ] == 'b' )
235
694
        || ( encryption_method[ 0 ] == 'B' ) )
236
213
  {
237
213
    if( ( ( encryption_method[ 1 ] == 'l' )
238
157
      ||  ( encryption_method[ 1 ] == 'L' ) )
239
143
     && ( ( encryption_method[ 2 ] == 'o' )
240
52
      ||  ( encryption_method[ 2 ] == 'O' ) )
241
114
     && ( ( encryption_method[ 3 ] == 'w' )
242
44
      ||  ( encryption_method[ 3 ] == 'W' ) )
243
87
     && ( ( encryption_method[ 4 ] == 'f' )
244
70
      ||  ( encryption_method[ 4 ] == 'F' ) )
245
63
     && ( ( encryption_method[ 5 ] == 'i' )
246
47
      ||  ( encryption_method[ 5 ] == 'I' ) )
247
46
     && ( ( encryption_method[ 6 ] == 's' )
248
29
      ||  ( encryption_method[ 6 ] == 'S' ) )
249
29
     && ( ( encryption_method[ 7 ] == 'h' )
250
27
      ||  ( encryption_method[ 7 ] == 'H' ) )
251
9
     &&   ( encryption_method[ 8 ] == 0 ) )
252
1
    {
253
1
      volume_header->encryption_method = LIBLUKSDE_ENCRYPTION_METHOD_BLOWFISH;
254
1
    }
255
213
  }
256
614
  else if( ( encryption_method[ 0 ] == 'c' )
257
508
        || ( encryption_method[ 0 ] == 'C' ) )
258
182
  {
259
182
    if( ( ( encryption_method[ 1 ] == 'a' )
260
120
      ||  ( encryption_method[ 1 ] == 'A' ) )
261
88
     && ( ( encryption_method[ 2 ] == 's' )
262
37
      ||  ( encryption_method[ 2 ] == 'S' ) )
263
64
     && ( ( encryption_method[ 3 ] == 't' )
264
36
      ||  ( encryption_method[ 3 ] == 'T' ) )
265
37
     &&   ( encryption_method[ 5 ] == 0 ) )
266
32
    {
267
32
      if( encryption_method[ 4 ] == '5' )
268
5
      {
269
5
        volume_header->encryption_method = LIBLUKSDE_ENCRYPTION_METHOD_CAST5;
270
5
      }
271
27
      else if( encryption_method[ 4 ] == '6' )
272
2
      {
273
2
        volume_header->encryption_method = LIBLUKSDE_ENCRYPTION_METHOD_CAST6;
274
2
      }
275
32
    }
276
182
  }
277
432
  else if( ( encryption_method[ 0 ] == 's' )
278
317
        || ( encryption_method[ 0 ] == 'S' ) )
279
145
  {
280
145
    if( ( ( encryption_method[ 1 ] == 'e' )
281
48
      ||  ( encryption_method[ 1 ] == 'E' ) )
282
110
     && ( ( encryption_method[ 2 ] == 'r' )
283
63
      ||  ( encryption_method[ 2 ] == 'R' ) )
284
93
     && ( ( encryption_method[ 3 ] == 'p' )
285
57
      ||  ( encryption_method[ 3 ] == 'P' ) )
286
69
     && ( ( encryption_method[ 4 ] == 'e' )
287
34
      ||  ( encryption_method[ 4 ] == 'E' ) )
288
49
     && ( ( encryption_method[ 5 ] == 'n' )
289
30
      ||  ( encryption_method[ 5 ] == 'N' ) )
290
29
     && ( ( encryption_method[ 6 ] == 't' )
291
23
      ||  ( encryption_method[ 6 ] == 'T' ) )
292
11
     &&   ( encryption_method[ 7 ] == 0 ) )
293
2
    {
294
2
      volume_header->encryption_method = LIBLUKSDE_ENCRYPTION_METHOD_SERPENT;
295
2
    }
296
145
  }
297
287
  else if( ( encryption_method[ 0 ] == 't' )
298
276
        || ( encryption_method[ 0 ] == 'T' ) )
299
148
  {
300
148
    if( ( ( encryption_method[ 1 ] == 'w' )
301
132
      ||  ( encryption_method[ 1 ] == 'W' ) )
302
113
     && ( ( encryption_method[ 2 ] == 'o' )
303
105
      ||  ( encryption_method[ 2 ] == 'O' ) )
304
88
     && ( ( encryption_method[ 3 ] == 'f' )
305
65
      ||  ( encryption_method[ 3 ] == 'F' ) )
306
65
     && ( ( encryption_method[ 4 ] == 'i' )
307
32
      ||  ( encryption_method[ 4 ] == 'I' ) )
308
45
     && ( ( encryption_method[ 5 ] == 's' )
309
34
      ||  ( encryption_method[ 5 ] == 'S' ) )
310
23
     && ( ( encryption_method[ 6 ] == 'h' )
311
21
      ||  ( encryption_method[ 6 ] == 'H' ) )
312
10
     &&   ( encryption_method[ 7 ] == 0 ) )
313
1
    {
314
1
      volume_header->encryption_method = LIBLUKSDE_ENCRYPTION_METHOD_TWOFISH;
315
1
    }
316
148
  }
317
1.16k
  return( 1 );
318
1.16k
}
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.16k
{
328
1.16k
  static char *function = "libluksde_volume_parse_encryption_mode";
329
1.16k
  int separator_index   = 0;
330
331
1.16k
  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.16k
  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.16k
  if( ( encryption_mode[ 0 ] == 'c' )
354
809
   || ( encryption_mode[ 0 ] == 'C' ) )
355
804
  {
356
804
    if( ( ( encryption_mode[ 1 ] == 'b' )
357
342
      ||  ( encryption_mode[ 1 ] == 'B' ) )
358
746
     && ( ( encryption_mode[ 2 ] == 'c' )
359
303
      ||  ( encryption_mode[ 2 ] == 'C' ) )
360
537
     &&   ( encryption_mode[ 3 ] == '-' ) )
361
478
    {
362
478
      volume_header->encryption_chaining_mode = LIBLUKSDE_ENCRYPTION_CHAINING_MODE_CBC;
363
364
478
      separator_index = 3;
365
478
    }
366
804
  }
367
365
  else if( ( encryption_mode[ 0 ] == 'e' )
368
322
        || ( encryption_mode[ 0 ] == 'E' ) )
369
103
  {
370
103
    if( ( ( encryption_mode[ 1 ] == 'c' )
371
67
      ||  ( encryption_mode[ 1 ] == 'C' ) )
372
46
     && ( ( encryption_mode[ 2 ] == 'b' )
373
37
      ||  ( encryption_mode[ 2 ] == 'B' ) )
374
29
     &&   ( encryption_mode[ 3 ] == 0 ) )
375
19
    {
376
19
      volume_header->encryption_chaining_mode = LIBLUKSDE_ENCRYPTION_CHAINING_MODE_ECB;
377
378
19
      separator_index = 3;
379
19
    }
380
103
  }
381
262
  else if( ( encryption_mode[ 0 ] == 'x' )
382
241
        || ( encryption_mode[ 0 ] == 'X' ) )
383
71
  {
384
71
    if( ( ( encryption_mode[ 1 ] == 't' )
385
49
      ||  ( encryption_mode[ 1 ] == 'T' ) )
386
42
     && ( ( encryption_mode[ 2 ] == 's' )
387
32
      ||  ( encryption_mode[ 2 ] == 'S' ) )
388
20
     &&   ( encryption_mode[ 3 ] == '-' ) )
389
7
    {
390
7
      volume_header->encryption_chaining_mode = LIBLUKSDE_ENCRYPTION_CHAINING_MODE_XTS;
391
392
7
      separator_index = 3;
393
7
    }
394
71
  }
395
1.16k
  if( ( separator_index > 0 )
396
504
   && ( separator_index < 31 ) )
397
504
  {
398
504
    volume_header->initialization_vector_mode = LIBLUKSDE_INITIALIZATION_VECTOR_MODE_NONE;
399
400
504
    if( ( encryption_mode[ separator_index + 1 ] == 'b' )
401
492
     || ( encryption_mode[ separator_index + 1 ] == 'B' ) )
402
63
    {
403
63
      if( ( ( encryption_mode[ separator_index + 2 ] == 'e' )
404
30
        ||  ( encryption_mode[ separator_index + 2 ] == 'E' ) )
405
52
       && ( ( encryption_mode[ separator_index + 3 ] == 'n' )
406
34
        ||  ( encryption_mode[ separator_index + 3 ] == 'N' ) )
407
44
       && ( ( encryption_mode[ separator_index + 4 ] == 'b' )
408
35
        ||  ( encryption_mode[ separator_index + 4 ] == 'B' ) )
409
28
       && ( ( encryption_mode[ separator_index + 5 ] == 'i' )
410
24
        ||  ( encryption_mode[ separator_index + 5 ] == 'I' ) )
411
10
       &&   ( encryption_mode[ separator_index + 6 ] == 0 ) )
412
1
      {
413
1
        volume_header->initialization_vector_mode = LIBLUKSDE_INITIALIZATION_VECTOR_MODE_BENBI;
414
1
      }
415
63
    }
416
441
    else if( ( encryption_mode[ separator_index + 1 ] == 'e' )
417
391
          || ( encryption_mode[ separator_index + 1 ] == 'E' ) )
418
171
    {
419
171
      if( ( ( encryption_mode[ separator_index + 2 ] == 's' )
420
159
        ||  ( encryption_mode[ separator_index + 2 ] == 'S' ) )
421
149
       && ( ( encryption_mode[ separator_index + 3 ] == 's' )
422
119
        ||  ( encryption_mode[ separator_index + 3 ] == 'S' ) )
423
135
       && ( ( encryption_mode[ separator_index + 4 ] == 'i' )
424
61
        ||  ( encryption_mode[ separator_index + 4 ] == 'I' ) )
425
117
       && ( ( encryption_mode[ separator_index + 5 ] == 'v' )
426
110
        ||  ( encryption_mode[ separator_index + 5 ] == 'V' ) )
427
101
       &&   ( encryption_mode[ separator_index + 6 ] == ':' ) )
428
92
      {
429
92
        if( ( ( encryption_mode[ separator_index + 7 ] == 's' )
430
85
          ||  ( encryption_mode[ separator_index + 7 ] == 'S' ) )
431
75
         && ( ( encryption_mode[ separator_index + 8 ] == 'h' )
432
46
          ||  ( encryption_mode[ separator_index + 8 ] == 'H' ) )
433
61
         && ( ( encryption_mode[ separator_index + 9 ] == 'a' )
434
22
          ||  ( encryption_mode[ separator_index + 9 ] == 'A' ) ) )
435
53
        {
436
53
          if( ( encryption_mode[ separator_index + 10 ] == '1' )
437
11
           && ( encryption_mode[ separator_index + 11 ] == 0 ) )
438
2
          {
439
2
            volume_header->initialization_vector_mode = LIBLUKSDE_INITIALIZATION_VECTOR_MODE_ESSIV;
440
2
            volume_header->essiv_hashing_method       = LIBLUKSDE_HASHING_METHOD_SHA1;
441
2
          }
442
51
          else if( ( encryption_mode[ separator_index + 10 ] == '2' )
443
26
                && ( encryption_mode[ separator_index + 11 ] == '5' )
444
15
                && ( 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
53
        }
451
/* TODO IV options */
452
92
      }
453
171
    }
454
270
    else if( ( encryption_mode[ separator_index + 1 ] == 'l' )
455
242
          || ( encryption_mode[ separator_index + 1 ] == 'L' ) )
456
38
    {
457
38
      if( ( ( encryption_mode[ separator_index + 2 ] == 'm' )
458
21
        ||  ( encryption_mode[ separator_index + 2 ] == 'M' ) )
459
31
       && ( ( encryption_mode[ separator_index + 3 ] == 'k' )
460
19
        ||  ( encryption_mode[ separator_index + 3 ] == 'K' ) )
461
14
       &&   ( encryption_mode[ separator_index + 4 ] == 0 ) )
462
4
      {
463
4
        volume_header->initialization_vector_mode = LIBLUKSDE_INITIALIZATION_VECTOR_MODE_LMK;
464
4
      }
465
38
    }
466
232
    else if( ( encryption_mode[ separator_index + 1 ] == 'n' )
467
196
          || ( encryption_mode[ separator_index + 1 ] == 'N' ) )
468
68
    {
469
68
      if( ( ( encryption_mode[ separator_index + 2 ] == 'u' )
470
37
        ||  ( encryption_mode[ separator_index + 2 ] == 'U' ) )
471
50
       && ( ( encryption_mode[ separator_index + 3 ] == 'l' )
472
36
        ||  ( encryption_mode[ separator_index + 3 ] == 'L' ) )
473
28
       && ( ( encryption_mode[ separator_index + 4 ] == 'l' )
474
26
        ||  ( encryption_mode[ separator_index + 4 ] == 'L' ) )
475
5
       &&   ( encryption_mode[ separator_index + 5 ] == 0 ) )
476
2
      {
477
2
        volume_header->initialization_vector_mode = LIBLUKSDE_INITIALIZATION_VECTOR_MODE_NULL;
478
2
      }
479
68
    }
480
164
    else if( ( encryption_mode[ separator_index + 1 ] == 'p' )
481
74
          || ( encryption_mode[ separator_index + 1 ] == 'P' ) )
482
115
    {
483
115
      if( ( ( encryption_mode[ separator_index + 2 ] == 'l' )
484
99
        ||  ( encryption_mode[ separator_index + 2 ] == 'L' ) )
485
97
       && ( ( encryption_mode[ separator_index + 3 ] == 'a' )
486
33
        ||  ( encryption_mode[ separator_index + 3 ] == 'A' ) )
487
81
       && ( ( encryption_mode[ separator_index + 4 ] == 'i' )
488
60
        ||  ( encryption_mode[ separator_index + 4 ] == 'I' ) )
489
61
       && ( ( encryption_mode[ separator_index + 5 ] == 'n' )
490
31
        ||  ( encryption_mode[ separator_index + 5 ] == 'N' ) ) )
491
39
      {
492
39
        if( encryption_mode[ separator_index + 6 ] == 0 )
493
2
        {
494
2
          volume_header->initialization_vector_mode = LIBLUKSDE_INITIALIZATION_VECTOR_MODE_PLAIN32;
495
2
        }
496
37
        else if( ( encryption_mode[ separator_index + 6 ] == '6' )
497
21
              && ( encryption_mode[ separator_index + 7 ] == '4' )
498
11
              && ( encryption_mode[ separator_index + 8 ] == 0 ) )
499
2
        {
500
2
          volume_header->initialization_vector_mode = LIBLUKSDE_INITIALIZATION_VECTOR_MODE_PLAIN64;
501
2
        }
502
39
      }
503
115
    }
504
504
  }
505
1.16k
  return( 1 );
506
1.16k
}
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.16k
{
516
1.16k
  static char *function = "libluksde_volume_parse_hashing_method";
517
518
1.16k
  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.16k
  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.16k
  if( ( hashing_method[ 0 ] == 'r' )
541
1.03k
   || ( hashing_method[ 0 ] == 'R' ) )
542
155
  {
543
155
    if( ( ( hashing_method[ 1 ] == 'i' )
544
61
      ||  ( hashing_method[ 1 ] == 'I' ) )
545
108
     && ( ( hashing_method[ 2 ] == 'p' )
546
66
      ||  ( hashing_method[ 2 ] == 'P' ) )
547
90
     && ( ( hashing_method[ 3 ] == 'e' )
548
35
      ||  ( hashing_method[ 3 ] == 'E' ) )
549
74
     && ( ( hashing_method[ 4 ] == 'm' )
550
33
      ||  ( hashing_method[ 4 ] == 'M' ) )
551
57
     && ( ( hashing_method[ 5 ] == 'd' )
552
30
      ||  ( hashing_method[ 5 ] == 'D' ) )
553
44
     &&   ( hashing_method[ 6 ] == '1' )
554
33
     &&   ( hashing_method[ 7 ] == '6' )
555
15
     &&   ( hashing_method[ 8 ] == '0' )
556
10
     &&   ( hashing_method[ 9 ] == 0 ) )
557
2
    {
558
2
      volume_header->hashing_method = LIBLUKSDE_HASHING_METHOD_RIPEMD160;
559
2
    }
560
155
  }
561
1.01k
  else if( ( hashing_method[ 0 ] == 's' )
562
744
        || ( hashing_method[ 0 ] == 'S' ) )
563
530
  {
564
530
    if( ( ( hashing_method[ 1 ] == 'h' )
565
141
      ||  ( hashing_method[ 1 ] == 'H' ) )
566
461
     && ( ( hashing_method[ 2 ] == 'a' )
567
180
      ||  ( hashing_method[ 2 ] == 'A' ) ) )
568
418
    {
569
418
      if( ( hashing_method[ 3 ] == '1' )
570
225
       && ( hashing_method[ 4 ] == 0 ) )
571
212
      {
572
212
        volume_header->hashing_method = LIBLUKSDE_HASHING_METHOD_SHA1;
573
212
      }
574
206
      else if( ( hashing_method[ 3 ] == '2' )
575
122
            && ( hashing_method[ 4 ] == '2' )
576
60
            && ( hashing_method[ 5 ] == '4' )
577
45
            && ( hashing_method[ 6 ] == 0 ) )
578
42
      {
579
42
        volume_header->hashing_method = LIBLUKSDE_HASHING_METHOD_SHA224;
580
42
      }
581
164
      else if( ( hashing_method[ 3 ] == '2' )
582
80
            && ( hashing_method[ 4 ] == '5' )
583
35
            && ( hashing_method[ 5 ] == '6' )
584
13
            && ( hashing_method[ 6 ] == 0 ) )
585
2
      {
586
2
        volume_header->hashing_method = LIBLUKSDE_HASHING_METHOD_SHA256;
587
2
      }
588
162
      else if( ( hashing_method[ 3 ] == '5' )
589
34
            && ( hashing_method[ 4 ] == '1' )
590
21
            && ( hashing_method[ 5 ] == '2' )
591
11
            && ( hashing_method[ 6 ] == 0 ) )
592
2
      {
593
2
        volume_header->hashing_method = LIBLUKSDE_HASHING_METHOD_SHA512;
594
2
      }
595
418
    }
596
530
  }
597
1.16k
  return( 1 );
598
1.16k
}
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.40k
{
609
1.40k
  libfguid_identifier_t *guid    = NULL;
610
1.40k
  libluksde_key_slot_t *key_slot = NULL;
611
1.40k
  static char *function          = "libluksde_volume_header_read_data";
612
1.40k
  size_t data_offset             = 0;
613
1.40k
  int entry_index                = 0;
614
1.40k
  int key_slot_index             = 0;
615
1.40k
  int result                     = 0;
616
617
#if defined( HAVE_DEBUG_OUTPUT )
618
  uint64_t value_64bit           = 0;
619
#endif
620
621
1.40k
  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.40k
  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.40k
  if( ( data_size < sizeof( luksde_volume_header_v1_t ) )
644
1.40k
   || ( 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.40k
  if( memory_compare(
668
1.40k
       ( (luksde_volume_header_v1_t *) data )->signature,
669
1.40k
       luksde_signature,
670
1.40k
       6 ) == 0 )
671
463
  {
672
463
  }
673
943
  else if( memory_compare(
674
943
            ( (luksde_volume_header_v1_t *) data )->signature,
675
943
            luksde_backup_volume_header_signature,
676
943
            6 ) == 0 )
677
889
  {
678
889
  }
679
54
  else
680
54
  {
681
54
    libcerror_error_set(
682
54
     error,
683
54
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
684
54
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
685
54
     "%s: unsupported signature.",
686
54
     function );
687
688
54
    goto on_error;
689
54
  }
690
1.35k
  byte_stream_copy_to_uint16_big_endian(
691
1.35k
   ( (luksde_volume_header_v1_t *) data )->format_version,
692
1.35k
   volume_header->format_version );
693
694
1.35k
  if( ( volume_header->format_version != 1 )
695
25
   && ( volume_header->format_version != 2 ) )
696
23
  {
697
23
    libcerror_error_set(
698
23
     error,
699
23
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
700
23
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
701
23
     "%s: unsupported format version.",
702
23
     function );
703
704
23
    goto on_error;
705
23
  }
706
1.32k
  if( volume_header->format_version == 2 )
707
2
  {
708
2
    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
2
  }
720
1.32k
  if( volume_header->format_version == 1 )
721
1.32k
  {
722
1.32k
    byte_stream_copy_to_uint32_big_endian(
723
1.32k
     ( (luksde_volume_header_v1_t *) data )->encrypted_volume_start_sector,
724
1.32k
     volume_header->encrypted_volume_start_sector );
725
726
1.32k
    byte_stream_copy_to_uint32_big_endian(
727
1.32k
     ( (luksde_volume_header_v1_t *) data )->master_key_size,
728
1.32k
     volume_header->master_key_size );
729
730
1.32k
    if( memory_copy(
731
1.32k
         volume_header->master_key_validation_hash,
732
1.32k
         ( (luksde_volume_header_v1_t *) data )->master_key_validation_hash,
733
1.32k
         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.32k
    if( memory_copy(
745
1.32k
         volume_header->master_key_salt,
746
1.32k
         ( (luksde_volume_header_v1_t *) data )->master_key_salt,
747
1.32k
         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.32k
    byte_stream_copy_to_uint32_big_endian(
759
1.32k
     ( (luksde_volume_header_v1_t *) data )->master_key_number_of_iterations,
760
1.32k
     volume_header->master_key_number_of_iterations );
761
1.32k
  }
762
1.32k
  if( libfguid_identifier_initialize(
763
1.32k
       &guid,
764
1.32k
       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.32k
  if( volume_header->format_version == 1 )
776
1.32k
  {
777
1.32k
    result = libfguid_identifier_copy_from_utf8_string(
778
1.32k
              guid,
779
1.32k
              ( (luksde_volume_header_v1_t *) data )->volume_identifier,
780
1.32k
              40,
781
1.32k
              LIBFGUID_STRING_FORMAT_FLAG_USE_MIXED_CASE,
782
1.32k
              error );
783
1.32k
  }
784
2
  else if( volume_header->format_version == 2 )
785
2
  {
786
2
    result = libfguid_identifier_copy_from_utf8_string(
787
2
              guid,
788
2
              ( (luksde_volume_header_v2_t *) data )->volume_identifier,
789
2
              40,
790
2
              LIBFGUID_STRING_FORMAT_FLAG_USE_MIXED_CASE,
791
2
              error );
792
2
  }
793
1.32k
  if( result != 1 )
794
159
  {
795
159
    libcerror_error_set(
796
159
     error,
797
159
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
798
159
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
799
159
     "%s: unable to copy GUID from string.",
800
159
     function );
801
802
159
    goto on_error;
803
159
  }
804
1.17k
  if( libfguid_identifier_copy_to_byte_stream(
805
1.17k
       guid,
806
1.17k
       volume_header->volume_identifier,
807
1.17k
       16,
808
1.17k
       LIBFGUID_ENDIAN_BIG,
809
1.17k
       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.17k
  if( libfguid_identifier_free(
821
1.17k
       &guid,
822
1.17k
       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.17k
  if( volume_header->format_version == 1 )
1085
1.16k
  {
1086
1.16k
    if( libluksde_volume_parse_encryption_method(
1087
1.16k
         volume_header,
1088
1.16k
         ( (luksde_volume_header_v1_t *) data )->encryption_method,
1089
1.16k
         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.16k
    if( libluksde_volume_parse_encryption_mode(
1101
1.16k
         volume_header,
1102
1.16k
         ( (luksde_volume_header_v1_t *) data )->encryption_mode,
1103
1.16k
         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.16k
    if( libluksde_volume_parse_hashing_method(
1115
1.16k
         volume_header,
1116
1.16k
         ( (luksde_volume_header_v1_t *) data )->hashing_method,
1117
1.16k
         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.16k
    data_offset = sizeof( luksde_volume_header_v1_t );
1129
1130
1.16k
    for( key_slot_index = 0;
1131
10.5k
         key_slot_index < 8;
1132
9.35k
         key_slot_index++ )
1133
9.35k
    {
1134
9.35k
      if( libluksde_key_slot_initialize(
1135
9.35k
           &key_slot,
1136
9.35k
           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
9.35k
      if( libluksde_key_slot_read_data(
1148
9.35k
           key_slot,
1149
9.35k
           &( data[ data_offset ] ),
1150
9.35k
           sizeof( luksde_volume_keyslot_t ),
1151
9.35k
           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
9.35k
      if( libcdata_array_append_entry(
1163
9.35k
           volume_header->key_slots_array,
1164
9.35k
           &entry_index,
1165
9.35k
           (intptr_t *) key_slot,
1166
9.35k
           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
9.35k
      key_slot = NULL;
1178
1179
9.35k
      data_offset += sizeof( luksde_volume_keyslot_t );
1180
9.35k
    }
1181
1.16k
  }
1182
1.17k
  return( 1 );
1183
1184
236
on_error:
1185
236
  if( key_slot != NULL )
1186
0
  {
1187
0
    libluksde_key_slot_free(
1188
0
     &key_slot,
1189
0
     NULL );
1190
0
  }
1191
236
  if( guid != NULL )
1192
159
  {
1193
159
    libfguid_identifier_free(
1194
159
     &guid,
1195
159
     NULL );
1196
159
  }
1197
236
  libcdata_array_empty(
1198
236
   volume_header->key_slots_array,
1199
236
   (int(*)(intptr_t **, libcerror_error_t **)) &libluksde_key_slot_free,
1200
236
   NULL );
1201
1202
236
  return( -1 );
1203
1.17k
}
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.42k
{
1214
1.42k
  uint8_t volume_header_data[ 4096 ];
1215
1216
1.42k
  static char *function = "libluksde_volume_header_read_file_io_handle";
1217
1.42k
  ssize_t read_count    = 0;
1218
1219
1.42k
  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.42k
  read_count = libbfio_handle_read_buffer_at_offset(
1241
1.42k
                file_io_handle,
1242
1.42k
                volume_header_data,
1243
1.42k
                4096,
1244
1.42k
                file_offset,
1245
1.42k
                error );
1246
1247
1.42k
  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.40k
  if( libluksde_volume_header_read_data(
1261
1.40k
       volume_header,
1262
1.40k
       volume_header_data,
1263
1.40k
       4096,
1264
1.40k
       error ) != 1 )
1265
236
  {
1266
236
    libcerror_error_set(
1267
236
     error,
1268
236
     LIBCERROR_ERROR_DOMAIN_IO,
1269
236
     LIBCERROR_IO_ERROR_READ_FAILED,
1270
236
     "%s: unable to read volume header.",
1271
236
     function );
1272
1273
236
    return( -1 );
1274
236
  }
1275
1.17k
  return( 1 );
1276
1.40k
}
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
49
{
1325
49
  static char *function = "libluksde_volume_header_get_volume_identifier";
1326
1327
49
  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
49
  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
49
  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
49
  if( memory_copy(
1361
49
       uuid_data,
1362
49
       volume_header->volume_identifier,
1363
49
       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
49
  return( 1 );
1375
49
}
1376