Coverage Report

Created: 2026-05-30 07:13

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libbde/libbde/libbde_encryption_context.c
Line
Count
Source
1
/*
2
 * Encryption functions
3
 *
4
 * Copyright (C) 2011-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 "libbde_definitions.h"
28
#include "libbde_diffuser.h"
29
#include "libbde_encryption_context.h"
30
#include "libbde_libcaes.h"
31
#include "libbde_libcerror.h"
32
#include "libbde_libcnotify.h"
33
34
/* Creates an encryption context
35
 * Make sure the value encryption context is referencing, is set to NULL
36
 * Returns 1 if successful or -1 on error
37
 */
38
int libbde_encryption_context_initialize(
39
     libbde_encryption_context_t **context,
40
     uint16_t method,
41
     libcerror_error_t **error )
42
969
{
43
969
  static char *function = "libbde_encryption_context_initialize";
44
45
969
  if( context == NULL )
46
0
  {
47
0
    libcerror_error_set(
48
0
     error,
49
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
50
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
51
0
     "%s: invalid context.",
52
0
     function );
53
54
0
    return( -1 );
55
0
  }
56
969
  if( *context != NULL )
57
0
  {
58
0
    libcerror_error_set(
59
0
     error,
60
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
61
0
     LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
62
0
     "%s: invalid context value already set.",
63
0
     function );
64
65
0
    return( -1 );
66
0
  }
67
969
  if( ( method != LIBBDE_ENCRYPTION_METHOD_AES_128_CBC )
68
942
   && ( method != LIBBDE_ENCRYPTION_METHOD_AES_128_CBC_DIFFUSER )
69
880
   && ( method != LIBBDE_ENCRYPTION_METHOD_AES_256_CBC )
70
828
   && ( method != LIBBDE_ENCRYPTION_METHOD_AES_256_CBC_DIFFUSER )
71
804
   && ( method != LIBBDE_ENCRYPTION_METHOD_AES_128_XTS )
72
782
   && ( method != LIBBDE_ENCRYPTION_METHOD_AES_256_XTS )
73
706
   && ( method != LIBBDE_ENCRYPTION_METHOD_NONE ) )
74
40
  {
75
40
    libcerror_error_set(
76
40
     error,
77
40
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
78
40
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
79
40
     "%s: unsupported method.",
80
40
     function );
81
82
40
    return( -1 );
83
40
  }
84
929
  *context = memory_allocate_structure(
85
929
              libbde_encryption_context_t );
86
87
929
  if( *context == NULL )
88
0
  {
89
0
    libcerror_error_set(
90
0
     error,
91
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
92
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
93
0
     "%s: unable to create context.",
94
0
     function );
95
96
0
    goto on_error;
97
0
  }
98
929
  if( memory_set(
99
929
       *context,
100
929
       0,
101
929
       sizeof( libbde_encryption_context_t ) ) == NULL )
102
0
  {
103
0
    libcerror_error_set(
104
0
     error,
105
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
106
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
107
0
     "%s: unable to clear context.",
108
0
     function );
109
110
0
    memory_free(
111
0
     *context );
112
113
0
    *context = NULL;
114
115
0
    return( -1 );
116
0
  }
117
929
  if( ( method == LIBBDE_ENCRYPTION_METHOD_AES_128_CBC )
118
902
   || ( method == LIBBDE_ENCRYPTION_METHOD_AES_128_CBC_DIFFUSER )
119
840
   || ( method == LIBBDE_ENCRYPTION_METHOD_AES_256_CBC )
120
788
   || ( method == LIBBDE_ENCRYPTION_METHOD_AES_256_CBC_DIFFUSER ) )
121
165
  {
122
165
    if( libcaes_context_initialize(
123
165
         &( ( *context )->fvek_decryption_context ),
124
165
         error ) != 1 )
125
0
    {
126
0
      libcerror_error_set(
127
0
       error,
128
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
129
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
130
0
       "%s: unable to initialize FVEK decryption context.",
131
0
       function );
132
133
0
      goto on_error;
134
0
    }
135
165
    if( libcaes_context_initialize(
136
165
         &( ( *context )->fvek_encryption_context ),
137
165
         error ) != 1 )
138
0
    {
139
0
      libcerror_error_set(
140
0
       error,
141
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
142
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
143
0
       "%s: unable to initialize FVEK encryption context.",
144
0
       function );
145
146
0
      goto on_error;
147
0
    }
148
165
  }
149
929
  if( ( method == LIBBDE_ENCRYPTION_METHOD_AES_128_CBC_DIFFUSER )
150
867
   || ( method == LIBBDE_ENCRYPTION_METHOD_AES_256_CBC_DIFFUSER ) )
151
86
  {
152
86
    if( libcaes_context_initialize(
153
86
         &( ( *context )->tweak_decryption_context ),
154
86
         error ) != 1 )
155
0
    {
156
0
      libcerror_error_set(
157
0
       error,
158
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
159
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
160
0
       "%s: unable to initialize TWEAK decryption context.",
161
0
       function );
162
163
0
      goto on_error;
164
0
    }
165
86
    if( libcaes_context_initialize(
166
86
         &( ( *context )->tweak_encryption_context ),
167
86
         error ) != 1 )
168
0
    {
169
0
      libcerror_error_set(
170
0
       error,
171
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
172
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
173
0
       "%s: unable to initialize TWEAK encryption context.",
174
0
       function );
175
176
0
      goto on_error;
177
0
    }
178
86
  }
179
929
  if( ( method == LIBBDE_ENCRYPTION_METHOD_AES_128_XTS )
180
907
   || ( method == LIBBDE_ENCRYPTION_METHOD_AES_256_XTS ) )
181
98
  {
182
98
    if( libcaes_tweaked_context_initialize(
183
98
         &( ( *context )->fvek_decryption_tweaked_context ),
184
98
         error ) != 1 )
185
0
    {
186
0
      libcerror_error_set(
187
0
       error,
188
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
189
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
190
0
       "%s: unable to initialize FVEK decryption tweaked context.",
191
0
       function );
192
193
0
      goto on_error;
194
0
    }
195
98
    if( libcaes_tweaked_context_initialize(
196
98
         &( ( *context )->fvek_encryption_tweaked_context ),
197
98
         error ) != 1 )
198
0
    {
199
0
      libcerror_error_set(
200
0
       error,
201
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
202
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
203
0
       "%s: unable to initialize FVEK encryption tweaked context.",
204
0
       function );
205
206
0
      goto on_error;
207
0
    }
208
98
  }
209
929
  ( *context )->method = method;
210
211
929
  return( 1 );
212
213
0
on_error:
214
0
  if( *context != NULL )
215
0
  {
216
0
    if( ( *context )->fvek_encryption_tweaked_context != NULL )
217
0
    {
218
0
      libcaes_tweaked_context_free(
219
0
       &( ( *context )->fvek_encryption_tweaked_context ),
220
0
       NULL );
221
0
    }
222
0
    if( ( *context )->fvek_decryption_tweaked_context != NULL )
223
0
    {
224
0
      libcaes_tweaked_context_free(
225
0
       &( ( *context )->fvek_decryption_tweaked_context ),
226
0
       NULL );
227
0
    }
228
0
    if( ( *context )->tweak_encryption_context != NULL )
229
0
    {
230
0
      libcaes_context_free(
231
0
       &( ( *context )->tweak_encryption_context ),
232
0
       NULL );
233
0
    }
234
0
    if( ( *context )->tweak_decryption_context != NULL )
235
0
    {
236
0
      libcaes_context_free(
237
0
       &( ( *context )->tweak_decryption_context ),
238
0
       NULL );
239
0
    }
240
0
    if( ( *context )->fvek_encryption_context != NULL )
241
0
    {
242
0
      libcaes_context_free(
243
0
       &( ( *context )->fvek_encryption_context ),
244
0
       NULL );
245
0
    }
246
0
    if( ( *context )->fvek_decryption_context != NULL )
247
0
    {
248
0
      libcaes_context_free(
249
0
       &( ( *context )->fvek_decryption_context ),
250
0
       NULL );
251
0
    }
252
0
    memory_free(
253
0
     *context );
254
255
0
    *context = NULL;
256
0
  }
257
0
  return( -1 );
258
929
}
259
260
/* Frees an encryption context
261
 * Returns 1 if successful or -1 on error
262
 */
