Coverage Report

Created: 2024-10-02 06:58

/src/libewf/libewf/libewf_sha1_hash_section.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * SHA1 hash section functions
3
 *
4
 * Copyright (C) 2006-2024, 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 <narrow_string.h>
26
#include <types.h>
27
28
#include "libewf_checksum.h"
29
#include "libewf_definitions.h"
30
#include "libewf_hash_sections.h"
31
#include "libewf_io_handle.h"
32
#include "libewf_libbfio.h"
33
#include "libewf_libcerror.h"
34
#include "libewf_libcnotify.h"
35
#include "libewf_section.h"
36
#include "libewf_section_descriptor.h"
37
#include "libewf_sha1_hash_section.h"
38
39
#include "ewf_hash.h"
40
41
/* Reads a version 2 SHA1 hash section
42
 * Returns 1 if successful or -1 on error
43
 */
44
int libewf_sha1_hash_section_read_data(
45
     const uint8_t *data,
46
     size_t data_size,
47
     libewf_hash_sections_t *hash_sections,
48
     libcerror_error_t **error )
49
0
{
50
0
  static char *function        = "libewf_sha1_hash_section_read_data";
51
0
  uint32_t calculated_checksum = 0;
52
0
  uint32_t stored_checksum     = 0;
53
0
  int result                   = 0;
54
55
0
  if( data == NULL )
56
0
  {
57
0
    libcerror_error_set(
58
0
     error,
59
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
60
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
61
0
     "%s: missing data.",
62
0
     function );
63
64
0
    return( -1 );
65
0
  }
66
0
  if( data_size != (size_t) sizeof( ewf_sha1_hash_t ) )
67
0
  {
68
0
    libcerror_error_set(
69
0
     error,
70
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
71
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
72
0
     "%s: invalid data size value out of bounds.",
73
0
     function );
74
75
0
    return( -1 );
76
0
  }
77
0
  if( hash_sections == NULL )
78
0
  {
79
0
    libcerror_error_set(
80
0
     error,
81
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
82
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
83
0
     "%s: invalid hash sections.",
84
0
     function );
85
86
0
    return( -1 );
87
0
  }
88
#if defined( HAVE_DEBUG_OUTPUT )
89
  if( libcnotify_verbose != 0 )
90
  {
91
    libcnotify_printf(
92
     "%s: SHA1 hash data:\n",
93
     function );
94
    libcnotify_print_data(
95
     data,
96
     data_size,
97
     0 );
98
  }
99
#endif
100
0
  byte_stream_copy_to_uint32_little_endian(
101
0
   ( (ewf_sha1_hash_t *) data )->checksum,
102
0
   stored_checksum );
103
104
#if defined( HAVE_DEBUG_OUTPUT )
105
  if( libcnotify_verbose != 0 )
106
  {
107
    libcnotify_printf(
108
     "%s: SHA1 hash:\n",
109
     function );
110
    libcnotify_print_data(
111
     data,
112
     20,
113
     0 );
114
115
    libcnotify_printf(
116
     "%s: checksum\t\t\t\t\t: 0x%08" PRIx32 "\n",
117
     function,
118
     stored_checksum );
119
120
    libcnotify_printf(
121
     "%s: padding:\n",
122
     function );
123
    libcnotify_print_data(
124
     ( (ewf_sha1_hash_t *) data )->padding,
125
     8,
126
     0 );
127
  }
128
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
129
130
0
  data_size -= 8;
131
132
0
  if( libewf_checksum_calculate_adler32(
133
0
       &calculated_checksum,
134
0
       data,
135
0
       data_size - 4,
136
0
       1,
137
0
       error ) != 1 )
138
0
  {
139
0
    libcerror_error_set(
140
0
     error,
141
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
142
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
143
0
     "%s: unable to calculate checksum.",
144
0
     function );
145
146
0
    return( -1 );
147
0
  }
148
0
  if( stored_checksum != calculated_checksum )
149
0
  {
150
0
    libcerror_error_set(
151
0
     error,
152
0
     LIBCERROR_ERROR_DOMAIN_INPUT,
153
0
     LIBCERROR_INPUT_ERROR_CHECKSUM_MISMATCH,
154
0
     "%s: checksum does not match (stored: 0x%08" PRIx32 ", calculated: 0x%08" PRIx32 ").",
155
0
     function,
156
0
     stored_checksum,
157
0
     calculated_checksum );
158
159
0
    return( -1 );
160
0
  }
161
0
  result = libewf_section_test_zero(
162
0
      data,
163
0
      20,
164
0
      error );
165
166
0
  if( result == -1 )
167
0
  {
168
0
    libcerror_error_set(
169
0
     error,
170
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
171
0
     LIBCERROR_RUNTIME_ERROR_GET_FAILED,
172
0
     "%s: unable to determine if SHA1 hash is empty.",
173
0
     function );
174
175
0
    return( -1 );
176
0
  }
177
0
  else if( result == 0 )
178
0
  {
179
0
    if( memory_copy(
180
0
         hash_sections->sha1_hash,
181
0
         data,
182
0
         20 ) == NULL )
183
0
    {
184
0
      libcerror_error_set(
185
0
       error,
186
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
187
0
       LIBCERROR_MEMORY_ERROR_COPY_FAILED,
188
0
       "%s: unable to set SHA1 hash in hash sections.",
189
0
       function );
190
191
0
      return( -1 );
192
0
    }
193
0
    hash_sections->sha1_hash_set = 1;
194
0
  }
195
0
  else
196
0
  {
197
0
    hash_sections->sha1_hash_set = 0;
198
0
  }
199
0
  return( 1 );
200
0
}
201
202
/* Reads a version 2 SHA1 hash section
203
 * Returns the number of bytes read or -1 on error
204
 */
