/*---------------------------------------------------------------------------* Project: TwlSDK - MATH - File: crc.c Copyright 2003-2008 Nintendo. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo of America Inc. and/or Nintendo Company Ltd., and are protected by Federal copyright law. They may not be disclosed to third parties or copied or duplicated in any form, in whole or in part, without the prior written consent of Nintendo. $Date:: 2008-09-18#$ $Rev: 8573 $ $Author:$ *---------------------------------------------------------------------------*/ #include /*****************************************************************************/ /* CRC-8 common */ /*****************************************************************************/ /*---------------------------------------------------------------------------* Name: MATHi_CRC8InitTable Description: Initializes the MATHCRC8Table structure used for requesting the CRC-8 value. Arguments: table: MATHCRC8Table structure. poly: Bit representation of the generator polynomial with the top bit removed. Returns: None. *---------------------------------------------------------------------------*/ void MATHi_CRC8InitTable(MATHCRC8Table * table, u8 poly) { u32 r; u32 i, j; u8 *t = table->table; for (i = 0; i < 256; i++) { r = i; for (j = 0; j < 8; j++) { if (r & 0x80) { r = (r << 1) ^ poly; } else { r <<= 1; } } t[i] = (u8)r; } } /*---------------------------------------------------------------------------* Name: MATHi_CRC8InitTableRev Description: Initializes the MATHCRC8Table structure used for requesting the CRC-8 value. The lower-order bit is handled as the higher-order digit. Arguments: table: MATHCRC8Table structure. poly: Inverted bit representation of the generator polynomial with the top bit removed. Returns: None. *---------------------------------------------------------------------------*/ void MATHi_CRC8InitTableRev(MATHCRC8Table * table, u8 poly) { u32 r; u32 i, j; u8 *t = table->table; for (i = 0; i < 256; i++) { r = i; for (j = 0; j < 8; j++) { if (r & 1) { r = (r >> 1) ^ poly; } else { r >>= 1; } } t[i] = (u8)r; } } /*---------------------------------------------------------------------------* Name: MATHi_CRC8Update Description: Updates the CRC-8 value with added data. Arguments: table: Pointer to the table for calculation, MATHCRC8Table. context: MATHCRC8Context structure. input: Pointer to input data. length: Length of input data. Returns: None. *---------------------------------------------------------------------------*/ void MATHi_CRC8Update(const MATHCRC8Table * table, MATHCRC8Context * context, const void *input, u32 length) { u32 r; u32 i; const u8 *t = table->table; u8 *data = (u8 *)input; r = (u32)*context; for (i = 0; i < length; i++) { r = t[(r ^ *data) & 0xff]; data++; } *context = (MATHCRC8Context) r; } /*****************************************************************************/ /* CRC-16 common */ /*****************************************************************************/ /*---------------------------------------------------------------------------* Name: MATHi_CRC16InitTable Description: Initializes the MATHCRC16Table structure used for requesting the CRC-16 value. Arguments: table: MATHCRC16Table structure. poly: Bit representation of the generator polynomial with the top bit removed. Returns: None. *---------------------------------------------------------------------------*/ void MATHi_CRC16InitTable(MATHCRC16Table * table, u16 poly) { u32 r; u32 i, j; u16 *t = table->table; for (i = 0; i < 256; i++) { r = i << 8; for (j = 0; j < 8; j++) { if (r & 0x8000) { r = (r << 1) ^ poly; } else { r <<= 1; } } t[i] = (u16)r; } } /*---------------------------------------------------------------------------* Name: MATHi_CRC16InitTableRev Description: Initializes the MATHCRC16Table structure used for requesting the CRC-16 value. The lower-order bit is handled as the higher-order digit. Arguments: table: MATHCRC16Table structure. poly: Inverted bit representation of the generator polynomial with the top bit removed. Returns: None. *---------------------------------------------------------------------------*/ void MATHi_CRC16InitTableRev(MATHCRC16Table * table, u16 poly) { u32 r; u32 i, j; u16 *t = table->table; for (i = 0; i < 256; i++) { r = i; for (j = 0; j < 8; j++) { if (r & 1) { r = (r >> 1) ^ poly; } else { r >>= 1; } } t[i] = (u16)r; } } /*---------------------------------------------------------------------------* Name: MATHi_CRC16Update Description: Updates the CRC-16 value with added data. Arguments: table: Pointer to the table for calculation, MATHCRC16Table. context: MATHCRC16Context structure. input: Pointer to input data. length: Length of input data. Returns: None. *---------------------------------------------------------------------------*/ void MATHi_CRC16Update(const MATHCRC16Table * table, MATHCRC16Context * context, const void *input, u32 length) { u32 r; u32 i; const u16 *t = table->table; u8 *data = (u8 *)input; r = (u32)*context; for (i = 0; i < length; i++) { r = (r << 8) ^ t[((r >> 8) ^ *data) & 0xff]; data++; } *context = (MATHCRC16Context) r; } /*---------------------------------------------------------------------------* Name: MATHi_CRC16UpdateRev Description: Updates the CRC-16 value with added data. The lower-order bit is handled as the higher-order digit. Arguments: table: Pointer to the table for calculation, MATHCRC16Table. context: MATHCRC16Context structure. input: Pointer to input data. length: Length of input data. Returns: None. *---------------------------------------------------------------------------*/ void MATHi_CRC16UpdateRev(const MATHCRC16Table * table, MATHCRC16Context * context, const void *input, u32 length) { u32 r; u32 i; const u16 *t = table->table; u8 *data = (u8 *)input; r = (u32)*context; for (i = 0; i < length; i++) { r = (r >> 8) ^ t[(r ^ *data) & 0xff]; data++; } *context = (MATHCRC16Context) r; } /*****************************************************************************/ /* CRC-32 common */ /*****************************************************************************/ /*---------------------------------------------------------------------------* Name: MATHi_CRC32InitTable Description: Initializes the MATHCRC32Table structure used for requesting the CRC-32 value. Arguments: table: MATHCRC32Table structure. poly: Bit representation of the generator polynomial with the top bit removed. Returns: None. *---------------------------------------------------------------------------*/ void MATHi_CRC32InitTable(MATHCRC32Table * table, u32 poly) { u32 r; u32 i, j; u32 *t = table->table; for (i = 0; i < 256; i++) { r = i << 24; for (j = 0; j < 8; j++) { if (r & 0x80000000U) { r = (r << 1) ^ poly; } else { r <<= 1; } } t[i] = r; } } /*---------------------------------------------------------------------------* Name: MATHi_CRC32InitTableRev Description: Initializes the MATHCRC32Table structure used for requesting the CRC-32 value. The lower-order bit is handled as the higher-order digit. Arguments: table: MATHCRC32Table structure. poly: Inverted bit representation of the generator polynomial with the top bit removed. Returns: None. *---------------------------------------------------------------------------*/ void MATHi_CRC32InitTableRev(MATHCRC32Table * table, u32 poly) { u32 r; u32 i, j; u32 *t = table->table; for (i = 0; i < 256; i++) { r = i; for (j = 0; j < 8; j++) { if (r & 1) { r = (r >> 1) ^ poly; } else { r >>= 1; } } t[i] = r; } } /*---------------------------------------------------------------------------* Name: MATHi_CRC32Update Description: Updates the CRC-32 value with added data. Arguments: table: Pointer to the table for calculation, MATHCRC32Table. context: MATHCRC32Context structure. input: Pointer to input data. length: Length of input data. Returns: None. *---------------------------------------------------------------------------*/ void MATHi_CRC32Update(const MATHCRC32Table * table, MATHCRC32Context * context, const void *input, u32 length) { u32 r; u32 i; const u32 *t = table->table; u8 *data = (u8 *)input; r = (u32)*context; for (i = 0; i < length; i++) { r = (r << 8) ^ t[((r >> 24) ^ *data) & 0xff]; data++; } *context = (MATHCRC32Context) r; } /*---------------------------------------------------------------------------* Name: MATHi_CRC32UpdateRev Description: Updates the CRC-32 value with added data. The lower-order bit is handled as the higher-order digit. Arguments: table: Pointer to the table for calculation, MATHCRC32Table. context: MATHCRC32Context structure. input: Pointer to input data. length: Length of input data. Returns: None. *---------------------------------------------------------------------------*/ void MATHi_CRC32UpdateRev(const MATHCRC32Table * table, MATHCRC32Context * context, const void *input, u32 length) { u32 r; u32 i; const u32 *t = table->table; u8 *data = (u8 *)input; r = (u32)*context; for (i = 0; i < length; i++) { r = (r >> 8) ^ t[(r ^ *data) & 0xff]; data++; } *context = (MATHCRC32Context) r; } /*****************************************************************************/ /* Utility functions. */ /*****************************************************************************/ /*---------------------------------------------------------------------------* Name: MATH_CalcCRC8 Description: Calculates the CRC-8 value. Arguments: table: Pointer to the table for calculation, MATHCRC8Table. data: Pointer to input data. dataLength: Length of input data. Returns: Calculation result. *---------------------------------------------------------------------------*/ u8 MATH_CalcCRC8(const MATHCRC8Table * table, const void *data, u32 dataLength) { MATHCRC8Context context; MATH_CRC8Init(&context); MATH_CRC8Update(table, &context, data, dataLength); return MATH_CRC8GetHash(&context); } /*---------------------------------------------------------------------------* Name: MATH_CalcCRC16 Description: Calculates the CRC-16 value. Arguments: table: Pointer to the table for calculation, MATHCRC16Table. data: Pointer to input data. dataLength: Length of input data. Returns: Calculation result. *---------------------------------------------------------------------------*/ u16 MATH_CalcCRC16(const MATHCRC16Table * table, const void *data, u32 dataLength) { MATHCRC16Context context; MATH_CRC16Init(&context); MATH_CRC16Update(table, &context, data, dataLength); return MATH_CRC16GetHash(&context); } /*---------------------------------------------------------------------------* Name: MATH_CalcCRC16CCITT Description: Calculates the CRC-16/CCITT values. Arguments: table: Pointer to the table for calculation, MATHCRC16Table. data: Pointer to input data. Arguments: data: Pointer to input data. dataLength: Length of input data. Returns: Calculation result. *---------------------------------------------------------------------------*/ u16 MATH_CalcCRC16CCITT(const MATHCRC16Table * table, const void *data, u32 dataLength) { MATHCRC16Context context; MATH_CRC16CCITTInit(&context); MATH_CRC16CCITTUpdate(table, &context, data, dataLength); return MATH_CRC16CCITTGetHash(&context); } /*---------------------------------------------------------------------------* Name: MATH_CalcCRC32 Description: Calculates the CRC-32 value. Arguments: table: Pointer to the table for calculation, MATHCRC32Table. data: Pointer to input data. dataLength: Length of input data. Returns: Calculation result. *---------------------------------------------------------------------------*/ u32 MATH_CalcCRC32(const MATHCRC32Table * table, const void *data, u32 dataLength) { MATHCRC32Context context; MATH_CRC32Init(&context); MATH_CRC32Update(table, &context, data, dataLength); return MATH_CRC32GetHash(&context); } /*---------------------------------------------------------------------------* Name: MATH_CalcCRC32POSIX Description: Calculates the CRC-32/POSIX values. Arguments: table: Pointer to the table for calculation, MATHCRC32Table. data: Pointer to input data. dataLength: Length of input data. Returns: Calculation result. *---------------------------------------------------------------------------*/ u32 MATH_CalcCRC32POSIX(const MATHCRC32Table * table, const void *data, u32 dataLength) { MATHCRC32Context context; MATH_CRC32POSIXInit(&context); MATH_CRC32POSIXUpdate(table, &context, data, dataLength); return MATH_CRC32POSIXGetHash(&context); }