Coverage Report

Created: 2026-07-25 07:30

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libfvde/libfvde/libfvde_deflate.c
Line
Count
Source
1
/*
2
 * Deflate (zlib) (un)compression functions
3
 *
4
 * Copyright (C) 2011-2026, Omar Choudary <choudary.omar@gmail.com>,
5
 *                          Joachim Metz <joachim.metz@gmail.com>
6
 *
7
 * Refer to AUTHORS for acknowledgements.
8
 *
9
 * This program is free software: you can redistribute it and/or modify
10
 * it under the terms of the GNU Lesser General Public License as published by
11
 * the Free Software Foundation, either version 3 of the License, or
12
 * (at your option) any later version.
13
 *
14
 * This program is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 * GNU General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU Lesser General Public License
20
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
21
 */
22
23
#include <common.h>
24
#include <byte_stream.h>
25
#include <memory.h>
26
#include <types.h>
27
28
#include "libfvde_bit_stream.h"
29
#include "libfvde_deflate.h"
30
#include "libfvde_huffman_tree.h"
31
#include "libfvde_libcerror.h"
32
#include "libfvde_libcnotify.h"
33
34
const uint8_t libfvde_deflate_code_sizes_sequence[ 19 ]  = {
35
  16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2,
36
        14, 1, 15 };
37
38
const uint16_t libfvde_deflate_literal_codes_base[ 29 ] = {
39
  3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
40
  35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258 };
41
42
const uint16_t libfvde_deflate_literal_codes_number_of_extra_bits[ 29 ] = {
43
  0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
44
  3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0 };
45
46
const uint16_t libfvde_deflate_distance_codes_base[ 30 ] = {
47
  1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
48
  257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193,
49
  12289, 16385, 24577 };
50
51
const uint16_t libfvde_deflate_distance_codes_number_of_extra_bits[ 30 ] = {
52
  0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
53
  7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13 };
54
55
/* Initializes the dynamic Huffman trees
56
 * Returns 1 on success or -1 on error
57
 */
58
int libfvde_deflate_build_dynamic_huffman_trees(
59
     libfvde_bit_stream_t *bit_stream,
60
     libfvde_huffman_tree_t *literals_tree,
61
     libfvde_huffman_tree_t *distances_tree,
62
     libcerror_error_t **error )
63
0
{
64
0
  uint8_t code_size_array[ 316 ];
65
66
0
  libfvde_huffman_tree_t *codes_tree = NULL;
67
0
  static char *function              = "libfvde_deflate_build_dynamic_huffman_trees";
68
0
  uint32_t code_size                 = 0;
69
0
  uint32_t code_size_index           = 0;
70
0
  uint32_t code_size_sequence        = 0;
71
0
  uint32_t number_of_code_sizes      = 0;
72
0
  uint32_t number_of_distance_codes  = 0;
73
0
  uint32_t number_of_literal_codes   = 0;
74
0
  uint32_t times_to_repeat           = 0;
75
0
  uint16_t symbol                    = 0;
76
77
0
  if( libfvde_bit_stream_get_value(
78
0
       bit_stream,
79
0
       14,
80
0
       &number_of_code_sizes,
81
0
       error ) != 1 )
82
0
  {
83
0
    libcerror_error_set(
84
0
     error,
85
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
86
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
87
0
     "%s: unable to retrieve value from bit stream.",
88
0
     function );
89
90
0
    goto on_error;
91
0
  }
92
0
  number_of_literal_codes  = number_of_code_sizes & 0x0000001fUL;
93
0
  number_of_code_sizes   >>= 5;
94
0
  number_of_distance_codes = number_of_code_sizes & 0x0000001fUL;
95
0
  number_of_code_sizes   >>= 5;
96
97
0
  number_of_literal_codes += 257;
98
99
0
  if( number_of_literal_codes > 286 )
100
0
  {
101
0
    libcerror_error_set(
102
0
     error,
103
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
104
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
105
0
     "%s: invalid number of literal codes value out of bounds.",
106
0
     function );
107
108
0
    goto on_error;
109
0
  }
110
0
  number_of_distance_codes += 1;
111
112
0
  if( number_of_distance_codes > 30 )
113
0
  {
114
0
    libcerror_error_set(
115
0
     error,
116
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
117
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
118
0
     "%s: invalid number of distance codes value out of bounds.",
119
0
     function );
120
121
0
    goto on_error;
122
0
  }
123
0
  number_of_code_sizes += 4;
124
125
0
  for( code_size_index = 0;
126
0
       code_size_index < number_of_code_sizes;
127
0
       code_size_index++ )
128
0
  {
129
0
    if( libfvde_bit_stream_get_value(
130
0
         bit_stream,
131
0
         3,
132
0
         &code_size,
133
0
         error ) != 1 )
134
0
    {
135
0
      libcerror_error_set(
136
0
       error,
137
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
138
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
139
0
       "%s: unable to retrieve value from bit stream.",
140
0
       function );
141
142
0
      goto on_error;
143
0
    }
144
0
    code_size_sequence = libfvde_deflate_code_sizes_sequence[ code_size_index ];
145
146
0
    code_size_array[ code_size_sequence ] = (uint8_t) code_size;
147
0
  }
148
0
  while( code_size_index < 19 )
149
0
  {
150
0
    code_size_sequence = libfvde_deflate_code_sizes_sequence[ code_size_index++ ];
151
152
0
    code_size_array[ code_size_sequence ] = 0;
153
0
  }
154
0
  if( libfvde_huffman_tree_initialize(
155
0
       &codes_tree,
156
0
       19,
157
0
       15,
158
0
       error ) != 1 )
159
0
  {
160
0
    libcerror_error_set(
161
0
     error,
162
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
163
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
164
0
     "%s: unable to build codes tree.",
165
0
     function );
166
167
0
    goto on_error;
168
0
  }
169
0
  if( libfvde_huffman_tree_build(
170
0
       codes_tree,
171
0
       code_size_array,
172
0
       19,
173
0
       error ) != 1 )
174
0
  {
175
0
    libcerror_error_set(
176
0
     error,
177
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
178
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
179
0
     "%s: unable to build codes tree.",
180
0
     function );
181
182
0
    goto on_error;
183
0
  }
184
0
  number_of_code_sizes = number_of_literal_codes + number_of_distance_codes;
185
186
0
  code_size_index = 0;
187
188
0
  while( code_size_index < number_of_code_sizes )
189
0
  {
190
0
    if( libfvde_huffman_tree_get_symbol_from_bit_stream(
191
0
         codes_tree,
192
0
         bit_stream,
193
0
         &symbol,
194
0
         error ) != 1 )
195
0
    {
196
0
      libcerror_error_set(
197
0
       error,
198
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
199
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
200
0
       "%s: unable to retrieve literal value from bit stream.",
201
0
       function );
202
203
0
      goto on_error;
204
0
    }
205
0
    if( symbol < 16 )
206
0
    {
207
0
      code_size_array[ code_size_index++ ] = (uint8_t) symbol;
208
209
0
      continue;
210
0
    }
211
0
    code_size = 0;
212
213
0
    if( symbol == 16 )
214
0
    {
215
0
      if( code_size_index == 0 )
216
0
      {
217
0
        libcerror_error_set(
218
0
         error,
219
0
         LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
220
0
         LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
221
0
         "%s: invalid code size index value out of bounds.",
222
0
         function );
223
224
0
        goto on_error;
225
0
      }
226
0
      code_size = (uint32_t) code_size_array[ code_size_index - 1 ];
227
228
0
      if( libfvde_bit_stream_get_value(
229
0
           bit_stream,
230
0
           2,
231
0
           &times_to_repeat,
232
0
           error ) != 1 )
233
0
      {
234
0
        libcerror_error_set(
235
0
         error,
236
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
237
0
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
238
0
         "%s: unable to retrieve value from bit stream.",
239
0
         function );
240
241
0
        goto on_error;
242
0
      }
243
0
      times_to_repeat += 3;
244
0
    }
245
0
    else if( symbol == 17 )
246
0
    {
247
0
      if( libfvde_bit_stream_get_value(
248
0
           bit_stream,
249
0
           3,
250
0
           &times_to_repeat,
251
0
           error ) != 1 )
252
0
      {
253
0
        libcerror_error_set(
254
0
         error,
255
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
256
0
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
257
0
         "%s: unable to retrieve value from bit stream.",
258
0
         function );
259
260
0
        goto on_error;
261
0
      }
262
0
      times_to_repeat += 3;
263
0
    }
264
0
    else if( symbol == 18 )
265
0
    {
266
0
      if( libfvde_bit_stream_get_value(
267
0
           bit_stream,
268
0
           7,
269
0
           &times_to_repeat,
270
0
           error ) != 1 )
271
0
      {
272
0
        libcerror_error_set(
273
0
         error,
274
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
275
0
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
276
0
         "%s: unable to retrieve value from bit stream.",
277
0
         function );
278
279
0
        goto on_error;
280
0
      }
281
0
      times_to_repeat += 11;
282
0
    }
283
0
    else
284
0
    {
285
0
      libcerror_error_set(
286
0
       error,
287
0
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
288
0
       LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
289
0
       "%s: invalid code value value out of bounds.",
290
0
       function );
291
292
0
      goto on_error;
293
0
    }
294
0
    if( ( code_size_index + times_to_repeat ) > number_of_code_sizes )
295
0
    {
296
0
      libcerror_error_set(
297
0
       error,
298
0
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
299
0
       LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
300
0
       "%s: invalid times to repeat value out of bounds.",
301
0
       function );
302
303
0
      goto on_error;
304
0
    }
305
0
    while( times_to_repeat > 0 )
306
0
    {
307
0
      code_size_array[ code_size_index++ ] = (uint8_t) code_size;
308
309
0
      times_to_repeat--;
310
0
    }
311
0
  }
312
0
  if( code_size_array[ 256 ] == 0 )
313
0
  {
314
0
    libcerror_error_set(
315
0
     error,
316
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
317
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
318
0
     "%s: end-of-block code value missing in literal codes array.",
319
0
     function );
320
321
0
    goto on_error;
322
0
  }
323
0
  if( libfvde_huffman_tree_free(
324
0
       &codes_tree,
325
0
       error ) != 1 )
326
0
  {
327
0
    libcerror_error_set(
328
0
     error,
329
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
330
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
331
0
     "%s: unable to free codes tree.",
332
0
     function );
333
334
0
    goto on_error;
335
0
  }
336
0
  if( libfvde_huffman_tree_build(
337
0
       literals_tree,
338
0
       code_size_array,
339
0
       number_of_literal_codes,
340
0
       error ) != 1 )
341
0
  {
342
0
    libcerror_error_set(
343
0
     error,
344
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
345
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
346
0
     "%s: unable to build literals tree.",
347
0
     function );
348
349
0
    goto on_error;
350
0
  }
351
0
  if( libfvde_huffman_tree_build(
352
0
       distances_tree,
353
0
       &( code_size_array[ number_of_literal_codes ] ),
354
0
       number_of_distance_codes,
355
0
       error ) != 1 )
356
0
  {
357
0
    libcerror_error_set(
358
0
     error,
359
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
360
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
361
0
     "%s: unable to build distances tree.",
362
0
     function );
363
364
0
    goto on_error;
365
0
  }
366
0
  return( 1 );
367
368
0
on_error:
369
0
  if( codes_tree != NULL )
370
0
  {
371
0
    libfvde_huffman_tree_free(
372
0
     &codes_tree,
373
0
     NULL );
374
0
  }
375
0
  return( -1 );
376
0
}
377
378
/* Initializes the fixed Huffman trees
379
 * Returns 1 on success or -1 on error
380
 */