205
ssize_t libewf_sha1_hash_section_read_file_io_pool(
206
         libewf_section_descriptor_t *section_descriptor,
207
         libewf_io_handle_t *io_handle,
208
         libbfio_pool_t *file_io_pool,
209
         int file_io_pool_entry,
210
         libewf_hash_sections_t *hash_sections,
211
         libcerror_error_t **error )
212
0
{
213
0
  uint8_t *section_data    = NULL;
214
0
  static char *function    = "libewf_sha1_hash_section_read_file_io_pool";
215
0
  size_t section_data_size = 0;
216
0
  ssize_t read_count       = 0;
217
218
0
  if( section_descriptor == NULL )
219
0
  {
220
0
    libcerror_error_set(
221
0
     error,
222
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
223
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
224
0
     "%s: invalid section descriptor.",
225
0
     function );
226
227
0
    return( -1 );
228
0
  }
229
0
  read_count = libewf_section_read_data(
230
0
                section_descriptor,
231
0
                io_handle,
232
0
                file_io_pool,
233
0
                file_io_pool_entry,
234
0
                &section_data,
235
0
                &section_data_size,
236
0
                error );
237
238
0
  if( read_count == -1 )
239
0
  {
240
0
    libcerror_error_set(
241
0
     error,
242
0
     LIBCERROR_ERROR_DOMAIN_IO,
243
0
     LIBCERROR_IO_ERROR_READ_FAILED,
244
0
     "%s: unable to read section data.",
245
0
     function );
246
247
0
    goto on_error;
248
0
  }
249
0
  else if( read_count != 0 )
250
0
  {
251
0
    if( libewf_sha1_hash_section_read_data(
252
0
         section_data,
253
0
         section_data_size,
254
0
         hash_sections,
255
0
         error ) != 1 )
256
0
    {
257
0
      libcerror_error_set(
258
0
       error,
259
0
       LIBCERROR_ERROR_DOMAIN_IO,
260
0
       LIBCERROR_IO_ERROR_READ_FAILED,
261
0
       "%s: unable to read section data.",
262
0
       function );
263
264
0
      goto on_error;
265
0
    }
266
0
  }
267
0
  memory_free(
268
0
   section_data );
269
270
0
  return( read_count );
271
272
0
on_error:
273
0
  if( section_data != NULL )
274
0
  {
275
0
    memory_free(
276
0
     section_data );
277
0
  }
278
0
  return( -1 );
279
0
}
280
281
/* Writes a version 2 SHA1 hash section
282
 * Returns 1 if successful or -1 on error
283
 */
284
int libewf_sha1_hash_section_write_data(
285
     uint8_t *data,
286
     size_t data_size,
287
     libewf_hash_sections_t *hash_sections,
288
     libcerror_error_t **error )
