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