diff --git a/build/tools/TamperDetectorForSrl/card_hash.cpp b/build/tools/TamperDetectorForSrl/card_hash.cpp index 3712e44..231633e 100644 --- a/build/tools/TamperDetectorForSrl/card_hash.cpp +++ b/build/tools/TamperDetectorForSrl/card_hash.cpp @@ -4,6 +4,7 @@ #include /* libcrypto.a */ #include "twl_format_rom.h" #include "card_hash.h" +#include "entry.h" #define MATH_SHA1_DIGEST_SIZE (160/8) @@ -100,16 +101,10 @@ void CARDi_Init( CARDRomHashContext *context, RomHeader* header) // rom image context->buffer = (u8*)malloc( header->digest1_block_size); - // rom size - { - int i; - u32 rom_size; - for( i=0; irom_size; i++) - { - rom_size *= 2; - } - context->rom_size = (rom_size * 1024 / 8 * 1024); - } + // 検証OK/NG記録 + context->hash_correct = (u8*)malloc( header->digest1_table_size / CARD_ROM_HASH_SIZE); + context->master_hash_correct = (u8*)malloc( header->digest1_table_size / header->digest2_covered_digest1_num / CARD_ROM_HASH_SIZE); + } @@ -142,9 +137,6 @@ u32 CARDi_GetHashSectorIndex(const CARDRomHashContext *context, u32 offset) return offset / context->bytes_per_sector; } -//static CARDRomHashBlock* CARDi_TouchRomHashBlock(CARDRomHashContext *context, u32 sector) -//{ -//} void CARDi_CheckHash(CARDRomHashContext *context, FILE* fp, u32 start, u32 size, RomHeader* header) { @@ -213,8 +205,10 @@ bool Digest1Check(CARDRomHashContext *context, FILE* fp, RomHeader* header, u32 /* ROMデータのHashをDigest1と比較 */ if( !CARDi_CompareHash( context->hash, context->buffer, context->bytes_per_sector)) { + context->hash_correct[digest1_index] = 0; // 結果記録 ret = false; } + context->hash_correct[digest1_index] = 1; // 結果記録 } rest -= context->bytes_per_sector; @@ -227,6 +221,7 @@ bool Digest1Check(CARDRomHashContext *context, FILE* fp, RomHeader* header, u32 bool Digest2Check(CARDRomHashContext *context, FILE* fp, RomHeader* header) { bool ret = true; + int digest2_index; int i, j; int digest1_index_num = (header->digest1_table_size / header->digest1_block_size); @@ -238,11 +233,14 @@ bool Digest2Check(CARDRomHashContext *context, FILE* fp, RomHeader* header) fread( &(context->hash[j * CARD_ROM_HASH_SIZE]), CARD_ROM_HASH_SIZE, 1, fp); } /* Digest1をDigest2と比較 */ - if( !CARDi_CompareHash( &(context->master_hash[(i/context->sectors_per_block) * CARD_ROM_HASH_SIZE]), + digest2_index = (i/context->sectors_per_block); + if( !CARDi_CompareHash( &(context->master_hash[digest2_index * CARD_ROM_HASH_SIZE]), context->hash, (CARD_ROM_HASH_SIZE * context->sectors_per_block))) { + context->master_hash_correct[digest2_index] = 0; ret = false; } + context->master_hash_correct[digest2_index] = 1; i+= header->digest2_covered_digest1_num; } @@ -285,184 +283,26 @@ void CARD_CheckHash(CARDRomHashContext *context, RomHeader* header, FILE* fp) printf( "-----------------------\n\n"); } -/* -static void CARDi_ReadRomHashImageDirect(CARDRomHashContext *context, void *buffer, u32 offset, u32 length) + +/* 特定のファイルに対応するダイジェストテーブルが正しいか検証する */ +void CARD_CheckFileDigest(CARDRomHashContext *context, MyFileEntry* file_entry, u8* ret_digest1, u8* ret_digest2) { - const u32 sectunit = context->bytes_per_sector; - const u32 blckunit = context->sectors_per_block; - u32 position = offset; - u32 end = length + offset; - u32 sector = CARDi_GetHashSectorIndex(context, position); - long nowgfp; - FILE* gfp; - - while (position < end) + u32 i; + u32 digest1_index_begin = CARDi_GetHashSectorIndex( context, file_entry->top); + u32 digest1_index_end = CARDi_GetHashSectorIndex( context, file_entry->bottom); + *ret_digest1 = 1; + *ret_digest2 = 1; + + for( i=digest1_index_begin; i<=digest1_index_end; i++) { - // 今回取得可能な最小単位のイメージを同期読み込み。 - nowgfp = ftell( gfp); - fseek( gfp, position, SEEK_SET); - u32 available = fread( buffer, end - position, 1, gfp); - // 今回の検証中に必要となりそうなブロックを前もってアクセス。 -// (void)CARDi_TouchRomHashBlock(context, sector); - // 取得したイメージの正当性を検証。 - while (available >= sectunit) + if( !context->hash_correct[i]) { - CARDRomHashBlock *block = CARDi_TouchRomHashBlock(context, sector); - u32 slot = sector - block->index * blckunit; - while ((slot < blckunit) && (available >= sectunit)) - { - // 必要ならここでブロック単位のハッシュテーブルを検証。 - if (block != context->valid_block) - { - OSIntrMode bak_cpsr = OS_DisableInterrupts(); - while (context->loading_block) - { - OS_SleepThread(NULL); - } - if (block == context->loaded_block) - { - context->loaded_block = block->next; - } - (void)OS_RestoreInterrupts(bak_cpsr); - CARDi_CompareHash(&context->master_hash[block->index * CARD_ROM_HASH_SIZE], - block->hash, CARD_ROM_HASH_SIZE * blckunit); - block->next = context->valid_block; - context->valid_block = block; - } - // イメージのハッシュを計算。 - CARDi_CompareHash(&block->hash[slot * CARD_ROM_HASH_SIZE], buffer, sectunit); - position += sectunit; - available -= sectunit; - buffer = ((u8 *)buffer) + sectunit; - slot += 1; - sector += 1; - } + *ret_digest1 = 0; } - } -} -*/ - -#if 0 -/*---------------------------------------------------------------------------* - Name: CARDi_ReadRomHashImageDirect - - Description: ハッシュコンテキストへキャッシュせずに転送先へ直接コピー。 - - Arguments: context : CARDRomHashContext構造体。 - buffer : 転送先バッファ。(4バイト整合されている必要がある) - offset : アクセスするROMオフセット。 - length : 転送サイズ。 - - Returns: None. - *---------------------------------------------------------------------------*/ -static void CARDi_ReadRomHashImageDirect(CARDRomHashContext *context, void *buffer, u32 offset, u32 length) -{ - const u32 sectunit = context->bytes_per_sector; - const u32 blckunit = context->sectors_per_block; - u32 position = offset; - u32 end = length + offset; - u32 sector = CARDi_GetHashSectorIndex(context, position); - while (position < end) - { - // 今回取得可能な最小単位のイメージを同期読み込み。 - u32 available = (u32)(*context->ReadSync)(context->userdata, buffer, position, end - position); - // 今回の検証中に必要となりそうなブロックを前もってアクセス。 - (void)CARDi_TouchRomHashBlock(context, sector); - // 次回に必要となる分の読み込み準備を要求。 - if (context->ReadAsync && (position + available < end)) + if( !context->master_hash_correct[i/context->sectors_per_block]) { - (void)(*context->ReadAsync)(context->userdata, NULL, position + available, end - (position + available)); - } - // 取得したイメージの正当性を検証。 - while (available >= sectunit) - { - CARDRomHashBlock *block = CARDi_TouchRomHashBlock(context, sector); - u32 slot = sector - block->index * blckunit; - while ((slot < blckunit) && (available >= sectunit)) - { - // 必要ならここでブロック単位のハッシュテーブルを検証。 - if (block != context->valid_block) - { - OSIntrMode bak_cpsr = OS_DisableInterrupts(); - while (context->loading_block) - { - OS_SleepThread(NULL); - } - if (block == context->loaded_block) - { - context->loaded_block = block->next; - } - (void)OS_RestoreInterrupts(bak_cpsr); - CARDi_CompareHash(&context->master_hash[block->index * CARD_ROM_HASH_SIZE], - block->hash, CARD_ROM_HASH_SIZE * blckunit); - block->next = context->valid_block; - context->valid_block = block; - } - // イメージのハッシュを計算。 - CARDi_CompareHash(&block->hash[slot * CARD_ROM_HASH_SIZE], buffer, sectunit); - position += sectunit; - available -= sectunit; - buffer = ((u8 *)buffer) + sectunit; - slot += 1; - sector += 1; - } + *ret_digest2 = 0; } } } -/*---------------------------------------------------------------------------* - Name: MATH_CalcHMACSHA1 - - Description: HMAC-SHA-1 を計算する。 - - Arguments: digest HMAC-SHA-1 値を格納する場所へのポインタ - data 入力データのポインタ - dataLength 入力データ長 - key 鍵のポインタ - keyLength 鍵の長さ - - Returns: None. - *---------------------------------------------------------------------------*/ -void MATH_CalcHMACSHA1(void *digest, const void *bin_ptr, u32 bin_len, const void *key_ptr, u32 key_len) -{ - MATHSHA1Context context; - unsigned char hash_buf[ MATH_SHA1_DIGEST_SIZE ]; /* ハッシュ関数から得るハッシュ値 */ - - MATHiHMACFuncs hash2funcs = { - MATH_SHA1_DIGEST_SIZE, - (512/8), - }; - - hash2funcs.context = &context; - hash2funcs.hash_buf = hash_buf; - hash2funcs.HashReset = (void (*)(void*)) MATH_SHA1Init; - hash2funcs.HashSetSource = (void (*)(void*, const void*, u32)) MATH_SHA1Update; - hash2funcs.HashGetDigest = (void (*)(void*, void*)) MATH_SHA1GetHash; - - MATHi_CalcHMAC(digest, bin_ptr, bin_len, key_ptr, key_len, &hash2funcs); -} - - -/*---------------------------------------------------------------------------* - Name: CARDi_CompareHash - - Description: ハッシュによる正当性チェック。(HMAC-SHA1) - - Arguments: hash : 比較基準となるハッシュ値 - src : チェック対象のイメージ - len : チェック対象のサイズ - - Returns: None. - *---------------------------------------------------------------------------*/ -static void CARDi_CompareHash(const void *hash, void *buffer, u32 length) -{ - u8 tmphash[CARD_ROM_HASH_SIZE]; - - MATH_CalcHMACSHA1(tmphash, buffer, length, CARDiHmacKey, sizeof(CARDiHmacKey)); - - if (MI_CpuComp8(hash, tmphash, sizeof(tmphash)) != 0) - { - printf("ROM-hash comparation error!\n"); - } -} -#endif diff --git a/build/tools/TamperDetectorForSrl/card_hash.h b/build/tools/TamperDetectorForSrl/card_hash.h index bc2b0ef..2ca5a4e 100644 --- a/build/tools/TamperDetectorForSrl/card_hash.h +++ b/build/tools/TamperDetectorForSrl/card_hash.h @@ -2,6 +2,8 @@ #ifndef CARD_HASH_H_ #define CARD_HASH_H_ +#include "entry.h" + // 現時点でCARDライブラリが妥当と判断した定数。 // パフォーマンス計測の結果によって適宜変更してもよい。 @@ -39,7 +41,6 @@ CARDRomRegion; // セクタも別途リスト構造として管理する必要がある。 typedef struct CARDRomHashContext { - u32 rom_size; // ROMヘッダから取得する基本設定 CARDRomRegion area_ntr; CARDRomRegion area_ltd; @@ -77,6 +78,9 @@ typedef struct CARDRomHashContext */ u8 *buffer; u8 *hash; + + u8 *master_hash_correct; + u8 *hash_correct; } CARDRomHashContext; @@ -85,6 +89,7 @@ void CARDi_Init( CARDRomHashContext *context, RomHeader* header); void CARDi_CheckHash(CARDRomHashContext *context, FILE* fp, u32 sect, u32 size, RomHeader* header); bool Digest2Check(CARDRomHashContext *context, FILE* fp, RomHeader* header); void CARD_CheckHash(CARDRomHashContext *context, RomHeader* header, FILE* fp); +void CARD_CheckFileDigest(CARDRomHashContext *context, MyFileEntry* file_entry, u8* ret_digest1, u8* ret_digest2); #endif //CARD_HASH_H_ diff --git a/build/tools/TamperDetectorForSrl/checker.cpp b/build/tools/TamperDetectorForSrl/checker.cpp index 34497fa..8ea06e4 100644 --- a/build/tools/TamperDetectorForSrl/checker.cpp +++ b/build/tools/TamperDetectorForSrl/checker.cpp @@ -3,6 +3,7 @@ #include "checker.h" //#include "nitro_romheader.h" #include "twl_format_rom.h" +#include "card_hash.h" extern Entry gEntry; extern Entry mEntry; @@ -844,7 +845,7 @@ void Checker::ExportGenuineBmpFiles( Entry* gEntry, PrintLevel print_enable) } /* ディレクトリとファイルをチェックする */ -void Checker::CheckAllEntries( Entry* gEntry, Entry* mEntry) +void Checker::CheckAllEntries( CARDRomHashContext *context, Entry* gEntry, Entry* mEntry) { { MyDirEntry *currentEntry = gEntry->dirEntry; @@ -895,6 +896,26 @@ void Checker::CheckAllEntries( Entry* gEntry, Entry* mEntry) false, PRINT_LEVEL_1) == false) { currentEntry->modified = true; // 改竄フラグ + } + { + u8 d1, d2; + CARD_CheckFileDigest( context, hisEntry, &d1, &d2); + if( d1) + { + printf( "(ファイル - digest1 検証はOK)\n"); + } + else + { + printf( "(ファイル - digest1 検証はNG)\n"); + } + if( d2) + { + printf( "(digest1 - digest2 検証はOK)\n"); + } + else + { + printf( "(digest1 - digest2 検証はNG)\n"); + } printf( "\n"); } } diff --git a/build/tools/TamperDetectorForSrl/checker.h b/build/tools/TamperDetectorForSrl/checker.h index 97167b7..4c0c137 100644 --- a/build/tools/TamperDetectorForSrl/checker.h +++ b/build/tools/TamperDetectorForSrl/checker.h @@ -10,6 +10,7 @@ #include "twl_format_rom.h" #include "banner.h" #include "entry.h" +#include "card_hash.h" typedef struct { @@ -62,7 +63,7 @@ class Checker bool FindEntry( u32 fnt_offset, u16 entry_id, RomHeader* headerBuf, FILE* fp, Entry* entry, u16 parent_id, PrintLevel print_enable); void FindAllocation( u16 entry_id, RomHeader* headerBuf, FILE* fp, Entry* entry, PrintLevel print_enable); - void CheckAllEntries( Entry* gEntry, Entry* mEntry); + void CheckAllEntries( CARDRomHashContext *context, Entry* gEntry, Entry* mEntry); /* ROM内のBMPファイルを全て切り出して出力する */ void ExportGenuineBmpFiles( Entry* gEntry, PrintLevel print_enable); diff --git a/build/tools/TamperDetectorForSrl/main.cpp b/build/tools/TamperDetectorForSrl/main.cpp index 919ef06..518a920 100644 --- a/build/tools/TamperDetectorForSrl/main.cpp +++ b/build/tools/TamperDetectorForSrl/main.cpp @@ -59,6 +59,8 @@ bool int_bits(void) int main (int argc, char *argv[]) { + CARDRomHashContext context; + // 処理系の unsignedビット数が想定外ならエラー終了(types.hを変更してビルドし直してください) if( !int_bits()) { @@ -91,8 +93,6 @@ int main (int argc, char *argv[]) // ダイジェスト検証(digest1, digest2) { - CARDRomHashContext context; - CARDi_Init( &context, &mHeaderBuf); CARD_CheckHash( &context, &mHeaderBuf, mfp); } @@ -116,7 +116,7 @@ int main (int argc, char *argv[]) { mEntry.FollowParent(); mEntry.AutoSetFullPath(); - checker.CheckAllEntries( &gEntry, &mEntry); + checker.CheckAllEntries( &context, &gEntry, &mEntry); } checker.ExportGenuineBmpFiles( &gEntry, PRINT_LEVEL_0); /*