289
0
{
290
0
  static char *function        = "libewf_sha1_hash_section_write_data";
291
0
  uint32_t calculated_checksum = 0;
292
293
0
  if( data == NULL )
294
0
  {
295
0
    libcerror_error_set(
296
0
     error,
297
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
298
0
     LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
299
0
     "%s: missing data.",
300
0
     function );
301
302
0
    return( -1 );
303
0
  }
304
0
  if( data_size != (size_t) sizeof( ewf_sha1_hash_t ) )
305
0
  {
306
0
    libcerror_error_set(
307
0
     error,
308
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
309
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
310
0
     "%s: invalid data size value out of bounds.",
311
0
     function );
312
313
0
    return( -1 );
314
0
  }
315
0
  if( hash_sections == NULL )
316
0
  {
317
0
    libcerror_error_set(
318
0
     error,
319
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
320
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
321
0
     "%s: invalid hash sections.",
322
0
     function );
323
324
0
    return( -1 );
325
0
  }
326
0
  if( memory_set(
327
0
       data,
328
0
       0,
329
0
       data_size ) == NULL )
330
0
  {
331
0
    libcerror_error_set(
332
0
     error,
333
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
334
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
335
0
     "%s: unable to clear data.",
336
0
     function );
337
338
0
    return( -1 );
339
0
  }
340
0
  if( hash_sections->sha1_hash_set != 0 )
341
0
  {
342
0
    if( memory_copy(
343
0
         data,
344
0
         hash_sections->sha1_hash,
345
0
         20 ) == NULL )
346
0
    {
347
0
      libcerror_error_set(
348
0
       error,
349
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
350
0
       LIBCERROR_MEMORY_ERROR_COPY_FAILED,
351
0
       "%s: unable to set SHA1 hash.",
352
0
       function );
353
354
0
      return( -1 );
355
0
    }
356
0
  }
357
0
  data_size -= 8;
358
359
0
  if( libewf_checksum_calculate_adler32(
360
0
       &calculated_checksum,
361
0
       data,
362
0
       data_size - 4,
363
0
       1,
364
0
       error ) != 1 )
365
0
  {
366
0
    libcerror_error_set(
367
0
     error,
368
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
369
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
370
0
     "%s: unable to calculate checksum.",
371
0
     function );
372
373
0
    return( -1 );
374
0
  }
375
0
  byte_stream_copy_from_uint32_little_endian(
376
0
   ( (ewf_sha1_hash_t *) data )->checksum,
377
0
   calculated_checksum );
378
379
0
  data_size += 8;
380
381
#if defined( HAVE_DEBUG_OUTPUT )
382
  if( libcnotify_verbose != 0 )
383
  {
384
    libcnotify_printf(
385
     "%s: SHA1 hash data:\n",
386
     function );
387
    libcnotify_print_data(
388
     data,
389
     data_size,
390
     0 );
391
  }
392
#endif
393
#if defined( HAVE_DEBUG_OUTPUT )
394
  if( libcnotify_verbose != 0 )
395
  {
396
    libcnotify_printf(
397
     "%s: SHA1 hash:\n",
398
     function );
399
    libcnotify_print_data(
400
     data,
401
     20,
402
     0 );
403
404
    libcnotify_printf(
405
     "%s: checksum\t\t\t\t\t: 0x%08" PRIx32 "\n",
406
     function,
407
     calculated_checksum );
408
409
    libcnotify_printf(
410
     "%s: padding:\n",
411
     function );
412
    libcnotify_print_data(
413
     ( (ewf_sha1_hash_t *) data )->padding,
414
     8,
415
     0 );
416
  }
417
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
418
419
0
  return( 1 );
420
0
}
421
422
/* Writes a version 2 SHA1 hash section
423
 * Returns the number of bytes written or -1 on error
424
 */
425
ssize_t libewf_sha1_hash_section_write_file_io_pool(
426
         libewf_section_descriptor_t *section_descriptor,
427
         libewf_io_handle_t *io_handle,
428
         libbfio_pool_t *file_io_pool,
429
         int file_io_pool_entry,
430
         uint8_t format_version,
431
         off64_t section_offset,
432
         libewf_hash_sections_t *hash_sections,
433
         libcerror_error_t **error )
