Coverage Report

Created: 2023-06-07 06:53

/src/libesedb/libesedb/libesedb_checksum.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Checksum functions
3
 *
4
 * Copyright (C) 2009-2023, 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 "libesedb_checksum.h"
27
#include "libesedb_libcerror.h"
28
29
/* The largest primary (or scalar) available
30
 * supported by a single load and store instruction
31
 */
32
typedef unsigned long int libesedb_aligned_t;
33
34
/* The ECC-32 mask lookup table
35
 */
36
const uint8_t libesedb_checksum_ecc32_include_lookup_table[ 256 ] = {
37
  0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
38
  1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
39
  1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
40
  0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
41
  1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
42
  0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
43
  0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
44
  1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
45
  1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
46
  0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
47
  0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
48
  1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
49
  0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
50
  1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
51
  1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
52
  0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0
53
};
54
55
/* Calculates the little-endian ECC-32 and XOR-32 of a buffer
56
 * It uses the initial value to calculate a new XOR-32
57
 * Returns 1 if successful or -1 on error
58
 */
59
int libesedb_checksum_calculate_little_endian_ecc32(
60
     uint32_t *ecc_checksum_value,
61
     uint32_t *xor_checksum_value,
62
     const uint8_t *buffer,
63
     size_t size,
64
     size_t offset,
65
     uint32_t initial_value,
66
     libcerror_error_t **error )
