Coverage Report

Created: 2025-09-05 06:58

/src/libfvde/libfvde/libfvde_checksum.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Checksum functions
3
 *
4
 * Copyright (C) 2011-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 <types.h>
24
25
#include "libfvde_libcerror.h"
26
27
/* Table of CRC-32 values of 8-bit values
28
 */
29
uint32_t libfvde_checksum_crc32_table[ 256 ];
30
31
/* Value to indicate the CRC-32 table been computed
32
 */
33
int libfvde_checksum_crc32_table_computed = 0;
34
35
/* Initializes the internal CRC-32 table
36
 * The table speeds up the CRC-32 calculation
37
 */
38
void libfvde_checksum_initialize_crc32_table(
39
      uint32_t polynomial )
40
1
{
41
1
  uint32_t checksum    = 0;
42
1
  uint32_t table_index = 0;
43
1
  uint8_t bit_iterator = 0;
44
45
1
  for( table_index = 0;
46
257
       table_index < 256;
47
256
       table_index++ )
48
256
  {
49
256
    checksum = (uint32_t) table_index;
50
51
256
    for( bit_iterator = 0;
52
2.30k
         bit_iterator < 8;
53
2.04k
         bit_iterator++ )
54
2.04k
    {
55
2.04k
      if( checksum & 1 )
56
1.02k
      {
57
1.02k
        checksum = polynomial ^ ( checksum >> 1 );
58
1.02k
      }
59
1.02k
      else
60
1.02k
      {
61
1.02k
        checksum = checksum >> 1;
62
1.02k
      }
63
2.04k
    }
64
256
    libfvde_checksum_crc32_table[ table_index ] = checksum;
65
256
  }
66
1
  libfvde_checksum_crc32_table_computed = 1;
67
1
}
68
69
/* Calculates the weak CRC-32 checksum of a buffer
70
 * Returns 1 if successful or -1 on error
71
 */
72
int libfvde_checksum_calculate_weak_crc32(
73
     uint32_t *checksum,
74
     const uint8_t *buffer,
75
     size_t size,
76
     uint32_t initial_value,
77
     libcerror_error_t **error )
78
1.24k
{
79
1.24k
  static char *function = "libfvde_checkcum_calculate_weak_crc32";
80
1.24k
  size_t buffer_offset  = 0;
81
1.24k
  uint32_t table_index  = 0;
82
83
1.24k
  if( checksum == NULL )
84
0
  {
85
0
    libcerror_error_set(
86
0
     error,
87
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
88
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
89
0
     "%s: invalid checksum.",
90
0
     function );
91
92
0
    return( -1 );
93
0
  }
94
1.24k
  if( buffer == NULL )
95
0
  {
96
0
    libcerror_error_set(
97
0
     error,
98
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
99
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
100
0
     "%s: invalid buffer.",
101
0
     function );
102
103
0
    return( -1 );
104
0
  }
105
1.24k
  if( size > (size_t) SSIZE_MAX )
106
0
  {
107
0
    libcerror_error_set(
108
0
     error,
109
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
110
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
111
0
     "%s: invalid size value exceeds maximum.",
112
0
     function );
113
114
0
    return( -1 );
115
0
  }
116
1.24k
        if( libfvde_checksum_crc32_table_computed == 0 )
117
1
  {
118
1
    libfvde_checksum_initialize_crc32_table(
119
1
     0x82f63b78UL );
120
1
  }
121
1.24k
  *checksum = initial_value;
122
123
1.24k
        for( buffer_offset = 0;
124
926k
       buffer_offset < size;
125
925k
       buffer_offset++ )
126
925k
  {
127
925k
    table_index = ( *checksum ^ buffer[ buffer_offset ] ) & 0x000000ffUL;
128
129
925k
    *checksum = libfvde_checksum_crc32_table[ table_index ] ^ ( *checksum >> 8 );
130
925k
        }
131
1.24k
  return( 1 );
132
1.24k
}
133