Coverage Report

Created: 2025-08-28 07:10

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