File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / sudo / zlib / crc32.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Feb 21 16:23:02 2012 UTC (12 years, 5 months ago) by misho
Branches: sudo, MAIN
CVS tags: v1_8_3p2, HEAD
sudo

    1: /* crc32.c -- compute the CRC-32 of a data stream
    2:  * Copyright (C) 1995-2006, 2010 Mark Adler
    3:  * For conditions of distribution and use, see copyright notice in zlib.h
    4:  *
    5:  * Thanks to Rodney Brown <rbrown64@csc.com.au> for his contribution of faster
    6:  * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing
    7:  * tables for updating the shift register in one step with three exclusive-ors
    8:  * instead of four steps with four exclusive-ors.  This results in about a
    9:  * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3.
   10:  */
   11: 
   12: /* @(#) $Id: crc32.c,v 1.1.1.1 2012/02/21 16:23:02 misho Exp $ */
   13: 
   14: /*
   15:   Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore
   16:   protection on the static variables used to control the first-use generation
   17:   of the crc tables.  Therefore, if you #define DYNAMIC_CRC_TABLE, you should
   18:   first call get_crc_table() to initialize the tables before allowing more than
   19:   one thread to use crc32().
   20:  */
   21: 
   22: #ifdef MAKECRCH
   23: #  include <stdio.h>
   24: #  ifndef DYNAMIC_CRC_TABLE
   25: #    define DYNAMIC_CRC_TABLE
   26: #  endif /* !DYNAMIC_CRC_TABLE */
   27: #endif /* MAKECRCH */
   28: 
   29: #include "zutil.h"      /* for STDC and FAR definitions */
   30: 
   31: #define local static
   32: 
   33: /* Find a four-byte integer type for crc32_little() and crc32_big(). */
   34: #ifndef NOBYFOUR
   35: #  ifdef STDC           /* need ANSI C limits.h to determine sizes */
   36: #    include <limits.h>
   37: #    define BYFOUR
   38: #    if (UINT_MAX == 0xffffffffUL)
   39:        typedef unsigned int u4;
   40: #    else
   41: #      if (ULONG_MAX == 0xffffffffUL)
   42:          typedef unsigned long u4;
   43: #      else
   44: #        if (USHRT_MAX == 0xffffffffUL)
   45:            typedef unsigned short u4;
   46: #        else
   47: #          undef BYFOUR     /* can't find a four-byte integer type! */
   48: #        endif
   49: #      endif
   50: #    endif
   51: #  endif /* STDC */
   52: #endif /* !NOBYFOUR */
   53: 
   54: /* Definitions for doing the crc four data bytes at a time. */
   55: #ifdef BYFOUR
   56: #  define REV(w) ((((w)>>24)&0xff)+(((w)>>8)&0xff00)+ \
   57:                 (((w)&0xff00)<<8)+(((w)&0xff)<<24))
   58:    local unsigned long crc32_little OF((unsigned long,
   59:                         const unsigned char FAR *, unsigned));
   60:    local unsigned long crc32_big OF((unsigned long,
   61:                         const unsigned char FAR *, unsigned));
   62: #  define TBLS 8
   63: #else
   64: #  define TBLS 1
   65: #endif /* BYFOUR */
   66: 
   67: /* Local functions for crc concatenation */
   68: local unsigned long gf2_matrix_times OF((unsigned long *mat,
   69:                                          unsigned long vec));
   70: local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat));
   71: local uLong crc32_combine_(uLong crc1, uLong crc2, z_off64_t len2);
   72: 
   73: 
   74: #ifdef DYNAMIC_CRC_TABLE
   75: 
   76: local volatile int crc_table_empty = 1;
   77: local unsigned long FAR crc_table[TBLS][256];
   78: local void make_crc_table OF((void));
   79: #ifdef MAKECRCH
   80:    local void write_table OF((FILE *, const unsigned long FAR *));
   81: #endif /* MAKECRCH */
   82: /*
   83:   Generate tables for a byte-wise 32-bit CRC calculation on the polynomial:
   84:   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.
   85: 
   86:   Polynomials over GF(2) are represented in binary, one bit per coefficient,
   87:   with the lowest powers in the most significant bit.  Then adding polynomials
   88:   is just exclusive-or, and multiplying a polynomial by x is a right shift by
   89:   one.  If we call the above polynomial p, and represent a byte as the
   90:   polynomial q, also with the lowest power in the most significant bit (so the
   91:   byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p,
   92:   where a mod b means the remainder after dividing a by b.
   93: 
   94:   This calculation is done using the shift-register method of multiplying and
   95:   taking the remainder.  The register is initialized to zero, and for each
   96:   incoming bit, x^32 is added mod p to the register if the bit is a one (where
   97:   x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by
   98:   x (which is shifting right by one and adding x^32 mod p if the bit shifted
   99:   out is a one).  We start with the highest power (least significant bit) of
  100:   q and repeat for all eight bits of q.
  101: 
  102:   The first table is simply the CRC of all possible eight bit values.  This is
  103:   all the information needed to generate CRCs on data a byte at a time for all
  104:   combinations of CRC register values and incoming bytes.  The remaining tables
  105:   allow for word-at-a-time CRC calculation for both big-endian and little-
  106:   endian machines, where a word is four bytes.
  107: */
  108: local void make_crc_table()
  109: {
  110:     unsigned long c;
  111:     int n, k;
  112:     unsigned long poly;                 /* polynomial exclusive-or pattern */
  113:     /* terms of polynomial defining this crc (except x^32): */
  114:     static volatile int first = 1;      /* flag to limit concurrent making */
  115:     static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
  116: 
  117:     /* See if another task is already doing this (not thread-safe, but better
  118:        than nothing -- significantly reduces duration of vulnerability in
  119:        case the advice about DYNAMIC_CRC_TABLE is ignored) */
  120:     if (first) {
  121:         first = 0;
  122: 
  123:         /* make exclusive-or pattern from polynomial (0xedb88320UL) */
  124:         poly = 0UL;
  125:         for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++)
  126:             poly |= 1UL << (31 - p[n]);
  127: 
  128:         /* generate a crc for every 8-bit value */
  129:         for (n = 0; n < 256; n++) {
  130:             c = (unsigned long)n;
  131:             for (k = 0; k < 8; k++)
  132:                 c = c & 1 ? poly ^ (c >> 1) : c >> 1;
  133:             crc_table[0][n] = c;
  134:         }
  135: 
  136: #ifdef BYFOUR
  137:         /* generate crc for each value followed by one, two, and three zeros,
  138:            and then the byte reversal of those as well as the first table */
  139:         for (n = 0; n < 256; n++) {
  140:             c = crc_table[0][n];
  141:             crc_table[4][n] = REV(c);
  142:             for (k = 1; k < 4; k++) {
  143:                 c = crc_table[0][c & 0xff] ^ (c >> 8);
  144:                 crc_table[k][n] = c;
  145:                 crc_table[k + 4][n] = REV(c);
  146:             }
  147:         }
  148: #endif /* BYFOUR */
  149: 
  150:         crc_table_empty = 0;
  151:     }
  152:     else {      /* not first */
  153:         /* wait for the other guy to finish (not efficient, but rare) */
  154:         while (crc_table_empty)
  155:             ;
  156:     }
  157: 
  158: #ifdef MAKECRCH
  159:     /* write out CRC tables to crc32.h */
  160:     {
  161:         FILE *out;
  162: 
  163:         out = fopen("crc32.h", "w");
  164:         if (out == NULL) return;
  165:         fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n");
  166:         fprintf(out, " * Generated automatically by crc32.c\n */\n\n");
  167:         fprintf(out, "local const unsigned long FAR ");
  168:         fprintf(out, "crc_table[TBLS][256] =\n{\n  {\n");
  169:         write_table(out, crc_table[0]);
  170: #  ifdef BYFOUR
  171:         fprintf(out, "#ifdef BYFOUR\n");
  172:         for (k = 1; k < 8; k++) {
  173:             fprintf(out, "  },\n  {\n");
  174:             write_table(out, crc_table[k]);
  175:         }
  176:         fprintf(out, "#endif\n");
  177: #  endif /* BYFOUR */
  178:         fprintf(out, "  }\n};\n");
  179:         fclose(out);
  180:     }
  181: #endif /* MAKECRCH */
  182: }
  183: 
  184: #ifdef MAKECRCH
  185: local void write_table(out, table)
  186:     FILE *out;
  187:     const unsigned long FAR *table;
  188: {
  189:     int n;
  190: 
  191:     for (n = 0; n < 256; n++)
  192:         fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : "    ", table[n],
  193:                 n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", "));
  194: }
  195: #endif /* MAKECRCH */
  196: 
  197: #else /* !DYNAMIC_CRC_TABLE */
  198: /* ========================================================================
  199:  * Tables of CRC-32s of all single-byte values, made by make_crc_table().
  200:  */
  201: #include "crc32.h"
  202: #endif /* DYNAMIC_CRC_TABLE */
  203: 
  204: /* =========================================================================
  205:  * This function can be used by asm versions of crc32()
  206:  */
  207: const unsigned long FAR * ZEXPORT get_crc_table()
  208: {
  209: #ifdef DYNAMIC_CRC_TABLE
  210:     if (crc_table_empty)
  211:         make_crc_table();
  212: #endif /* DYNAMIC_CRC_TABLE */
  213:     return (const unsigned long FAR *)crc_table;
  214: }
  215: 
  216: /* ========================================================================= */
  217: #define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8)
  218: #define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1
  219: 
  220: /* ========================================================================= */
  221: unsigned long ZEXPORT crc32(crc, buf, len)
  222:     unsigned long crc;
  223:     const unsigned char FAR *buf;
  224:     uInt len;
  225: {
  226:     if (buf == Z_NULL) return 0UL;
  227: 
  228: #ifdef DYNAMIC_CRC_TABLE
  229:     if (crc_table_empty)
  230:         make_crc_table();
  231: #endif /* DYNAMIC_CRC_TABLE */
  232: 
  233: #ifdef BYFOUR
  234:     if (sizeof(void *) == sizeof(ptrdiff_t)) {
  235:         u4 endian;
  236: 
  237:         endian = 1;
  238:         if (*((unsigned char *)(&endian)))
  239:             return crc32_little(crc, buf, len);
  240:         else
  241:             return crc32_big(crc, buf, len);
  242:     }
  243: #endif /* BYFOUR */
  244:     crc = crc ^ 0xffffffffUL;
  245:     while (len >= 8) {
  246:         DO8;
  247:         len -= 8;
  248:     }
  249:     if (len) do {
  250:         DO1;
  251:     } while (--len);
  252:     return crc ^ 0xffffffffUL;
  253: }
  254: 
  255: #ifdef BYFOUR
  256: 
  257: /* ========================================================================= */
  258: #define DOLIT4 c ^= *buf4++; \
  259:         c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \
  260:             crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24]
  261: #define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4
  262: 
  263: /* ========================================================================= */
  264: local unsigned long crc32_little(crc, buf, len)
  265:     unsigned long crc;
  266:     const unsigned char FAR *buf;
  267:     unsigned len;
  268: {
  269:     register u4 c;
  270:     register const u4 FAR *buf4;
  271: 
  272:     c = (u4)crc;
  273:     c = ~c;
  274:     while (len && ((ptrdiff_t)buf & 3)) {
  275:         c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
  276:         len--;
  277:     }
  278: 
  279:     buf4 = (const u4 FAR *)(const void FAR *)buf;
  280:     while (len >= 32) {
  281:         DOLIT32;
  282:         len -= 32;
  283:     }
  284:     while (len >= 4) {
  285:         DOLIT4;
  286:         len -= 4;
  287:     }
  288:     buf = (const unsigned char FAR *)buf4;
  289: 
  290:     if (len) do {
  291:         c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
  292:     } while (--len);
  293:     c = ~c;
  294:     return (unsigned long)c;
  295: }
  296: 
  297: /* ========================================================================= */
  298: #define DOBIG4 c ^= *++buf4; \
  299:         c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \
  300:             crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24]
  301: #define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4
  302: 
  303: /* ========================================================================= */
  304: local unsigned long crc32_big(crc, buf, len)
  305:     unsigned long crc;
  306:     const unsigned char FAR *buf;
  307:     unsigned len;
  308: {
  309:     register u4 c;
  310:     register const u4 FAR *buf4;
  311: 
  312:     c = REV((u4)crc);
  313:     c = ~c;
  314:     while (len && ((ptrdiff_t)buf & 3)) {
  315:         c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
  316:         len--;
  317:     }
  318: 
  319:     buf4 = (const u4 FAR *)(const void FAR *)buf;
  320:     buf4--;
  321:     while (len >= 32) {
  322:         DOBIG32;
  323:         len -= 32;
  324:     }
  325:     while (len >= 4) {
  326:         DOBIG4;
  327:         len -= 4;
  328:     }
  329:     buf4++;
  330:     buf = (const unsigned char FAR *)buf4;
  331: 
  332:     if (len) do {
  333:         c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
  334:     } while (--len);
  335:     c = ~c;
  336:     return (unsigned long)(REV(c));
  337: }
  338: 
  339: #endif /* BYFOUR */
  340: 
  341: #define GF2_DIM 32      /* dimension of GF(2) vectors (length of CRC) */
  342: 
  343: /* ========================================================================= */
  344: local unsigned long gf2_matrix_times(mat, vec)
  345:     unsigned long *mat;
  346:     unsigned long vec;
  347: {
  348:     unsigned long sum;
  349: 
  350:     sum = 0;
  351:     while (vec) {
  352:         if (vec & 1)
  353:             sum ^= *mat;
  354:         vec >>= 1;
  355:         mat++;
  356:     }
  357:     return sum;
  358: }
  359: 
  360: /* ========================================================================= */
  361: local void gf2_matrix_square(square, mat)
  362:     unsigned long *square;
  363:     unsigned long *mat;
  364: {
  365:     int n;
  366: 
  367:     for (n = 0; n < GF2_DIM; n++)
  368:         square[n] = gf2_matrix_times(mat, mat[n]);
  369: }
  370: 
  371: /* ========================================================================= */
  372: local uLong crc32_combine_(crc1, crc2, len2)
  373:     uLong crc1;
  374:     uLong crc2;
  375:     z_off64_t len2;
  376: {
  377:     int n;
  378:     unsigned long row;
  379:     unsigned long even[GF2_DIM];    /* even-power-of-two zeros operator */
  380:     unsigned long odd[GF2_DIM];     /* odd-power-of-two zeros operator */
  381: 
  382:     /* degenerate case (also disallow negative lengths) */
  383:     if (len2 <= 0)
  384:         return crc1;
  385: 
  386:     /* put operator for one zero bit in odd */
  387:     odd[0] = 0xedb88320UL;          /* CRC-32 polynomial */
  388:     row = 1;
  389:     for (n = 1; n < GF2_DIM; n++) {
  390:         odd[n] = row;
  391:         row <<= 1;
  392:     }
  393: 
  394:     /* put operator for two zero bits in even */
  395:     gf2_matrix_square(even, odd);
  396: 
  397:     /* put operator for four zero bits in odd */
  398:     gf2_matrix_square(odd, even);
  399: 
  400:     /* apply len2 zeros to crc1 (first square will put the operator for one
  401:        zero byte, eight zero bits, in even) */
  402:     do {
  403:         /* apply zeros operator for this bit of len2 */
  404:         gf2_matrix_square(even, odd);
  405:         if (len2 & 1)
  406:             crc1 = gf2_matrix_times(even, crc1);
  407:         len2 >>= 1;
  408: 
  409:         /* if no more bits set, then done */
  410:         if (len2 == 0)
  411:             break;
  412: 
  413:         /* another iteration of the loop with odd and even swapped */
  414:         gf2_matrix_square(odd, even);
  415:         if (len2 & 1)
  416:             crc1 = gf2_matrix_times(odd, crc1);
  417:         len2 >>= 1;
  418: 
  419:         /* if no more bits set, then done */
  420:     } while (len2 != 0);
  421: 
  422:     /* return combined crc */
  423:     crc1 ^= crc2;
  424:     return crc1;
  425: }
  426: 
  427: /* ========================================================================= */
  428: uLong ZEXPORT crc32_combine(crc1, crc2, len2)
  429:     uLong crc1;
  430:     uLong crc2;
  431:     z_off_t len2;
  432: {
  433:     return crc32_combine_(crc1, crc2, len2);
  434: }
  435: 
  436: uLong ZEXPORT crc32_combine64(crc1, crc2, len2)
  437:     uLong crc1;
  438:     uLong crc2;
  439:     z_off64_t len2;
  440: {
  441:     return crc32_combine_(crc1, crc2, len2);
  442: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>