434
0
{
435
0
  uint8_t *section_data               = NULL;
436
0
  static char *function               = "libewf_sha1_hash_section_write_file_io_pool";
437
0
  size_t sha1_hash_data_size          = 0;
438
0
  size_t section_descriptor_data_size = 0;
439
0
  size_t section_padding_size         = 0;
440
0
  ssize_t total_write_count           = 0;
441
0
  ssize_t write_count                 = 0;
442
443
0
  if( section_descriptor == NULL )
444
0
  {
445
0
    libcerror_error_set(
446
0
     error,
447
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
448
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
449
0
     "%s: invalid section descriptor.",
450
0
     function );
451
452
0
    return( -1 );
453
0
  }
454
0
  if( format_version == 2 )
455
0
  {
456
0
    section_descriptor_data_size = sizeof( ewf_section_descriptor_v2_t );
457
0
    sha1_hash_data_size          = sizeof( ewf_sha1_hash_t );
458
0
    section_padding_size         = 8;
459
0
  }
460
0
  else
461
0
  {
462
0
    libcerror_error_set(
463
0
     error,
464
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
465
0
     LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
466
0
     "%s: unsupported format version.",
467
0
     function );
468
469
0
    return( -1 );
470
0
  }
471
0
  if( hash_sections == NULL )
472
0
  {
473
0
    libcerror_error_set(
474
0
     error,
475
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
476
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
477
0
     "%s: invalid hash sections.",
478
0
     function );
479
480
0
    return( -1 );
481
0
  }
482
0
  if( libewf_section_descriptor_set(
483
0
       section_descriptor,
484
0
       LIBEWF_SECTION_TYPE_SHA1_HASH,
485
0
       NULL,
486
0
       0,
487
0
       section_offset,
488
0
       (size64_t) ( section_descriptor_data_size + sha1_hash_data_size ),
489
0
       (size64_t) sha1_hash_data_size,
490
0
       (uint32_t) section_padding_size,
491
0
       error ) != 1 )
492
0
  {
493
0
    libcerror_error_set(
494
0
     error,
495
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
496
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
497
0
     "%s: unable to set section descriptor.",
498
0
     function );
499
500
0
    goto on_error;
501
0
  }
502
0
  section_data = (uint8_t *) memory_allocate(
503
0
                              sha1_hash_data_size );
504
505
0
  if( section_data == NULL )
506
0
  {
507
0
    libcerror_error_set(
508
0
     error,
509
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
510
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
511
0
     "%s: unable to create section data.",
512
0
     function );
513
514
0
    goto on_error;
515
0
  }
516
0
  if( libewf_sha1_hash_section_write_data(
517
0
       section_data,
518
0
       sha1_hash_data_size,
519
0
       hash_sections,
520
0
       error ) != 1 )
521
0
  {
522
0
    libcerror_error_set(
523
0
     error,
524
0
     LIBCERROR_ERROR_DOMAIN_IO,
525
0
     LIBCERROR_IO_ERROR_READ_FAILED,
526
0
     "%s: unable to write section data.",
527
0
     function );
528
529
0
    goto on_error;
530
0
  }
531
0
  write_count = libewf_section_write_data(
532
0
                 section_descriptor,
533
0
                 io_handle,
534
0
                 file_io_pool,
535
0
                 file_io_pool_entry,
536
0
                 section_data,
537
0
                 sha1_hash_data_size,
538
0
                 error );
539
540
0
  if( write_count == -1 )
541
0
  {
542
0
    libcerror_error_set(
543
0
     error,
544
0
     LIBCERROR_ERROR_DOMAIN_IO,
545
0
     LIBCERROR_IO_ERROR_WRITE_FAILED,
546
0
     "%s: unable to write section data.",
547
0
     function );
548
549
0
    goto on_error;
550
0
  }
551
0
  total_write_count += write_count;
552
553
0
  memory_free(
554
0
   section_data );
555
556
0
  section_data = NULL;
557
558
0
  write_count = libewf_section_descriptor_write_file_io_pool(
559
0
           section_descriptor,
560
0
           file_io_pool,
561
0
           file_io_pool_entry,
562
0
           format_version,
563
0
           error );
564
565
0
  if( write_count != (ssize_t) section_descriptor_data_size )
566
0
  {
567
0
    libcerror_error_set(
568
0
     error,
569
0
     LIBCERROR_ERROR_DOMAIN_IO,
570
0
     LIBCERROR_IO_ERROR_WRITE_FAILED,
571
0
     "%s: unable to write section descriptor data.",
572
0
     function );
573
574
0
    goto on_error;
575
0
  }
576
0
  total_write_count += write_count;
577
578
0
  return( total_write_count );
579
580
0
on_error:
581
0
  if( section_data != NULL )
582
0
  {
583
0
    memory_free(
584
0
     section_data );
585
0
  }
586
0
  return( -1 );
587
0
}
588