381
int libfvde_deflate_build_fixed_huffman_trees(
382
     libfvde_huffman_tree_t *literals_tree,
383
     libfvde_huffman_tree_t *distances_tree,
384
     libcerror_error_t **error )
385
0
{
386
0
  uint8_t code_size_array[ 318 ];
387
388
0
  static char *function = "libfvde_deflate_build_fixed_huffman_trees";
389
0
  uint16_t symbol       = 0;
390
391
0
  for( symbol = 0;
392
0
       symbol < 318;
393
0
       symbol++ )
394
0
  {
395
0
    if( symbol < 144 )
396
0
    {
397
0
      code_size_array[ symbol ] = 8;
398
0
    }
399
0
    else if( symbol < 256 )
400
0
    {
401
0
      code_size_array[ symbol ] = 9;
402
0
    }
403
0
    else if( symbol < 280 )
404
0
    {
405
0
      code_size_array[ symbol ] = 7;
406
0
    }
407
0
    else if( symbol < 288 )
408
0
    {
409
0
      code_size_array[ symbol ] = 8;
410
0
    }
411
0
    else
412
0
    {
413
0
      code_size_array[ symbol ] = 5;
414
0
    }
415
0
  }
416
0
  if( libfvde_huffman_tree_build(
417
0
       literals_tree,
418
0
       code_size_array,
419
0
       288,
420
0
       error ) != 1 )
421
0
  {
422
0
    libcerror_error_set(
423
0
     error,
424
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
425
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
426
0
     "%s: unable to build literals tree.",
427
0
     function );
428
429
0
    return( -1 );
430
0
  }
431
0
  if( libfvde_huffman_tree_build(
432
0
       distances_tree,
433
0
       &( code_size_array[ 288 ] ),
434
0
       30,
435
0
       error ) != 1 )
436
0
  {
437
0
    libcerror_error_set(
438
0
     error,
439
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
440
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
441
0
     "%s: unable to build distances tree.",
442
0
     function );
443
444
0
    return( -1 );
445
0
  }
446
0
  return( 1 );
447
0
}
448
449
/* Decodes a Huffman compressed block
450
 * Returns 1 on success or -1 on error
451
 */
452
int libfvde_deflate_decode_huffman(
453
     libfvde_bit_stream_t *bit_stream,
454
     libfvde_huffman_tree_t *literals_tree,
455
     libfvde_huffman_tree_t *distances_tree,
456
     uint8_t *uncompressed_data,
457
     size_t uncompressed_data_size,
458
     size_t *uncompressed_data_offset,
459
     libcerror_error_t **error )
