Annotation of embedaddon/sudo/zlib/crc32.c, revision 1.1

1.1     ! misho       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$ */
        !            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>