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 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*7c478bd9Sstevel@tonic-gate 
29*7c478bd9Sstevel@tonic-gate #include <string.h>
30*7c478bd9Sstevel@tonic-gate #include <limits.h>
31*7c478bd9Sstevel@tonic-gate 
32*7c478bd9Sstevel@tonic-gate #include "crcmodel.h"
33*7c478bd9Sstevel@tonic-gate 
34*7c478bd9Sstevel@tonic-gate #if defined(LITTLE_ENDIAN)
35*7c478bd9Sstevel@tonic-gate 
36*7c478bd9Sstevel@tonic-gate /* Little-endian architectures need byte-swapping. */
37*7c478bd9Sstevel@tonic-gate 
38*7c478bd9Sstevel@tonic-gate #define	sws(x) (((x >> 8) & 0x00ff) | ((x << 8) & 0xff00))
39*7c478bd9Sstevel@tonic-gate #define	swl(x) (sws(x >> 16) | (sws(x) << 16))
40*7c478bd9Sstevel@tonic-gate 
41*7c478bd9Sstevel@tonic-gate #define	swap_short(x) (x = sws(x))
42*7c478bd9Sstevel@tonic-gate #define	swap_long(x) (x = swl(x))
43*7c478bd9Sstevel@tonic-gate 
44*7c478bd9Sstevel@tonic-gate #else   /* if !LITTLE_ENDIAN */
45*7c478bd9Sstevel@tonic-gate 
46*7c478bd9Sstevel@tonic-gate /* Big-endian anchictectures don't need byte-swapping. */
47*7c478bd9Sstevel@tonic-gate 
48*7c478bd9Sstevel@tonic-gate #define	sws(x) (x)
49*7c478bd9Sstevel@tonic-gate #define	swl(x) (x)
50*7c478bd9Sstevel@tonic-gate 
51*7c478bd9Sstevel@tonic-gate #define	swap_short(x) (x = sws(x))
52*7c478bd9Sstevel@tonic-gate #define	swap_long(x) (x = swl(x))
53*7c478bd9Sstevel@tonic-gate 
54*7c478bd9Sstevel@tonic-gate #endif  /* LITTLE_ENDIAN */
55*7c478bd9Sstevel@tonic-gate 
56*7c478bd9Sstevel@tonic-gate unsigned char
compute_crc8(unsigned char * bytes,int length)57*7c478bd9Sstevel@tonic-gate compute_crc8(unsigned char *bytes, int length)
58*7c478bd9Sstevel@tonic-gate {
59*7c478bd9Sstevel@tonic-gate 	cm_t crc_mdl;
60*7c478bd9Sstevel@tonic-gate 	p_cm_t p_crc;
61*7c478bd9Sstevel@tonic-gate 	int i;
62*7c478bd9Sstevel@tonic-gate 	unsigned char aCRC;
63*7c478bd9Sstevel@tonic-gate 
64*7c478bd9Sstevel@tonic-gate 	p_crc = &crc_mdl;
65*7c478bd9Sstevel@tonic-gate 
66*7c478bd9Sstevel@tonic-gate 	p_crc->cm_width = 8;
67*7c478bd9Sstevel@tonic-gate 	p_crc->cm_poly = 0x107; /* = X^8 + x^2 + x + 1 */
68*7c478bd9Sstevel@tonic-gate 	p_crc->cm_init = 0;
69*7c478bd9Sstevel@tonic-gate 	p_crc->cm_refin = TRUE;
70*7c478bd9Sstevel@tonic-gate 	p_crc->cm_refot = TRUE;
71*7c478bd9Sstevel@tonic-gate 	p_crc->cm_xorot = 0;
72*7c478bd9Sstevel@tonic-gate 
73*7c478bd9Sstevel@tonic-gate 	cm_ini(p_crc);
74*7c478bd9Sstevel@tonic-gate 
75*7c478bd9Sstevel@tonic-gate 	for (i = 0; i < length; i++) {
76*7c478bd9Sstevel@tonic-gate 		cm_nxt(p_crc, bytes[i]);
77*7c478bd9Sstevel@tonic-gate 	}
78*7c478bd9Sstevel@tonic-gate 
79*7c478bd9Sstevel@tonic-gate 	aCRC = (unsigned char)cm_crc(p_crc);
80*7c478bd9Sstevel@tonic-gate 
81*7c478bd9Sstevel@tonic-gate 	return (aCRC);
82*7c478bd9Sstevel@tonic-gate }
83*7c478bd9Sstevel@tonic-gate 
84*7c478bd9Sstevel@tonic-gate uint32_t
compute_crc32(unsigned char * bytes,int length)85*7c478bd9Sstevel@tonic-gate compute_crc32(unsigned char *bytes, int length)
86*7c478bd9Sstevel@tonic-gate {
87*7c478bd9Sstevel@tonic-gate 	cm_t crc_mdl;
88*7c478bd9Sstevel@tonic-gate 	p_cm_t p_crc;
89*7c478bd9Sstevel@tonic-gate 	int i;
90*7c478bd9Sstevel@tonic-gate 	uint32_t aCRC;
91*7c478bd9Sstevel@tonic-gate 
92*7c478bd9Sstevel@tonic-gate 	p_crc = &crc_mdl;
93*7c478bd9Sstevel@tonic-gate 
94*7c478bd9Sstevel@tonic-gate 	p_crc->cm_width = 32;
95*7c478bd9Sstevel@tonic-gate 	p_crc->cm_poly = 0x04c11db7;
96*7c478bd9Sstevel@tonic-gate 	p_crc->cm_init = 0xffffffff;
97*7c478bd9Sstevel@tonic-gate 	p_crc->cm_refin = TRUE;
98*7c478bd9Sstevel@tonic-gate 	p_crc->cm_refot = TRUE;
99*7c478bd9Sstevel@tonic-gate 	p_crc->cm_xorot = 0xffffffff;
100*7c478bd9Sstevel@tonic-gate 
101*7c478bd9Sstevel@tonic-gate 	cm_ini(p_crc);
102*7c478bd9Sstevel@tonic-gate 
103*7c478bd9Sstevel@tonic-gate 	for (i = 0; i < length; i++) {
104*7c478bd9Sstevel@tonic-gate 		cm_nxt(p_crc, bytes[i]);
105*7c478bd9Sstevel@tonic-gate 	}
106*7c478bd9Sstevel@tonic-gate 
107*7c478bd9Sstevel@tonic-gate 	aCRC = (uint32_t)cm_crc(p_crc);
108*7c478bd9Sstevel@tonic-gate 
109*7c478bd9Sstevel@tonic-gate 	return (aCRC);
110*7c478bd9Sstevel@tonic-gate }
111*7c478bd9Sstevel@tonic-gate 
112*7c478bd9Sstevel@tonic-gate /*
113*7c478bd9Sstevel@tonic-gate  * This is the max value an uint32_t value can hold...
114*7c478bd9Sstevel@tonic-gate  * Define this for Windows compilers which don't have "limits.h" or equivalant
115*7c478bd9Sstevel@tonic-gate  */
116*7c478bd9Sstevel@tonic-gate #define	UINT32_T_MAX 0xFFFFFFFF
117*7c478bd9Sstevel@tonic-gate 
118*7c478bd9Sstevel@tonic-gate uint32_t
compute_checksum32(unsigned char * bytes,int length)119*7c478bd9Sstevel@tonic-gate compute_checksum32(unsigned char *bytes, int length)
120*7c478bd9Sstevel@tonic-gate {
121*7c478bd9Sstevel@tonic-gate 	uint32_t regval = 0;
122*7c478bd9Sstevel@tonic-gate 	int i, j, k;
123*7c478bd9Sstevel@tonic-gate 	uint32_t next4bytes;
124*7c478bd9Sstevel@tonic-gate 	unsigned char tailbytes[4] = { 0x00, 0x00, 0x00, 0x00 };
125*7c478bd9Sstevel@tonic-gate 
126*7c478bd9Sstevel@tonic-gate 	/* Grab bytes in 4-byte chunks */
127*7c478bd9Sstevel@tonic-gate 	for (i = 0; i < length-4; i += 4) {
128*7c478bd9Sstevel@tonic-gate 		/* Grab chunk as an int */
129*7c478bd9Sstevel@tonic-gate 		(void) memcpy(&next4bytes, &(bytes[i]), 4);
130*7c478bd9Sstevel@tonic-gate 		swap_long(next4bytes);
131*7c478bd9Sstevel@tonic-gate 
132*7c478bd9Sstevel@tonic-gate 		if (next4bytes > UINT32_T_MAX - regval) {
133*7c478bd9Sstevel@tonic-gate 			next4bytes -= UINT32_T_MAX - regval;
134*7c478bd9Sstevel@tonic-gate 			regval = 0;
135*7c478bd9Sstevel@tonic-gate 		}
136*7c478bd9Sstevel@tonic-gate 
137*7c478bd9Sstevel@tonic-gate 		/* Add intval to regval */
138*7c478bd9Sstevel@tonic-gate 		regval += next4bytes;
139*7c478bd9Sstevel@tonic-gate 	}
140*7c478bd9Sstevel@tonic-gate 
141*7c478bd9Sstevel@tonic-gate 	/* Grab any remaining bytes at the end */
142*7c478bd9Sstevel@tonic-gate 	for (j = length-1, k = 3; j >= i; j--, k--) {
143*7c478bd9Sstevel@tonic-gate 		tailbytes[k] = bytes[j];
144*7c478bd9Sstevel@tonic-gate 	}
145*7c478bd9Sstevel@tonic-gate 
146*7c478bd9Sstevel@tonic-gate /*
147*7c478bd9Sstevel@tonic-gate  * Treat any remaining bytes put into tailbytes as if they were
148*7c478bd9Sstevel@tonic-gate  * a left-zero-padded unsigned int (uint32_t == 4 bytes!)
149*7c478bd9Sstevel@tonic-gate  */
150*7c478bd9Sstevel@tonic-gate 	(void) memcpy(&next4bytes, tailbytes, 4);
151*7c478bd9Sstevel@tonic-gate 	swap_long(next4bytes);
152*7c478bd9Sstevel@tonic-gate 	if (next4bytes > UINT32_T_MAX - regval) {
153*7c478bd9Sstevel@tonic-gate 		next4bytes -= UINT32_T_MAX - regval;
154*7c478bd9Sstevel@tonic-gate 		regval = 0;
155*7c478bd9Sstevel@tonic-gate 	}
156*7c478bd9Sstevel@tonic-gate 	regval += next4bytes;
157*7c478bd9Sstevel@tonic-gate 
158*7c478bd9Sstevel@tonic-gate 	return ((uint32_t)regval);
159*7c478bd9Sstevel@tonic-gate }
160