460
0
{
461
0
  static char *function         = "libfvde_deflate_decode_huffman";
462
0
  size_t data_offset            = 0;
463
0
  uint32_t extra_bits           = 0;
464
0
  uint16_t compression_offset   = 0;
465
0
  uint16_t compression_size     = 0;
466
0
  uint16_t number_of_extra_bits = 0;
467
0
  uint16_t symbol               = 0;
468
469
0
  if( uncompressed_data == NULL )
470
0
  {
471
0
    libcerror_error_set(
472
0
     error,
473
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
474
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
475
0
     "%s: invalid uncompressed data.",
476
0
     function );
477
478
0
    return( -1 );
479
0
  }
480
0
  if( uncompressed_data_size > (size_t) SSIZE_MAX )
481
0
  {
482
0
    libcerror_error_set(
483
0
     error,
484
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
485
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
486
0
     "%s: invalid uncompressed data size value exceeds maximum.",
487
0
     function );
488
489
0
    return( -1 );
490
0
  }
491
0
  if( uncompressed_data_offset == NULL )
492
0
  {
493
0
    libcerror_error_set(
494
0
     error,
495
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
496
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
497
0
     "%s: invalid uncompressed data offset.",
498
0
     function );
499
500
0
    return( -1 );
501
0
  }
502
0
  data_offset = *uncompressed_data_offset;
503
504
0
  do
505
0
  {
506
0
    if( libfvde_huffman_tree_get_symbol_from_bit_stream(
507
0
         literals_tree,
508
0
         bit_stream,
509
0
         &symbol,
510
0
         error ) != 1 )
511
0
    {
512
0
      libcerror_error_set(
513
0
       error,
514
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
515
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
516
0
       "%s: unable to retrieve literal value from bit stream.",
517
0
       function );
518
519
0
      return( -1 );
520
0
    }
521
0
    if( symbol < 256 )
522
0
    {
523
0
      if( data_offset >= uncompressed_data_size )
524
0
      {
525
0
        libcerror_error_set(
526
0
         error,
527
0
         LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
528
0
         LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
529
0
         "%s: invalid uncompressed data value too small.",
530
0
         function );
531
532
0
        return( -1 );
533
0
      }
534
0
      uncompressed_data[ data_offset++ ] = (uint8_t) symbol;
535
0
    }
536
0
    else if( ( symbol > 256 )
537
0
          && ( symbol < 286 ) )
538
0
    {
539
0
      symbol -= 257;
540
541
0
      number_of_extra_bits = libfvde_deflate_literal_codes_number_of_extra_bits[ symbol ];
542
543
0
      if( libfvde_bit_stream_get_value(
544
0
           bit_stream,
545
0
           (uint8_t) number_of_extra_bits,
546
0
           &extra_bits,
547
0
           error ) != 1 )
548
0
      {
549
0
        libcerror_error_set(
550
0
         error,
551
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
552
0
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
553
0
         "%s: unable to retrieve literal extra value from bit stream.",
554
0
         function );
555
556
0
        return( -1 );
557
0
      }
558
0
      compression_size = libfvde_deflate_literal_codes_base[ symbol ] + (uint16_t) extra_bits;
559
560
0
      if( libfvde_huffman_tree_get_symbol_from_bit_stream(
561
0
           distances_tree,
562
0
           bit_stream,
563
0
           &symbol,
564
0
           error ) != 1 )
565
0
      {
566
0
        libcerror_error_set(
567
0
         error,
568
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
569
0
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
570
0
         "%s: unable to retrieve distance value from bit stream.",
571
0
         function );
572
573
0
        return( -1 );
574
0
      }
575
0
      number_of_extra_bits = libfvde_deflate_distance_codes_number_of_extra_bits[ symbol ];
576
577
0
      if( libfvde_bit_stream_get_value(
578
0
           bit_stream,
579
0
           (uint8_t) number_of_extra_bits,
580
0
           &extra_bits,
581
0
           error ) != 1 )
582
0
      {
583
0
        libcerror_error_set(
584
0
         error,
585
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
586
0
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
587
0
         "%s: unable to retrieve distance extra value from bit stream.",
588
0
         function );
589
590
0
        return( -1 );
591
0
      }
592
0
      compression_offset = libfvde_deflate_distance_codes_base[ symbol ] + (uint16_t) extra_bits;
593
594
0
      if( compression_offset > data_offset )
595
0
      {
596
0
        libcerror_error_set(
597
0
         error,
598
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
599
0
         LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
600
0
         "%s: invalid compression offset value out of bounds.",
601
0
         function );
602
603
0
        return( -1 );
604
0
      }
605
0
      if( ( data_offset + compression_size ) > uncompressed_data_size )
606
0
      {
607
0
        libcerror_error_set(
608
0
         error,
609
0
         LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
610
0
         LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
611
0
         "%s: invalid uncompressed data value too small.",
612
0
         function );
613
614
0
        return( -1 );
615
0
      }
616
0
      while( compression_size > 0 )
617
0
      {
618
0
        uncompressed_data[ data_offset ] = uncompressed_data[ data_offset - compression_offset ];
619
620
0
        data_offset++;
621
0
        compression_size--;
622
0
      }
623
0
    }
624
0
    else if( symbol != 256 )
625
0
    {
626
0
      libcerror_error_set(
627
0
       error,
628
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
629
0
       LIBCERROR_RUNTIME_ERROR_GET_FAILED,
630
0
       "%s: invalid code value: %" PRIu16 ".",
631
0
       function,
632
0
       symbol );
633
634
0
      return( -1 );
635
0
    }
636
0
  }
637
0
  while( symbol != 256 );
638
639
0
  *uncompressed_data_offset = data_offset;
640
641
0
  return( 1 );
642
0
}
643
644
/* Calculates the little-endian Adler-32 of a buffer
645
 * It uses the initial value to calculate a new Adler-32
646
 * Returns 1 if successful or -1 on error
647
 */
648
int libfvde_deflate_calculate_adler32(
649
     uint32_t *checksum_value,
650
     const uint8_t *data,
651
     size_t data_size,
652
     uint32_t initial_value,
653
     libcerror_error_t **error )
654
0
{
655
0
  static char *function = "libfvde_deflate_calculate_adler32";
656
0
  size_t data_offset    = 0;
657
0
  uint32_t lower_word   = 0;
658
0
  uint32_t upper_word   = 0;
659
0
  uint32_t value_32bit  = 0;
660
0
  int block_index       = 0;
661
662
0
  if( checksum_value == NULL )
663
0
  {
664
0
    libcerror_error_set(
665
0
     error,
666
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
667
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
668
0
     "%s: invalid checksum value.",
669
0
     function );
670
671
0
    return( -1 );
672
0
  }
673
0
  if( data == NULL )
674
0
  {
675
0
    libcerror_error_set(
676
0
     error,
677
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
678
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
679
0
     "%s: invalid data.",
680
0
     function );
681
682
0
    return( -1 );
683
0
  }
684
0
  if( data_size > (size_t) SSIZE_MAX )
685
0
  {
686
0
    libcerror_error_set(
687
0
     error,
688
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
689
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
690
0
     "%s: invalid data size value exceeds maximum.",
691
0
     function );
692
693
0
    return( -1 );
694
0
  }
695
0
  lower_word = initial_value & 0xffff;
696
0
  upper_word = ( initial_value >> 16 ) & 0xffff;
697
698
0
  while( data_size >= 0x15b0 )
699
0
  {
700
    /* The modulo calculation is needed per 5552 (0x15b0) bytes
701
     * 5552 / 16 = 347
702
     */
703
0
    for( block_index = 0;
704
0
         block_index < 347;
705
0
         block_index++ )
706
0
    {
707
0
      lower_word += data[ data_offset++ ];
708
0
      upper_word += lower_word;
709
710
0
      lower_word += data[ data_offset++ ];
711
0
      upper_word += lower_word;
712
713
0
      lower_word += data[ data_offset++ ];
714
0
      upper_word += lower_word;
715
716
0
      lower_word += data[ data_offset++ ];
717
0
      upper_word += lower_word;
718
719
0
      lower_word += data[ data_offset++ ];
720
0
      upper_word += lower_word;
721
722
0
      lower_word += data[ data_offset++ ];
723
0
      upper_word += lower_word;
724
725
0
      lower_word += data[ data_offset++ ];
726
0
      upper_word += lower_word;
727
728
0
      lower_word += data[ data_offset++ ];
729
0
      upper_word += lower_word;
730
731
0
      lower_word += data[ data_offset++ ];
732
0
      upper_word += lower_word;
733
734
0
      lower_word += data[ data_offset++ ];
735
0
      upper_word += lower_word;
736
737
0
      lower_word += data[ data_offset++ ];
738
0
      upper_word += lower_word;
739
740
0
      lower_word += data[ data_offset++ ];
741
0
      upper_word += lower_word;
742
743
0
      lower_word += data[ data_offset++ ];
744
0
      upper_word += lower_word;
745
746
0
      lower_word += data[ data_offset++ ];
747
0
      upper_word += lower_word;
748
749
0
      lower_word += data[ data_offset++ ];
750
0
      upper_word += lower_word;
751
752
0
      lower_word += data[ data_offset++ ];
753
0
      upper_word += lower_word;
754
0
    }
755
    /* Optimized equivalent of:
756
     * lower_word %= 0xfff1
757
     */
758
0
    value_32bit = lower_word >> 16;
759
0
    lower_word &= 0x0000ffffUL;
760
0
    lower_word += ( value_32bit << 4 ) - value_32bit;
761
762
0
    if( lower_word > 65521 )
763
0
    {
764
0
      value_32bit = lower_word >> 16;
765
0
      lower_word &= 0x0000ffffUL;
766
0
      lower_word += ( value_32bit << 4 ) - value_32bit;
767
0
    }
768
0
    if( lower_word >= 65521 )
769
0
    {
770
0
      lower_word -= 65521;
771
0
    }
772
    /* Optimized equivalent of:
773
     * upper_word %= 0xfff1
774
     */
775
0
    value_32bit = upper_word >> 16;
776
0
    upper_word &= 0x0000ffffUL;
777
0
    upper_word += ( value_32bit << 4 ) - value_32bit;
778
779
0
    if( upper_word > 65521 )
780
0
    {
781
0
      value_32bit = upper_word >> 16;
782
0
      upper_word &= 0x0000ffffUL;
783
0
      upper_word += ( value_32bit << 4 ) - value_32bit;
784
0
    }
785
0
    if( upper_word >= 65521 )
786
0
    {
787
0
      upper_word -= 65521;
788
0
    }
789
0
    data_size -= 0x15b0;
790
0
  }
791
0
  if( data_size > 0 )
792
0
  {
793
0
    while( data_size > 16 )
794
0
    {
795
0
      lower_word += data[ data_offset++ ];
796
0
      upper_word += lower_word;
797
798
0
      lower_word += data[ data_offset++ ];
799
0
      upper_word += lower_word;
800
801
0
      lower_word += data[ data_offset++ ];
802
0
      upper_word += lower_word;
803
804
0
      lower_word += data[ data_offset++ ];
805
0
      upper_word += lower_word;
806
807
0
      lower_word += data[ data_offset++ ];
808
0
      upper_word += lower_word;
809
810
0
      lower_word += data[ data_offset++ ];
811
0
      upper_word += lower_word;
812
813
0
      lower_word += data[ data_offset++ ];
814
0
      upper_word += lower_word;
815
816
0
      lower_word += data[ data_offset++ ];
817
0
      upper_word += lower_word;
818
819
0
      lower_word += data[ data_offset++ ];
820
0
      upper_word += lower_word;
821
822
0
      lower_word += data[ data_offset++ ];
823
0
      upper_word += lower_word;
824
825
0
      lower_word += data[ data_offset++ ];
826
0
      upper_word += lower_word;
827
828
0
      lower_word += data[ data_offset++ ];
829
0
      upper_word += lower_word;
830
831
0
      lower_word += data[ data_offset++ ];
832
0
      upper_word += lower_word;
833
834
0
      lower_word += data[ data_offset++ ];
835
0
      upper_word += lower_word;
836
837
0
      lower_word += data[ data_offset++ ];
838
0
      upper_word += lower_word;
839
840
0
      lower_word += data[ data_offset++ ];
841
0
      upper_word += lower_word;
842
843
0
      data_size -= 16;
844
0
    }
845
0
    while( data_size > 0 )
846
0
    {
847
0
      lower_word += data[ data_offset++ ];
848
0
      upper_word += lower_word;
849
850
0
      data_size--;
851
0
    }
852
    /* Optimized equivalent of:
853
     * lower_word %= 0xfff1
854
     */
855
0
    value_32bit = lower_word >> 16;
856
0
    lower_word &= 0x0000ffffUL;
857
0
    lower_word += ( value_32bit << 4 ) - value_32bit;
858
859
0
    if( lower_word > 65521 )
860
0
    {
861
0
      value_32bit = lower_word >> 16;
862
0
      lower_word &= 0x0000ffffUL;
863
0
      lower_word += ( value_32bit << 4 ) - value_32bit;
864
0
    }
865
0
    if( lower_word >= 65521 )
866
0
    {
867
0
      lower_word -= 65521;
868
0
    }
869
    /* Optimized equivalent of:
870
     * upper_word %= 0xfff1
871
     */
872
0
    value_32bit = upper_word >> 16;
873
0
    upper_word &= 0x0000ffffUL;
874
0
    upper_word += ( value_32bit << 4 ) - value_32bit;
875
876
0
    if( upper_word > 65521 )
877
0
    {
878
0
      value_32bit = upper_word >> 16;
879
0
      upper_word &= 0x0000ffffUL;
880
0
      upper_word += ( value_32bit << 4 ) - value_32bit;
881
0
    }
882
0
    if( upper_word >= 65521 )
883
0
    {
884
0
      upper_word -= 65521;
885
0
    }
886
0
  }
887
0
  *checksum_value = ( upper_word << 16 ) | lower_word;
888
889
0
  return( 1 );
890
0
}
891
892
/* Reads the compressed data header
893
 * Returns 1 on success or -1 on error
894
 */
