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