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