Coverage Report

Created: 2026-07-10 07:32

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libevtx/libevtx/libevtx_checksum.c
Line
Count
Source
1
/*
2
 * Checksum functions
3
 *
4
 * Copyright (C) 2011-2026, 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 "libevtx_libcerror.h"
26
27
/* Table of CRC-32 values of 8-bit values
28
 */
29
uint32_t libevtx_checksum_crc32_table[ 256 ];
30
31
/* Value to indicate the CRC-32 table been computed
32
 */
33
int libevtx_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 libevtx_checksum_initialize_crc32_table(
39
      void )
40
2
{
41
2
  uint32_t crc32             = 0;
42
2
  uint32_t crc32_table_index = 0;
43
2
  uint8_t bit_iterator       = 0;
44
45
2
  for( crc32_table_index = 0;
46
514
       crc32_table_index < 256;
47
512
       crc32_table_index++ )
48
512
  {
49
512
    crc32 = (uint32_t) crc32_table_index;
50
51
512
    for( bit_iterator = 0;
52
4.60k
         bit_iterator < 8;
53
4.09k
         bit_iterator++ )
54
4.09k
    {
55
4.09k
      if( crc32 & 1 )
56
2.04k
      {
57
2.04k
        crc32 = (uint32_t) 0xedb88320UL ^ ( crc32 >> 1 );
58
2.04k
      }
59
2.04k
      else
60
2.04k
      {
61
2.04k
        crc32 = crc32 >> 1;
62
2.04k
      }
63
4.09k
    }
64
512
    libevtx_checksum_crc32_table[ crc32_table_index ] = crc32;
65
512
  }
66
2
  libevtx_checksum_crc32_table_computed = 1;
67
2
}
68
69
/* Calculates the CRC-32 of a buffer
70
 * Based on RFC 1952
71
 * Returns 1 if successful or -1 on error
72
 */
73
int libevtx_checksum_calculate_little_endian_crc32(
74
     uint32_t *crc32,
75
     uint8_t *buffer,
76
     size_t size,
77
     uint32_t initial_value,
78
     libcerror_error_t **error )
79
14.6k
{
80
14.6k
  static char *function      = "libevtx_checksum_calculate_little_endian_crc32";
81
14.6k
  size_t buffer_offset       = 0;
82
14.6k
  uint32_t crc32_table_index = 0;
83
84
14.6k
  if( crc32 == NULL )
85
0
  {
86
0
    libcerror_error_set(
87
0
     error,
88
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
89
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
90
0
     "%s: invalid CRC-32.",
91
0
     function );
92
93
0
    return( -1 );
94
0
  }
95
14.6k
  if( buffer == NULL )
96
0
  {
97
0
    libcerror_error_set(
98
0
     error,
99
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
100
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
101
0
     "%s: invalid buffer.",
102
0
     function );
103
104
0
    return( -1 );
105
0
  }
106
14.6k
  if( size > (size_t) SSIZE_MAX )
107
0
  {
108
0
    libcerror_error_set(
109
0
     error,
110
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
111
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
112
0
     "%s: invalid size value exceeds maximum.",
113
0
     function );
114
115
0
    return( -1 );
116
0
  }
117
14.6k
  *crc32 = initial_value ^ (uint32_t) 0xffffffffUL;
118
119
14.6k
        if( libevtx_checksum_crc32_table_computed == 0 )
120
2
  {
121
2
    libevtx_checksum_initialize_crc32_table();
122
2
  }
123
14.6k
        for( buffer_offset = 0;
124
179M
       buffer_offset < size;
125
179M
       buffer_offset++ )
126
179M
  {
127
179M
    crc32_table_index = ( *crc32 ^ buffer[ buffer_offset ] ) & 0x000000ffUL;
128
129
179M
    *crc32 = libevtx_checksum_crc32_table[ crc32_table_index ] ^ ( *crc32 >> 8 );
130
179M
        }
131
14.6k
        *crc32 ^= 0xffffffffUL;
132
133
14.6k
  return( 1 );
134
14.6k
}
135
136
/* Calculates the weak CRC-32 of a buffer
137
 * Based on RFC 1952, without initial and final XOR operation
138
 * Returns 1 if successful or -1 on error
139
 */
140
int libevtx_checksum_calculate_little_endian_weak_crc32(
141
     uint32_t *crc32,
142
     uint8_t *buffer,
143
     size_t size,
144
     uint32_t initial_value,
145
     libcerror_error_t **error )
146
0
{
147
0
  static char *function      = "libevtx_checksum_calculate_little_endian_weak_crc32";
148
0
  size_t buffer_offset       = 0;
149
0
  uint32_t crc32_table_index = 0;
150
151
0
  if( crc32 == NULL )
152
0
  {
153
0
    libcerror_error_set(
154
0
     error,
155
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
156
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
157
0
     "%s: invalid CRC-32.",
158
0
     function );
159
160
0
    return( -1 );
161
0
  }
162
0
  if( buffer == NULL )
163
0
  {
164
0
    libcerror_error_set(
165
0
     error,
166
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
167
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
168
0
     "%s: invalid buffer.",
169
0
     function );
170
171
0
    return( -1 );
172
0
  }
173
0
  if( size > (size_t) SSIZE_MAX )
174
0
  {
175
0
    libcerror_error_set(
176
0
     error,
177
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
178
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
179
0
     "%s: invalid size value exceeds maximum.",
180
0
     function );
181
182
0
    return( -1 );
183
0
  }
184
0
  *crc32 = initial_value;
185
186
0
        if( libevtx_checksum_crc32_table_computed == 0 )
187
0
  {
188
0
    libevtx_checksum_initialize_crc32_table();
189
0
  }
190
0
        for( buffer_offset = 0;
191
0
       buffer_offset < size;
192
0
       buffer_offset++ )
193
0
  {
194
0
    crc32_table_index = ( *crc32 ^ buffer[ buffer_offset ] ) & 0x000000ffUL;
195
196
0
    *crc32 = libevtx_checksum_crc32_table[ crc32_table_index ] ^ ( *crc32 >> 8 );
197
0
        }
198
0
        return( 1 );
199
0
}
200