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