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