895
int libfvde_deflate_read_data_header(
896
     const uint8_t *compressed_data,
897
     size_t compressed_data_size,
898
     size_t *compressed_data_offset,
899
     libcerror_error_t **error )
900
0
{
901
0
  static char *function                 = "libfvde_deflate_read_data_header";
902
0
  size_t safe_offset                    = 0;
903
0
  uint32_t compression_window_size      = 0;
904
0
  uint8_t flags                         = 0;
905
0
  uint8_t compression_data              = 0;
906
0
  uint8_t compression_information       = 0;
907
0
  uint8_t compression_method            = 0;
908
0
  uint8_t compression_window_bits       = 0;
909
910
#if defined( HAVE_DEBUG_OUTPUT )
911
  uint32_t preset_dictionary_identifier = 0;
912
#endif
913
914
0
  if( compressed_data == NULL )
915
0
  {
916
0
    libcerror_error_set(
917
0
     error,
918
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
919
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
920
0
     "%s: invalid compressed data.",
921
0
     function );
922
923
0
    return( -1 );
924
0
  }
925
0
  if( compressed_data_size > (size_t) SSIZE_MAX )
926
0
  {
927
0
    libcerror_error_set(
928
0
     error,
929
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
930
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
931
0
     "%s: invalid compressed data size value exceeds maximum.",
932
0
     function );
933
934
0
    return( -1 );
935
0
  }
936
0
  if( compressed_data_offset == NULL )
937
0
  {
938
0
    libcerror_error_set(
939
0
     error,
940
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
941
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
942
0
     "%s: invalid compressed data offset.",
943
0
     function );
944
945
0
    return( -1 );
946
0
  }
947
0
  safe_offset = *compressed_data_offset;
948
949
0
  if( ( compressed_data_size < 2 )
950
0
   || ( safe_offset > ( compressed_data_size - 2 ) ) )
951
0
  {
952
0
    libcerror_error_set(
953
0
     error,
954
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
955
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
956
0
     "%s: invalid compressed data value too small.",
957
0
     function );
958
959
0
    return( -1 );
960
0
  }
961
0
  compression_data = compressed_data[ safe_offset++ ];
962
0
  flags            = compressed_data[ safe_offset++ ];
963
964
0
  compression_method      = compression_data & 0x0f;
965
0
  compression_information = compression_data >> 4;
966
967
/* TODO validate check bits */
968
0
  if( ( flags & 0x20 ) != 0 )
969
0
  {
970
0
    if( ( compressed_data_size < 6 )
971
0
     || ( safe_offset > ( compressed_data_size - 6 ) ) )
972
0
    {
973
0
      libcerror_error_set(
974
0
       error,
975
0
       LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
976
0
       LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
977
0
       "%s: invalid compressed data value too small.",
978
0
       function );
979
980
0
      return( -1 );
981
0
    }
982
#if defined( HAVE_DEBUG_OUTPUT )
983
    byte_stream_copy_to_uint32_big_endian(
984
     &( compressed_data[ 2 ] ),
985
     preset_dictionary_identifier );
986
#endif
987
0
    safe_offset += 4;
988
0
  }
989
0
  if( compression_method != 8 )
990
0
  {
991
0
    libcerror_error_set(
992
0
     error,
993
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
994
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
995
0
     "%s: unsupported compression method: %" PRIu8 ".",
996
0
     function,
997
0
     compression_method );
998
999
0
    return( -1 );
1000
0
  }
1001
0
  compression_window_bits = (uint8_t) compression_information + 8;
1002
0
  compression_window_size = (uint32_t) 1UL << compression_window_bits;
1003
1004
0
  if( compression_window_size > 32768 )
1005
0
  {
1006
0
    libcerror_error_set(
1007
0
     error,
1008
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1009
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
1010
0
     "%s: unsupported compression window size: %" PRIu32 ".",
1011
0
     function,
1012
0
     compression_window_size );
1013
1014
0
    return( -1 );
1015
0
  }
1016
0
  *compressed_data_offset += safe_offset;
1017
1018
0
  return( 1 );
1019
0
}
1020
1021
/* Reads the header of a block of compressed data
1022
 * Returns 1 on success or -1 on error
1023
 */
1024
int libfvde_deflate_read_block_header(
1025
     libfvde_bit_stream_t *bit_stream,
1026
     uint8_t *block_type,
1027
     uint8_t *last_block_flag,
1028
     libcerror_error_t **error )
