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 2004 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include <sys/types.h> 30 31 /* 32 * Fast CRC32 calculation algorithm suggested by Ferenc Rakoczi 33 * (ferenc.rakoczi (at) sun.com). The basic idea is to look at it 34 * four bytes (one word) at a time, using four tables. The 35 * standard algorithm in RFC 3309 uses one table. 36 */ 37 38 /* 39 * SCTP uses reflected/reverse polynomial CRC32 with generating 40 * polynomial 0x1EDC6F41L 41 */ 42 #define SCTP_POLY 0x1EDC6F41L 43 44 /* The four CRC tables. */ 45 static uint32_t crctab[4][256]; 46 47 static uint32_t 48 reflect_32(uint32_t b) 49 { 50 int i; 51 uint32_t rw = 0; 52 53 for (i = 0; i < 32; i++) { 54 if (b & 1) { 55 rw |= 1 << (31 - i); 56 } 57 b >>= 1; 58 } 59 return (rw); 60 } 61 62 #ifdef _BIG_ENDIAN 63 64 /* 65 * This function is only used for big endian processor. 66 */ 67 static uint32_t 68 flip32(uint32_t w) 69 { 70 return (((w >> 24) | ((w >> 8) & 0xff00) | ((w << 8) & 0xff0000) | 71 (w << 24))); 72 } 73 74 #endif 75 76 void 77 sctp_crc32_init(void) 78 { 79 uint32_t i, j, k, crc; 80 81 for (i = 0; i < 256; i++) { 82 crc = reflect_32(i); 83 for (k = 0; k < 4; k++) { 84 for (j = 0; j < 8; j++) { 85 crc = (crc & 0x80000000) ? 86 (crc << 1) ^ SCTP_POLY : crc << 1; 87 } 88 #ifdef _BIG_ENDIAN 89 crctab[3 - k][i] = flip32(reflect_32(crc)); 90 #else 91 crctab[k][i] = reflect_32(crc); 92 #endif 93 } 94 } 95 } 96 97 static void 98 sctp_crc_byte(uint32_t *crcptr, const uint8_t *buf, int len) 99 { 100 uint32_t crc; 101 int i; 102 103 crc = *crcptr; 104 for (i = 0; i < len; i++) { 105 #ifdef _BIG_ENDIAN 106 crc = (crc << 8) ^ crctab[3][buf[i] ^ (crc >> 24)]; 107 #else 108 crc = (crc >> 8) ^ crctab[0][buf[i] ^ (crc & 0xff)]; 109 #endif 110 } 111 *crcptr = crc; 112 } 113 114 static void 115 sctp_crc_word(uint32_t *crcptr, const uint32_t *buf, int len) 116 { 117 uint32_t w, crc; 118 int i; 119 120 crc = *crcptr; 121 for (i = 0; i < len; i++) { 122 w = crc ^ buf[i]; 123 crc = crctab[0][w >> 24] ^ crctab[1][(w >> 16) & 0xff] ^ 124 crctab[2][(w >> 8) & 0xff] ^ crctab[3][w & 0xff]; 125 } 126 *crcptr = crc; 127 } 128 129 uint32_t 130 sctp_crc32(uint32_t crc32, const uint8_t *buf, int len) 131 { 132 int rem; 133 134 rem = 4 - ((uintptr_t)buf) & 3; 135 if (rem != 0) { 136 if (len < rem) { 137 rem = len; 138 } 139 sctp_crc_byte(&crc32, buf, rem); 140 buf = buf + rem; 141 len = len - rem; 142 } 143 144 if (len > 3) { 145 sctp_crc_word(&crc32, (const uint32_t *)buf, len / 4); 146 } 147 148 rem = len & 3; 149 if (rem != 0) { 150 sctp_crc_byte(&crc32, buf + len - rem, rem); 151 } 152 return (crc32); 153 } 154