CRC16とHMACSHA1の計算結果を表示するように修正。

(計算方法がもしかしたら違うかもしれない。。。)

git-svn-id: file:///Users/lillianskinner/Downloads/platinum/twl/TwlIPL/trunk@2884 b08762b0-b915-fc4b-9d8c-17b2551a87ff
This commit is contained in:
(no author) 2009-07-24 07:25:57 +00:00
parent 9db1c78a77
commit 4bafb330df

View File

@ -18,12 +18,9 @@
#include <twl/fatfs.h> #include <twl/fatfs.h>
#include <twl/os/common/format_rom.h> #include <twl/os/common/format_rom.h>
#include <twl/nam.h> #include <twl/nam.h>
#include <twl/aes.h>
#include <twl/os/common/banner.h> #include <twl/os/common/banner.h>
#include <nitro/nvram.h>
#include <nitro/math/rand.h> #include <nitro/math/rand.h>
#include "application_jump_private.h"
#include "common.h" #include "common.h"
#include "screen.h" #include "screen.h"
@ -35,11 +32,10 @@
#define ES_ERR_OK 0 #define ES_ERR_OK 0
// 表示する対象をユーザーアプリだけにする場合 #define CRCPOLY 0x1021
#define USER_APP_ONLY
// デバッグ用 // 表示する対象をユーザーアプリだけにする場合
//#define DEBUG_MODE //#define USER_APP_ONLY
/*---------------------------------------------------------------------------* /*---------------------------------------------------------------------------*
@ -55,7 +51,6 @@ static KeyInfo gKey;
// インストールされている NAND アプリの数 // インストールされている NAND アプリの数
static s32 gNandAppNum; static s32 gNandAppNum;
static s32 gNandInstalledAppNum;
static s32 gNandAllAppNum; static s32 gNandAllAppNum;
// カーソル位置 // カーソル位置
@ -71,34 +66,17 @@ static u32 gMaxPage;
// Error // Error
static BOOL gErrorFlg; static BOOL gErrorFlg;
// eTicketType
typedef enum ETicketType {
ETICKET_TYPE_COMMON = 0,
ETICKET_TYPE_PERSONALIZED = 1
}ETicketType;
typedef struct DataStruct typedef struct DataStruct
{ {
NAMTitleId id; NAMTitleId id;
BOOL commonTicketFlg;
BOOL isSrlFlg;
u32 numTicket;
ETicketType tType[ETICKET_NUM_MAX];
u8 Sha1_digest[SVC_SHA1_DIGEST_SIZE];
u16 crc16;
} DataStruct; } DataStruct;
typedef struct {
u8 pad1[ 12 ];
u32 deviceId;
u8 pad2[ 216 - 16 ];
} ESTicketView;
typedef s32 ESError;
extern ESError ES_GetTicketViews(u64 titleId, ESTicketView* ticketViewList, u32* ticketViewCnt);
static DataStruct gDataList[TITLE_NUM_PAGE * 2]; static DataStruct gDataList[TITLE_NUM_PAGE * 2];
static DataStruct gInstalledDataList[TITLE_NUM_PAGE];
static u16 crc_table[0x100];
#ifdef DEBUG_MODE #ifdef DEBUG_MODE
static MATHRandContext32 context; static MATHRandContext32 context;
@ -108,7 +86,7 @@ static MATHRandContext32 context;
Prototype Prototype
*---------------------------------------------------------------------------*/ *---------------------------------------------------------------------------*/
static void DrawScene(DataStruct* list); static void DrawScene(DataStruct* list);
static BOOL GetDataStruct(DataStruct* list, DataStruct* Ilist); BOOL GetDataStruct(DataStruct* list);
static void ConvertTitleIdLo(u8* code, u8* titleid_lo); static void ConvertTitleIdLo(u8* code, u8* titleid_lo);
static void ConvertGameCode(u8* code, u32 game_code); static void ConvertGameCode(u8* code, u32 game_code);
@ -117,10 +95,14 @@ static void ConvertInitialCode(u8* code, u32 titleid_lo);
static void* AllocForNAM(u32 size); static void* AllocForNAM(u32 size);
static void FreeForNAM(void* ptr); static void FreeForNAM(void* ptr);
static s32 GetETicketType(DataStruct* data, ETicketType *pETicketType ); static BOOL ProcessTitleHashCheck(void);
static s32 GetTicketViews(ESTicketView** pptv, u32* pNumTicket, NAMTitleId titleId); static BOOL GetAppPath(DataStruct* list, char* path_buf);
BOOL CulcuHash(DataStruct* list, char* full_path);
u16 newGetCRC(u16 start, u16 *datap, u32 size);
static void inittable(unsigned short *table);
BOOL GetETicketData( void );
void* MyNAMUT_Alloc(u32 size); void* MyNAMUT_Alloc(u32 size);
void MyNAMUT_Free(void* buffer); void MyNAMUT_Free(void* buffer);
@ -149,7 +131,6 @@ void TwlMain(void)
spFreeFunc = FreeForNAM; spFreeFunc = FreeForNAM;
gNandAppNum = 0; gNandAppNum = 0;
gNandInstalledAppNum = 0;
gNandAllAppNum = 0; gNandAllAppNum = 0;
gErrorFlg = FALSE; gErrorFlg = FALSE;
@ -158,7 +139,6 @@ void TwlMain(void)
NAM_Init(AllocForNAM, FreeForNAM); NAM_Init(AllocForNAM, FreeForNAM);
MI_CpuClear8( gDataList, sizeof(gDataList)); MI_CpuClear8( gDataList, sizeof(gDataList));
MI_CpuClear8( gInstalledDataList, sizeof(gInstalledDataList));
#ifdef DEBUG_MODE #ifdef DEBUG_MODE
MATH_InitRand32( &context, 15 ); MATH_InitRand32( &context, 15 );
@ -166,10 +146,7 @@ void TwlMain(void)
ClearScreen(); ClearScreen();
PutMainScreen( 7, 12, 0xf6, "--- Now Loading ---"); (void)ProcessTitleHashCheck();
PutSubScreen( 7, 12, 0xf6, "--- Now Loading ---");
(void) GetETicketData();
while(TRUE) while(TRUE)
{ {
@ -303,6 +280,7 @@ static void DrawScene(DataStruct* list)
u8 init_code[5]; u8 init_code[5];
u8 color; u8 color;
u32 start; u32 start;
u32* digest;
DataStruct* p = list; DataStruct* p = list;
@ -317,8 +295,8 @@ static void DrawScene(DataStruct* list)
// 上画面 一覧表示 // 上画面 一覧表示
PutMainScreen( 1, 0, 0xf2, "------ Title Hash Checker ------ "); PutMainScreen( 1, 0, 0xf2, "------ Title Hash Checker ------ ");
PutMainScreen( 1, 1, 0xfa, "<Page %d/%d>", (gCurrentPage+1), (gMaxPage+1)); PutMainScreen( 1, 1, 0xfa, "<Page %d/%d>", (gCurrentPage+1), (gMaxPage+1));
PutMainScreen( 1, 2, 0xf4, " Game Ticket Ticket"); PutMainScreen( 1, 2, 0xf4, " Game");
PutMainScreen( 1, 3, 0xf4, " Code srl Num Type"); PutMainScreen( 1, 3, 0xf4, " Code");
PutMainScreen( 0, 4, 0xff, "--------------------------------"); PutMainScreen( 0, 4, 0xff, "--------------------------------");
// カーソル表示 // カーソル表示
@ -343,33 +321,10 @@ static void DrawScene(DataStruct* list)
ConvertInitialCode(init_code, NAM_GetTitleIdLo(p->id)); ConvertInitialCode(init_code, NAM_GetTitleIdLo(p->id));
color = p->commonTicketFlg ? COMMON_COLOR : PERSONALIZED_COLOR; color = COMMON_COLOR;
// ゲームコード表示 // ゲームコード表示
PutMainScreen( GAME_CODE_BASE_X, TITLE_SHOW_BASE_Y+tmp_i, color, "%2d:%s", (tmp_i+1), init_code); PutMainScreen( GAME_CODE_BASE_X, TITLE_SHOW_BASE_Y+tmp_i, color, "%2d:%s", (tmp_i+1), init_code);
// srlの有無表示
if(p->isSrlFlg)
{
PutMainScreen( GAME_CODE_BASE_X + 9, TITLE_SHOW_BASE_Y+tmp_i, color, "o");
}
else
{
PutMainScreen( GAME_CODE_BASE_X + 9, TITLE_SHOW_BASE_Y+tmp_i, color, "x");
}
// ETicketの数の表示
PutMainScreen( GAME_CODE_BASE_X + 12, TITLE_SHOW_BASE_Y+tmp_i, color, "%d", p->numTicket);
// ETicketのタイプの表示
if(p->commonTicketFlg)
{
PutMainScreen(GAME_CODE_BASE_X + 19, TITLE_SHOW_BASE_Y+tmp_i, color, "common");
}
else
{
PutMainScreen(GAME_CODE_BASE_X + 19, TITLE_SHOW_BASE_Y+tmp_i, color, "personalized");
}
} }
PutMainScreen( 0, TITLE_MAX_SHOW + TITLE_SHOW_BASE_Y, 0xff, "--------------------------------"); PutMainScreen( 0, TITLE_MAX_SHOW + TITLE_SHOW_BASE_Y, 0xff, "--------------------------------");
@ -379,26 +334,82 @@ static void DrawScene(DataStruct* list)
// 下画面 詳細表示 // 下画面 詳細表示
ConvertInitialCode(init_code, NAM_GetTitleIdLo(list[gCurrentElem].id)); ConvertInitialCode(init_code, NAM_GetTitleIdLo(list[gCurrentElem].id));
PutSubScreen(3, 2, 0xf4, "Selected Title : [ %s ]", init_code); PutSubScreen(3, 1, 0xf4, "Selected Title : [ %s ]", init_code);
PutSubScreen(3, 4, 0xff, "- Ticket List -"); PutSubScreen(3, 4, 0xff, "- CRC16 Data -");
for( i=0; i < list[gCurrentElem].numTicket; i++){ PutSubScreen(3, 6, 0xf4, "0x%04x", list[gCurrentElem].crc16);
if(i > 15)
{
break;
}
PutSubScreen(5, 6+i, 0xf4, "Ticket%d : ", (i+1));
if(list[gCurrentElem].tType[i] == ETICKET_TYPE_COMMON) digest = (u32 *)list[gCurrentElem].Sha1_digest;
{
PutSubScreen(15, 6+i, COMMON_COLOR, "COMMON"); PutSubScreen(3, 10, 0xff, "- SHA1 Digest Data -");
}
else PutSubScreen(3, 12, 0xf4, "0x%08x", digest[0]);
{ PutSubScreen(3, 14, 0xf4, "0x%08x", digest[1]);
PutSubScreen(15, 6+i, PERSONALIZED_COLOR, "PERSONALIZED"); PutSubScreen(3, 16, 0xf4, "0x%08x", digest[2]);
} PutSubScreen(3, 18, 0xf4, "0x%08x", digest[3]);
PutSubScreen(3, 20, 0xf4, "0x%08x", digest[4]);
}
/*---------------------------------------------------------------------------*
Name: ProcessTitleHashCheck
Description:
*---------------------------------------------------------------------------*/
BOOL ProcessTitleHashCheck( void )
{
u32 i;
s32 result = TRUE;
char full_path[FS_ENTRY_LONGNAME_MAX+6];
DataStruct* list;
// NAND にインポートされているNAND アプリの数を取得する
if ( (gNandAppNum = NAM_GetNumTitles()) < 0)
{
OS_Panic("NAM_GetNumTitles() failed.");
}
gNandAllAppNum = gNandAppNum;
// 情報の取得
if ( !GetDataStruct(gDataList) )
{
OS_Panic("GetDataStruct() failed.");
}
list = gDataList;
// srlのHash値とcrc16を求める
for ( i=0; i < gNandAppNum; i++, list++ )
{
PutMainScreen( 7, 10, 0xf6, "--- Now Loading ---");
PutMainScreen( 7, 14, 0xf6, " %2d / %2d compleate", i+1, gNandAppNum);
PutSubScreen( 7, 10, 0xf6, "--- Now Loading ---");
PutSubScreen( 7, 14, 0xf6, " %2d / %2d compleate", i+1, gNandAppNum);
// バッファのクリア
MI_CpuClear8(full_path, sizeof(full_path));
// ファイルパスの取得
if ( !GetAppPath(list, full_path) )
{
OS_Panic("CulcuHash() failed.");
}
// Hash, CRC16の計算
if ( !CulcuHash(list, full_path) )
{
OS_Panic("CulcuHash() failed.");
}
} }
OS_PutString("ProcessTitleHashCheck Finish!!\n");
return result;
} }
@ -408,7 +419,7 @@ static void DrawScene(DataStruct* list)
Description: TitleIDリストを取得する関数 Description: TitleIDリストを取得する関数
NAM_GetTitleList NAM_GetInstalledTitleList 使 NAM_GetTitleList NAM_GetInstalledTitleList 使
*---------------------------------------------------------------------------*/ *---------------------------------------------------------------------------*/
static BOOL GetDataStruct(DataStruct* list, DataStruct* Ilist) BOOL GetDataStruct(DataStruct* list)
{ {
// タイトルIDリストバッファ // タイトルIDリストバッファ
NAMTitleId titleIdList[TITLE_NUM_PAGE]; NAMTitleId titleIdList[TITLE_NUM_PAGE];
@ -432,258 +443,269 @@ static BOOL GetDataStruct(DataStruct* list, DataStruct* Ilist)
OS_TPrintf("id : 0x%08x\n", titleIdList[i]); OS_TPrintf("id : 0x%08x\n", titleIdList[i]);
list->id = titleIdList[i]; list->id = titleIdList[i];
list->isSrlFlg = TRUE;
} }
MI_CpuClear8(titleIdList, sizeof(titleIdList)); MI_CpuClear8(titleIdList, sizeof(titleIdList));
OS_PutString("\n\n"); OS_PutString("\n\n");
// --- GetInstalledTitleList
if ( NAM_GetInstalledTitleList(titleIdList, TITLE_NUM_PAGE) != NAM_OK )
{
OS_PutString("NAM_GetInstalledTitleList failed.");
return FALSE;
}
// データリストの作成
for ( i=0; i<TITLE_NUM_PAGE; i++, Ilist++)
{
// そもそも NAND アプリの数が 1ページにも満たない場合は途中で終了する
if ( i >= gNandInstalledAppNum )
{
break;
}
OS_TPrintf("id : 0x%08x\n", titleIdList[i]);
Ilist->id = titleIdList[i];
Ilist->isSrlFlg = FALSE;
}
return TRUE; return TRUE;
} }
/*---------------------------------------------------------------------------* /*---------------------------------------------------------------------------*
Name: GetETicketType Name: GetAppPath
Description: titleID eTicket Description:
Arguments: titleID: common eTicket 調 titleID Arguments:
pETicketType : ESETicketTypeポインタ
Returns:
Returns: NAM_OK :
:
*---------------------------------------------------------------------------*/ *---------------------------------------------------------------------------*/
static s32 GetETicketType(DataStruct* data, ETicketType *pETicketType ) static BOOL GetAppPath(DataStruct* list, char* path_buf)
{ {
s32 result; FSFile dir;
ESTicketView* ptv; BOOL ret = TRUE;
u32 numTicket;
#ifdef DEBUG_MODE // ディレクトリパスの作成
u32 i; STD_TSNPrintf( path_buf, FS_ENTRY_LONGNAME_MAX,
#endif "nand:/title/%08x/%08x/content/", (u32)( list->id >> 32 ), list->id );
*pETicketType = ETICKET_TYPE_PERSONALIZED; // .appファイルを見つける
if ( !FS_OpenDirectory(&dir, path_buf, FS_FILEMODE_R | FS_FILEMODE_W) )
result = GetTicketViews(&ptv, &numTicket, data->id);
#ifndef DEBUG_MODE
data->numTicket = numTicket;
#else
data->numTicket = MATH_Rand32( &context, 10 );
#endif
if( result == NAM_OK )
{ {
if( numTicket > 0 ) ret = FALSE;
{ OS_PutString("Error FS_OpenDirectory\n\n");
int i;
// eTicket は、そのままもしくは追加しかありえないので、プリインストールされたアプリでは、必ずCommon eTikcetが存在する。
// よって、全ての eTicket のうち、ひとつでも deviceId が 0x00000000 なら、common eTicket と判断。
for( i = 0; i < numTicket; i++ )
{
if( ptv[i].deviceId == 0x00000000 )
{
*pETicketType = ETICKET_TYPE_COMMON;
data->tType[i] = ETICKET_TYPE_COMMON;
}
else
{
data->tType[i] = ETICKET_TYPE_PERSONALIZED;
}
}
}
MyNAMUT_Free(ptv);
}
#ifdef DEBUG_MODE
for( i=0; i<data->numTicket; i++)
{
if( MATH_Rand32( &context, 10 ) % 5 )
{
data->tType[i] = ETICKET_TYPE_COMMON;
}
else
{
data->tType[i] = ETICKET_TYPE_PERSONALIZED;
}
}
#endif
return result;
}
/*---------------------------------------------------------------------------*
Name: GetTicketViews
Description: eTicket
        nam_title.c GetTicketViews
Arguments: pptv : eTicket
pNumTicket : eTicket
titleID : eTicket titleID
Returns: NAM_OK :
:
*---------------------------------------------------------------------------*/
static s32 GetTicketViews(ESTicketView** pptv, u32* pNumTicket, NAMTitleId titleId)
{
s32 result;
u32 numTicket;
ESTicketView* ptv = NULL;
result = ES_GetTicketViews(titleId, NULL, &numTicket);
if( result != ES_ERR_OK )
{
return result;
}
if( numTicket != 0 )
{
ptv = MyNAMUT_Alloc(sizeof(ESTicketView) * numTicket);
if( ptv == NULL )
{
return NAM_NO_MEMORY;
}
result = ES_GetTicketViews(titleId, ptv, &numTicket);
}
if( result == ES_ERR_OK )
{
*pptv = ptv;
*pNumTicket = numTicket;
} }
else else
{ {
MyNAMUT_Free(ptv); FSDirectoryEntryInfo info[1];
// .app を探してファイル名を保存しておく
while (FS_ReadDirectory(&dir, info))
{
if ((info->attributes & (FS_ATTRIBUTE_DOS_DIRECTORY | FS_ATTRIBUTE_IS_DIRECTORY)) != 0)
{
}
else
{
char* pExtension;
OS_Printf(" (%d BYTEs)\n", info->filesize);
// 拡張子のチェック
pExtension = STD_SearchCharReverse( info->longname, '.');
if (pExtension)
{
if (!STD_CompareString( pExtension, ".app"))
{
STD_ConcatenateString( path_buf, info->longname );
OS_TPrintf("OK! File Path : %s\n", path_buf);
break;
}
}
}
}
(void)FS_CloseDirectory(&dir);
} }
return result; return ret;
} }
/*---------------------------------------------------------------------------* /*---------------------------------------------------------------------------*
Name: GetETicketData Name: CulcuHash
Description:
Arguments:
Returns:
Description: ETicketデータを取得する
*---------------------------------------------------------------------------*/ *---------------------------------------------------------------------------*/
BOOL GetETicketData( void ) #define READ_SIZE 0x200 // とりあえずのリードサイズ
BOOL CulcuHash(DataStruct* list, char* full_path)
{ {
s32 result = TRUE; FSFile file;
s32 i,j; BOOL open_is_ok;
BOOL seek_is_ok;
BOOL read_is_ok;
u32 file_size;
u32 read_size = 0;
u32 data_size = 0;
u32 i;
u8* pTempBuf;
SVCHMACSHA1Context hash;
// NAND にインポートされているNAND アプリの数を取得する FSResult result;
if ( (gNandAppNum = NAM_GetNumTitles()) < 0)
{ // CRC16計算用テーブルの初期化
OS_Panic("NAM_GetNumTitles() failed."); MI_CpuClear8(crc_table, sizeof(crc_table));
} inittable(crc_table);
// 実体があるタイトル数
if ( (gNandInstalledAppNum = NAM_GetNumInstalledTitles()) < 0) // ハッシュ初期化
{ SVC_HMACSHA1Init( &hash, list->Sha1_digest, SVC_SHA1_DIGEST_SIZE );
OS_Panic("NAM_GetNumInstalledTitles() failed.");
} // FS初期化
// 情報の取得 FS_InitFile(&file);
if ( !GetDataStruct(gDataList, gInstalledDataList) )
// ファイルオープン
open_is_ok = FS_OpenFile(&file, full_path);
if (!open_is_ok)
{ {
OS_Panic("GetDataStruct() failed."); OS_Warning("Failure! FS_OpenFile");
return FALSE;
} }
// NAM_GetTitleList -- 削除されているがeTicketのみ存在するタイトルがリストアップされない // ファイル長取得
// NAM_GetInstalledTitleList -- SRLはあるがeTicketがないタイトルがリストアップされない file_size = FS_GetFileLength(&file);
// そのため両者をマージする OS_TPrintf("File Size : %d bytes\n", file_size);
gNandAllAppNum = gNandAppNum;
for (i=0; i<gNandInstalledAppNum; i++) // ファイルが大きいものもあるから細切れで読む
{ for(i=1;;i++){
BOOL find = FALSE; MI_CpuClear(pTempBuf, sizeof(pTempBuf));
for (j=0; j<gNandAppNum; j++)
// バッファ確保
pTempBuf = spAllocFunc( READ_SIZE );
if (pTempBuf == NULL)
{
FS_CloseFile(&file);
OS_Warning("Failure! Alloc Buffer");
return FALSE;
}
// 読み込むサイズを決める
if( (READ_SIZE * i) >= file_size )
{ {
if (gInstalledDataList[i].id == gDataList[j].id) data_size = file_size % READ_SIZE;
}
else
{
data_size = READ_SIZE;
}
// ファイルリード
read_is_ok = FS_ReadFile( &file, pTempBuf, READ_SIZE );
result = FS_GetResultCode(&file);
if (!read_is_ok)
{
FS_CloseFile(&file);
spFreeFunc(pTempBuf);
OS_Warning("Failure! Read File (Error Code : %d)", result);
return FALSE;
}
// 読んだサイズを更新
read_size += READ_SIZE;
// Hash値 UpDate
SVC_HMACSHA1Update( &hash, pTempBuf, data_size );
// CRC16計算
list->crc16 = newGetCRC(list->crc16, (u16 *)pTempBuf, data_size);
// ファイルが全部読めたらwhileをぬける
if( read_size >= file_size )
{
break;
}
else
{
// ファイルシーク
seek_is_ok = FS_SeekFile( &file, READ_SIZE * i, FS_SEEK_SET );
result = FS_GetResultCode(&file);
if(!seek_is_ok)
{ {
find = TRUE; FS_CloseFile(&file);
break; spFreeFunc(pTempBuf);
OS_Warning("Failure! Seek File [read size : %d bytes] (Error Code : %d)", read_size, result);
return FALSE;
} }
} }
if (find == FALSE) spFreeFunc( pTempBuf );
{
MI_CpuCopy8(&gInstalledDataList[i], &gDataList[gNandAllAppNum], sizeof(DataStruct));
gNandAllAppNum++;
}
} }
#ifdef USER_APP_ONLY OS_TPrintf("CRC16 : 0x%08x\n", list->crc16);
// ユーザーアプリだけ抽出する
getUserApplication( gDataList );
#endif
// 必要なページ数を求める // Hash値算出
gMaxPage = (u32)(gNandAllAppNum >> 4); SVC_HMACSHA1GetHash( &hash, list->Sha1_digest );
if( gMaxPage != 0 && (gNandAllAppNum & 0xf) == 0 )
{
gMaxPage--;
}
// 現在ページの初期化 // ファイルクローズ
gCurrentPage = 0; FS_CloseFile(&file);
OS_TPrintf("gNandAllAppNum : %d\n",gNandAllAppNum); return TRUE;
OS_TPrintf("gMaxPage : %d\n",gMaxPage);
if( gNandAllAppNum == 0 )
{
gErrorFlg = TRUE;
return FALSE;
}
// アプリのETicketデータを取得する
for (i=0; i<gNandAllAppNum; i++)
{
ETicketType eTicketType = ETICKET_TYPE_PERSONALIZED; // default
if( GetETicketType( &gDataList[i], &eTicketType ) != NAM_OK )
{
result = FALSE;
}
else
{
u32 numTicket = 0;
(void)ES_GetTicketViews( gDataList[i].id, NULL, &numTicket);
gDataList[i].commonTicketFlg = (eTicketType == ETICKET_TYPE_COMMON) ? TRUE : FALSE;
}
}
return result;
} }
/*---------------------------------------------------------------------------*
Name: newGetCRC
Description: CRC計算
CRCテーブルを使ったCRC計算関数
*---------------------------------------------------------------------------*/
u16 newGetCRC
(
u16 start, // CRC初期値累積値
u16 *datap, // データの先頭を指すポインタ、
u32 size // バイト単位でのデータサイズ
)
{
u32 i;
u16 crc;
u8* byte;
crc = start;
byte = (u8 *)datap;
for (i=0; i<size; i+=2)
{
u8 byte0, byte1;
byte0 = *byte; byte++;
byte1 = *byte; byte++;
crc = (crc << 8) ^ crc_table[(crc >> 8) ^ byte1];
crc = (crc << 8) ^ crc_table[(crc >> 8) ^ byte0];
}
return crc;
}
/*----------------------------------------------------------------------------
inittable - initialize table
static void inittable(unsigned short *table);
CRC算出を高速化するための参照テーブルを作成する
----------------------------------------------------------------------------*/
static void inittable(unsigned short *table)
{
unsigned short i, j, r;
for(i = 0; i < 0x100; i++) {
r = i << 8;
for(j = 0; j < 8; j++) {
if(r & 0x8000U)
r = (r << 1) ^ CRCPOLY;
else
r <<= 1;
}
*table++ = r;
}
}
#ifdef USER_APP_ONLY #ifdef USER_APP_ONLY
/*---------------------------------------------------------------------------* /*---------------------------------------------------------------------------*