1029
0
{
1030
0
  static char *function = "libfvde_deflate_read_block_header";
1031
0
  uint32_t value_32bit  = 0;
1032
1033
0
  if( block_type == NULL )
1034
0
  {
1035
0
    libcerror_error_set(
1036
0
     error,
1037
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1038
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1039
0
     "%s: invalid block type.",
1040
0
     function );
1041
1042
0
    return( -1 );
1043
0
  }
1044
0
  if( last_block_flag == NULL )
1045
0
  {
1046
0
    libcerror_error_set(
1047
0
     error,
1048
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1049
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1050
0
     "%s: invalid last block flag.",
1051
0
     function );
1052
1053
0
    return( -1 );
1054
0
  }
1055
0
  if( libfvde_bit_stream_get_value(
1056
0
       bit_stream,
1057
0
       3,
1058
0
       &value_32bit,
1059
0
       error ) != 1 )
1060
0
  {
1061
0
    libcerror_error_set(
1062
0
     error,
1063
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1064
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1065
0
     "%s: unable to retrieve value from bit stream.",
1066
0
     function );
1067
1068
0
    return( -1 );
1069
0
  }
1070
0
  *last_block_flag = (uint8_t) ( value_32bit & 0x00000001UL );
1071
0
  value_32bit    >>= 1;
1072
0
  *block_type      = (uint8_t) value_32bit;
1073
1074
#if defined( HAVE_DEBUG_OUTPUT )
1075
  if( libcnotify_verbose != 0 )
1076
  {
1077
    libcnotify_printf(
1078
     "%s: block header last block flag\t\t\t: %" PRIu8 "\n",
1079
     function,
1080
     *last_block_flag );
1081
1082
    libcnotify_printf(
1083
     "%s: block header block type\t\t\t: %" PRIu8 " (",
1084
     function,
1085
     *block_type );
1086
1087
    switch( *block_type )
1088
    {
1089
      case LIBFVDE_DEFLATE_BLOCK_TYPE_UNCOMPRESSED:
1090
        libcnotify_printf(
1091
         "Uncompressed" );
1092
        break;
1093
1094
      case LIBFVDE_DEFLATE_BLOCK_TYPE_HUFFMAN_FIXED:
1095
        libcnotify_printf(
1096
         "Fixed Huffman" );
1097
        break;
1098
1099
      case LIBFVDE_DEFLATE_BLOCK_TYPE_HUFFMAN_DYNAMIC:
1100
        libcnotify_printf(
1101
         "Dynamic Huffman" );
1102
        break;
1103
1104
      case LIBFVDE_DEFLATE_BLOCK_TYPE_RESERVED:
1105
      default:
1106
        libcnotify_printf(
1107
         "Reserved" );
1108
        break;
1109
    }
1110
    libcnotify_printf(
1111
     ")\n" );
1112
1113
    libcnotify_printf(
1114
     "\n" );
1115
  }
1116
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
1117
1118
0
  return( 1 );
1119
0
}
1120
1121
/* Reads a block of compressed data
1122
 * Returns 1 on success or -1 on error
1123
 */
1124
int libfvde_deflate_read_block(
1125
     libfvde_bit_stream_t *bit_stream,
1126
     uint8_t block_type,
1127
     libfvde_huffman_tree_t *fixed_huffman_literals_tree,
1128
     libfvde_huffman_tree_t *fixed_huffman_distances_tree,
1129
     uint8_t *uncompressed_data,
1130
     size_t uncompressed_data_size,
1131
     size_t *uncompressed_data_offset,
1132
     libcerror_error_t **error )
1133
0
{
1134
0
  libfvde_huffman_tree_t *dynamic_huffman_distances_tree = NULL;
1135
0
  libfvde_huffman_tree_t *dynamic_huffman_literals_tree  = NULL;
1136
0
  static char *function                                  = "libfvde_deflate_read_block";
1137
0
  size_t safe_uncompressed_data_offset                   = 0;
1138
0
  uint32_t block_size                                    = 0;
1139
0
  uint32_t block_size_copy                               = 0;
1140
0
  uint32_t value_32bit                                   = 0;
1141
0
  uint8_t skip_bits                                      = 0;
1142
1143
0
  if( bit_stream == NULL )
1144
0
  {
1145
0
    libcerror_error_set(
1146
0
     error,
1147
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1148
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1149
0
     "%s: invalid bit stream.",
1150
0
     function );
1151
1152
0
    return( -1 );
1153
0
  }
1154
0
  if( uncompressed_data == NULL )
1155
0
  {
1156
0
    libcerror_error_set(
1157
0
     error,
1158
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1159
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1160
0
     "%s: invalid uncompressed data.",
1161
0
     function );
1162
1163
0
    return( -1 );
1164
0
  }
1165
0
  if( uncompressed_data_size > (size_t) SSIZE_MAX )
1166
0
  {
1167
0
    libcerror_error_set(
1168
0
     error,
1169
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1170
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
1171
0
     "%s: invalid uncompressed data size value exceeds maximum.",
1172
0
     function );
1173
1174
0
    return( -1 );
1175
0
  }
1176
0
  if( uncompressed_data_offset == NULL )
1177
0
  {
1178
0
    libcerror_error_set(
1179
0
     error,
1180
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1181
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1182
0
     "%s: invalid uncompressed data.",
1183
0
     function );
1184
1185
0
    return( -1 );
1186
0
  }
1187
0
  safe_uncompressed_data_offset = *uncompressed_data_offset;
1188
1189
0
  switch( block_type )
1190
0
  {
1191
0
    case LIBFVDE_DEFLATE_BLOCK_TYPE_UNCOMPRESSED:
1192
      /* Ignore the bits in the buffer upto the next byte
1193
       */
1194
0
      skip_bits = bit_stream->bit_buffer_size & 0x07;
1195
1196
0
      if( skip_bits > 0 )
1197
0
      {
1198
0
        if( libfvde_bit_stream_get_value(
1199
0
             bit_stream,
1200
0
             skip_bits,
1201
0
             &value_32bit,
1202
0
             error ) != 1 )
1203
0
        {
1204
0
          libcerror_error_set(
1205
0
           error,
1206
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
1207
0
           LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1208
0
           "%s: unable to retrieve value from bit stream.",
1209
0
           function );
1210
1211
0
          goto on_error;
1212
0
        }
1213
0
      }
1214
0
      if( libfvde_bit_stream_get_value(
1215
0
           bit_stream,
1216
0
           32,
1217
0
           &block_size,
1218
0
           error ) != 1 )
1219
0
      {
1220
0
        libcerror_error_set(
1221
0
         error,
1222
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1223
0
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1224
0
         "%s: unable to retrieve value from bit stream.",
1225
0
         function );
1226
1227
0
        goto on_error;
1228
0
      }
1229
0
      block_size_copy = ( block_size >> 16 ) ^ 0x0000ffffUL;
1230
0
      block_size     &= 0x0000ffffUL;
1231
1232
0
      if( block_size != block_size_copy )
1233
0
      {
1234
0
        libcerror_error_set(
1235
0
         error,
1236
0
         LIBCERROR_ERROR_DOMAIN_INPUT,
1237
0
         LIBCERROR_INPUT_ERROR_VALUE_MISMATCH,
1238
0
         "%s: mismatch in block size ( %" PRIu32 " != %" PRIu32 " ).",
1239
0
         function,
1240
0
         block_size,
1241
0
         block_size_copy );
1242
1243
0
        goto on_error;
1244
0
      }
1245
0
      if( block_size == 0 )
1246
0
      {
1247
0
        break;
1248
0
      }
1249
0
      if( (size_t) block_size > ( bit_stream->byte_stream_size - bit_stream->byte_stream_offset ) )
1250
0
      {
1251
0
        libcerror_error_set(
1252
0
         error,
1253
0
         LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1254
0
         LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
1255
0
         "%s: invalid compressed data value too small.",
1256
0
         function );
1257
1258
0
        goto on_error;
1259
0
      }
1260
0
      if( (size_t) block_size > ( uncompressed_data_size - safe_uncompressed_data_offset ) )
1261
0
      {
1262
0
        libcerror_error_set(
1263
0
         error,
1264
0
         LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1265
0
         LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
1266
0
         "%s: invalid uncompressed data value too small.",
1267
0
         function );
1268
1269
0
        goto on_error;
1270
0
      }
1271
0
      if( memory_copy(
1272
0
           &( uncompressed_data[ safe_uncompressed_data_offset ] ),
1273
0
           &( bit_stream->byte_stream[ bit_stream->byte_stream_offset ] ),
1274
0
           (size_t) block_size ) == NULL )
1275
0
      {
1276
0
        libcerror_error_set(
1277
0
         error,
1278
0
         LIBCERROR_ERROR_DOMAIN_MEMORY,
1279
0
         LIBCERROR_MEMORY_ERROR_COPY_FAILED,
1280
0
         "%s: unable to initialize lz buffer.",
1281
0
         function );
1282
1283
0
        goto on_error;
1284
0
      }
1285
0
      bit_stream->byte_stream_offset += block_size;
1286
0
      safe_uncompressed_data_offset  += block_size;
1287
1288
      /* Flush the bit stream buffer
1289
       */
1290
0
      bit_stream->bit_buffer      = 0;
1291
0
      bit_stream->bit_buffer_size = 0;
1292
1293
0
      break;
1294
1295
0
    case LIBFVDE_DEFLATE_BLOCK_TYPE_HUFFMAN_FIXED:
1296
0
      if( libfvde_deflate_decode_huffman(
1297
0
           bit_stream,
1298
0
           fixed_huffman_literals_tree,
1299
0
           fixed_huffman_distances_tree,
1300
0
           uncompressed_data,
1301
0
           uncompressed_data_size,
1302
0
           &safe_uncompressed_data_offset,
1303
0
           error ) != 1 )
1304
0
      {
1305
0
        libcerror_error_set(
1306
0
         error,
1307
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1308
0
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1309
0
         "%s: unable to decode fixed Huffman encoded bit stream.",
1310
0
         function );
1311
1312
0
        goto on_error;
1313
0
      }
1314
0
      break;
1315
1316
0
    case LIBFVDE_DEFLATE_BLOCK_TYPE_HUFFMAN_DYNAMIC:
1317
0
      if( libfvde_huffman_tree_initialize(
1318
0
           &dynamic_huffman_literals_tree,
1319
0
           288,
1320
0
           15,
1321
0
           error ) != 1 )
1322
0
      {
1323
0
        libcerror_error_set(
1324
0
         error,
1325
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1326
0
         LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1327
0
         "%s: unable to build dynamic literals Huffman tree.",
1328
0
         function );
1329
1330
0
        goto on_error;
1331
0
      }
1332
0
      if( libfvde_huffman_tree_initialize(
1333
0
           &dynamic_huffman_distances_tree,
1334
0
           30,
1335
0
           15,
1336
0
           error ) != 1 )
1337
0
      {
1338
0
        libcerror_error_set(
1339
0
         error,
1340
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1341
0
         LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1342
0
         "%s: unable to build dynamic distances Huffman tree.",
1343
0
         function );
1344
1345
0
        goto on_error;
1346
0
      }
1347
0
      if( libfvde_deflate_build_dynamic_huffman_trees(
1348
0
           bit_stream,
1349
0
           dynamic_huffman_literals_tree,
1350
0
           dynamic_huffman_distances_tree,
1351
0
           error ) != 1 )
1352
0
      {
1353
0
        libcerror_error_set(
1354
0
         error,
1355
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1356
0
         LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1357
0
         "%s: unable to build dynamic Huffman trees.",
1358
0
         function );
1359
1360
0
        goto on_error;
1361
0
      }
1362
0
      if( libfvde_deflate_decode_huffman(
1363
0
           bit_stream,
1364
0
           dynamic_huffman_literals_tree,
1365
0
           dynamic_huffman_distances_tree,
1366
0
           uncompressed_data,
1367
0
           uncompressed_data_size,
1368
0
           &safe_uncompressed_data_offset,
1369
0
           error ) != 1 )
1370
0
      {
1371
0
        libcerror_error_set(
1372
0
         error,
1373
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1374
0
         LIBCERROR_RUNTIME_ERROR_GET_FAILED,
1375
0
         "%s: unable to decode dynamic Huffman encoded bit stream.",
1376
0
         function );
1377
1378
0
        goto on_error;
1379
0
      }
1380
0
      if( libfvde_huffman_tree_free(
1381
0
           &dynamic_huffman_distances_tree,
1382
0
           error ) != 1 )
1383
0
      {
1384
0
        libcerror_error_set(
1385
0
         error,
1386
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1387
0
         LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1388
0
         "%s: unable to free dynamic distances Huffman tree.",
1389
0
         function );
1390
1391
0
        goto on_error;
1392
0
      }
1393
0
      if( libfvde_huffman_tree_free(
1394
0
           &dynamic_huffman_literals_tree,
1395
0
           error ) != 1 )
1396
0
      {
1397
0
        libcerror_error_set(
1398
0
         error,
1399
0
         LIBCERROR_ERROR_DOMAIN_RUNTIME,
1400
0
         LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1401
0
         "%s: unable to free dynamic literals Huffman tree.",
1402
0
         function );
1403
1404
0
        goto on_error;
1405
0
      }
1406
0
      break;
1407
1408
0
    case LIBFVDE_DEFLATE_BLOCK_TYPE_RESERVED:
1409
0
    default:
1410
0
      libcerror_error_set(
1411
0
       error,
1412
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1413
0
       LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
1414
0
       "%s: unsupported block type.",
1415
0
       function );
1416
1417
0
      goto on_error;
1418
0
  }
1419
0
  *uncompressed_data_offset = safe_uncompressed_data_offset;
1420
1421
0
  return( 1 );
1422
1423
0
on_error:
1424
0
  if( dynamic_huffman_distances_tree != NULL )
1425
0
  {
1426
0
    libfvde_huffman_tree_free(
1427
0
     &dynamic_huffman_distances_tree,
1428
0
     NULL );
1429
0
  }
1430
0
  if( dynamic_huffman_literals_tree != NULL )
1431
0
  {
1432
0
    libfvde_huffman_tree_free(
1433
0
     &dynamic_huffman_literals_tree,
1434
0
     NULL );
1435
0
  }
1436
0
  return( -1 );
1437
0
}
1438
1439
/* Decompresses data using deflate compression
1440
 * Returns 1 on success or -1 on error
1441
 */
