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