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 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 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 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