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