13984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt/*
23984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt *      crc16.c
33984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt *
43984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * This source code is licensed under the GNU General Public License,
53984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * Version 2. See the file COPYING for more details.
63984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt */
73984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
83984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#if HAVE_SYS_TYPES_H
93984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#include <sys/types.h>
103984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#endif
113984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#include <ext2fs/ext2_types.h>
123984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
133984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#include "crc16.h"
143984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
153984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt/** CRC table for the CRC-16. The poly is 0x8005 (x16 + x15 + x2 + 1) */
163984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtstatic __u16 const crc16_table[256] = {
173984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
183984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
193984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
203984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
213984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
223984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
233984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
243984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
253984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
263984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
273984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
283984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
293984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
303984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
313984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
323984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
333984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
343984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
353984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
363984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
373984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
383984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
393984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
403984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
413984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
423984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
433984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
443984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
453984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
463984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
473984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
483984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040
493984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt};
503984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
513984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt/**
523984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * Compute the CRC-16 for the data buffer
533984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt *
543984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * @param crc     previous CRC value
553984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * @param buffer  data pointer
563984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * @param len     number of bytes in the buffer
573984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * @return        the updated CRC value
583984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt */
593984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtcrc16_t ext2fs_crc16(crc16_t crc, const void *buffer, unsigned int len)
603984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt{
613984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	const unsigned char *cp = buffer;
623984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
633984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	while (len--)
643984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		/*
653984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		 * for an unknown reason, PPC treats __u16 as signed
663984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		 * and keeps doing sign extension on the value.
673984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		 * Instead, use only the low 16 bits of an unsigned
683984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		 * int for holding the CRC value to avoid this.
693984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		 */
703984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		crc = (((crc >> 8) & 0xffU) ^
713984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		       crc16_table[(crc ^ *cp++) & 0xffU]) & 0x0000ffffU;
723984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	return crc;
733984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt}
74