1442
int libfvde_deflate_decompress(
1443
     const uint8_t *compressed_data,
1444
     size_t compressed_data_size,
1445
     uint8_t *uncompressed_data,
1446
     size_t *uncompressed_data_size,
1447
     libcerror_error_t **error )
1448
0
{
1449
0
  libfvde_bit_stream_t *bit_stream                     = NULL;
1450
0
  libfvde_huffman_tree_t *fixed_huffman_distances_tree = NULL;
1451
0
  libfvde_huffman_tree_t *fixed_huffman_literals_tree  = NULL;
1452
0
  static char *function                                = "libfvde_deflate_decompress";
1453
0
  size_t compressed_data_offset                        = 0;
1454
0
  size_t safe_uncompressed_data_size                   = 0;
1455
0
  size_t uncompressed_data_offset                      = 0;
1456
0
  uint8_t block_type                                   = 0;
1457
0
  uint8_t last_block_flag                              = 0;
1458
1459
0
  if( compressed_data == NULL )
1460
0
  {
1461
0
    libcerror_error_set(
1462
0
     error,
1463
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1464
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1465
0
     "%s: invalid compressed data.",
1466
0
     function );
1467
1468
0
    return( -1 );
1469
0
  }
1470
0
  if( compressed_data_size > (size_t) SSIZE_MAX )
1471
0
  {
1472
0
    libcerror_error_set(
1473
0
     error,
1474
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1475
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
1476
0
     "%s: invalid compressed data size value exceeds maximum.",
1477
0
     function );
1478
1479
0
    return( -1 );
1480
0
  }
1481
0
  if( uncompressed_data == NULL )
1482
0
  {
1483
0
    libcerror_error_set(
1484
0
     error,
1485
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1486
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1487
0
     "%s: invalid uncompressed data.",
1488
0
     function );
1489
1490
0
    return( -1 );
1491
0
  }
1492
0
  if( uncompressed_data_size == NULL )
1493
0
  {
1494
0
    libcerror_error_set(
1495
0
     error,
1496
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1497
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1498
0
     "%s: invalid uncompressed data size.",
1499
0
     function );
1500
1501
0
    return( -1 );
1502
0
  }
1503
0
  safe_uncompressed_data_size = *uncompressed_data_size;
1504
1505
0
  if( safe_uncompressed_data_size > (size_t) SSIZE_MAX )
1506
0
  {
1507
0
    libcerror_error_set(
1508
0
     error,
1509
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1510
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
1511
0
     "%s: invalid uncompressed data size value exceeds maximum.",
1512
0
     function );
1513
1514
0
    return( -1 );
1515
0
  }
1516
0
  if( compressed_data_offset >= compressed_data_size )
1517
0
  {
1518
0
    libcerror_error_set(
1519
0
     error,
1520
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1521
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
1522
0
     "%s: invalid compressed data value too small.",
1523
0
     function );
1524
1525
0
    return( -1 );
1526
0
  }
1527
0
  if( libfvde_bit_stream_initialize(
1528
0
       &bit_stream,
1529
0
       compressed_data,
1530
0
       compressed_data_size,
1531
0
       compressed_data_offset,
1532
0
       LIBFVDE_BIT_STREAM_STORAGE_TYPE_BYTE_BACK_TO_FRONT,
1533
0
       error ) != 1 )
1534
0
  {
1535
0
    libcerror_error_set(
1536
0
     error,
1537
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1538
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1539
0
     "%s: unable to create bit stream.",
1540
0
     function );
1541
1542
0
    goto on_error;
1543
0
  }
1544
0
  while( bit_stream->byte_stream_offset < bit_stream->byte_stream_size )
1545
0
  {
1546
0
    if( libfvde_deflate_read_block_header(
1547
0
         bit_stream,
1548
0
         &block_type,
1549
0
         &last_block_flag,
1550
0
         error ) != 1 )
1551
0
    {
1552
0
      libcerror_error_set(
1553
0
       error,
1554
0
       LIBCERROR_ERROR_DOMAIN_IO,
1555
0
       LIBCERROR_IO_ERROR_READ_FAILED,
1556
0
       "%s: unable to read compressed data block header.",
1557
0
       function );
1558
1559
0
      goto on_error;
1560
0
    }
1561
0
    if( block_type == LIBFVDE_DEFLATE_BLOCK_TYPE_HUFFMAN_FIXED )
1562
0
    {
1563
0
      if( ( fixed_huffman_literals_tree == NULL )
1564
0
       && ( fixed_huffman_distances_tree == NULL ) )
1565
0
      {
1566
0
        if( libfvde_huffman_tree_initialize(
1567
0
             &fixed_huffman_literals_tree,
1568
0
             288,
1569
0
             15,
1570
0
             error ) != 1 )
1571
0
        {
1572
0
          libcerror_error_set(
1573
0
           error,
1574
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
1575
0
           LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1576
0
           "%s: unable to build fixed literals Huffman tree.",
1577
0
           function );
1578
1579
0
          goto on_error;
1580
0
        }
1581
0
        if( libfvde_huffman_tree_initialize(
1582
0
             &fixed_huffman_distances_tree,
1583
0
             30,
1584
0
             15,
1585
0
             error ) != 1 )
1586
0
        {
1587
0
          libcerror_error_set(
1588
0
           error,
1589
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
1590
0
           LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1591
0
           "%s: unable to build fixed distances Huffman tree.",
1592
0
           function );
1593
1594
0
          goto on_error;
1595
0
        }
1596
0
        if( libfvde_deflate_build_fixed_huffman_trees(
1597
0
             fixed_huffman_literals_tree,
1598
0
             fixed_huffman_distances_tree,
1599
0
             error ) != 1 )
1600
0
        {
1601
0
          libcerror_error_set(
1602
0
           error,
1603
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
1604
0
           LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1605
0
           "%s: unable to build fixed Huffman trees.",
1606
0
           function );
1607
1608
0
          goto on_error;
1609
0
        }
1610
0
      }
1611
0
    }
1612
0
    if( libfvde_deflate_read_block(
1613
0
         bit_stream,
1614
0
         block_type,
1615
0
         fixed_huffman_literals_tree,
1616
0
         fixed_huffman_distances_tree,
1617
0
         uncompressed_data,
1618
0
         safe_uncompressed_data_size,
1619
0
         &uncompressed_data_offset,
1620
0
         error ) != 1 )
1621
0
    {
1622
0
      libcerror_error_set(
1623
0
       error,
1624
0
       LIBCERROR_ERROR_DOMAIN_IO,
1625
0
       LIBCERROR_IO_ERROR_READ_FAILED,
1626
0
       "%s: unable to read block of compressed data.",
1627
0
       function );
1628
1629
0
      goto on_error;
1630
0
    }
1631
0
    if( last_block_flag != 0 )
1632
0
    {
1633
0
      break;
1634
0
    }
1635
0
  }
1636
0
  if( fixed_huffman_distances_tree != NULL )
1637
0
  {
1638
0
    if( libfvde_huffman_tree_free(
1639
0
         &fixed_huffman_distances_tree,
1640
0
         error ) != 1 )
1641
0
    {
1642
0
      libcerror_error_set(
1643
0
       error,
1644
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1645
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1646
0
       "%s: unable to free fixed distances Huffman tree.",
1647
0
       function );
1648
1649
0
      goto on_error;
1650
0
    }
1651
0
  }
1652
0
  if( fixed_huffman_literals_tree != NULL )
1653
0
  {
1654
0
    if( libfvde_huffman_tree_free(
1655
0
         &fixed_huffman_literals_tree,
1656
0
         error ) != 1 )
1657
0
    {
1658
0
      libcerror_error_set(
1659
0
       error,
1660
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1661
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1662
0
       "%s: unable to free fixed literals Huffman tree.",
1663
0
       function );
1664
1665
0
      goto on_error;
1666
0
    }
1667
0
  }
1668
0
  if( libfvde_bit_stream_free(
1669
0
       &bit_stream,
1670
0
       error ) != 1 )
1671
0
  {
1672
0
    libcerror_error_set(
1673
0
     error,
1674
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1675
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1676
0
     "%s: unable to free bit stream.",
1677
0
     function );
1678
1679
0
    goto on_error;
1680
0
  }
1681
0
  *uncompressed_data_size = uncompressed_data_offset;
1682
1683
0
  return( 1 );
1684
1685
0
on_error:
1686
0
  if( fixed_huffman_distances_tree != NULL )
1687
0
  {
1688
0
    libfvde_huffman_tree_free(
1689
0
     &fixed_huffman_distances_tree,
1690
0
     NULL );
1691
0
  }
1692
0
  if( fixed_huffman_literals_tree != NULL )
1693
0
  {
1694
0
    libfvde_huffman_tree_free(
1695
0
     &fixed_huffman_literals_tree,
1696
0
     NULL );
1697
0
  }
1698
0
  if( bit_stream != NULL )
1699
0
  {
1700
0
    libfvde_bit_stream_free(
1701
0
     &bit_stream,
1702
0
     NULL );
1703
0
  }
1704
0
  return( -1 );
1705
0
}
1706
1707
/* Decompresses data using zlib compression
1708
 * Returns 1 on success or -1 on error
1709
 */
