1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - MATH -
3   File:     crc.c
4 
5   Copyright 2003-2008 Nintendo. All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain
8   proprietary information of Nintendo of America Inc. and/or Nintendo
9   Company Ltd., and are protected by Federal copyright law. They may
10   not be disclosed to third parties or copied or duplicated in any form,
11   in whole or in part, without the prior written consent of Nintendo.
12 
13   $Date:: 2008-09-18#$
14   $Rev: 8573 $
15   $Author:$
16  *---------------------------------------------------------------------------*/
17 
18 #include <nitro/math/crc.h>
19 
20 /*****************************************************************************/
21 /* CRC-8 common                                                                */
22 /*****************************************************************************/
23 
24 /*---------------------------------------------------------------------------*
25   Name:         MATHi_CRC8InitTable
26 
27   Description:  Initializes the MATHCRC8Table structure used for requesting the CRC-8 value.
28 
29   Arguments:    table: MATHCRC8Table structure.
30                 poly:  Bit representation of the generator polynomial with the top bit removed.
31 
32   Returns:      None.
33  *---------------------------------------------------------------------------*/
MATHi_CRC8InitTable(MATHCRC8Table * table,u8 poly)34 void MATHi_CRC8InitTable(MATHCRC8Table * table, u8 poly)
35 {
36     u32     r;
37     u32     i, j;
38     u8     *t = table->table;
39 
40     for (i = 0; i < 256; i++)
41     {
42         r = i;
43         for (j = 0; j < 8; j++)
44         {
45             if (r & 0x80)
46             {
47                 r = (r << 1) ^ poly;
48             }
49             else
50             {
51                 r <<= 1;
52             }
53         }
54         t[i] = (u8)r;
55     }
56 }
57 
58 /*---------------------------------------------------------------------------*
59   Name:         MATHi_CRC8InitTableRev
60 
61   Description:  Initializes the MATHCRC8Table structure used for requesting the CRC-8 value.
62                 The lower-order bit is handled as the higher-order digit.
63 
64   Arguments:    table: MATHCRC8Table structure.
65                 poly:  Inverted bit representation of the generator polynomial with the top bit removed.
66 
67 
68   Returns:      None.
69  *---------------------------------------------------------------------------*/
MATHi_CRC8InitTableRev(MATHCRC8Table * table,u8 poly)70 void MATHi_CRC8InitTableRev(MATHCRC8Table * table, u8 poly)
71 {
72     u32     r;
73     u32     i, j;
74     u8     *t = table->table;
75 
76     for (i = 0; i < 256; i++)
77     {
78         r = i;
79         for (j = 0; j < 8; j++)
80         {
81             if (r & 1)
82             {
83                 r = (r >> 1) ^ poly;
84             }
85             else
86             {
87                 r >>= 1;
88             }
89         }
90         t[i] = (u8)r;
91     }
92 }
93 
94 /*---------------------------------------------------------------------------*
95   Name:         MATHi_CRC8Update
96 
97   Description:  Updates the CRC-8 value with added data.
98 
99   Arguments:    table:   Pointer to the table for calculation, MATHCRC8Table.
100                 context:  MATHCRC8Context structure.
101                 input:   Pointer to input data.
102                 length:  Length of input data.
103 
104   Returns:      None.
105  *---------------------------------------------------------------------------*/
106 void
MATHi_CRC8Update(const MATHCRC8Table * table,MATHCRC8Context * context,const void * input,u32 length)107 MATHi_CRC8Update(const MATHCRC8Table * table, MATHCRC8Context * context, const void *input,
108                  u32 length)
109 {
110     u32     r;
111     u32     i;
112     const u8 *t = table->table;
113     u8     *data = (u8 *)input;
114 
115     r = (u32)*context;
116     for (i = 0; i < length; i++)
117     {
118         r = t[(r ^ *data) & 0xff];
119         data++;
120     }
121     *context = (MATHCRC8Context) r;
122 }
123 
124 /*****************************************************************************/
125 /* CRC-16 common                                                               */
126 /*****************************************************************************/
127 
128 /*---------------------------------------------------------------------------*
129   Name:         MATHi_CRC16InitTable
130 
131   Description:  Initializes the MATHCRC16Table structure used for requesting the CRC-16 value.
132 
133   Arguments:    table:  MATHCRC16Table structure.
134                 poly:  Bit representation of the generator polynomial with the top bit removed.
135 
136   Returns:      None.
137  *---------------------------------------------------------------------------*/
MATHi_CRC16InitTable(MATHCRC16Table * table,u16 poly)138 void MATHi_CRC16InitTable(MATHCRC16Table * table, u16 poly)
139 {
140     u32     r;
141     u32     i, j;
142     u16    *t = table->table;
143 
144     for (i = 0; i < 256; i++)
145     {
146         r = i << 8;
147         for (j = 0; j < 8; j++)
148         {
149             if (r & 0x8000)
150             {
151                 r = (r << 1) ^ poly;
152             }
153             else
154             {
155                 r <<= 1;
156             }
157         }
158         t[i] = (u16)r;
159     }
160 }
161 
162 /*---------------------------------------------------------------------------*
163   Name:         MATHi_CRC16InitTableRev
164 
165   Description:  Initializes the MATHCRC16Table structure used for requesting the CRC-16 value.
166                 The lower-order bit is handled as the higher-order digit.
167 
168   Arguments:    table:  MATHCRC16Table structure.
169                 poly:  Inverted bit representation of the generator polynomial with the top bit removed.
170 
171 
172   Returns:      None.
173  *---------------------------------------------------------------------------*/
MATHi_CRC16InitTableRev(MATHCRC16Table * table,u16 poly)174 void MATHi_CRC16InitTableRev(MATHCRC16Table * table, u16 poly)
175 {
176     u32     r;
177     u32     i, j;
178     u16    *t = table->table;
179 
180     for (i = 0; i < 256; i++)
181     {
182         r = i;
183         for (j = 0; j < 8; j++)
184         {
185             if (r & 1)
186             {
187                 r = (r >> 1) ^ poly;
188             }
189             else
190             {
191                 r >>= 1;
192             }
193         }
194         t[i] = (u16)r;
195     }
196 }
197 
198 /*---------------------------------------------------------------------------*
199   Name:         MATHi_CRC16Update
200 
201   Description:  Updates the CRC-16 value with added data.
202 
203   Arguments:    table:   Pointer to the table for calculation, MATHCRC16Table.
204                 context:   MATHCRC16Context structure.
205                 input:   Pointer to input data.
206                 length:  Length of input data.
207 
208   Returns:      None.
209  *---------------------------------------------------------------------------*/
210 void
MATHi_CRC16Update(const MATHCRC16Table * table,MATHCRC16Context * context,const void * input,u32 length)211 MATHi_CRC16Update(const MATHCRC16Table * table, MATHCRC16Context * context, const void *input,
212                   u32 length)
213 {
214     u32     r;
215     u32     i;
216     const u16 *t = table->table;
217     u8     *data = (u8 *)input;
218 
219     r = (u32)*context;
220     for (i = 0; i < length; i++)
221     {
222         r = (r << 8) ^ t[((r >> 8) ^ *data) & 0xff];
223         data++;
224     }
225     *context = (MATHCRC16Context) r;
226 }
227 
228 /*---------------------------------------------------------------------------*
229   Name:         MATHi_CRC16UpdateRev
230 
231   Description:  Updates the CRC-16 value with added data.
232                 The lower-order bit is handled as the higher-order digit.
233 
234   Arguments:    table:   Pointer to the table for calculation, MATHCRC16Table.
235                 context:   MATHCRC16Context structure.
236                 input:   Pointer to input data.
237                 length:  Length of input data.
238 
239   Returns:      None.
240  *---------------------------------------------------------------------------*/
241 void
MATHi_CRC16UpdateRev(const MATHCRC16Table * table,MATHCRC16Context * context,const void * input,u32 length)242 MATHi_CRC16UpdateRev(const MATHCRC16Table * table, MATHCRC16Context * context, const void *input,
243                      u32 length)
244 {
245     u32     r;
246     u32     i;
247     const u16 *t = table->table;
248     u8     *data = (u8 *)input;
249 
250     r = (u32)*context;
251     for (i = 0; i < length; i++)
252     {
253         r = (r >> 8) ^ t[(r ^ *data) & 0xff];
254         data++;
255     }
256     *context = (MATHCRC16Context) r;
257 }
258 
259 /*****************************************************************************/
260 /* CRC-32 common                                                               */
261 /*****************************************************************************/
262 
263 /*---------------------------------------------------------------------------*
264   Name:         MATHi_CRC32InitTable
265 
266   Description:  Initializes the MATHCRC32Table structure used for requesting the CRC-32 value.
267 
268   Arguments:    table:   MATHCRC32Table structure.
269                 poly:  Bit representation of the generator polynomial with the top bit removed.
270 
271   Returns:      None.
272  *---------------------------------------------------------------------------*/
MATHi_CRC32InitTable(MATHCRC32Table * table,u32 poly)273 void MATHi_CRC32InitTable(MATHCRC32Table * table, u32 poly)
274 {
275     u32     r;
276     u32     i, j;
277     u32    *t = table->table;
278 
279     for (i = 0; i < 256; i++)
280     {
281         r = i << 24;
282         for (j = 0; j < 8; j++)
283         {
284             if (r & 0x80000000U)
285             {
286                 r = (r << 1) ^ poly;
287             }
288             else
289             {
290                 r <<= 1;
291             }
292         }
293         t[i] = r;
294     }
295 }
296 
297 /*---------------------------------------------------------------------------*
298   Name:         MATHi_CRC32InitTableRev
299 
300   Description:  Initializes the MATHCRC32Table structure used for requesting the CRC-32 value.
301                 The lower-order bit is handled as the higher-order digit.
302 
303   Arguments:    table:   MATHCRC32Table structure.
304                 poly:  Inverted bit representation of the generator polynomial with the top bit removed.
305 
306 
307   Returns:      None.
308  *---------------------------------------------------------------------------*/
MATHi_CRC32InitTableRev(MATHCRC32Table * table,u32 poly)309 void MATHi_CRC32InitTableRev(MATHCRC32Table * table, u32 poly)
310 {
311     u32     r;
312     u32     i, j;
313     u32    *t = table->table;
314 
315     for (i = 0; i < 256; i++)
316     {
317         r = i;
318         for (j = 0; j < 8; j++)
319         {
320             if (r & 1)
321             {
322                 r = (r >> 1) ^ poly;
323             }
324             else
325             {
326                 r >>= 1;
327             }
328         }
329         t[i] = r;
330     }
331 }
332 
333 /*---------------------------------------------------------------------------*
334   Name:         MATHi_CRC32Update
335 
336   Description:  Updates the CRC-32 value with added data.
337 
338   Arguments:    table:   Pointer to the table for calculation, MATHCRC32Table.
339                 context:   MATHCRC32Context structure.
340                 input:   Pointer to input data.
341                 length:  Length of input data.
342 
343   Returns:      None.
344  *---------------------------------------------------------------------------*/
345 void
MATHi_CRC32Update(const MATHCRC32Table * table,MATHCRC32Context * context,const void * input,u32 length)346 MATHi_CRC32Update(const MATHCRC32Table * table, MATHCRC32Context * context, const void *input,
347                   u32 length)
348 {
349     u32     r;
350     u32     i;
351     const u32 *t = table->table;
352     u8     *data = (u8 *)input;
353 
354     r = (u32)*context;
355     for (i = 0; i < length; i++)
356     {
357         r = (r << 8) ^ t[((r >> 24) ^ *data) & 0xff];
358         data++;
359     }
360     *context = (MATHCRC32Context) r;
361 }
362 
363 /*---------------------------------------------------------------------------*
364   Name:         MATHi_CRC32UpdateRev
365 
366   Description:  Updates the CRC-32 value with added data.
367                 The lower-order bit is handled as the higher-order digit.
368 
369   Arguments:    table:   Pointer to the table for calculation, MATHCRC32Table.
370                 context:   MATHCRC32Context structure.
371                 input:   Pointer to input data.
372                 length:  Length of input data.
373 
374   Returns:      None.
375  *---------------------------------------------------------------------------*/
376 void
MATHi_CRC32UpdateRev(const MATHCRC32Table * table,MATHCRC32Context * context,const void * input,u32 length)377 MATHi_CRC32UpdateRev(const MATHCRC32Table * table, MATHCRC32Context * context, const void *input,
378                      u32 length)
379 {
380     u32     r;
381     u32     i;
382     const u32 *t = table->table;
383     u8     *data = (u8 *)input;
384 
385     r = (u32)*context;
386     for (i = 0; i < length; i++)
387     {
388         r = (r >> 8) ^ t[(r ^ *data) & 0xff];
389         data++;
390     }
391     *context = (MATHCRC32Context) r;
392 }
393 
394 
395 /*****************************************************************************/
396 /* Utility functions.                                                        */
397 /*****************************************************************************/
398 
399 /*---------------------------------------------------------------------------*
400   Name:         MATH_CalcCRC8
401 
402   Description:  Calculates the CRC-8 value.
403 
404   Arguments:    table:   Pointer to the table for calculation, MATHCRC8Table.
405                 data:    Pointer to input data.
406                 dataLength:   Length of input data.
407 
408   Returns:      Calculation result.
409  *---------------------------------------------------------------------------*/
MATH_CalcCRC8(const MATHCRC8Table * table,const void * data,u32 dataLength)410 u8 MATH_CalcCRC8(const MATHCRC8Table * table, const void *data, u32 dataLength)
411 {
412     MATHCRC8Context context;
413     MATH_CRC8Init(&context);
414     MATH_CRC8Update(table, &context, data, dataLength);
415     return MATH_CRC8GetHash(&context);
416 }
417 
418 /*---------------------------------------------------------------------------*
419   Name:         MATH_CalcCRC16
420 
421   Description:  Calculates the CRC-16 value.
422 
423   Arguments:    table:   Pointer to the table for calculation, MATHCRC16Table.
424                 data:    Pointer to input data.
425                 dataLength:   Length of input data.
426 
427   Returns:      Calculation result.
428  *---------------------------------------------------------------------------*/
MATH_CalcCRC16(const MATHCRC16Table * table,const void * data,u32 dataLength)429 u16 MATH_CalcCRC16(const MATHCRC16Table * table, const void *data, u32 dataLength)
430 {
431     MATHCRC16Context context;
432     MATH_CRC16Init(&context);
433     MATH_CRC16Update(table, &context, data, dataLength);
434     return MATH_CRC16GetHash(&context);
435 }
436 
437 /*---------------------------------------------------------------------------*
438   Name:         MATH_CalcCRC16CCITT
439 
440   Description:  Calculates the CRC-16/CCITT values.
441 
442   Arguments:    table:   Pointer to the table for calculation, MATHCRC16Table.
443                 data:    Pointer to input data.
444   Arguments:    data:    Pointer to input data.
445                 dataLength:   Length of input data.
446 
447   Returns:      Calculation result.
448  *---------------------------------------------------------------------------*/
MATH_CalcCRC16CCITT(const MATHCRC16Table * table,const void * data,u32 dataLength)449 u16 MATH_CalcCRC16CCITT(const MATHCRC16Table * table, const void *data, u32 dataLength)
450 {
451     MATHCRC16Context context;
452     MATH_CRC16CCITTInit(&context);
453     MATH_CRC16CCITTUpdate(table, &context, data, dataLength);
454     return MATH_CRC16CCITTGetHash(&context);
455 }
456 
457 /*---------------------------------------------------------------------------*
458   Name:         MATH_CalcCRC32
459 
460   Description:  Calculates the CRC-32 value.
461 
462   Arguments:    table:   Pointer to the table for calculation, MATHCRC32Table.
463                 data:    Pointer to input data.
464                 dataLength:   Length of input data.
465 
466   Returns:      Calculation result.
467  *---------------------------------------------------------------------------*/
MATH_CalcCRC32(const MATHCRC32Table * table,const void * data,u32 dataLength)468 u32 MATH_CalcCRC32(const MATHCRC32Table * table, const void *data, u32 dataLength)
469 {
470     MATHCRC32Context context;
471     MATH_CRC32Init(&context);
472     MATH_CRC32Update(table, &context, data, dataLength);
473     return MATH_CRC32GetHash(&context);
474 }
475 
476 /*---------------------------------------------------------------------------*
477   Name:         MATH_CalcCRC32POSIX
478 
479   Description:  Calculates the CRC-32/POSIX values.
480 
481   Arguments:    table:   Pointer to the table for calculation, MATHCRC32Table.
482                 data:    Pointer to input data.
483                 dataLength:   Length of input data.
484 
485   Returns:      Calculation result.
486  *---------------------------------------------------------------------------*/
MATH_CalcCRC32POSIX(const MATHCRC32Table * table,const void * data,u32 dataLength)487 u32 MATH_CalcCRC32POSIX(const MATHCRC32Table * table, const void *data, u32 dataLength)
488 {
489     MATHCRC32Context context;
490     MATH_CRC32POSIXInit(&context);
491     MATH_CRC32POSIXUpdate(table, &context, data, dataLength);
492     return MATH_CRC32POSIXGetHash(&context);
493 }
494