263
int libbde_encryption_context_free(
264
     libbde_encryption_context_t **context,
265
     libcerror_error_t **error )
266
929
{
267
929
  static char *function = "libbde_encryption_context_free";
268
929
  int result            = 1;
269
270
929
  if( context == NULL )
271
0
  {
272
0
    libcerror_error_set(
273
0
     error,
274
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
275
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
276
0
     "%s: invalid context.",
277
0
     function );
278
279
0
    return( -1 );
280
0
  }
281
929
  if( *context != NULL )
282
929
  {
283
929
    if( ( *context )->fvek_decryption_context != NULL )
284
165
    {
285
165
      if( libcaes_context_free(
286
165
           &( ( *context )->fvek_decryption_context ),
287
165
           error ) != 1 )
288
0
      {
289
0
        libcerror_error_set(
290
0
         error,
291
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
292
0
         LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
293
0
         "%s: unable free FVEK decryption context.",
294
0
         function );
295
296
0
        result = -1;
297
0
      }
298
165
    }
299
929
    if( ( *context )->fvek_encryption_context != NULL )
300
165
    {
301
165
      if( libcaes_context_free(
302
165
           &( ( *context )->fvek_encryption_context ),
303
165
           error ) != 1 )
304
0
      {
305
0
        libcerror_error_set(
306
0
         error,
307
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
308
0
         LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
309
0
         "%s: unable free FVEK encryption context.",
310
0
         function );
311
312
0
        result = -1;
313
0
      }
314
165
    }
315
929
    if( ( *context )->tweak_decryption_context != NULL )
316
86
    {
317
86
      if( libcaes_context_free(
318
86
           &( ( *context )->tweak_decryption_context ),
319
86
           error ) != 1 )
320
0
      {
321
0
        libcerror_error_set(
322
0
         error,
323
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
324
0
         LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
325
0
         "%s: unable free TWEAK decryption context.",
326
0
         function );
327
328
0
        result = -1;
329
0
      }
330
86
    }
331
929
    if( ( *context )->tweak_encryption_context != NULL )
332
86
    {
333
86
      if( libcaes_context_free(
334
86
           &( ( *context )->tweak_encryption_context ),
335
86
           error ) != 1 )
336
0
      {
337
0
        libcerror_error_set(
338
0
         error,
339
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
340
0
         LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
341
0
         "%s: unable free TWEAK encryption context.",
342
0
         function );
343
344
0
        result = -1;
345
0
      }
346
86
    }
347
929
    if( ( *context )->fvek_decryption_tweaked_context != NULL )
348
98
    {
349
98
      if( libcaes_tweaked_context_free(
350
98
           &( ( *context )->fvek_decryption_tweaked_context ),
351
98
           error ) != 1 )
352
0
      {
353
0
        libcerror_error_set(
354
0
         error,
355
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
356
0
         LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
357
0
         "%s: unable free FVEK decryption tweaked context.",
358
0
         function );
359
360
0
        result = -1;
361
0
      }
362
98
    }
363
929
    if( ( *context )->fvek_encryption_tweaked_context != NULL )
364
98
    {
365
98
      if( libcaes_tweaked_context_free(
366
98
           &( ( *context )->fvek_encryption_tweaked_context ),
367
98
           error ) != 1 )
368
0
      {
369
0
        libcerror_error_set(
370
0
         error,
371
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
372
0
         LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
373
0
         "%s: unable free FVEK encryption tweaked context.",
374
0
         function );
375
376
0
        result = -1;
377
0
      }
378
98
    }
379
929
    memory_free(
380
929
     *context );
381
382
929
    *context = NULL;
383
929
  }
384
929
  return( result );
385
929
}
386
387
/* Sets the de- and encryption keys
388
 * Returns 1 if successful or -1 on error
389
 */