1710
int libfvde_deflate_decompress_zlib(
1711
     const uint8_t *compressed_data,
1712
     size_t compressed_data_size,
1713
     uint8_t *uncompressed_data,
1714
     size_t *uncompressed_data_size,
1715
     libcerror_error_t **error )
1716
0
{
1717
0
  libfvde_bit_stream_t *bit_stream                     = NULL;
1718
0
  libfvde_huffman_tree_t *fixed_huffman_distances_tree = NULL;
1719
0
  libfvde_huffman_tree_t *fixed_huffman_literals_tree  = NULL;
1720
0
  static char *function                                = "libfvde_deflate_decompress_zlib";
1721
0
  size_t compressed_data_offset                        = 0;
1722
0
  size_t safe_uncompressed_data_size                   = 0;
1723
0
  size_t uncompressed_data_offset                      = 0;
1724
0
  uint32_t calculated_checksum                         = 0;
1725
0
  uint32_t stored_checksum                             = 0;
1726
0
  uint8_t block_type                                   = 0;
1727
0
  uint8_t last_block_flag                              = 0;
1728
1729
0
  if( compressed_data == NULL )
1730
0
  {
1731
0
    libcerror_error_set(
1732
0
     error,
1733
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1734
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1735
0
     "%s: invalid compressed data.",
1736
0
     function );
1737
1738
0
    return( -1 );
1739
0
  }
1740
0
  if( compressed_data_size > (size_t) SSIZE_MAX )
1741
0
  {
1742
0
    libcerror_error_set(
1743
0
     error,
1744
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1745
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
1746
0
     "%s: invalid compressed data size value exceeds maximum.",
1747
0
     function );
1748
1749
0
    return( -1 );
1750
0
  }
1751
0
  if( uncompressed_data == NULL )
1752
0
  {
1753
0
    libcerror_error_set(
1754
0
     error,
1755
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1756
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1757
0
     "%s: invalid uncompressed data.",
1758
0
     function );
1759
1760
0
    return( -1 );
1761
0
  }
1762
0
  if( uncompressed_data_size == NULL )
1763
0
  {
1764
0
    libcerror_error_set(
1765
0
     error,
1766
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1767
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
1768
0
     "%s: invalid uncompressed data size.",
1769
0
     function );
1770
1771
0
    return( -1 );
1772
0
  }
1773
0
  safe_uncompressed_data_size = *uncompressed_data_size;
1774
1775
0
  if( safe_uncompressed_data_size > (size_t) SSIZE_MAX )
1776
0
  {
1777
0
    libcerror_error_set(
1778
0
     error,
1779
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1780
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
1781
0
     "%s: invalid uncompressed data size value exceeds maximum.",
1782
0
     function );
1783
1784
0
    return( -1 );
1785
0
  }
1786
0
  if( libfvde_deflate_read_data_header(
1787
0
       compressed_data,
1788
0
       compressed_data_size,
1789
0
       &compressed_data_offset,
1790
0
       error ) != 1 )
1791
0
  {
1792
0
    libcerror_error_set(
1793
0
     error,
1794
0
     LIBCERROR_ERROR_DOMAIN_IO,
1795
0
     LIBCERROR_IO_ERROR_READ_FAILED,
1796
0
     "%s: unable to read data header.",
1797
0
     function );
1798
1799
0
    goto on_error;
1800
0
  }
1801
0
  if( compressed_data_offset >= compressed_data_size )
1802
0
  {
1803
0
    libcerror_error_set(
1804
0
     error,
1805
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
1806
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
1807
0
     "%s: invalid compressed data value too small.",
1808
0
     function );
1809
1810
0
    goto on_error;
1811
0
  }
1812
0
  if( libfvde_bit_stream_initialize(
1813
0
       &bit_stream,
1814
0
       compressed_data,
1815
0
       compressed_data_size,
1816
0
       compressed_data_offset,
1817
0
       LIBFVDE_BIT_STREAM_STORAGE_TYPE_BYTE_BACK_TO_FRONT,
1818
0
       error ) != 1 )
1819
0
  {
1820
0
    libcerror_error_set(
1821
0
     error,
1822
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
1823
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1824
0
     "%s: unable to create bit stream.",
1825
0
     function );
1826
1827
0
    goto on_error;
1828
0
  }
1829
0
  while( bit_stream->byte_stream_offset < bit_stream->byte_stream_size )
1830
0
  {
1831
0
    if( libfvde_deflate_read_block_header(
1832
0
         bit_stream,
1833
0
         &block_type,
1834
0
         &last_block_flag,
1835
0
         error ) != 1 )
1836
0
    {
1837
0
      libcerror_error_set(
1838
0
       error,
1839
0
       LIBCERROR_ERROR_DOMAIN_IO,
1840
0
       LIBCERROR_IO_ERROR_READ_FAILED,
1841
0
       "%s: unable to read compressed data block header.",
1842
0
       function );
1843
1844
0
      goto on_error;
1845
0
    }
1846
0
    if( block_type == LIBFVDE_DEFLATE_BLOCK_TYPE_HUFFMAN_FIXED )
1847
0
    {
1848
0
      if( ( fixed_huffman_literals_tree == NULL )
1849
0
       && ( fixed_huffman_distances_tree == NULL ) )
1850
0
      {
1851
0
        if( libfvde_huffman_tree_initialize(
1852
0
             &fixed_huffman_literals_tree,
1853
0
             288,
1854
0
             15,
1855
0
             error ) != 1 )
1856
0
        {
1857
0
          libcerror_error_set(
1858
0
           error,
1859
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
1860
0
           LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1861
0
           "%s: unable to build fixed literals Huffman tree.",
1862
0
           function );
1863
1864
0
          goto on_error;
1865
0
        }
1866
0
        if( libfvde_huffman_tree_initialize(
1867
0
             &fixed_huffman_distances_tree,
1868
0
             30,
1869
0
             15,
1870
0
             error ) != 1 )
1871
0
        {
1872
0
          libcerror_error_set(
1873
0
           error,
1874
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
1875
0
           LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1876
0
           "%s: unable to build fixed distances Huffman tree.",
1877
0
           function );
1878
1879
0
          goto on_error;
1880
0
        }
1881
0
        if( libfvde_deflate_build_fixed_huffman_trees(
1882
0
             fixed_huffman_literals_tree,
1883
0
             fixed_huffman_distances_tree,
1884
0
             error ) != 1 )
1885
0
        {
1886
0
          libcerror_error_set(
1887
0
           error,
1888
0
           LIBCERROR_ERROR_DOMAIN_RUNTIME,
1889
0
           LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
1890
0
           "%s: unable to build fixed Huffman trees.",
1891
0
           function );
1892
1893
0
          goto on_error;
1894
0
        }
1895
0
      }
1896
0
    }
1897
0
    if( libfvde_deflate_read_block(
1898
0
         bit_stream,
1899
0
         block_type,
1900
0
         fixed_huffman_literals_tree,
1901
0
         fixed_huffman_distances_tree,
1902
0
         uncompressed_data,
1903
0
         safe_uncompressed_data_size,
1904
0
         &uncompressed_data_offset,
1905
0
         error ) != 1 )
1906
0
    {
1907
0
      libcerror_error_set(
1908
0
       error,
1909
0
       LIBCERROR_ERROR_DOMAIN_IO,
1910
0
       LIBCERROR_IO_ERROR_READ_FAILED,
1911
0
       "%s: unable to read block of compressed data.",
1912
0
       function );
1913
1914
0
      goto on_error;
1915
0
    }
1916
0
    if( last_block_flag != 0 )
1917
0
    {
1918
0
      break;
1919
0
    }
1920
0
  }
1921
0
  if( ( bit_stream->byte_stream_size - bit_stream->byte_stream_offset ) >= 4 )
1922
0
  {
1923
0
    while( bit_stream->bit_buffer_size >= 8 )
1924
0
    {
1925
0
      bit_stream->byte_stream_offset -= 1;
1926
0
      bit_stream->bit_buffer_size    -= 8;
1927
0
    }
1928
0
    byte_stream_copy_to_uint32_big_endian(
1929
0
     &( bit_stream->byte_stream[ bit_stream->byte_stream_offset ] ),
1930
0
     stored_checksum );
1931
1932
0
    if( libfvde_deflate_calculate_adler32(
1933
0
         &calculated_checksum,
1934
0
         uncompressed_data,
1935
0
         uncompressed_data_offset,
1936
0
         1,
1937
0
         error ) != 1 )
1938
0
    {
1939
0
      libcerror_error_set(
1940
0
       error,
1941
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1942
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
1943
0
       "%s: unable to calculate checksum.",
1944
0
       function );
1945
1946
0
      goto on_error;
1947
0
    }
1948
0
    if( stored_checksum != calculated_checksum )
1949
0
    {
1950
0
      libcerror_error_set(
1951
0
       error,
1952
0
       LIBCERROR_ERROR_DOMAIN_INPUT,
1953
0
       LIBCERROR_INPUT_ERROR_CHECKSUM_MISMATCH,
1954
0
       "%s: checksum does not match (stored: 0x%08" PRIx32 ", calculated: 0x%08" PRIx32 ").",
1955
0
       function,
1956
0
       stored_checksum,
1957
0
       calculated_checksum );
1958
1959
0
      goto on_error;
1960
0
    }
1961
0
  }
1962
0
  if( fixed_huffman_distances_tree != NULL )
1963
0
  {
1964
0
    if( libfvde_huffman_tree_free(
1965
0
         &fixed_huffman_distances_tree,
1966
0
         error ) != 1 )
1967
0
    {
1968
0
      libcerror_error_set(
1969
0
       error,
1970
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1971
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1972
0
       "%s: unable to free fixed distances Huffman tree.",
1973
0
       function );
1974
1975
0
      goto on_error;
1976
0
    }
1977
0
  }
1978
0
  if( fixed_huffman_literals_tree != NULL )
1979
0
  {
1980
0
    if( libfvde_huffman_tree_free(
1981
0
         &fixed_huffman_literals_tree,
1982
0
         error ) != 1 )
1983
0
    {
1984
0
      libcerror_error_set(
1985
0
       error,
1986
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
1987
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
1988
0
       "%s: unable to free fixed literals Huffman tree.",
1989
0
       function );
1990
1991
0
      goto on_error;
1992
0
    }
1993
0
  }
1994
0
  if( libfvde_bit_stream_free(
1995
0
       &bit_stream,
1996
0
       error ) != 1 )
1997
0
  {
1998
0
    libcerror_error_set(
1999
0
     error,
2000
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
2001
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
2002
0
     "%s: unable to free bit stream.",
2003
0
     function );
2004
2005
0
    goto on_error;
2006
0
  }
2007
0
  *uncompressed_data_size = uncompressed_data_offset;
2008
2009
0
  return( 1 );
2010
2011
0
on_error:
2012
0
  if( fixed_huffman_distances_tree != NULL )
2013
0
  {
2014
0
    libfvde_huffman_tree_free(
2015
0
     &fixed_huffman_distances_tree,
2016
0
     NULL );
2017
0
  }
2018
0
  if( fixed_huffman_literals_tree != NULL )
2019
0
  {
2020
0
    libfvde_huffman_tree_free(
2021
0
     &fixed_huffman_literals_tree,
2022
0
     NULL );
2023
0
  }
2024
0
  if( bit_stream != NULL )
2025
0
  {
2026
0
    libfvde_bit_stream_free(
2027
0
     &bit_stream,
2028
     NULL );
2029
0
  }
2030
0
  return( -1 );
2031
0
}
2032