67
2.27k
{
68
2.27k
  static char *function          = "libesedb_checksum_calculate_little_endian_ecc32";
69
2.27k
  size_t buffer_iterator         = 0;
70
2.27k
  size_t buffer_alignment        = 0;
71
2.27k
  uint32_t bitmask               = 0;
72
2.27k
  uint32_t bit_iterator          = 0;
73
2.27k
  uint32_t final_bitmask         = 0;
74
2.27k
  uint32_t value_32bit           = 0;
75
2.27k
  uint32_t xor32_value           = 0;
76
2.27k
  uint32_t xor32_vertical_first  = 0;
77
2.27k
  uint32_t xor32_vertical_second = 0;
78
2.27k
  uint32_t xor32_vertical_third  = 0;
79
2.27k
  uint32_t xor32_vertical_fourth = 0;
80
2.27k
  uint8_t mask_table_index       = 0;
81
82
2.27k
  if( ecc_checksum_value == NULL )
83
0
  {
84
0
    libcerror_error_set(
85
0
     error,
86
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
87
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
88
0
     "%s: invalid ECC checksum value.",
89
0
     function );
90
91
0
    return( -1 );
92
0
  }
93
2.27k
  if( xor_checksum_value == NULL )
94
0
  {
95
0
    libcerror_error_set(
96
0
     error,
97
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
98
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
99
0
     "%s: invalid XOR checksum value.",
100
0
     function );
101
102
0
    return( -1 );
103
0
  }
104
2.27k
  if( buffer == NULL )
105
0
  {
106
0
    libcerror_error_set(
107
0
     error,
108
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
109
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
110
0
     "%s: invalid buffer.",
111
0
     function );
112
113
0
    return( -1 );
114
0
  }
115
2.27k
  if( size > (size_t) SSIZE_MAX )
116
0
  {
117
0
    libcerror_error_set(
118
0
     error,
119
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
120
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
121
0
     "%s: invalid size value exceeds maximum.",
122
0
     function );
123
124
0
    return( -1 );
125
0
  }
126
2.27k
  if( offset > size )
127
0
  {
128
0
    libcerror_error_set(
129
0
     error,
130
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
131
0
     LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
132
0
     "%s: invalid offset value out of bounds.",
133
0
     function );
134
135
0
    return( -1 );
136
0
  }
137
2.27k
  buffer_alignment = offset % 16;
138
139
2.27k
  if( ( buffer_alignment % sizeof( uint32_t ) ) != 0 )
140
0
  {
141
0
    libcerror_error_set(
142
0
     error,
143
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
144
0
     LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
145
0
     "%s: offset is not 32-bit aligned.",
146
0
     function );
147
148
0
    return( -1 );
149
0
  }
150
2.27k
  *ecc_checksum_value = 0;
151
2.27k
  *xor_checksum_value = initial_value;
152
2.27k
  bitmask             = 0xff800000UL;
153
2.27k
  buffer             += offset;
154
155
2.27k
  for( buffer_iterator = offset;
156
1.16M
       buffer_iterator < size;
157
1.16M
       buffer_iterator += 4 )
158
1.16M
  {
159
1.16M
    byte_stream_copy_to_uint32_little_endian(
160
1.16M
     buffer,
161
1.16M
     value_32bit );
162
163
1.16M
    if( buffer_alignment == 0 )
164
289k
    {
165
289k
      xor32_vertical_first ^= value_32bit;
166
289k
    }
167
873k
    else if( buffer_alignment == 4 )
168
289k
    {
169
289k
      xor32_vertical_second ^= value_32bit;
170
289k
    }
171
583k
    else if( buffer_alignment == 8 )
172
291k
    {
173
291k
      xor32_vertical_third ^= value_32bit;
174
291k
    }
175
291k
    else
176
291k
    {
177
291k
      xor32_vertical_fourth ^= value_32bit;
178
291k
    }
179
1.16M
    xor32_value      ^= value_32bit;
180
1.16M
    buffer           += 4;
181
1.16M
    buffer_alignment += 4;
182
183
1.16M
    if( buffer_alignment >= 16 )
184
291k
    {
185
291k
      mask_table_index  = ( xor32_value & 0xff );
186
291k
      xor32_value     >>= 8;
187
291k
      mask_table_index ^= ( xor32_value & 0xff );
188
291k
      xor32_value     >>= 8;
189
291k
      mask_table_index ^= ( xor32_value & 0xff );
190
291k
      xor32_value     >>= 8;
191
291k
      mask_table_index ^= ( xor32_value & 0xff );
192
193
291k
      if( libesedb_checksum_ecc32_include_lookup_table[ mask_table_index ] != 0 )
194
100k
      {
195
100k
        *ecc_checksum_value ^= bitmask;
196
100k
      }
197
291k
      bitmask         -= 0x007fff80UL;
198
291k
      buffer_alignment = 0;
199
291k
      xor32_value      = 0;
200
291k
    }
201
1.16M
  }
202
2.27k
  if( xor32_value != 0 )
203
0
  {
204
0
    mask_table_index  = ( xor32_value & 0xff );
205
0
    xor32_value     >>= 8;
206
0
    mask_table_index ^= ( xor32_value & 0xff );
207
0
    xor32_value     >>= 8;
208
0
    mask_table_index ^= ( xor32_value & 0xff );
209
0
    xor32_value     >>= 8;
210
0
    mask_table_index ^= ( xor32_value & 0xff );
211
212
0
    if( libesedb_checksum_ecc32_include_lookup_table[ mask_table_index ] != 0 )
213
0
    {
214
0
      *ecc_checksum_value ^= bitmask;
215
0
    }
216
0
  }
217
  /* Determine the checksum part of the combination of
218
   * the first and second vertical XOR
219
   */
220
2.27k
  xor32_value  = xor32_vertical_first;
221
2.27k
  xor32_value ^= xor32_vertical_second;
222
223
2.27k
  mask_table_index  = ( xor32_value & 0xff );
224
2.27k
  xor32_value     >>= 8;
225
2.27k
  mask_table_index ^= ( xor32_value & 0xff );
226
2.27k
  xor32_value     >>= 8;
227
2.27k
  mask_table_index ^= ( xor32_value & 0xff );
228
2.27k
  xor32_value     >>= 8;
229
2.27k
  mask_table_index ^= ( xor32_value & 0xff );
230
231
2.27k
  if( libesedb_checksum_ecc32_include_lookup_table[ mask_table_index ] != 0 )
232
1.05k
  {
233
1.05k
    *ecc_checksum_value ^= 0x00400000UL;
234
1.05k
  }
235
  /* Determine the checksum part of the combination of
236
   * the first and third vertical XOR
237
   */
238
2.27k
  xor32_value  = xor32_vertical_first;
239
2.27k
  xor32_value ^= xor32_vertical_third;
240
241
2.27k
  mask_table_index  = ( xor32_value & 0xff );
242
2.27k
  xor32_value     >>= 8;
243
2.27k
  mask_table_index ^= ( xor32_value & 0xff );
244
2.27k
  xor32_value     >>= 8;
245
2.27k
  mask_table_index ^= ( xor32_value & 0xff );
246
2.27k
  xor32_value     >>= 8;
247
2.27k
  mask_table_index ^= ( xor32_value & 0xff );
248
249
2.27k
  if( libesedb_checksum_ecc32_include_lookup_table[ mask_table_index ] != 0 )
250
981
  {
251
981
    *ecc_checksum_value ^= 0x00200000UL;
252
981
  }
253
  /* Determine the checksum part of the combination of
254
   * the second and fourth vertical XOR
255
   */
256
2.27k
  xor32_value  = xor32_vertical_second;
257
2.27k
  xor32_value ^= xor32_vertical_fourth;
258
259
2.27k
  mask_table_index  = ( xor32_value & 0xff );
260
2.27k
  xor32_value     >>= 8;
261
2.27k
  mask_table_index ^= ( xor32_value & 0xff );
262
2.27k
  xor32_value     >>= 8;
263
2.27k
  mask_table_index ^= ( xor32_value & 0xff );
264
2.27k
  xor32_value     >>= 8;
265
2.27k
  mask_table_index ^= ( xor32_value & 0xff );
266
267
2.27k
  if( libesedb_checksum_ecc32_include_lookup_table[ mask_table_index ] != 0 )
268
1.10k
  {
269
1.10k
    *ecc_checksum_value ^= 0x00000020UL;
270
1.10k
  }
271
  /* Determine the checksum part of the combination of
272
   * the third and fourth vertical XOR
273
   */
274
2.27k
  xor32_value  = xor32_vertical_third;
275
2.27k
  xor32_value ^= xor32_vertical_fourth;
276
277
2.27k
  mask_table_index  = ( xor32_value & 0xff );
278
2.27k
  xor32_value     >>= 8;
279
2.27k
  mask_table_index ^= ( xor32_value & 0xff );
280
2.27k
  xor32_value     >>= 8;
281
2.27k
  mask_table_index ^= ( xor32_value & 0xff );
282
2.27k
  xor32_value     >>= 8;
283
2.27k
  mask_table_index ^= ( xor32_value & 0xff );
284
285
2.27k
  if( libesedb_checksum_ecc32_include_lookup_table[ mask_table_index ] != 0 )
286
1.10k
  {
287
1.10k
    *ecc_checksum_value ^= 0x00000040UL;
288
1.10k
  }
289
  /* Determine the XOR-32
290
   */
291
2.27k
  xor32_value  = xor32_vertical_first;
292
2.27k
  xor32_value ^= xor32_vertical_second;
293
2.27k
  xor32_value ^= xor32_vertical_third;
294
2.27k
  xor32_value ^= xor32_vertical_fourth;
295
296
  /* Determine the final bitmask
297
   */
298
2.27k
  bitmask       = 0xffff0000UL;
299
2.27k
  final_bitmask = 0;
300
301
2.27k
  for( bit_iterator = 1;
302
75.0k
       bit_iterator != 0;
303
72.8k
       bit_iterator <<= 1 )
304
72.8k
  {
305
72.8k
    if( ( xor32_value & bit_iterator ) != 0 )
306
36.2k
    {
307
36.2k
      final_bitmask ^= bitmask;
308
36.2k
    }
309
72.8k
    bitmask -= 0x0000ffffUL;
310
72.8k
  }
311
  /* Determine the buffer size bitmask
312
   */
313
2.27k
  if( size < 8192 )
314
2.27k
  {
315
2.27k
    *ecc_checksum_value &= 0xffffffffUL ^ (uint32_t) ( size << 19 );
316
2.27k
  }
317
2.27k
  *ecc_checksum_value ^= ( *ecc_checksum_value ^ final_bitmask ) & 0x001f001fUL;
318
2.27k
  *xor_checksum_value ^= xor32_value;
319
320
2.27k
  return( 1 );
321
2.27k
}
322
323
/* Calculates the little-endian XOR-32 of a buffer
324
 * It uses the initial value to calculate a new XOR-32
325
 * Returns 1 if successful or -1 on error
326
 */