390
int libbde_encryption_context_set_keys(
391
     libbde_encryption_context_t *context,
392
     const uint8_t *key,
393
     size_t key_size,
394
     const uint8_t *tweak_key,
395
     size_t tweak_key_size,
396
     libcerror_error_t **error )
397
929
{
398
929
  static char *function = "libbde_encryption_context_set_keys";
399
929
  size_t key_bit_size   = 0;
400
929
  size_t key_byte_size  = 0;
401
402
929
  if( context == NULL )
403
0
  {
404
0
    libcerror_error_set(
405
0
     error,
406
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
407
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
408
0
     "%s: invalid context.",
409
0
     function );
410
411
0
    return( -1 );
412
0
  }
413
929
  if( key == NULL )
414
0
  {
415
0
    libcerror_error_set(
416
0
     error,
417
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
418
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
419
0
     "%s: invalid key.",
420
0
     function );
421
422
0
    return( -1 );
423
0
  }
424
929
  if( key_size > (size_t) SSIZE_MAX )
425
0
  {
426
0
    libcerror_error_set(
427
0
     error,
428
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
429
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
430
0
     "%s: invalid key size value exceeds maximum.",
431
0
     function );
432
433
0
    return( -1 );
434
0
  }
435
929
  if( ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_128_CBC_DIFFUSER )
436
867
   || ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_256_CBC_DIFFUSER ) )
