1b33c96954667ba382fa595baf7b31290bfdd517vboxsync/* crc32.c -- compute the CRC-32 of a data stream
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync * Copyright (C) 1995-2006, 2010, 2011 Mark Adler
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync * For conditions of distribution and use, see copyright notice in zlib.h
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync *
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync * Thanks to Rodney Brown <rbrown64@csc.com.au> for his contribution of faster
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync * tables for updating the shift register in one step with three exclusive-ors
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync * instead of four steps with four exclusive-ors. This results in about a
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3.
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync/* @(#) $Id$ */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync/*
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync protection on the static variables used to control the first-use generation
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync first call get_crc_table() to initialize the tables before allowing more than
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync one thread to use crc32().
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync DYNAMIC_CRC_TABLE and MAKECRCH can be #defined to write out crc32.h.
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync#ifdef MAKECRCH
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync# include <stdio.h>
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync# ifndef DYNAMIC_CRC_TABLE
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync# define DYNAMIC_CRC_TABLE
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync# endif /* !DYNAMIC_CRC_TABLE */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync#endif /* MAKECRCH */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync#include "zutil.h" /* for STDC and FAR definitions */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync#define local static
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync/* Find a four-byte integer type for crc32_little() and crc32_big(). */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync#ifndef NOBYFOUR
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync# ifdef STDC /* need ANSI C limits.h to determine sizes */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync# include <limits.h>
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync# define BYFOUR
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync# if (UINT_MAX == 0xffffffffUL)
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync typedef unsigned int u4;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync# else
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync# if (ULONG_MAX == 0xffffffffUL)
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync typedef unsigned long u4;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync# else
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync# if (USHRT_MAX == 0xffffffffUL)
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync typedef unsigned short u4;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync# else
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync# undef BYFOUR /* can't find a four-byte integer type! */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync# endif
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync# endif
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync# endif
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync# endif /* STDC */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync#endif /* !NOBYFOUR */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync/* Definitions for doing the crc four data bytes at a time. */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync#ifdef BYFOUR
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync typedef u4 crc_table_t;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync# define REV(w) ((((w)>>24)&0xff)+(((w)>>8)&0xff00)+ \
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync (((w)&0xff00)<<8)+(((w)&0xff)<<24))
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync local unsigned long crc32_little OF((unsigned long,
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync const unsigned char FAR *, unsigned));
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync local unsigned long crc32_big OF((unsigned long,
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync const unsigned char FAR *, unsigned));
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync# define TBLS 8
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync#else
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync typedef unsigned long crc_table_t;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync# define TBLS 1
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync#endif /* BYFOUR */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync/* Local functions for crc concatenation */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsynclocal unsigned long gf2_matrix_times OF((unsigned long *mat,
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync unsigned long vec));
1b33c96954667ba382fa595baf7b31290bfdd517vboxsynclocal void gf2_matrix_square OF((unsigned long *square, unsigned long *mat));
1b33c96954667ba382fa595baf7b31290bfdd517vboxsynclocal uLong crc32_combine_ OF((uLong crc1, uLong crc2, z_off64_t len2));
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync#ifdef DYNAMIC_CRC_TABLE
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsynclocal volatile int crc_table_empty = 1;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsynclocal crc_table_t FAR crc_table[TBLS][256];
1b33c96954667ba382fa595baf7b31290bfdd517vboxsynclocal void make_crc_table OF((void));
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync#ifdef MAKECRCH
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync local void write_table OF((FILE *, const crc_table_t FAR *));
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync#endif /* MAKECRCH */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync/*
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync Generate tables for a byte-wise 32-bit CRC calculation on the polynomial:
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync Polynomials over GF(2) are represented in binary, one bit per coefficient,
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync with the lowest powers in the most significant bit. Then adding polynomials
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync is just exclusive-or, and multiplying a polynomial by x is a right shift by
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync one. If we call the above polynomial p, and represent a byte as the
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync polynomial q, also with the lowest power in the most significant bit (so the
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p,
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync where a mod b means the remainder after dividing a by b.
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync This calculation is done using the shift-register method of multiplying and
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync taking the remainder. The register is initialized to zero, and for each
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync incoming bit, x^32 is added mod p to the register if the bit is a one (where
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync x (which is shifting right by one and adding x^32 mod p if the bit shifted
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync out is a one). We start with the highest power (least significant bit) of
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync q and repeat for all eight bits of q.
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync The first table is simply the CRC of all possible eight bit values. This is
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync all the information needed to generate CRCs on data a byte at a time for all
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync combinations of CRC register values and incoming bytes. The remaining tables
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync allow for word-at-a-time CRC calculation for both big-endian and little-
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync endian machines, where a word is four bytes.
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync*/
1b33c96954667ba382fa595baf7b31290bfdd517vboxsynclocal void make_crc_table()
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync{
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync crc_table_t c;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync int n, k;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync crc_table_t poly; /* polynomial exclusive-or pattern */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync /* terms of polynomial defining this crc (except x^32): */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync static volatile int first = 1; /* flag to limit concurrent making */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync /* See if another task is already doing this (not thread-safe, but better
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync than nothing -- significantly reduces duration of vulnerability in
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync case the advice about DYNAMIC_CRC_TABLE is ignored) */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync if (first) {
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync first = 0;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync /* make exclusive-or pattern from polynomial (0xedb88320UL) */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync poly = 0;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync for (n = 0; n < (int)(sizeof(p)/sizeof(unsigned char)); n++)
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync poly |= (crc_table_t)1 << (31 - p[n]);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync /* generate a crc for every 8-bit value */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync for (n = 0; n < 256; n++) {
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync c = (crc_table_t)n;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync for (k = 0; k < 8; k++)
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync c = c & 1 ? poly ^ (c >> 1) : c >> 1;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync crc_table[0][n] = c;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync }
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync#ifdef BYFOUR
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync /* generate crc for each value followed by one, two, and three zeros,
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync and then the byte reversal of those as well as the first table */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync for (n = 0; n < 256; n++) {
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync c = crc_table[0][n];
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync crc_table[4][n] = REV(c);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync for (k = 1; k < 4; k++) {
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync c = crc_table[0][c & 0xff] ^ (c >> 8);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync crc_table[k][n] = c;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync crc_table[k + 4][n] = REV(c);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync }
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync }
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync#endif /* BYFOUR */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync crc_table_empty = 0;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync }
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync else { /* not first */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync /* wait for the other guy to finish (not efficient, but rare) */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync while (crc_table_empty)
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync ;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync }
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync#ifdef MAKECRCH
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync /* write out CRC tables to crc32.h */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync {
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync FILE *out;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync out = fopen("crc32.h", "w");
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync if (out == NULL) return;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n");
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync fprintf(out, " * Generated automatically by crc32.c\n */\n\n");
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync fprintf(out, "local const crc_table_t FAR ");
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync fprintf(out, "crc_table[TBLS][256] =\n{\n {\n");
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync write_table(out, crc_table[0]);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync# ifdef BYFOUR
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync fprintf(out, "#ifdef BYFOUR\n");
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync for (k = 1; k < 8; k++) {
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync fprintf(out, " },\n {\n");
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync write_table(out, crc_table[k]);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync }
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync fprintf(out, "#endif\n");
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync# endif /* BYFOUR */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync fprintf(out, " }\n};\n");
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync fclose(out);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync }
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync#endif /* MAKECRCH */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync}
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync#ifdef MAKECRCH
1b33c96954667ba382fa595baf7b31290bfdd517vboxsynclocal void write_table(out, table)
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync FILE *out;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync const crc_table_t FAR *table;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync{
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync int n;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync for (n = 0; n < 256; n++)
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ",
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync (unsigned long)(table[n]),
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", "));
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync}
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync#endif /* MAKECRCH */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync#else /* !DYNAMIC_CRC_TABLE */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync/* ========================================================================
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync * Tables of CRC-32s of all single-byte values, made by make_crc_table().
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync#include "crc32.h"
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync#endif /* DYNAMIC_CRC_TABLE */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync/* =========================================================================
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync * This function can be used by asm versions of crc32()
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsyncconst unsigned long FAR * ZEXPORT get_crc_table()
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync{
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync#ifdef DYNAMIC_CRC_TABLE
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync if (crc_table_empty)
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync make_crc_table();
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync#endif /* DYNAMIC_CRC_TABLE */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync return (const unsigned long FAR *)crc_table;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync}
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync/* ========================================================================= */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8)
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync/* ========================================================================= */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsyncunsigned long ZEXPORT crc32(crc, buf, len)
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync unsigned long crc;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync const unsigned char FAR *buf;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync uInt len;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync{
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync if (buf == Z_NULL) return 0UL;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync#ifdef DYNAMIC_CRC_TABLE
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync if (crc_table_empty)
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync make_crc_table();
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync#endif /* DYNAMIC_CRC_TABLE */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync#ifdef BYFOUR
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync if (sizeof(void *) == sizeof(ptrdiff_t)) {
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync u4 endian;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync endian = 1;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync if (*((unsigned char *)(&endian)))
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync return crc32_little(crc, buf, len);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync else
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync return crc32_big(crc, buf, len);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync }
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync#endif /* BYFOUR */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync crc = crc ^ 0xffffffffUL;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync while (len >= 8) {
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync DO8;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync len -= 8;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync }
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync if (len) do {
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync DO1;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync } while (--len);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync return crc ^ 0xffffffffUL;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync}
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync#ifdef BYFOUR
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync/* ========================================================================= */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync#define DOLIT4 c ^= *buf4++; \
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24]
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync/* ========================================================================= */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsynclocal unsigned long crc32_little(crc, buf, len)
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync unsigned long crc;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync const unsigned char FAR *buf;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync unsigned len;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync{
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync register u4 c;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync register const u4 FAR *buf4;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync c = (u4)crc;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync c = ~c;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync while (len && ((ptrdiff_t)buf & 3)) {
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync len--;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync }
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync buf4 = (const u4 FAR *)(const void FAR *)buf;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync while (len >= 32) {
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync DOLIT32;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync len -= 32;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync }
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync while (len >= 4) {
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync DOLIT4;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync len -= 4;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync }
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync buf = (const unsigned char FAR *)buf4;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync if (len) do {
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync } while (--len);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync c = ~c;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync return (unsigned long)c;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync}
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync/* ========================================================================= */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync#define DOBIG4 c ^= *++buf4; \
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24]
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync/* ========================================================================= */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsynclocal unsigned long crc32_big(crc, buf, len)
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync unsigned long crc;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync const unsigned char FAR *buf;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync unsigned len;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync{
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync register u4 c;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync register const u4 FAR *buf4;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync c = REV((u4)crc);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync c = ~c;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync while (len && ((ptrdiff_t)buf & 3)) {
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync len--;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync }
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync buf4 = (const u4 FAR *)(const void FAR *)buf;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync buf4--;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync while (len >= 32) {
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync DOBIG32;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync len -= 32;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync }
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync while (len >= 4) {
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync DOBIG4;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync len -= 4;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync }
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync buf4++;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync buf = (const unsigned char FAR *)buf4;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync if (len) do {
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync } while (--len);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync c = ~c;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync return (unsigned long)(REV(c));
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync}
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync#endif /* BYFOUR */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync#define GF2_DIM 32 /* dimension of GF(2) vectors (length of CRC) */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync/* ========================================================================= */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsynclocal unsigned long gf2_matrix_times(mat, vec)
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync unsigned long *mat;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync unsigned long vec;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync{
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync unsigned long sum;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync sum = 0;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync while (vec) {
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync if (vec & 1)
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync sum ^= *mat;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync vec >>= 1;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync mat++;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync }
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync return sum;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync}
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync/* ========================================================================= */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsynclocal void gf2_matrix_square(square, mat)
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync unsigned long *square;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync unsigned long *mat;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync{
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync int n;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync for (n = 0; n < GF2_DIM; n++)
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync square[n] = gf2_matrix_times(mat, mat[n]);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync}
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync/* ========================================================================= */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsynclocal uLong crc32_combine_(crc1, crc2, len2)
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync uLong crc1;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync uLong crc2;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync z_off64_t len2;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync{
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync int n;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync unsigned long row;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync unsigned long even[GF2_DIM]; /* even-power-of-two zeros operator */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync unsigned long odd[GF2_DIM]; /* odd-power-of-two zeros operator */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync /* degenerate case (also disallow negative lengths) */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync if (len2 <= 0)
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync return crc1;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync /* put operator for one zero bit in odd */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync odd[0] = 0xedb88320UL; /* CRC-32 polynomial */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync row = 1;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync for (n = 1; n < GF2_DIM; n++) {
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync odd[n] = row;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync row <<= 1;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync }
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync /* put operator for two zero bits in even */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync gf2_matrix_square(even, odd);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync /* put operator for four zero bits in odd */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync gf2_matrix_square(odd, even);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync /* apply len2 zeros to crc1 (first square will put the operator for one
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync zero byte, eight zero bits, in even) */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync do {
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync /* apply zeros operator for this bit of len2 */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync gf2_matrix_square(even, odd);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync if (len2 & 1)
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync crc1 = gf2_matrix_times(even, crc1);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync len2 >>= 1;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync /* if no more bits set, then done */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync if (len2 == 0)
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync break;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync /* another iteration of the loop with odd and even swapped */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync gf2_matrix_square(odd, even);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync if (len2 & 1)
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync crc1 = gf2_matrix_times(odd, crc1);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync len2 >>= 1;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync /* if no more bits set, then done */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync } while (len2 != 0);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync /* return combined crc */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync crc1 ^= crc2;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync return crc1;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync}
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync/* ========================================================================= */
1b33c96954667ba382fa595baf7b31290bfdd517vboxsyncuLong ZEXPORT crc32_combine(crc1, crc2, len2)
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync uLong crc1;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync uLong crc2;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync z_off_t len2;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync{
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync return crc32_combine_(crc1, crc2, len2);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync}
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync
1b33c96954667ba382fa595baf7b31290bfdd517vboxsyncuLong ZEXPORT crc32_combine64(crc1, crc2, len2)
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync uLong crc1;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync uLong crc2;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync z_off64_t len2;
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync{
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync return crc32_combine_(crc1, crc2, len2);
1b33c96954667ba382fa595baf7b31290bfdd517vboxsync}