1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate  * with the License.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate  * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate  *
20*7c478bd9Sstevel@tonic-gate  * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate  */
22*7c478bd9Sstevel@tonic-gate /*
23*7c478bd9Sstevel@tonic-gate  * Copyright (c) 2000 by Sun Microsystems, Inc.
24*7c478bd9Sstevel@tonic-gate  * All rights reserved.
25*7c478bd9Sstevel@tonic-gate  */
26*7c478bd9Sstevel@tonic-gate 
27*7c478bd9Sstevel@tonic-gate #include <string.h>
28*7c478bd9Sstevel@tonic-gate #include <limits.h>
29*7c478bd9Sstevel@tonic-gate 
30*7c478bd9Sstevel@tonic-gate #include "crcmodel.h"
31*7c478bd9Sstevel@tonic-gate 
32*7c478bd9Sstevel@tonic-gate #if defined(LITTLE_ENDIAN)
33*7c478bd9Sstevel@tonic-gate 
34*7c478bd9Sstevel@tonic-gate /* Little-endian architectures need byte-swapping. */
35*7c478bd9Sstevel@tonic-gate 
36*7c478bd9Sstevel@tonic-gate #define	sws(x) (((x >> 8) & 0x00ff) | ((x << 8) & 0xff00))
37*7c478bd9Sstevel@tonic-gate #define	swl(x) (sws(x >> 16) | (sws(x) << 16))
38*7c478bd9Sstevel@tonic-gate 
39*7c478bd9Sstevel@tonic-gate #define	swap_short(x) (x = sws(x))
40*7c478bd9Sstevel@tonic-gate #define	swap_long(x) (x = swl(x))
41*7c478bd9Sstevel@tonic-gate 
42*7c478bd9Sstevel@tonic-gate #else   /* if !LITTLE_ENDIAN */
43*7c478bd9Sstevel@tonic-gate 
44*7c478bd9Sstevel@tonic-gate /* Big-endian anchictectures don't need byte-swapping. */
45*7c478bd9Sstevel@tonic-gate 
46*7c478bd9Sstevel@tonic-gate #define	sws(x) (x)
47*7c478bd9Sstevel@tonic-gate #define	swl(x) (x)
48*7c478bd9Sstevel@tonic-gate 
49*7c478bd9Sstevel@tonic-gate #define	swap_short(x) (x = sws(x))
50*7c478bd9Sstevel@tonic-gate #define	swap_long(x) (x = swl(x))
51*7c478bd9Sstevel@tonic-gate 
52*7c478bd9Sstevel@tonic-gate #endif  /* LITTLE_ENDIAN */
53*7c478bd9Sstevel@tonic-gate 
54*7c478bd9Sstevel@tonic-gate unsigned char
compute_crc8(unsigned char * bytes,int length)55*7c478bd9Sstevel@tonic-gate compute_crc8(unsigned char *bytes, int length)
56*7c478bd9Sstevel@tonic-gate {
57*7c478bd9Sstevel@tonic-gate 	cm_t crc_mdl;
58*7c478bd9Sstevel@tonic-gate 	p_cm_t p_crc;
59*7c478bd9Sstevel@tonic-gate 	int i;
60*7c478bd9Sstevel@tonic-gate 	unsigned char aCRC;
61*7c478bd9Sstevel@tonic-gate 
62*7c478bd9Sstevel@tonic-gate 	p_crc = &crc_mdl;
63*7c478bd9Sstevel@tonic-gate 
64*7c478bd9Sstevel@tonic-gate 	p_crc->cm_width = 8;
65*7c478bd9Sstevel@tonic-gate 	p_crc->cm_poly = 0x107; /* = X^8 + x^2 + x + 1 */
66*7c478bd9Sstevel@tonic-gate 	p_crc->cm_init = 0;
67*7c478bd9Sstevel@tonic-gate 	p_crc->cm_refin = TRUE;
68*7c478bd9Sstevel@tonic-gate 	p_crc->cm_refot = TRUE;
69*7c478bd9Sstevel@tonic-gate 	p_crc->cm_xorot = 0;
70*7c478bd9Sstevel@tonic-gate 
71*7c478bd9Sstevel@tonic-gate 	cm_ini(p_crc);
72*7c478bd9Sstevel@tonic-gate 
73*7c478bd9Sstevel@tonic-gate 	for (i = 0; i < length; i++) {
74*7c478bd9Sstevel@tonic-gate 		cm_nxt(p_crc, bytes[i]);
75*7c478bd9Sstevel@tonic-gate 	}
76*7c478bd9Sstevel@tonic-gate 
77*7c478bd9Sstevel@tonic-gate 	aCRC = (unsigned char)cm_crc(p_crc);
78*7c478bd9Sstevel@tonic-gate 
79*7c478bd9Sstevel@tonic-gate 	return (aCRC);
80*7c478bd9Sstevel@tonic-gate }
81*7c478bd9Sstevel@tonic-gate 
82*7c478bd9Sstevel@tonic-gate uint32_t
compute_crc32(unsigned char * bytes,int length)83*7c478bd9Sstevel@tonic-gate compute_crc32(unsigned char *bytes, int length)
84*7c478bd9Sstevel@tonic-gate {
85*7c478bd9Sstevel@tonic-gate 	cm_t crc_mdl;
86*7c478bd9Sstevel@tonic-gate 	p_cm_t p_crc;
87*7c478bd9Sstevel@tonic-gate 	int i;
88*7c478bd9Sstevel@tonic-gate 	uint32_t aCRC;
89*7c478bd9Sstevel@tonic-gate 
90*7c478bd9Sstevel@tonic-gate 	p_crc = &crc_mdl;
91*7c478bd9Sstevel@tonic-gate 
92*7c478bd9Sstevel@tonic-gate 	p_crc->cm_width = 32;
93*7c478bd9Sstevel@tonic-gate 	p_crc->cm_poly = 0x04c11db7;
94*7c478bd9Sstevel@tonic-gate 	p_crc->cm_init = 0xffffffff;
95*7c478bd9Sstevel@tonic-gate 	p_crc->cm_refin = TRUE;
96*7c478bd9Sstevel@tonic-gate 	p_crc->cm_refot = TRUE;
97*7c478bd9Sstevel@tonic-gate 	p_crc->cm_xorot = 0xffffffff;
98*7c478bd9Sstevel@tonic-gate 
99*7c478bd9Sstevel@tonic-gate 	cm_ini(p_crc);
100*7c478bd9Sstevel@tonic-gate 
101*7c478bd9Sstevel@tonic-gate 	for (i = 0; i < length; i++) {
102*7c478bd9Sstevel@tonic-gate 		cm_nxt(p_crc, bytes[i]);
103*7c478bd9Sstevel@tonic-gate 	}
104*7c478bd9Sstevel@tonic-gate 
105*7c478bd9Sstevel@tonic-gate 	aCRC = (uint32_t)cm_crc(p_crc);
106*7c478bd9Sstevel@tonic-gate 
107*7c478bd9Sstevel@tonic-gate 	return (aCRC);
108*7c478bd9Sstevel@tonic-gate }
109*7c478bd9Sstevel@tonic-gate 
110*7c478bd9Sstevel@tonic-gate /*
111*7c478bd9Sstevel@tonic-gate  * This is the max value an uint32_t value can hold...
112*7c478bd9Sstevel@tonic-gate  * Define this for Windows compilers which don't have "limits.h" or equivalant
113*7c478bd9Sstevel@tonic-gate  */
114*7c478bd9Sstevel@tonic-gate #define	UINT32_T_MAX 0xFFFFFFFF
115*7c478bd9Sstevel@tonic-gate 
116*7c478bd9Sstevel@tonic-gate uint32_t
compute_checksum32(unsigned char * bytes,int length)117*7c478bd9Sstevel@tonic-gate compute_checksum32(unsigned char *bytes, int length)
118*7c478bd9Sstevel@tonic-gate {
119*7c478bd9Sstevel@tonic-gate 	uint32_t regval = 0;
120*7c478bd9Sstevel@tonic-gate 	int i, j, k;
121*7c478bd9Sstevel@tonic-gate 	uint32_t next4bytes;
122*7c478bd9Sstevel@tonic-gate 	unsigned char tailbytes[4] = { 0x00, 0x00, 0x00, 0x00 };
123*7c478bd9Sstevel@tonic-gate 
124*7c478bd9Sstevel@tonic-gate 	/* Grab bytes in 4-byte chunks */
125*7c478bd9Sstevel@tonic-gate 	for (i = 0; i < length-4; i += 4) {
126*7c478bd9Sstevel@tonic-gate 		/* Grab chunk as an int */
127*7c478bd9Sstevel@tonic-gate 		(void) memcpy(&next4bytes, &(bytes[i]), 4);
128*7c478bd9Sstevel@tonic-gate 		swap_long(next4bytes);
129*7c478bd9Sstevel@tonic-gate 
130*7c478bd9Sstevel@tonic-gate 		if (next4bytes > UINT32_T_MAX - regval) {
131*7c478bd9Sstevel@tonic-gate 			next4bytes -= UINT32_T_MAX - regval;
132*7c478bd9Sstevel@tonic-gate 			regval = 0;
133*7c478bd9Sstevel@tonic-gate 		}
134*7c478bd9Sstevel@tonic-gate 
135*7c478bd9Sstevel@tonic-gate 		/* Add intval to regval */
136*7c478bd9Sstevel@tonic-gate 		regval += next4bytes;
137*7c478bd9Sstevel@tonic-gate 	}
138*7c478bd9Sstevel@tonic-gate 
139*7c478bd9Sstevel@tonic-gate 	/* Grab any remaining bytes at the end */
140*7c478bd9Sstevel@tonic-gate 	for (j = length-1, k = 3; j >= i; j--, k--) {
141*7c478bd9Sstevel@tonic-gate 		tailbytes[k] = bytes[j];
142*7c478bd9Sstevel@tonic-gate 	}
143*7c478bd9Sstevel@tonic-gate 
144*7c478bd9Sstevel@tonic-gate /*
145*7c478bd9Sstevel@tonic-gate  * Treat any remaining bytes put into tailbytes as if they were
146*7c478bd9Sstevel@tonic-gate  * a left-zero-padded unsigned int (uint32_t == 4 bytes!)
147*7c478bd9Sstevel@tonic-gate  */
148*7c478bd9Sstevel@tonic-gate 	(void) memcpy(&next4bytes, tailbytes, 4);
149*7c478bd9Sstevel@tonic-gate 	swap_long(next4bytes);
150*7c478bd9Sstevel@tonic-gate 	if (next4bytes > UINT32_T_MAX - regval) {
151*7c478bd9Sstevel@tonic-gate 		next4bytes -= UINT32_T_MAX - regval;
152*7c478bd9Sstevel@tonic-gate 		regval = 0;
153*7c478bd9Sstevel@tonic-gate 	}
154*7c478bd9Sstevel@tonic-gate 	regval += next4bytes;
155*7c478bd9Sstevel@tonic-gate 
156*7c478bd9Sstevel@tonic-gate 	return ((uint32_t)regval);
157*7c478bd9Sstevel@tonic-gate }
158