437
86
  {
438
86
    if( tweak_key == NULL )
439
0
    {
440
0
      libcerror_error_set(
441
0
       error,
442
0
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
443
0
       LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
444
0
       "%s: invalid tweak key.",
445
0
       function );
446
447
0
      return( -1 );
448
0
    }
449
86
    if( tweak_key_size > (size_t) SSIZE_MAX )
450
0
    {
451
0
      libcerror_error_set(
452
0
       error,
453
0
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
454
0
       LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
455
0
       "%s: invalid tweak key size value exceeds maximum.",
456
0
       function );
457
458
0
      return( -1 );
459
0
    }
460
86
  }
461
929
  if( ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_128_CBC )
462
902
   || ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_128_CBC_DIFFUSER ) )
463
89
  {
464
89
    key_byte_size = 16;
465
89
  }
466
840
  else if( ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_256_CBC )
467
788
        || ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_256_CBC_DIFFUSER ) )
468
76
  {
469
76
    key_byte_size = 32;
470
76
  }
471
764
  else if( context->method == LIBBDE_ENCRYPTION_METHOD_AES_128_XTS )
472
22
  {
473
22
    key_byte_size = 32;
474
22
  }
475
742
  else if( context->method == LIBBDE_ENCRYPTION_METHOD_AES_256_XTS )
476
76
  {
477
76
    key_byte_size = 64;
478
76
  }
479
929
  if( key_size < key_byte_size )
480
0
  {
481
0
    libcerror_error_set(
482
0
     error,
483
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
484
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
485
0
     "%s: invalid key value too small.",
486
0
     function );
487
488
0
    return( -1 );
489
0
  }
490
929
  if( ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_128_CBC_DIFFUSER )
491
867
   || ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_256_CBC_DIFFUSER ) )
492
86
  {
493
86
    if( tweak_key_size < key_byte_size )
494
0
    {
495
0
      libcerror_error_set(
496
0
       error,
497
0
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
498
0
       LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
499
0
       "%s: invalid tweak key value too small.",
500
0
       function );
501
502
0
      return( -1 );
503
0
    }
504
86
  }
505
929
  key_bit_size = key_byte_size * 8;
506
507
929
  if( ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_128_CBC )
508
902
   || ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_128_CBC_DIFFUSER )
509
840
   || ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_256_CBC )
510
788
   || ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_256_CBC_DIFFUSER ) )
