|
24 | 24 | #include <memory.h>
|
25 | 25 | #include <types.h>
|
26 | 26 |
|
| 27 | +#include "libfsext_checksum.h" |
27 | 28 | #include "libfsext_definitions.h"
|
28 | 29 | #include "libfsext_group_descriptor.h"
|
29 | 30 | #include "libfsext_io_handle.h"
|
@@ -146,14 +147,16 @@ int libfsext_group_descriptor_read_data(
|
146 | 147 | size_t data_size,
|
147 | 148 | libcerror_error_t **error )
|
148 | 149 | {
|
| 150 | + uint8_t checksum_data[ 4 ]; |
| 151 | + uint8_t empty_checksum_data[ 2 ] = { 0, 0 }; |
| 152 | + |
149 | 153 | static char *function = "libfsext_group_descriptor_read_data";
|
150 | 154 | size_t group_descriptor_data_size = 0;
|
151 | 155 | uint64_t value_64bit = 0;
|
| 156 | + uint32_t calculated_checksum = 0; |
| 157 | + uint32_t stored_checksum = 0; |
152 | 158 | uint32_t value_32bit = 0;
|
153 |
| - |
154 |
| -#if defined( HAVE_DEBUG_OUTPUT ) |
155 | 159 | uint16_t value_16bit = 0;
|
156 |
| -#endif |
157 | 160 |
|
158 | 161 | if( group_descriptor == NULL )
|
159 | 162 | {
|
@@ -331,6 +334,12 @@ int libfsext_group_descriptor_read_data(
|
331 | 334 | ( (fsext_group_descriptor_ext4_t *) data )->number_of_unused_inodes_lower,
|
332 | 335 | group_descriptor->number_of_unused_inodes );
|
333 | 336 |
|
| 337 | + byte_stream_copy_to_uint16_little_endian( |
| 338 | + ( (fsext_group_descriptor_ext4_t *) data )->checksum, |
| 339 | + value_16bit ); |
| 340 | + |
| 341 | + stored_checksum = value_16bit; |
| 342 | + |
334 | 343 | #if defined( HAVE_DEBUG_OUTPUT )
|
335 | 344 | if( libcnotify_verbose != 0 )
|
336 | 345 | {
|
@@ -587,21 +596,123 @@ int libfsext_group_descriptor_read_data(
|
587 | 596 | function,
|
588 | 597 | group_descriptor->number_of_unused_inodes );
|
589 | 598 |
|
590 |
| - libcnotify_printf( |
591 |
| - "%s: block bitmap checksum\t\t\t: 0x%04" PRIx32 "\n", |
592 |
| - function, |
593 |
| - group_descriptor->block_bitmap_checksum ); |
| 599 | + if( ( io_handle->read_only_compatible_features_flags & LIBFSEXT_READ_ONLY_COMPATIBLE_FEATURES_FLAG_METADATA_CHECKSUM ) != 0 ) |
| 600 | + { |
| 601 | + libcnotify_printf( |
| 602 | + "%s: block bitmap checksum\t\t\t: 0x%08" PRIx32 "\n", |
| 603 | + function, |
| 604 | + group_descriptor->block_bitmap_checksum ); |
594 | 605 |
|
595 |
| - libcnotify_printf( |
596 |
| - "%s: inode bitmap checksum\t\t\t: 0x%04" PRIx32 "\n", |
597 |
| - function, |
598 |
| - group_descriptor->inode_bitmap_checksum ); |
| 606 | + libcnotify_printf( |
| 607 | + "%s: inode bitmap checksum\t\t\t: 0x%08" PRIx32 "\n", |
| 608 | + function, |
| 609 | + group_descriptor->inode_bitmap_checksum ); |
| 610 | + } |
| 611 | + else |
| 612 | + { |
| 613 | + libcnotify_printf( |
| 614 | + "%s: block bitmap checksum\t\t\t: 0x%04" PRIx32 "\n", |
| 615 | + function, |
| 616 | + group_descriptor->block_bitmap_checksum ); |
599 | 617 |
|
| 618 | + libcnotify_printf( |
| 619 | + "%s: inode bitmap checksum\t\t\t: 0x%04" PRIx32 "\n", |
| 620 | + function, |
| 621 | + group_descriptor->inode_bitmap_checksum ); |
| 622 | + } |
600 | 623 | libcnotify_printf(
|
601 | 624 | "\n" );
|
602 | 625 | }
|
603 | 626 | #endif /* defined( HAVE_DEBUG_OUTPUT ) */
|
604 | 627 | }
|
| 628 | +/* TODO add support for crc16 checksum */ |
| 629 | + if( ( io_handle->read_only_compatible_features_flags & LIBFSEXT_READ_ONLY_COMPATIBLE_FEATURES_FLAG_METADATA_CHECKSUM ) != 0 ) |
| 630 | + { |
| 631 | + byte_stream_copy_from_uint32_little_endian( |
| 632 | + checksum_data, |
| 633 | + group_descriptor->group_number ); |
| 634 | + |
| 635 | + if( libfsext_checksum_calculate_crc32( |
| 636 | + &calculated_checksum, |
| 637 | + checksum_data, |
| 638 | + 4, |
| 639 | + io_handle->metadata_checksum_seed, |
| 640 | + error ) != 1 ) |
| 641 | + { |
| 642 | + libcerror_error_set( |
| 643 | + error, |
| 644 | + LIBCERROR_ERROR_DOMAIN_RUNTIME, |
| 645 | + LIBCERROR_RUNTIME_ERROR_SET_FAILED, |
| 646 | + "%s: unable to calculate CRC-32.", |
| 647 | + function ); |
| 648 | + |
| 649 | + return( -1 ); |
| 650 | + } |
| 651 | + if( libfsext_checksum_calculate_crc32( |
| 652 | + &calculated_checksum, |
| 653 | + data, |
| 654 | + 30, |
| 655 | + calculated_checksum, |
| 656 | + error ) != 1 ) |
| 657 | + { |
| 658 | + libcerror_error_set( |
| 659 | + error, |
| 660 | + LIBCERROR_ERROR_DOMAIN_RUNTIME, |
| 661 | + LIBCERROR_RUNTIME_ERROR_SET_FAILED, |
| 662 | + "%s: unable to calculate CRC-32.", |
| 663 | + function ); |
| 664 | + |
| 665 | + return( -1 ); |
| 666 | + } |
| 667 | + if( libfsext_checksum_calculate_crc32( |
| 668 | + &calculated_checksum, |
| 669 | + empty_checksum_data, |
| 670 | + 2, |
| 671 | + calculated_checksum, |
| 672 | + error ) != 1 ) |
| 673 | + { |
| 674 | + libcerror_error_set( |
| 675 | + error, |
| 676 | + LIBCERROR_ERROR_DOMAIN_RUNTIME, |
| 677 | + LIBCERROR_RUNTIME_ERROR_SET_FAILED, |
| 678 | + "%s: unable to calculate CRC-32.", |
| 679 | + function ); |
| 680 | + |
| 681 | + return( -1 ); |
| 682 | + } |
| 683 | + if( libfsext_checksum_calculate_crc32( |
| 684 | + &calculated_checksum, |
| 685 | + &( data[ 32 ] ), |
| 686 | + data_size - 32, |
| 687 | + calculated_checksum, |
| 688 | + error ) != 1 ) |
| 689 | + { |
| 690 | + libcerror_error_set( |
| 691 | + error, |
| 692 | + LIBCERROR_ERROR_DOMAIN_RUNTIME, |
| 693 | + LIBCERROR_RUNTIME_ERROR_SET_FAILED, |
| 694 | + "%s: unable to calculate CRC-32.", |
| 695 | + function ); |
| 696 | + |
| 697 | + return( -1 ); |
| 698 | + } |
| 699 | + calculated_checksum = ( 0xffffffffUL - calculated_checksum ) & 0x0000ffffUL; |
| 700 | + |
| 701 | + if( ( stored_checksum != 0 ) |
| 702 | + && ( stored_checksum != calculated_checksum ) ) |
| 703 | + { |
| 704 | +#if defined( HAVE_DEBUG_OUTPUT ) |
| 705 | + if( libcnotify_verbose != 0 ) |
| 706 | + { |
| 707 | + libcnotify_printf( |
| 708 | + "%s: mismatch in checksum ( 0x%08" PRIx32 " != 0x%08" PRIx32 " ).\n", |
| 709 | + function, |
| 710 | + stored_checksum, |
| 711 | + calculated_checksum ); |
| 712 | + } |
| 713 | +#endif |
| 714 | + } |
| 715 | + } |
605 | 716 | return( 1 );
|
606 | 717 | }
|
607 | 718 |
|
|
0 commit comments