Coverage Report

Created: 2026-04-10 07:49

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-2025, 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
907
{
43
907
  static char *function = "libbde_encryption_context_initialize";
44
45
907
  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
907
  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
907
  if( ( method != LIBBDE_ENCRYPTION_METHOD_AES_128_CBC )
68
864
   && ( method != LIBBDE_ENCRYPTION_METHOD_AES_128_CBC_DIFFUSER )
69
790
   && ( method != LIBBDE_ENCRYPTION_METHOD_AES_256_CBC )
70
758
   && ( method != LIBBDE_ENCRYPTION_METHOD_AES_256_CBC_DIFFUSER )
71
738
   && ( method != LIBBDE_ENCRYPTION_METHOD_AES_128_XTS )
72
706
   && ( method != LIBBDE_ENCRYPTION_METHOD_AES_256_XTS )
73
655
   && ( method != LIBBDE_ENCRYPTION_METHOD_NONE ) )
74
35
  {
75
35
    libcerror_error_set(
76
35
     error,
77
35
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
78
35
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
79
35
     "%s: unsupported method.",
80
35
     function );
81
82
35
    return( -1 );
83
35
  }
84
872
  *context = memory_allocate_structure(
85
872
              libbde_encryption_context_t );
86
87
872
  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
872
  if( memory_set(
99
872
       *context,
100
872
       0,
101
872
       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
872
  if( ( method == LIBBDE_ENCRYPTION_METHOD_AES_128_CBC )
118
829
   || ( method == LIBBDE_ENCRYPTION_METHOD_AES_128_CBC_DIFFUSER )
119
755
   || ( method == LIBBDE_ENCRYPTION_METHOD_AES_256_CBC )
120
723
   || ( method == LIBBDE_ENCRYPTION_METHOD_AES_256_CBC_DIFFUSER ) )
121
169
  {
122
169
    if( libcaes_context_initialize(
123
169
         &( ( *context )->fvek_decryption_context ),
124
169
         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
169
    if( libcaes_context_initialize(
136
169
         &( ( *context )->fvek_encryption_context ),
137
169
         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
169
  }
149
872
  if( ( method == LIBBDE_ENCRYPTION_METHOD_AES_128_CBC_DIFFUSER )
150
798
   || ( method == LIBBDE_ENCRYPTION_METHOD_AES_256_CBC_DIFFUSER ) )
151
94
  {
152
94
    if( libcaes_context_initialize(
153
94
         &( ( *context )->tweak_decryption_context ),
154
94
         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
94
    if( libcaes_context_initialize(
166
94
         &( ( *context )->tweak_encryption_context ),
167
94
         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
94
  }
179
872
  if( ( method == LIBBDE_ENCRYPTION_METHOD_AES_128_XTS )
180
840
   || ( method == LIBBDE_ENCRYPTION_METHOD_AES_256_XTS ) )
181
83
  {
182
83
    if( libcaes_tweaked_context_initialize(
183
83
         &( ( *context )->fvek_decryption_tweaked_context ),
184
83
         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
83
    if( libcaes_tweaked_context_initialize(
196
83
         &( ( *context )->fvek_encryption_tweaked_context ),
197
83
         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
83
  }
209
872
  ( *context )->method = method;
210
211
872
  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
872
}
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
872
{
267
872
  static char *function = "libbde_encryption_context_free";
268
872
  int result            = 1;
269
270
872
  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
872
  if( *context != NULL )
282
872
  {
283
872
    if( ( *context )->fvek_decryption_context != NULL )
284
169
    {
285
169
      if( libcaes_context_free(
286
169
           &( ( *context )->fvek_decryption_context ),
287
169
           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
169
    }
299
872
    if( ( *context )->fvek_encryption_context != NULL )
300
169
    {
301
169
      if( libcaes_context_free(
302
169
           &( ( *context )->fvek_encryption_context ),
303
169
           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
169
    }
315
872
    if( ( *context )->tweak_decryption_context != NULL )
316
94
    {
317
94
      if( libcaes_context_free(
318
94
           &( ( *context )->tweak_decryption_context ),
319
94
           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
94
    }
331
872
    if( ( *context )->tweak_encryption_context != NULL )
332
94
    {
333
94
      if( libcaes_context_free(
334
94
           &( ( *context )->tweak_encryption_context ),
335
94
           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
94
    }
347
872
    if( ( *context )->fvek_decryption_tweaked_context != NULL )
348
83
    {
349
83
      if( libcaes_tweaked_context_free(
350
83
           &( ( *context )->fvek_decryption_tweaked_context ),
351
83
           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
83
    }
363
872
    if( ( *context )->fvek_encryption_tweaked_context != NULL )
364
83
    {
365
83
      if( libcaes_tweaked_context_free(
366
83
           &( ( *context )->fvek_encryption_tweaked_context ),
367
83
           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
83
    }
379
872
    memory_free(
380
872
     *context );
381
382
872
    *context = NULL;
383
872
  }
384
872
  return( result );
385
872
}
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
872
{
398
872
  static char *function = "libbde_encryption_context_set_keys";
399
872
  size_t key_bit_size   = 0;
400
872
  size_t key_byte_size  = 0;
401
402
872
  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
872
  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
872
  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
872
  if( ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_128_CBC_DIFFUSER )
436
798
   || ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_256_CBC_DIFFUSER ) )
437
94
  {
438
94
    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
94
    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
94
  }
461
872
  if( ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_128_CBC )
462
829
   || ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_128_CBC_DIFFUSER ) )
463
117
  {
464
117
    key_byte_size = 16;
465
117
  }
466
755
  else if( ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_256_CBC )
467
723
        || ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_256_CBC_DIFFUSER ) )
468
52
  {
469
52
    key_byte_size = 32;
470
52
  }
471
703
  else if( context->method == LIBBDE_ENCRYPTION_METHOD_AES_128_XTS )
472
32
  {
473
32
    key_byte_size = 32;
474
32
  }
475
671
  else if( context->method == LIBBDE_ENCRYPTION_METHOD_AES_256_XTS )
476
51
  {
477
51
    key_byte_size = 64;
478
51
  }
479
872
  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
872
  if( ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_128_CBC_DIFFUSER )
491
798
   || ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_256_CBC_DIFFUSER ) )
492
94
  {
493
94
    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
94
  }
505
872
  key_bit_size = key_byte_size * 8;
506
507
872
  if( ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_128_CBC )
508
829
   || ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_128_CBC_DIFFUSER )
509
755
   || ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_256_CBC )
510
723
   || ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_256_CBC_DIFFUSER ) )
511
169
  {
512
169
    if( libcaes_context_set_key(
513
169
         context->fvek_decryption_context,
514
169
         LIBCAES_CRYPT_MODE_DECRYPT,
515
169
         key,
516
169
         key_bit_size,
517
169
         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
169
    if( libcaes_context_set_key(
529
169
         context->fvek_encryption_context,
530
169
         LIBCAES_CRYPT_MODE_ENCRYPT,
531
169
         key,
532
169
         key_bit_size,
533
169
         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
169
    if( ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_128_CBC_DIFFUSER )
547
95
     || ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_256_CBC_DIFFUSER ) )
548
94
    {
549
94
      if( libcaes_context_set_key(
550
94
           context->tweak_decryption_context,
551
94
           LIBCAES_CRYPT_MODE_DECRYPT,
552
94
           tweak_key,
553
94
           key_bit_size,
554
94
           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
94
      if( libcaes_context_set_key(
566
94
           context->tweak_encryption_context,
567
94
           LIBCAES_CRYPT_MODE_ENCRYPT,
568
94
           tweak_key,
569
94
           key_bit_size,
570
94
           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
94
    }
582
169
  }
583
703
  else if( ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_128_XTS )
584
671
        || ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_256_XTS ) )
585
83
  {
586
83
    key_byte_size /= 2;
587
83
    key_bit_size  /= 2;
588
589
83
    if( libcaes_tweaked_context_set_keys(
590
83
         context->fvek_decryption_tweaked_context,
591
83
         LIBCAES_CRYPT_MODE_DECRYPT,
592
83
         key,
593
83
         key_bit_size,
594
83
         &( key[ key_byte_size ] ),
595
83
         key_bit_size,
596
83
         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
83
    if( libcaes_tweaked_context_set_keys(
608
83
         context->fvek_encryption_tweaked_context,
609
83
         LIBCAES_CRYPT_MODE_ENCRYPT,
610
83
         key,
611
83
         key_bit_size,
612
83
         &( key[ key_byte_size ] ),
613
83
         key_bit_size,
614
83
         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
83
  }
626
872
  return( 1 );
627
872
}
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
79
{
642
79
  uint8_t block_key_data[ 16 ];
643
79
  uint8_t initialization_vector[ 16 ];
644
79
  uint8_t sector_key_data[ 32 ];
645
646
79
  static char *function        = "libbde_encryption_context_crypt";
647
79
  size_t data_index            = 0;
648
79
  size_t sector_key_data_index = 0;
649
650
79
  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
79
  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
79
  if( memory_set(
674
79
       initialization_vector,
675
79
       0,
676
79
       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
79
  if( memory_set(
688
79
       block_key_data,
689
79
       0,
690
79
       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
79
  if( memory_set(
702
79
       sector_key_data,
703
79
       0,
704
79
       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
79
  if( ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_128_CBC )
716
65
   || ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_128_CBC_DIFFUSER )
717
47
   || ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_256_CBC )
718
41
   || ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_256_CBC_DIFFUSER ) )
719
45
  {
720
45
    byte_stream_copy_from_uint64_little_endian(
721
45
     block_key_data,
722
45
     block_key );
723
724
    /* The block key for the initialization vector is encrypted
725
     * with the FVEK
726
     */
727
45
    if( libcaes_crypt_ecb(
728
45
         context->fvek_encryption_context,
729
45
         LIBCAES_CRYPT_MODE_ENCRYPT,
730
45
         block_key_data,
731
45
         16,
732
45
         initialization_vector,
733
45
         16,
734
45
         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
45
    if( ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_128_CBC_DIFFUSER )
746
27
     || ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_256_CBC_DIFFUSER ) )
747
25
    {
748
      /* The block key for the sector key data is encrypted
749
       * with the TWEAK key
750
       */
751
25
      if( libcaes_crypt_ecb(
752
25
           context->tweak_encryption_context,
753
25
           LIBCAES_CRYPT_MODE_ENCRYPT,
754
25
           block_key_data,
755
25
           16,
756
25
           sector_key_data,
757
25
           16,
758
25
           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
25
      block_key_data[ 15 ] = 0x80;
772
773
25
      if( libcaes_crypt_ecb(
774
25
           context->tweak_encryption_context,
775
25
           LIBCAES_CRYPT_MODE_ENCRYPT,
776
25
           block_key_data,
777
25
           16,
778
25
           &( sector_key_data[ 16 ] ),
779
25
           16,
780
25
           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
25
    }
792
45
  }
793
34
  else if( ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_128_XTS )
794
17
        || ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_256_XTS ) )
795
34
  {
796
34
    byte_stream_copy_from_uint64_little_endian(
797
34
     initialization_vector,
798
34
     block_key );
799
34
  }
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
79
  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
79
  else
900
79
  {
901
79
    if( ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_128_CBC )
902
65
     || ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_128_CBC_DIFFUSER )
903
47
     || ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_256_CBC )
904
41
     || ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_256_CBC_DIFFUSER ) )
905
45
    {
906
45
      if( libcaes_crypt_cbc(
907
45
           context->fvek_decryption_context,
908
45
           LIBCAES_CRYPT_MODE_DECRYPT,
909
45
           initialization_vector,
910
45
           16,
911
45
           input_data,
912
45
           input_data_size,
913
45
           output_data,
914
45
           output_data_size,
915
45
           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
45
    }
927
34
    else if( ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_128_XTS )
928
17
          || ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_256_XTS ) )
929
34
    {
930
34
      if( libcaes_crypt_xts(
931
34
           context->fvek_decryption_tweaked_context,
932
34
           LIBCAES_CRYPT_MODE_DECRYPT,
933
34
           initialization_vector,
934
34
           16,
935
34
           input_data,
936
34
           input_data_size,
937
34
           output_data,
938
34
           output_data_size,
939
34
           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
34
    }
951
79
    if( ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_128_CBC_DIFFUSER )
952
61
     || ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_256_CBC_DIFFUSER ) )
953
25
    {
954
25
      if( libbde_diffuser_decrypt(
955
25
           output_data,
956
25
           output_data_size,
957
25
           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
25
      sector_key_data_index = 0;
969
970
25
      for( data_index = 0;
971
18.4k
           data_index < input_data_size;
972
18.4k
           data_index++ )
973
18.4k
      {
974
18.4k
        output_data[ data_index ] ^= sector_key_data[ sector_key_data_index ];
975
976
18.4k
        sector_key_data_index++;
977
978
18.4k
        if( sector_key_data_index >= 32 )
979
576
        {
980
576
          sector_key_data_index -= 32;
981
576
        }
982
18.4k
      }
983
25
    }
984
79
  }
985
79
  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
79
}
1005