511
165
  {
512
165
    if( libcaes_context_set_key(
513
165
         context->fvek_decryption_context,
514
165
         LIBCAES_CRYPT_MODE_DECRYPT,
515
165
         key,
516
165
         key_bit_size,
517
165
         error ) != 1 )
518
0
    {
519
0
      libcerror_error_set(
520
0
       error,
521
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
522
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
523
0
       "%s: unable to set key in decryption context.",
524
0
       function );
525
526
0
      return( -1 );
527
0
    }
528
165
    if( libcaes_context_set_key(
529
165
         context->fvek_encryption_context,
530
165
         LIBCAES_CRYPT_MODE_ENCRYPT,
531
165
         key,
532
165
         key_bit_size,
533
165
         error ) != 1 )
534
0
    {
535
0
      libcerror_error_set(
536
0
       error,
537
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
538
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
539
0
       "%s: unable to set key in encryption context.",
540
0
       function );
541
542
0
      return( -1 );
543
0
    }
544
    /* The TWEAK key is only used with diffuser
545
     */
546
165
    if( ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_128_CBC_DIFFUSER )
547
103
     || ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_256_CBC_DIFFUSER ) )
548
86
    {
549
86
      if( libcaes_context_set_key(
550
86
           context->tweak_decryption_context,
551
86
           LIBCAES_CRYPT_MODE_DECRYPT,
552
86
           tweak_key,
553
86
           key_bit_size,
554
86
           error ) != 1 )
555
0
      {
556
0
        libcerror_error_set(
557
0
         error,
558
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
559
0
         LIBCERROR_RUNTIME_ERROR_SET_FAILED,
560
0
         "%s: unable to set tweak key in decryption context.",
561
0
         function );
562
563
0
        return( -1 );
564
0
      }
565
86
      if( libcaes_context_set_key(
566
86
           context->tweak_encryption_context,
567
86
           LIBCAES_CRYPT_MODE_ENCRYPT,
568
86
           tweak_key,
569
86
           key_bit_size,
570
86
           error ) != 1 )
571
0
      {
572
0
        libcerror_error_set(
573
0
         error,
574
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
575
0
         LIBCERROR_RUNTIME_ERROR_SET_FAILED,
576
0
         "%s: unable to set tweak key in encryption context.",
577
0
         function );
578
579
0
        return( -1 );
580
0
      }
581
86
    }
582
165
  }
583
764
  else if( ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_128_XTS )
584
742
        || ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_256_XTS ) )
585
98
  {
586
98
    key_byte_size /= 2;
587
98
    key_bit_size  /= 2;
588
589
98
    if( libcaes_tweaked_context_set_keys(
590
98
         context->fvek_decryption_tweaked_context,
591
98
         LIBCAES_CRYPT_MODE_DECRYPT,
592
98
         key,
593
98
         key_bit_size,
594
98
         &( key[ key_byte_size ] ),
595
98
         key_bit_size,
596
98
         error ) != 1 )
597
0
    {
598
0
      libcerror_error_set(
599
0
       error,
600
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
601
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
602
0
       "%s: unable to set keys in decryption tweaked context.",
603
0
       function );
604
605
0
      return( -1 );
606
0
    }
607
98
    if( libcaes_tweaked_context_set_keys(
608
98
         context->fvek_encryption_tweaked_context,
609
98
         LIBCAES_CRYPT_MODE_ENCRYPT,
610
98
         key,
611
98
         key_bit_size,
612
98
         &( key[ key_byte_size ] ),
613
98
         key_bit_size,
614
98
         error ) != 1 )
615
0
    {
616
0
      libcerror_error_set(
617
0
       error,
618
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
619
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
620
0
       "%s: unable to set keys in encryption tweaked context.",
621
0
       function );
622
623
0
      return( -1 );
624
0
    }
625
98
  }
626
929
  return( 1 );
627
929
}
628
629
/* De- or encrypts a block of data
630
 * Returns 1 if successful or -1 on error
631
 */
632
int libbde_encryption_context_crypt(
633
     libbde_encryption_context_t *context,
634
     int mode,
635
     const uint8_t *input_data,
636
     size_t input_data_size,
637
     uint8_t *output_data,
638
     size_t output_data_size,
639
     uint64_t block_key,
640
     libcerror_error_t **error )