327
int libesedb_checksum_calculate_little_endian_xor32(
328
     uint32_t *checksum_value,
329
     const uint8_t *buffer,
330
     size_t size,
331
     uint32_t initial_value,
332
     libcerror_error_t **error )
333
16.7k
{
334
16.7k
  libesedb_aligned_t *aligned_buffer_iterator = NULL;
335
16.7k
  uint8_t *buffer_iterator                    = NULL;
336
16.7k
  static char *function                       = "libesedb_checksum_calculate_little_endian_xor32";
337
16.7k
  libesedb_aligned_t value_aligned            = 0;
338
16.7k
  uint32_t big_endian_value_32bit             = 0;
339
16.7k
  uint32_t safe_checksum_value                = 0;
340
16.7k
  uint32_t value_32bit                        = 0;
341
16.7k
  uint8_t alignment_count                     = 0;
342
16.7k
  uint8_t alignment_size                      = 0;
343
16.7k
  uint8_t byte_count                          = 0;
344
16.7k
  uint8_t byte_order                          = 0;
345
16.7k
  uint8_t byte_size                           = 0;
346
347
16.7k
  if( checksum_value == NULL )
348
0
  {
349
0
    libcerror_error_set(
350
0
     error,
351
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
352
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
353
0
     "%s: invalid checksum value.",
354
0
     function );
355
356
0
    return( -1 );
357
0
  }
358
16.7k
  if( buffer == NULL )
359
0
  {
360
0
    libcerror_error_set(
361
0
     error,
362
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
363
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
364
0
     "%s: invalid buffer.",
365
0
     function );
366
367
0
    return( -1 );
368
0
  }
369
16.7k
  if( size > (size_t) SSIZE_MAX )
370
0
  {
371
0
    libcerror_error_set(
372
0
     error,
373
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
374
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
375
0
     "%s: invalid size value exceeds maximum.",
376
0
     function );
377
378
0
    return( -1 );
379
0
  }
380
16.7k
  safe_checksum_value = initial_value;
381
382
16.7k
  buffer_iterator = (uint8_t *) buffer;
383
384
  /* Only optimize when there is the alignment is a multitude of 32-bit
385
   * and for buffers larger than the alignment
386
   */
387
16.7k
  if( ( ( sizeof( libesedb_aligned_t ) % 4 ) == 0 )
388
16.7k
   && ( size > ( 2 * sizeof( libesedb_aligned_t ) ) ) )
389
16.7k
  {
390
    /* Align the buffer iterator
391
     */
392
16.7k
    alignment_size = (uint8_t) ( (intptr_t) buffer_iterator % sizeof( libesedb_aligned_t ) );
393
394
16.7k
    if( alignment_size > 0 )
395
16.7k
    {
396
16.7k
      byte_size = sizeof( libesedb_aligned_t ) - alignment_size;
397
398
      /* Align the buffer iterator in 4-byte steps
399
       */
400
33.5k
      while( byte_size != 0 )
401
16.7k
      {
402
16.7k
        value_32bit = 0;
403
16.7k
        byte_count  = 1;
404
405
16.7k
        if( byte_size >= 4 )
406
16.7k
        {
407
16.7k
          value_32bit |= buffer_iterator[ 3 ];
408
16.7k
          value_32bit <<= 8;
409
410
16.7k
          byte_count++;
411
16.7k
        }
412
16.7k
        if( byte_size >= 3 )
413
16.7k
        {
414
16.7k
          value_32bit |= buffer_iterator[ 2 ];
415
16.7k
          value_32bit <<= 8;
416
417
16.7k
          byte_count++;
418
16.7k
        }
419
16.7k
        if( byte_size >= 2 )
420
16.7k
        {
421
16.7k
          value_32bit |= buffer_iterator[ 1 ];
422
16.7k
          value_32bit <<= 8;
423
424
16.7k
          byte_count++;
425
16.7k
        }
426
16.7k
        value_32bit |= buffer_iterator[ 0 ];
427
428
16.7k
        buffer_iterator += byte_count;
429
16.7k
        byte_size       -= byte_count;
430
431
16.7k
        safe_checksum_value ^= value_32bit;
432
16.7k
      }
433
16.7k
      size -= byte_count;
434
16.7k
    }
435
16.7k
    aligned_buffer_iterator = (libesedb_aligned_t *) buffer_iterator;
436
437
16.7k
    if( *buffer_iterator != (uint8_t) ( *aligned_buffer_iterator & 0xff ) )
438
0
    {
439
0
      byte_order = _BYTE_STREAM_ENDIAN_BIG;
440
0
    }
441
16.7k
    else
442
16.7k
    {
443
16.7k
      byte_order = _BYTE_STREAM_ENDIAN_LITTLE;
444
16.7k
    }
445
    /* Calculate the XOR value using the aligned buffer iterator
446
     */
447
2.12M
    while( size > sizeof( libesedb_aligned_t ) )
448
2.11M
    {
449
2.11M
      value_aligned ^= *aligned_buffer_iterator;
450
451
2.11M
      aligned_buffer_iterator++;
452
453
2.11M
      size -= sizeof( libesedb_aligned_t );
454
2.11M
    }
455
    /* Align the aligned XOR value with the 32-bit XOR value
456
     */
457
16.7k
    if( alignment_size > 0 )
458
16.7k
    {
459
16.7k
      byte_count      = ( alignment_size % 4 ) * 8;
460
16.7k
      alignment_count = ( sizeof( libesedb_aligned_t ) - alignment_size ) * 8;
461
462
16.7k
      if( byte_order == _BYTE_STREAM_ENDIAN_BIG )
463
0
      {
464
        /* Shift twice to set unused bytes to 0
465
         */
466
0
        big_endian_value_32bit = (uint32_t) ( ( value_aligned >> alignment_count ) << byte_count );
467
468
        /* Change big-endian into little-endian
469
         */
470
0
        value_32bit = ( ( big_endian_value_32bit & 0x000000ffUL ) << 24 )
471
0
                    | ( ( big_endian_value_32bit & 0x0000ff00UL ) << 8 )
472
0
                    | ( ( big_endian_value_32bit >> 8 ) & 0x0000ff00UL )
473
0
                    | ( ( big_endian_value_32bit >> 24 ) & 0x000000ffUL );
474
475
        /* Strip-off the used part of the aligned value
476
         */
477
0
        value_aligned <<= alignment_count;
478
0
      }
479
16.7k
      else if( byte_order == _BYTE_STREAM_ENDIAN_LITTLE )
480
16.7k
      {
481
16.7k
        value_32bit = (uint32_t) ( value_aligned << byte_count );
482
483
        /* Strip-off the used part of the aligned value
484
         */
485
16.7k
        value_aligned >>= alignment_count;
486
16.7k
      }
487
16.7k
      safe_checksum_value ^= value_32bit;
488
16.7k
    }
489
    /* Update the 32-bit XOR value with the aligned XOR value
490
     */
491
16.7k
    byte_size = (uint8_t) sizeof( libesedb_aligned_t );
492
493
50.2k
    while( byte_size != 0 )
494
33.5k
    {
495
33.5k
      byte_count = ( ( byte_size / 4 ) - 1 ) * 32;
496
497
33.5k
      if( byte_order == _BYTE_STREAM_ENDIAN_BIG )
498
0
      {
499
0
        big_endian_value_32bit = (uint32_t) ( ( value_aligned >> byte_count ) & 0xffffffffUL );
500
501
        /* Change big-endian into little-endian
502
         */
503
0
        value_32bit = ( ( big_endian_value_32bit & 0x000000ffUL ) << 24 )
504
0
                    | ( ( big_endian_value_32bit & 0x0000ff00UL ) << 8 )
505
0
                    | ( ( big_endian_value_32bit >> 8 ) & 0x0000ff00UL )
506
0
                    | ( ( big_endian_value_32bit >> 24 ) & 0x000000ffUL );
507
0
      }
508
33.5k
      else if( byte_order == _BYTE_STREAM_ENDIAN_LITTLE )
509
33.5k
      {
510
33.5k
        value_32bit = (uint32_t) value_aligned;
511
512
33.5k
        value_aligned >>= byte_count;
513
33.5k
      }
514
33.5k
      byte_size -= 4;
515
516
33.5k
      safe_checksum_value ^= value_32bit;
517
33.5k
    }
518
    /* Re-align the buffer iterator
519
     */
520
16.7k
    buffer_iterator = (uint8_t *) aligned_buffer_iterator;
521
522
16.7k
    byte_size = 4 - ( alignment_size % 4 );
523
524
16.7k
    if( byte_size != 4 )
525
0
    {
526
0
      value_32bit   = buffer_iterator[ 0 ];
527
0
      value_32bit <<= 8;
528
529
0
      if( byte_size >= 2 )
530
0
      {
531
0
        value_32bit |= buffer_iterator[ 1 ];
532
0
      }
533
0
      value_32bit <<= 8;
534
535
0
      if( byte_size >= 3 )
536
0
      {
537
0
        value_32bit |= buffer_iterator[ 2 ];
538
0
      }
539
0
      value_32bit <<= 8;
540
541
0
      buffer_iterator += byte_size;
542
0
      size            -= byte_size;
543
544
0
      safe_checksum_value ^= value_32bit;
545
0
    }
546
16.7k
  }
547
37.6k
  while( size > 0 )
548
20.8k
  {
549
20.8k
    value_32bit = 0;
550
20.8k
    byte_count  = 1;
551
552
20.8k
    if( size >= 4 )
553
20.8k
    {
554
20.8k
      value_32bit |= buffer_iterator[ 3 ];
555
20.8k
      value_32bit <<= 8;
556
557
20.8k
      byte_count++;
558
20.8k
    }
559
20.8k
    if( size >= 3 )
560
20.8k
    {
561
20.8k
      value_32bit |= buffer_iterator[ 2 ];
562
20.8k
      value_32bit <<= 8;
563
564
20.8k
      byte_count++;
565
20.8k
    }
566
20.8k
    if( size >= 2 )
567
20.8k
    {
568
20.8k
      value_32bit |= buffer_iterator[ 1 ];
569
20.8k
      value_32bit <<= 8;
570
571
20.8k
      byte_count++;
572
20.8k
    }
573
20.8k
    value_32bit |= buffer_iterator[ 0 ];
574
575
20.8k
    buffer_iterator += byte_count;
576
20.8k
    size            -= byte_count;
577
578
20.8k
    safe_checksum_value ^= value_32bit;
579
20.8k
  }
580
16.7k
  *checksum_value = safe_checksum_value;
581
582
16.7k
  return( 1 );
583
16.7k
}
584