1ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos/* 2ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos * crc16.c 3ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos * 4ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos * This source code is licensed under the GNU General Public License, 5ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos * Version 2. See the file COPYING for more details. 6ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos */ 7ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos 8d1154eb460efe588eaed3d439c1caaca149fa362Theodore Ts'o#include "config.h" 90eeec8ac61bf1eaa31533b2be825cd75580829c9Theodore Ts'o#if HAVE_SYS_TYPES_H 100eeec8ac61bf1eaa31533b2be825cd75580829c9Theodore Ts'o#include <sys/types.h> 110eeec8ac61bf1eaa31533b2be825cd75580829c9Theodore Ts'o#endif 120eeec8ac61bf1eaa31533b2be825cd75580829c9Theodore Ts'o#include <ext2fs/ext2_types.h> 130eeec8ac61bf1eaa31533b2be825cd75580829c9Theodore Ts'o 14ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos#include "crc16.h" 15ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos 16ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos/** CRC table for the CRC-16. The poly is 0x8005 (x16 + x15 + x2 + 1) */ 17c4dcb1c10ae5e3d523823fe0a2c84d0841ca2ea1Theodore Ts'ostatic __u16 const crc16_table[256] = { 18ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos 0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241, 19ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos 0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440, 20ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos 0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40, 21ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos 0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841, 22ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos 0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40, 23ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos 0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41, 24ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos 0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641, 25ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos 0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040, 26ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos 0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240, 27ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos 0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441, 28ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos 0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41, 29ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos 0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840, 30ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos 0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41, 31ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos 0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40, 32ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos 0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640, 33ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos 0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041, 34ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos 0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240, 35ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos 0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441, 36ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos 0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41, 37ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos 0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840, 38ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos 0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41, 39ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos 0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40, 40ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos 0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640, 41ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos 0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041, 42ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos 0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241, 43ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos 0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440, 44ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos 0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40, 45ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos 0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841, 46ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos 0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40, 47ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos 0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41, 48ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos 0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641, 49ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos 0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040 50ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos}; 51ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos 52ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos/** 53ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos * Compute the CRC-16 for the data buffer 54ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos * 55ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos * @param crc previous CRC value 56ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos * @param buffer data pointer 57ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos * @param len number of bytes in the buffer 58ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos * @return the updated CRC value 59ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos */ 60c4dcb1c10ae5e3d523823fe0a2c84d0841ca2ea1Theodore Ts'ocrc16_t ext2fs_crc16(crc16_t crc, const void *buffer, unsigned int len) 61ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos{ 62ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos const unsigned char *cp = buffer; 63ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos 64ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos while (len--) 65c4dcb1c10ae5e3d523823fe0a2c84d0841ca2ea1Theodore Ts'o /* 66c4dcb1c10ae5e3d523823fe0a2c84d0841ca2ea1Theodore Ts'o * for an unknown reason, PPC treats __u16 as signed 67c4dcb1c10ae5e3d523823fe0a2c84d0841ca2ea1Theodore Ts'o * and keeps doing sign extension on the value. 68c4dcb1c10ae5e3d523823fe0a2c84d0841ca2ea1Theodore Ts'o * Instead, use only the low 16 bits of an unsigned 69c4dcb1c10ae5e3d523823fe0a2c84d0841ca2ea1Theodore Ts'o * int for holding the CRC value to avoid this. 70c4dcb1c10ae5e3d523823fe0a2c84d0841ca2ea1Theodore Ts'o */ 71c4dcb1c10ae5e3d523823fe0a2c84d0841ca2ea1Theodore Ts'o crc = (((crc >> 8) & 0xffU) ^ 72c4dcb1c10ae5e3d523823fe0a2c84d0841ca2ea1Theodore Ts'o crc16_table[(crc ^ *cp++) & 0xffU]) & 0x0000ffffU; 73ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos return crc; 74ca2634a46ab9da85a3a015a7772770d9dbe5848eJose R. Santos} 75