crcutils.c revision 11015:0a0751599d31
138494Sobrien/* 2174294Sobrien * CDDL HEADER START 338494Sobrien * 438494Sobrien * The contents of this file are subject to the terms of the 538494Sobrien * Common Development and Distribution License (the "License"). 638494Sobrien * You may not use this file except in compliance with the License. 738494Sobrien * 838494Sobrien * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 938494Sobrien * or http://www.opensolaris.org/os/licensing. 1038494Sobrien * See the License for the specific language governing permissions 1138494Sobrien * and limitations under the License. 1238494Sobrien * 1338494Sobrien * When distributing Covered Code, include this CDDL HEADER in each 1438494Sobrien * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 1538494Sobrien * If applicable, add the following below this CDDL HEADER, with the 1638494Sobrien * fields enclosed by brackets "[]" replaced with your own identifying 1738494Sobrien * information: Portions Copyright [yyyy] [name of copyright owner] 1838494Sobrien * 1938494Sobrien * CDDL HEADER END 2042629Sobrien */ 2138494Sobrien 2238494Sobrien/* 2338494Sobrien * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 2438494Sobrien * Use is subject to license terms. 2538494Sobrien */ 2638494Sobrien 2738494Sobrien#include <string.h> 2838494Sobrien#include <limits.h> 2938494Sobrien 3038494Sobrien#include "crcmodel.h" 3138494Sobrien 3238494Sobrien#if defined(_LITTLE_ENDIAN) 3338494Sobrien 3438494Sobrien/* Little-endian architectures need byte-swapping. */ 3538494Sobrien 3638494Sobrien#define sws(x) (((x >> 8) & 0x00ff) | ((x << 8) & 0xff00)) 3738494Sobrien#define swl(x) (sws(x >> 16) | (sws(x) << 16)) 3838494Sobrien 3938494Sobrien#define swap_short(x) (x = sws(x)) 40174294Sobrien#define swap_long(x) (x = swl(x)) 4138494Sobrien 4238494Sobrien#else /* if !_LITTLE_ENDIAN */ 4338494Sobrien 4438494Sobrien/* Big-endian anchictectures don't need byte-swapping. */ 4538494Sobrien 4638494Sobrien#define sws(x) (x) 4738494Sobrien#define swl(x) (x) 4838494Sobrien 4938494Sobrien#define swap_short(x) (x = sws(x)) 5038494Sobrien#define swap_long(x) (x = swl(x)) 5138494Sobrien 5238494Sobrien#endif /* _LITTLE_ENDIAN */ 5338494Sobrien 5438494Sobrienunsigned char 5582794Sobriencompute_crc8(unsigned char *bytes, int length) 5638494Sobrien{ 5738494Sobrien cm_t crc_mdl; 5838494Sobrien p_cm_t p_crc; 5938494Sobrien int i; 6038494Sobrien unsigned char aCRC; 6138494Sobrien 6238494Sobrien p_crc = &crc_mdl; 6338494Sobrien 6482794Sobrien p_crc->cm_width = 8; 6538494Sobrien p_crc->cm_poly = 0x107; /* = X^8 + x^2 + x + 1 */ 6682794Sobrien p_crc->cm_init = 0; 6738494Sobrien p_crc->cm_refin = TRUE; 6838494Sobrien p_crc->cm_refot = TRUE; 6938494Sobrien p_crc->cm_xorot = 0; 7038494Sobrien 7182794Sobrien cm_ini(p_crc); 7238494Sobrien 7382794Sobrien for (i = 0; i < length; i++) { 7482794Sobrien cm_nxt(p_crc, bytes[i]); 7538494Sobrien } 7682794Sobrien 7782794Sobrien aCRC = (unsigned char)cm_crc(p_crc); 7838494Sobrien 7982794Sobrien return (aCRC); 8082794Sobrien} 8138494Sobrien 8282794Sobrienuint32_t 8382794Sobriencompute_crc32(unsigned char *bytes, int length) 8438494Sobrien{ 8582794Sobrien cm_t crc_mdl; 8682794Sobrien p_cm_t p_crc; 8738494Sobrien int i; 8882794Sobrien uint32_t aCRC; 8938494Sobrien 9038494Sobrien p_crc = &crc_mdl; 9138494Sobrien 9238494Sobrien p_crc->cm_width = 32; 9338494Sobrien p_crc->cm_poly = 0x04c11db7; 9438494Sobrien p_crc->cm_init = 0xffffffff; 9538494Sobrien p_crc->cm_refin = TRUE; 9638494Sobrien p_crc->cm_refot = TRUE; 9738494Sobrien p_crc->cm_xorot = 0xffffffff; 9838494Sobrien 9938494Sobrien cm_ini(p_crc); 10038494Sobrien 10138494Sobrien for (i = 0; i < length; i++) { 10238494Sobrien cm_nxt(p_crc, bytes[i]); 10338494Sobrien } 10438494Sobrien 10538494Sobrien aCRC = (uint32_t)cm_crc(p_crc); 10638494Sobrien 10738494Sobrien return (aCRC); 10838494Sobrien} 10938494Sobrien 11038494Sobrien/* 11138494Sobrien * This is the max value an uint32_t value can hold... 11238494Sobrien * Define this for Windows compilers which don't have "limits.h" or equivalant 11338494Sobrien */ 11438494Sobrien#define UINT32_T_MAX 0xFFFFFFFF 11538494Sobrien 11638494Sobrienuint32_t 11738494Sobriencompute_checksum32(unsigned char *bytes, int length) 11838494Sobrien{ 11938494Sobrien uint32_t regval = 0; 12038494Sobrien int i, j, k; 12138494Sobrien uint32_t next4bytes; 12238494Sobrien unsigned char tailbytes[4] = { 0x00, 0x00, 0x00, 0x00 }; 12338494Sobrien 12438494Sobrien /* Grab bytes in 4-byte chunks */ 125174294Sobrien for (i = 0; i < length-4; i += 4) { 12638494Sobrien /* Grab chunk as an int */ 12738494Sobrien (void) memcpy(&next4bytes, &(bytes[i]), 4); 12838494Sobrien swap_long(next4bytes); 129119679Smbr 13038494Sobrien if (next4bytes > UINT32_T_MAX - regval) { 13182794Sobrien next4bytes -= UINT32_T_MAX - regval; 13238494Sobrien regval = 0; 13382794Sobrien } 13482794Sobrien 13538494Sobrien /* Add intval to regval */ 13682794Sobrien regval += next4bytes; 13782794Sobrien } 13838494Sobrien 13982794Sobrien /* Grab any remaining bytes at the end */ 14082794Sobrien for (j = length-1, k = 3; j >= i; j--, k--) { 14138494Sobrien tailbytes[k] = bytes[j]; 14282794Sobrien } 14338494Sobrien 14438494Sobrien/* 14538494Sobrien * Treat any remaining bytes put into tailbytes as if they were 14638494Sobrien * a left-zero-padded unsigned int (uint32_t == 4 bytes!) 14738494Sobrien */ 148174294Sobrien (void) memcpy(&next4bytes, tailbytes, 4); 14938494Sobrien swap_long(next4bytes); 15038494Sobrien if (next4bytes > UINT32_T_MAX - regval) { 151174294Sobrien next4bytes -= UINT32_T_MAX - regval; 15238494Sobrien regval = 0; 15338494Sobrien } 15438494Sobrien regval += next4bytes; 155174294Sobrien 15638494Sobrien return ((uint32_t)regval); 157174294Sobrien} 158174294Sobrien