641
61
{
642
61
  uint8_t block_key_data[ 16 ];
643
61
  uint8_t initialization_vector[ 16 ];
644
61
  uint8_t sector_key_data[ 32 ];
645
646
61
  static char *function        = "libbde_encryption_context_crypt";
647
61
  size_t data_index            = 0;
648
61
  size_t sector_key_data_index = 0;
649
650
61
  if( context == NULL )
651
0
  {
652
0
    libcerror_error_set(
653
0
     error,
654
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
655
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
656
0
     "%s: invalid context.",
657
0
     function );
658
659
0
    return( -1 );
660
0
  }
661
61
  if( ( mode != LIBBDE_ENCRYPTION_CRYPT_MODE_DECRYPT )
662
0
   && ( mode != LIBBDE_ENCRYPTION_CRYPT_MODE_ENCRYPT ) )
663
0
  {
664
0
    libcerror_error_set(
665
0
     error,
666
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
667
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
668
0
     "%s: unsupported mode.",
669
0
     function );
670
671
0
    return( -1 );
672
0
  }
673
61
  if( memory_set(
674
61
       initialization_vector,
675
61
       0,
676
61
       16 ) == NULL )
677
0
  {
678
0
    libcerror_error_set(
679
0
     error,
680
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
681
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
682
0
     "%s: unable to clear initialization vector.",
683
0
     function );
684
685
0
    return( -1 );
686
0
  }
687
61
  if( memory_set(
688
61
       block_key_data,
689
61
       0,
690
61
       16 ) == NULL )
691
0
  {
692
0
    libcerror_error_set(
693
0
     error,
694
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
695
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
696
0
     "%s: unable to clear block key data.",
697
0
     function );
698
699
0
    return( -1 );
700
0
  }
701
61
  if( memory_set(
702
61
       sector_key_data,
703
61
       0,
704
61
       32 ) == NULL )
705
0
  {
706
0
    libcerror_error_set(
707
0
     error,
708
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
709
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
710
0
     "%s: unable to clear sector key data.",
711
0
     function );
712
713
0
    return( -1 );
714
0
  }
715
61
  if( ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_128_CBC )
716
51
   || ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_128_CBC_DIFFUSER )
717
40
   || ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_256_CBC )
718
37
   || ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_256_CBC_DIFFUSER ) )
719
33
  {
720
33
    byte_stream_copy_from_uint64_little_endian(
721
33
     block_key_data,
722
33
     block_key );
723
724
    /* The block key for the initialization vector is encrypted
725
     * with the FVEK
726
     */
727
33
    if( libcaes_crypt_ecb(
728
33
         context->fvek_encryption_context,
729
33
         LIBCAES_CRYPT_MODE_ENCRYPT,
730
33
         block_key_data,
731
33
         16,
732
33
         initialization_vector,
733
33
         16,
734
33
         error ) != 1 )
735
0
    {
736
0
      libcerror_error_set(
737
0
       error,
738
0
       LIBCERROR_ERROR_DOMAIN_ENCRYPTION,
739
0
       LIBCERROR_ENCRYPTION_ERROR_GENERIC,
740
0
       "%s: unable to encrypt initialization vector.",
741
0
       function );
742
743
0
      goto on_error;
744
0
    }
745
33
    if( ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_128_CBC_DIFFUSER )
746
22
     || ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_256_CBC_DIFFUSER ) )
747
20
    {
748
      /* The block key for the sector key data is encrypted
749
       * with the TWEAK key
750
       */
751
20
      if( libcaes_crypt_ecb(
752
20
           context->tweak_encryption_context,
753
20
           LIBCAES_CRYPT_MODE_ENCRYPT,
754
20
           block_key_data,
755
20
           16,
756
20
           sector_key_data,
757
20
           16,
758
20
           error ) != 1 )
759
0
      {
760
0
        libcerror_error_set(
761
0
         error,
762
0
         LIBCERROR_ERROR_DOMAIN_ENCRYPTION,
763
0
         LIBCERROR_ENCRYPTION_ERROR_GENERIC,
764
0
         "%s: unable to encrypt sector key data.",
765
0
         function );
766
767
0
        goto on_error;
768
0
      }
769
      /* Set the last byte to contain 0x80 (128)
770
       */
771
20
      block_key_data[ 15 ] = 0x80;
772
773
20
      if( libcaes_crypt_ecb(
774
20
           context->tweak_encryption_context,
775
20
           LIBCAES_CRYPT_MODE_ENCRYPT,
776
20
           block_key_data,
777
20
           16,
778
20
           &( sector_key_data[ 16 ] ),
779
20
           16,
780
20
           error ) != 1 )
781
0
      {
782
0
        libcerror_error_set(
783
0
         error,
784
0
         LIBCERROR_ERROR_DOMAIN_ENCRYPTION,
785
0
         LIBCERROR_ENCRYPTION_ERROR_GENERIC,
786
0
         "%s: unable to encrypt sector key data.",
787
0
         function );
788
789
0
        goto on_error;
790
0
      }
791
20
    }
