xref: /rkdeveloptool/crc.cpp (revision 5b7562f2de7374e1e6d47cfc37120a2d9cd243f1)
1 /*
2  * (C) Copyright 2017 Fuzhou Rockchip Electronics Co., Ltd
3  * Seth Liu 2017.03.01
4  *
5  * SPDX-License-Identifier:	GPL-2.0+
6  */
7 #include "DefineHeader.h"
8 UINT gTable_Crc32[256] =
9 {//crfc32 factor 0x04C10DB7
10 		0x00000000, 0x04c10db7, 0x09821b6e, 0x0d4316d9,
11 		0x130436dc, 0x17c53b6b, 0x1a862db2, 0x1e472005,
12 		0x26086db8, 0x22c9600f, 0x2f8a76d6, 0x2b4b7b61,
13 		0x350c5b64, 0x31cd56d3, 0x3c8e400a, 0x384f4dbd,
14 		0x4c10db70, 0x48d1d6c7, 0x4592c01e, 0x4153cda9,
15 		0x5f14edac, 0x5bd5e01b, 0x5696f6c2, 0x5257fb75,
16 		0x6a18b6c8, 0x6ed9bb7f, 0x639aada6, 0x675ba011,
17 		0x791c8014, 0x7ddd8da3, 0x709e9b7a, 0x745f96cd,
18 		0x9821b6e0, 0x9ce0bb57, 0x91a3ad8e, 0x9562a039,
19 		0x8b25803c, 0x8fe48d8b, 0x82a79b52, 0x866696e5,
20 		0xbe29db58, 0xbae8d6ef, 0xb7abc036, 0xb36acd81,
21 		0xad2ded84, 0xa9ece033, 0xa4aff6ea, 0xa06efb5d,
22 		0xd4316d90, 0xd0f06027, 0xddb376fe, 0xd9727b49,
23 		0xc7355b4c, 0xc3f456fb, 0xceb74022, 0xca764d95,
24 		0xf2390028, 0xf6f80d9f, 0xfbbb1b46, 0xff7a16f1,
25 		0xe13d36f4, 0xe5fc3b43, 0xe8bf2d9a, 0xec7e202d,
26 		0x34826077, 0x30436dc0, 0x3d007b19, 0x39c176ae,
27 		0x278656ab, 0x23475b1c, 0x2e044dc5, 0x2ac54072,
28 		0x128a0dcf, 0x164b0078, 0x1b0816a1, 0x1fc91b16,
29 		0x018e3b13, 0x054f36a4, 0x080c207d, 0x0ccd2dca,
30 		0x7892bb07, 0x7c53b6b0, 0x7110a069, 0x75d1adde,
31 		0x6b968ddb, 0x6f57806c, 0x621496b5, 0x66d59b02,
32 		0x5e9ad6bf, 0x5a5bdb08, 0x5718cdd1, 0x53d9c066,
33 		0x4d9ee063, 0x495fedd4, 0x441cfb0d, 0x40ddf6ba,
34 		0xaca3d697, 0xa862db20, 0xa521cdf9, 0xa1e0c04e,
35 		0xbfa7e04b, 0xbb66edfc, 0xb625fb25, 0xb2e4f692,
36 		0x8aabbb2f, 0x8e6ab698, 0x8329a041, 0x87e8adf6,
37 		0x99af8df3, 0x9d6e8044, 0x902d969d, 0x94ec9b2a,
38 		0xe0b30de7, 0xe4720050, 0xe9311689, 0xedf01b3e,
39 		0xf3b73b3b, 0xf776368c, 0xfa352055, 0xfef42de2,
40 		0xc6bb605f, 0xc27a6de8, 0xcf397b31, 0xcbf87686,
41 		0xd5bf5683, 0xd17e5b34, 0xdc3d4ded, 0xd8fc405a,
42 		0x6904c0ee, 0x6dc5cd59, 0x6086db80, 0x6447d637,
43 		0x7a00f632, 0x7ec1fb85, 0x7382ed5c, 0x7743e0eb,
44 		0x4f0cad56, 0x4bcda0e1, 0x468eb638, 0x424fbb8f,
45 		0x5c089b8a, 0x58c9963d, 0x558a80e4, 0x514b8d53,
46 		0x25141b9e, 0x21d51629, 0x2c9600f0, 0x28570d47,
47 		0x36102d42, 0x32d120f5, 0x3f92362c, 0x3b533b9b,
48 		0x031c7626, 0x07dd7b91, 0x0a9e6d48, 0x0e5f60ff,
49 		0x101840fa, 0x14d94d4d, 0x199a5b94, 0x1d5b5623,
50 		0xf125760e, 0xf5e47bb9, 0xf8a76d60, 0xfc6660d7,
51 		0xe22140d2, 0xe6e04d65, 0xeba35bbc, 0xef62560b,
52 		0xd72d1bb6, 0xd3ec1601, 0xdeaf00d8, 0xda6e0d6f,
53 		0xc4292d6a, 0xc0e820dd, 0xcdab3604, 0xc96a3bb3,
54 		0xbd35ad7e, 0xb9f4a0c9, 0xb4b7b610, 0xb076bba7,
55 		0xae319ba2, 0xaaf09615, 0xa7b380cc, 0xa3728d7b,
56 		0x9b3dc0c6, 0x9ffccd71, 0x92bfdba8, 0x967ed61f,
57 		0x8839f61a, 0x8cf8fbad, 0x81bbed74, 0x857ae0c3,
58 		0x5d86a099, 0x5947ad2e, 0x5404bbf7, 0x50c5b640,
59 		0x4e829645, 0x4a439bf2, 0x47008d2b, 0x43c1809c,
60 		0x7b8ecd21, 0x7f4fc096, 0x720cd64f, 0x76cddbf8,
61 		0x688afbfd, 0x6c4bf64a, 0x6108e093, 0x65c9ed24,
62 		0x11967be9, 0x1557765e, 0x18146087, 0x1cd56d30,
63 		0x02924d35, 0x06534082, 0x0b10565b, 0x0fd15bec,
64 		0x379e1651, 0x335f1be6, 0x3e1c0d3f, 0x3add0088,
65 		0x249a208d, 0x205b2d3a, 0x2d183be3, 0x29d93654,
66 		0xc5a71679, 0xc1661bce, 0xcc250d17, 0xc8e400a0,
67 		0xd6a320a5, 0xd2622d12, 0xdf213bcb, 0xdbe0367c,
68 		0xe3af7bc1, 0xe76e7676, 0xea2d60af, 0xeeec6d18,
69 		0xf0ab4d1d, 0xf46a40aa, 0xf9295673, 0xfde85bc4,
70 		0x89b7cd09, 0x8d76c0be, 0x8035d667, 0x84f4dbd0,
71 		0x9ab3fbd5, 0x9e72f662, 0x9331e0bb, 0x97f0ed0c,
72 		0xafbfa0b1, 0xab7ead06, 0xa63dbbdf, 0xa2fcb668,
73 		0xbcbb966d, 0xb87a9bda, 0xb5398d03, 0xb1f880b4,
74 };
75 #define rr_max  104	/* Number of parity checks, rr = deg[g(x)] */
76 #define parallel 8 //bit count
77 #define mm 13//limit count
78 #define nn 8191//code size
79 #define kk 4120//info length
80 #define tt 8//correct count
81 
82 #define tt2 2*tt
83 UINT s[tt2+1]; // Syndrome values
84 
85 UINT rr;//redundant length		// BCH code parameters
86 
87 
88 UINT p[mm + 1];
89 UINT alpha_to[nn+1], index_of[nn+1] ;	// Galois field
90 UINT gg[rr_max+1] ;		// Generator polynomial
91 
92 UINT ggx1=0;
93 UINT ggx2=0;
94 UINT ggx3=0;
95 UINT ggx4=0;
96 // get crc32 value
97 UINT CRC_32(unsigned char* pData, UINT ulSize)
98 {
99     UINT i;
100     UINT nAccum = 0;
101 
102     for ( i=0; i<ulSize; i++)
103         nAccum = (nAccum<<8)^gTable_Crc32[(nAccum>>24)^(*pData++)];
104     return nAccum;
105 }
106 #define CRC16_CCITT         0x1021  //CRC operator
107 void CRCBuildTable16(unsigned short aPoly , unsigned short *crcTable)
108 {
109     unsigned short i, j;
110     unsigned short nData;
111     unsigned short nAccum;
112 
113     for (i = 0; i < 256; i++)
114     {
115         nData = (unsigned short)(i << 8);
116         nAccum = 0;
117         for (j = 0; j < 8; j++)
118         {
119             if ((nData ^ nAccum) & 0x8000)
120                 nAccum = (nAccum << 1) ^ aPoly;
121             else
122                 nAccum <<= 1;
123             nData <<= 1;
124         }
125         crcTable[i] = nAccum;
126     }
127 }
128 
129 unsigned short CRC_16(unsigned char* aData, UINT aSize)
130 {
131     UINT i;
132     unsigned short nAccum = 0;
133     unsigned short crcTable[256];
134 
135     CRCBuildTable16(CRC16_CCITT , crcTable);
136     for (i = 0; i < aSize; i++)
137         nAccum = (nAccum << 8) ^ crcTable[(nAccum >> 8) ^ *aData++];
138 
139     return nAccum;
140 }
141 
142 void P_RC4(unsigned char* buf, unsigned short len)
143 {
144 	unsigned char S[256],K[256],temp;
145 	unsigned short i,j,t,x;
146 	unsigned char key[16]={124,78,3,4,85,5,9,7,45,44,123,56,23,13,23,17};
147 
148 	j = 0;
149 	for(i=0; i<256; i++){
150 		S[i] = (unsigned char)i;
151 		j&=0x0f;
152 		K[i] = key[j];
153 		j++;
154 	}
155 
156 	j = 0;
157 	for(i=0; i<256; i++){
158 		j = (j + S[i] + K[i]) % 256;
159 		temp = S[i];
160 		S[i] = S[j];
161 		S[j] = temp;
162 	}
163 
164 	i = j = 0;
165 	for(x=0; x<len; x++){
166 		i = (i+1) % 256;
167 		j = (j + S[i]) % 256;
168 		temp = S[i];
169 		S[i] = S[j];
170 		S[j] = temp;
171 		t = (S[i] + (S[j] % 256)) % 256;
172 		buf[x] = buf[x] ^ S[t];
173 	}
174 }
175 
176 void bch_encode(unsigned char* encode_in, unsigned char* encode_out)
177 {
178 	UINT i,j;
179 	bool feed_back;
180 	UINT bch1=0;
181 	UINT bch2=0;
182 	UINT bch3=0;
183 	UINT bch4=0;
184 
185 	for (i=0;i<515;i++)
186 	{
187 		for (j=0;j<8;j++)
188 		{
189 			feed_back = (bch1&1) ^ ((encode_in[i]>>j) & 1);
190 			bch1=((bch1>>1)|((bch2&1)*0x80000000))^(ggx1*feed_back);
191 			bch2=((bch2>>1)|((bch3&1)*0x80000000))^(ggx2*feed_back);
192 			bch3=((bch3>>1)|((bch4&1)*0x80000000))^(ggx3*feed_back);
193 			bch4=(((bch4>>1)^(ggx4*feed_back))) | (feed_back*0x80);
194 		}
195 	}
196 
197 	//********Handle FF***********************
198 	bch1 = ~(bch1 ^ 0xad6273b1);
199 	bch2 = ~(bch2 ^ 0x348393d2);
200 	bch3 = ~(bch3 ^ 0xe6ebed3c);
201 	bch4 = ~(bch4 ^ 0xc8);
202 	//*********************************************
203 
204 	for (i=0;i<515;i++)
205 		encode_out[i] = encode_in[i];
206 	encode_out[515] = bch1&0x000000ff;
207 	encode_out[516] = (bch1&0x0000ff00)>>8;
208 	encode_out[517] = (bch1&0x00ff0000)>>16;
209 	encode_out[518] = (bch1&0xff000000)>>24;
210 	encode_out[519] = bch2&0x000000ff;
211 	encode_out[520] = (bch2&0x0000ff00)>>8;
212 	encode_out[521] = (bch2&0x00ff0000)>>16;
213 	encode_out[522] = (bch2&0xff000000)>>24;
214 	encode_out[523] = bch3&0x000000ff;
215 	encode_out[524] = (bch3&0x0000ff00)>>8;
216 	encode_out[525] = (bch3&0x00ff0000)>>16;
217 	encode_out[526] = (bch3&0xff000000)>>24;
218 	encode_out[527] = bch4&0x000000ff;
219 }
220 
221 #define poly16_CCITT	0x1021          /* crc-ccitt mask */
222 
223 unsigned short CRC_Calculate(unsigned short crc, unsigned char ch)
224 {
225 	UINT i;
226 	for(i=0x80; i!=0; i>>=1)
227 	{
228 		if((crc & 0x8000) != 0)
229 		{
230 			crc <<= 1;
231 			crc ^= poly16_CCITT;
232 		}
233 		else
234 			crc <<= 1;
235 		if((ch & i)!=0)
236 			crc ^= poly16_CCITT;
237 	}
238 	return crc;
239 }
240 unsigned short CRC_CCITT(unsigned char* p, UINT CalculateNumber)
241 {
242     unsigned short crc = 0xffff;
243     while(CalculateNumber--)
244 	{
245 		crc = CRC_Calculate(crc, *p);
246 		p++;
247     }
248     return crc;
249 }
250 void gen_poly()
251 {
252 	UINT gen_roots[nn + 1], gen_roots_true[nn + 1] ; 	// Roots of generator polynomial
253 	UINT i, j, Temp ;
254 
255 // Initialization of gen_roots
256 	for (i = 0; i <= nn; i++)
257 	{	gen_roots_true[i] = 0;
258 		gen_roots[i] = 0;
259 	}
260 
261 // Cyclotomic cosets of gen_roots
262 	for (i = 1; i <= 2*tt ; i++)
263 	{
264 		for (j = 0; j < mm; j++)
265 		{
266 			Temp = ((1<<j)*i)%nn;
267 			gen_roots_true[Temp] = 1;
268 		}
269 	}
270 	rr = 0;		// Count thenumber of parity check bits
271 	for (i = 0; i < nn; i++)
272 	{
273 		if (gen_roots_true[i] == 1)
274 		{
275 			rr++;
276 			gen_roots[rr] = i;
277 		}
278 	}
279 // Compute generator polynomial based on its roots
280 	gg[0] = 2 ;	// g(x) = (X + alpha) initially
281 	gg[1] = 1 ;
282 	for (i = 2; i <= rr; i++)
283 	{
284 		gg[i] = 1 ;
285 		for (j = i - 1; j > 0; j--)
286 			if (gg[j] != 0)
287 				gg[j] = gg[j-1]^ alpha_to[(index_of[gg[j]] + index_of[alpha_to[gen_roots[i]]]) % nn] ;
288 			else
289 				gg[j] = gg[j-1] ;
290 		gg[0] = alpha_to[(index_of[gg[0]] + index_of[alpha_to[gen_roots[i]]]) % nn] ;
291 	}
292 
293 ggx1 = gg[103] | (gg[102]<<1) | (gg[101]<<2) | (gg[100]<<3) | (gg[99]<<4) |(gg[98]<<5)| (gg[97]<<6)|(gg[96]<<7)
294 	| (gg[95]<<8) | (gg[94]<<9) | (gg[93]<<10) | (gg[92]<<11) |(gg[91]<<12)| (gg[90]<<13)|(gg[89]<<14) |(gg[88]<<15)
295 	| (gg[87]<<16) | (gg[86]<<17) | (gg[85]<<18) | (gg[84]<<19) | (gg[83]<<20) |(gg[82]<<21)| (gg[81]<<22)|(gg[80]<<23)
296 	| (gg[79]<<24) | (gg[78]<<25) | (gg[77]<<26) | (gg[76]<<27) |(gg[75]<<28)| (gg[74]<<29)|(gg[73]<<30) |(gg[72]<<31);
297 ggx2 = gg[71] | (gg[70]<<1) | (gg[69]<<2) | (gg[68]<<3) | (gg[67]<<4) |(gg[66]<<5)| (gg[65]<<6)|(gg[64]<<7)
298 	| (gg[63]<<8) | (gg[62]<<9) | (gg[61]<<10) | (gg[60]<<11) |(gg[59]<<12)| (gg[58]<<13)|(gg[57]<<14) |(gg[56]<<15)
299 	| (gg[55]<<16) | (gg[54]<<17) | (gg[53]<<18) | (gg[52]<<19) | (gg[51]<<20) |(gg[50]<<21)| (gg[49]<<22)|(gg[48]<<23)
300 	| (gg[47]<<24) | (gg[46]<<25) | (gg[45]<<26) | (gg[44]<<27) |(gg[43]<<28)| (gg[42]<<29)|(gg[41]<<30) |(gg[40]<<31);
301 ggx3 = gg[39] | (gg[38]<<1) | (gg[37]<<2) | (gg[36]<<3) | (gg[35]<<4) |(gg[34]<<5)| (gg[33]<<6)|(gg[32]<<7)
302 	| (gg[31]<<8) | (gg[30]<<9) | (gg[29]<<10) | (gg[28]<<11) |(gg[27]<<12)| (gg[26]<<13)|(gg[25]<<14) |(gg[24]<<15)
303 	| (gg[23]<<16) | (gg[22]<<17) | (gg[21]<<18) | (gg[20]<<19) | (gg[19]<<20) |(gg[18]<<21)| (gg[17]<<22)|(gg[16]<<23)
304 	| (gg[15]<<24) | (gg[14]<<25) | (gg[13]<<26) | (gg[12]<<27) |(gg[11]<<28)| (gg[10]<<29)|(gg[9]<<30) |(gg[8]<<31);
305 ggx4 = gg[7] | (gg[6]<<1) | (gg[5]<<2) | (gg[4]<<3) | (gg[3]<<4) |(gg[2]<<5)| (gg[1]<<6);
306 
307 }
308 
309 void generate_gf()
310 {
311 	UINT i;
312 	UINT mask ;	// Register states
313 
314 	// Primitive polynomials
315 	for (i = 1; i < mm; i++)
316 		p[i] = 0;
317 	p[0] = p[mm] = 1;
318 	if (mm == 2)		p[1] = 1;
319 	else if (mm == 3)	p[1] = 1;
320 	else if (mm == 4)	p[1] = 1;
321 	else if (mm == 5)	p[2] = 1;
322 	else if (mm == 6)	p[1] = 1;
323 	else if (mm == 7)	p[1] = 1;
324 	else if (mm == 8)	p[4] = p[5] = p[6] = 1;
325 	else if (mm == 9)	p[4] = 1;
326 	else if (mm == 10)	p[3] = 1;
327 	else if (mm == 11)	p[2] = 1;
328 	else if (mm == 12)	p[3] = p[4] = p[7] = 1;
329 	else if (mm == 13)	p[1] = p[2] = p[3] = p[5] = p[7] = p[8] = p[10] = 1;	// 25AF
330 	else if (mm == 14)	p[2] = p[4] = p[6] = p[7] = p[8] = 1;	// 41D5
331 	else if (mm == 15)	p[1] = 1;
332 	else if (mm == 16)	p[2] = p[3] = p[5] = 1;
333 	else if (mm == 17)	p[3] = 1;
334 	else if (mm == 18)	p[7] = 1;
335 	else if (mm == 19)	p[1] = p[5] = p[6] = 1;
336 	else if (mm == 20)	p[3] = 1;
337 	// Galois field implementation with shift registers
338 	// Ref: L&C, Chapter 6.7, pp. 217
339 	mask = 1 ;
340 	alpha_to[mm] = 0 ;
341 	for (i = 0; i < mm; i++)
342 	{
343 		alpha_to[i] = mask ;
344 		index_of[alpha_to[i]] = i ;
345 		if (p[i] != 0)
346 			alpha_to[mm] ^= mask ;
347 		mask <<= 1 ;
348 	}
349 
350 	index_of[alpha_to[mm]] = mm ;
351 	mask >>= 1 ;
352 	for (i = mm + 1; i < nn; i++)
353 	{
354 		if (alpha_to[i-1] >= mask)
355 			alpha_to[i] = alpha_to[mm] ^ ((alpha_to[i-1] ^ mask) << 1) ;
356 		else
357 			alpha_to[i] = alpha_to[i-1] << 1 ;
358 
359 		index_of[alpha_to[i]] = i ;
360 	}
361 	index_of[0] = -1 ;
362 }