1*d2c16535SElliott Hughes // SPDX-License-Identifier: 0BSD 2*d2c16535SElliott Hughes 3*d2c16535SElliott Hughes /* 4*d2c16535SElliott Hughes * CRC32 using the polynomial from IEEE-802.3 5*d2c16535SElliott Hughes * 6*d2c16535SElliott Hughes * Authors: Lasse Collin <[email protected]> 7*d2c16535SElliott Hughes * Igor Pavlov <https://7-zip.org/> 8*d2c16535SElliott Hughes */ 9*d2c16535SElliott Hughes 10*d2c16535SElliott Hughes /* 11*d2c16535SElliott Hughes * This is not the fastest implementation, but it is pretty compact. 12*d2c16535SElliott Hughes * The fastest versions of xz_crc32() on modern CPUs without hardware 13*d2c16535SElliott Hughes * accelerated CRC instruction are 3-5 times as fast as this version, 14*d2c16535SElliott Hughes * but they are bigger and use more memory for the lookup table. 15*d2c16535SElliott Hughes */ 16*d2c16535SElliott Hughes 17*d2c16535SElliott Hughes #include "xz_private.h" 18*d2c16535SElliott Hughes 19*d2c16535SElliott Hughes /* 20*d2c16535SElliott Hughes * STATIC_RW_DATA is used in the pre-boot environment on some architectures. 21*d2c16535SElliott Hughes * See <linux/decompress/mm.h> for details. 22*d2c16535SElliott Hughes */ 23*d2c16535SElliott Hughes #ifndef STATIC_RW_DATA 24*d2c16535SElliott Hughes # define STATIC_RW_DATA static 25*d2c16535SElliott Hughes #endif 26*d2c16535SElliott Hughes 27*d2c16535SElliott Hughes STATIC_RW_DATA uint32_t xz_crc32_table[256]; 28*d2c16535SElliott Hughes xz_crc32_init(void)29*d2c16535SElliott HughesXZ_EXTERN void xz_crc32_init(void) 30*d2c16535SElliott Hughes { 31*d2c16535SElliott Hughes const uint32_t poly = 0xEDB88320; 32*d2c16535SElliott Hughes 33*d2c16535SElliott Hughes uint32_t i; 34*d2c16535SElliott Hughes uint32_t j; 35*d2c16535SElliott Hughes uint32_t r; 36*d2c16535SElliott Hughes 37*d2c16535SElliott Hughes for (i = 0; i < 256; ++i) { 38*d2c16535SElliott Hughes r = i; 39*d2c16535SElliott Hughes for (j = 0; j < 8; ++j) 40*d2c16535SElliott Hughes r = (r >> 1) ^ (poly & ~((r & 1) - 1)); 41*d2c16535SElliott Hughes 42*d2c16535SElliott Hughes xz_crc32_table[i] = r; 43*d2c16535SElliott Hughes } 44*d2c16535SElliott Hughes 45*d2c16535SElliott Hughes return; 46*d2c16535SElliott Hughes } 47*d2c16535SElliott Hughes xz_crc32(const uint8_t * buf,size_t size,uint32_t crc)48*d2c16535SElliott HughesXZ_EXTERN uint32_t xz_crc32(const uint8_t *buf, size_t size, uint32_t crc) 49*d2c16535SElliott Hughes { 50*d2c16535SElliott Hughes crc = ~crc; 51*d2c16535SElliott Hughes 52*d2c16535SElliott Hughes while (size != 0) { 53*d2c16535SElliott Hughes crc = xz_crc32_table[*buf++ ^ (crc & 0xFF)] ^ (crc >> 8); 54*d2c16535SElliott Hughes --size; 55*d2c16535SElliott Hughes } 56*d2c16535SElliott Hughes 57*d2c16535SElliott Hughes return ~crc; 58*d2c16535SElliott Hughes } 59