792
33
  }
793
28
  else if( ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_128_XTS )
794
16
        || ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_256_XTS ) )
795
28
  {
796
28
    byte_stream_copy_from_uint64_little_endian(
797
28
     initialization_vector,
798
28
     block_key );
799
28
  }
800
#if defined( HAVE_DEBUG_OUTPUT )
801
  if( libcnotify_verbose != 0 )
802
  {
803
    libcnotify_printf(
804
     "%s: initialization vector:\n",
805
     function );
806
    libcnotify_print_data(
807
     initialization_vector,
808
     16,
809
     0 );
810
  }
811
#endif
812
61
  if( mode == LIBBDE_ENCRYPTION_CRYPT_MODE_ENCRYPT )
813
0
  {
814
/* TODO safe guard input data ? */
815
0
    if( ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_128_CBC_DIFFUSER )
816
0
     || ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_256_CBC_DIFFUSER ) )
817
0
    {
818
0
      sector_key_data_index = 0;
819
820
0
      for( data_index = 0;
821
0
           data_index < input_data_size;
822
0
           data_index++ )
823
0
      {
824
0
        output_data[ data_index ] ^= sector_key_data[ sector_key_data_index ];
825
826
0
        sector_key_data_index++;
827
828
0
        if( sector_key_data_index >= 32 )
829
0
        {
830
0
          sector_key_data_index -= 32;
831
0
        }
832
0
      }
833
0
      if( libbde_diffuser_encrypt(
834
0
           output_data,
835
0
           output_data_size,
836
0
           error ) != 1 )
837
0
      {
838
0
        libcerror_error_set(
839
0
         error,
840
0
         LIBCERROR_ERROR_DOMAIN_ENCRYPTION,
841
0
         LIBCERROR_ENCRYPTION_ERROR_ENCRYPT_FAILED,
842
0
         "%s: unable to encrypt data using Diffuser.",
843
0
         function );
844
845
0
        goto on_error;
846
0
      }
847
0
    }
848
0
    if( ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_128_CBC )
849
0
     || ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_128_CBC_DIFFUSER )
850
0
     || ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_256_CBC )
851
0
     || ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_256_CBC_DIFFUSER ) )
852
0
    {
853
0
      if( libcaes_crypt_cbc(
854
0
           context->fvek_encryption_context,
855
0
           LIBCAES_CRYPT_MODE_ENCRYPT,
856
0
           initialization_vector,
857
0
           16,
858
0
           input_data,
859
0
           input_data_size,
860
0
           output_data,
861
0
           output_data_size,
862
0
           error ) != 1 )
863
0
      {
864
0
        libcerror_error_set(
865
0
         error,
866
0
         LIBCERROR_ERROR_DOMAIN_ENCRYPTION,
867
0
         LIBCERROR_ENCRYPTION_ERROR_GENERIC,
868
0
         "%s: unable to AES-CBC encrypt output data.",
869
0
         function );
870
871
0
        goto on_error;
872
0
      }
873
0
    }
874
0
    else if( ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_128_XTS )
875
0
          || ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_256_XTS ) )
