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