876
0
    {
877
0
      if( libcaes_crypt_xts(
878
0
           context->fvek_encryption_tweaked_context,
879
0
           LIBCAES_CRYPT_MODE_ENCRYPT,
880
0
           initialization_vector,
881
0
           16,
882
0
           input_data,
883
0
           input_data_size,
884
0
           output_data,
885
0
           output_data_size,
886
0
           error ) != 1 )
887
0
      {
888
0
        libcerror_error_set(
889
0
         error,
890
0
         LIBCERROR_ERROR_DOMAIN_ENCRYPTION,
891
0
         LIBCERROR_ENCRYPTION_ERROR_GENERIC,
892
0
         "%s: unable to AES-XTS decrypt output data.",
893
0
         function );
894
895
0
        goto on_error;
896
0
      }
897
0
    }
898
0
  }
899
61
  else
900
61
  {
901
61
    if( ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_128_CBC )
902
51
     || ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_128_CBC_DIFFUSER )
903
40
     || ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_256_CBC )
904
37
     || ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_256_CBC_DIFFUSER ) )
905
33
    {
906
33
      if( libcaes_crypt_cbc(
907
33
           context->fvek_decryption_context,
908
33
           LIBCAES_CRYPT_MODE_DECRYPT,
909
33
           initialization_vector,
910
33
           16,
911
33
           input_data,
912
33
           input_data_size,
913
33
           output_data,
914
33
           output_data_size,
915
33
           error ) != 1 )
916
0
      {
917
0
        libcerror_error_set(
918
0
         error,
919
0
         LIBCERROR_ERROR_DOMAIN_ENCRYPTION,
920
0
         LIBCERROR_ENCRYPTION_ERROR_GENERIC,
921
0
         "%s: unable to AES-CBC decrypt output data.",
922
0
         function );
923
924
0
        goto on_error;
925
0
      }
926
33
    }
927
28
    else if( ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_128_XTS )
928
16
          || ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_256_XTS ) )
929
28
    {
930
28
      if( libcaes_crypt_xts(
931
28
           context->fvek_decryption_tweaked_context,
932
28
           LIBCAES_CRYPT_MODE_DECRYPT,
933
28
           initialization_vector,
934
28
           16,
935
28
           input_data,
936
28
           input_data_size,
937
28
           output_data,
938
28
           output_data_size,
939
28
           error ) != 1 )
940
0
      {
941
0
        libcerror_error_set(
942
0
         error,
943
0
         LIBCERROR_ERROR_DOMAIN_ENCRYPTION,
944
0
         LIBCERROR_ENCRYPTION_ERROR_GENERIC,
945
0
         "%s: unable to AES-XTS decrypt output data.",
946
0
         function );
947
948
0
        goto on_error;
949
0
      }
950
28
    }
951
61
    if( ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_128_CBC_DIFFUSER )
952
50
     || ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_256_CBC_DIFFUSER ) )
953
20
    {
954
20
      if( libbde_diffuser_decrypt(
955
20
           output_data,
956
20
           output_data_size,
957
20
           error ) != 1 )
958
0
      {
959
0
        libcerror_error_set(
960
0
         error,
961
0
         LIBCERROR_ERROR_DOMAIN_ENCRYPTION,
962
0
         LIBCERROR_ENCRYPTION_ERROR_DECRYPT_FAILED,
963
0
         "%s: unable to decrypt data using Diffuser.",
964
0
         function );
965
966
0
        goto on_error;
967
0
      }
968
20
      sector_key_data_index = 0;
969
970
20
      for( data_index = 0;
971
15.8k
           data_index < input_data_size;
972
15.8k
           data_index++ )
973
15.8k
      {
974
15.8k
        output_data[ data_index ] ^= sector_key_data[ sector_key_data_index ];
975
976
15.8k
        sector_key_data_index++;
977
978
15.8k
        if( sector_key_data_index >= 32 )
979
496
        {
980
496
          sector_key_data_index -= 32;
981
496
        }
982
15.8k
      }
983
20
    }
984
61
  }
985
61
  return( 1 );
986
987
0
on_error:
988
0
  memory_set(
989
0
   sector_key_data,
990
0
   0,
991
0
   32 );
992
993
0
  memory_set(
994
0
   block_key_data,
995
0
   0,
996
0
   16 );
997
998
0
  memory_set(
999
0
   initialization_vector,
1000
0
   0,
1001
0
   16 );
1002
1003
0
  return( -1 );
1004
61
}
1005