DSカードのDHTチェックをベタ実装(phase1はロード時に行う予定)(デバッガ起動時無効、既存のNTRタイトルのみ)

ホワイトリスト署名チェックを実装(デバッガ起動時無効、実質的には製品版マスタリングされたNTRカードのみ製品版ボンディングオプションのボード上で起動可能)
HOTSWからDHT_TEST関係のコードを削除(紛らわしいので)

git-svn-id: file:///Users/lillianskinner/Downloads/platinum/twl/TwlIPL/trunk@1439 b08762b0-b915-fc4b-9d8c-17b2551a87ff
This commit is contained in:
yoshida_teruhisa 2008-05-21 06:49:24 +00:00
parent 30ac4805cb
commit 2f2e69823a
5 changed files with 147 additions and 115 deletions

View File

@ -38,13 +38,6 @@ SRCS = blowfish.c \
TARGET_LIB = libhotsw_sp$(TWL_LIBSUFFIX).a
ifneq ($(DHT_TEST),)
MACRO_FLAGS += -DDHT_TEST
ifeq ($(DO_NOT_SHOW_LAUNCHER),TRUE)
MACRO_FLAGS += -DDO_NOT_SHOW_LAUNCHER
endif
endif
include $(TWL_IPL_RED_ROOT)/build/buildtools/commondefs
INSTALL_TARGETS = $(TARGETS)

View File

@ -183,13 +183,6 @@ static CardSecureModeFunction s_funcTable[] = {
{ReadIDSecure_ROMEMU, ReadSegSecure_ROMEMU, SwitchONPNGSecure_ROMEMU, ChangeModeSecure_ROMEMU}
};
#ifdef DHT_TEST
#include <twl/os/ARM7/debugLED.h>
#include <sysmenu/dht/dht.h>
DHTFile* dht;
static DHTPhase2Work* p2work = (void*)0x02e80000;
#endif
// Global Values ------------------------------------------------------------
BLOWFISH_CTX HotSwBlowfishInitTableBufDS;
CardThreadData HotSwThreadData;
@ -452,9 +445,7 @@ static HotSwState LoadCardData(void)
s_cbData.twlFlg = TRUE;
}
else{
#ifdef DHT_TEST
if ( !s_cbData.pBootSegBuf->rh.s.enable_nitro_whitelist_signature )
#endif
// NTRカードの場合はRomHeaderバッファの1ページ目以降をクリアしておく。
MI_CpuClearFast((void *)(SYSM_CARD_ROM_HEADER_BAK + PAGE_SIZE), SYSM_APP_ROM_HEADER_SIZE - PAGE_SIZE);
}
@ -1141,81 +1132,6 @@ static HotSwState LoadStaticModule(void)
(void)CheckStaticModuleHash();
#endif
}
#ifdef DHT_TEST
else
{
SVCHMACSHA1Context ctx;
const u8* hash0;
const u8* hash1;
if ( !s_cbData.pBootSegBuf->rh.s.enable_nitro_whitelist_signature ) // ホワイトリストエントリ
{
const DHTDatabase* db;
while (!dht)
{
OS_Sleep(1);
}
OS_SetDebugLED(0x00);
OS_TPrintf("Searching DHT for %.4s(%02X)...", s_cbData.pBootSegBuf->rh.s.game_code, s_cbData.pBootSegBuf->rh.s.rom_version);
db = DHT_GetDatabase(dht, &s_cbData.pBootSegBuf->rh.s);
if ( !db )
{
OS_TPrintf(" Failed.\n");
OS_SetDebugLED(0xFF);
#ifdef DO_NOT_SHOW_LAUNCHER
while(1){ OS_WaitVBlankIntr(); }
#endif
return HOTSW_HASH_CHECK_ERROR;
}
OS_TPrintf(" Done.\n");
hash0 = db->hash[0];
hash1 = db->hash[1];
}
else // マスタリング済みエントリ
{
hash0 = s_cbData.pBootSegBuf->rh.s.nitro_whitelist_phase1_digest;
hash1 = s_cbData.pBootSegBuf->rh.s.nitro_whitelist_phase2_diegst;
}
OS_TPrintf("DHT Pahse1...");
DHT_CheckHashPhase1Init(&ctx, (ROM_Header_Short*)s_cbData.pBootSegBuf);
if( s_cbData.pBootSegBuf->rh.s.main_size > SECURE_SEGMENT_SIZE )
{
DHT_CheckHashPhase1Update(&ctx, s_cbData.pSecureSegBuf, SECURE_SEGMENT_SIZE);
DHT_CheckHashPhase1Update(&ctx, (u32 *)(s_cbData.arm9Stc + SECURE_SEGMENT_SIZE), s_cbData.pBootSegBuf->rh.s.main_size - SECURE_SEGMENT_SIZE );
}
else
{
OS_SetDebugLED(0x00);
OS_TPrintf("%.4s(%02X) is mastering for DHT format.\n", s_cbData.pBootSegBuf->rh.s.game_code, s_cbData.pBootSegBuf->rh.s.rom_version);
// 署名チェック!!!
DHT_CheckHashPhase1Update(&ctx, s_cbData.pSecureSegBuf, s_cbData.pBootSegBuf->rh.s.main_size);
}
DHT_CheckHashPhase1Update(&ctx, (u32 *)s_cbData.arm7Stc, s_cbData.pBootSegBuf->rh.s.sub_size);
if ( !DHT_CheckHashPhase1Final(&ctx, hash0) )
{
OS_TPrintf(" Failed.\n");
OS_SetDebugLED(0xAA);
#ifdef DO_NOT_SHOW_LAUNCHER
while(1){ OS_WaitVBlankIntr(); }
#endif
return HOTSW_HASH_CHECK_ERROR;
}
OS_TPrintf(" Done.\n");
OS_TPrintf("DHT Pahse2...");
if ( !DHT_CheckHashPhase2(hash1, &s_cbData.pBootSegBuf->rh.s, p2work, ReadImage, &s_cbData) )
{
OS_TPrintf(" Failed.\n");
OS_SetDebugLED(0xCC);
#ifdef DO_NOT_SHOW_LAUNCHER
while(1){ OS_WaitVBlankIntr(); }
#endif
return HOTSW_HASH_CHECK_ERROR;
}
OS_TPrintf(" Done.\n");
}
#endif
return retval;
}

View File

@ -32,10 +32,6 @@ SRCS = hotsw_ctrl.c
TARGET_LIB = libhotsw$(TWL_LIBSUFFIX).a
ifneq ($(DHT_TEST),)
MACRO_FLAGS += -DDHT_TEST
endif
include $(TWL_IPL_RED_ROOT)/build/buildtools/commondefs
INSTALL_TARGETS = $(TARGETS)

View File

@ -46,6 +46,13 @@
#define WRAM_SLOT_FOR_FS 5
#define WRAM_SIZE_FOR_FS MI_WRAM_SIZE_96KB
#include <sysmenu/dht/dht.h>
#define DS_HASH_TABLE_SIZE (256*1024)
static u8 dht_buffer[DS_HASH_TABLE_SIZE] ATTRIBUTE_ALIGN(256);
static DHTFile *const dht = (DHTFile*)dht_buffer;
static const u8* hash0;
static const u8* hash1;
typedef struct MbAuthCode
{
char magic_code[2]; // マジックナンバー
@ -138,6 +145,87 @@ static const u8 nitro_dl_sign_key[AUTH_KEY_BUFFER_LEN] = {
0xA3,0xAE,0xF0,0xA9,0xFA,0x3A,0x70,0x56,0xD2,0x34,0xA9,0xC5,0x9E,0x5D,0xF5,0xE1
};
// ============================================================================
// DHT
// ============================================================================
static BOOL GetDatabaseFilepath(char *path)
{
u8 title[4] = { 'H','N','H','A' };
#if( USE_LCFG_STRING == 0 )
char *title0 = "HNGA";
#endif
u32 titleID_hi;
u32 titleID_lo;
u64 titleID = 0;
#if( USE_LCFG_STRING == 0 )
{
int i;
if( title[0] == 0 ) {
for( i = 0 ; i < 4 ; i++ ) {
title[i] = (u8)*title0++;
}
}
}
#endif
titleID_hi = (( 3 /* Nintendo */ << 16) | 8 /* CHANNEL_DATA_ONLY */ | 4 /* CHANNEL_CARD */ | 2 /* isLaunch */ | 1 /* isSystem */);
titleID_lo = ((u32)( title[0] ) & 0xff) << 24;
titleID_lo |= ((u32)( title[1] )& 0xff) << 16;
titleID_lo |= ((u32)( title[2] )& 0xff) << 8;
titleID_lo |= (u32)( title[3] ) & 0xff;
titleID = ((u64)(titleID_hi) << 32) | (u64)titleID_lo;
// OS_TPrintf( "[DHT] titleID = 0x%08x%08x\n", titleID_hi, titleID_lo);
if( NAM_OK == NAM_GetTitleBootContentPathFast(path, titleID) ) {
OS_TPrintf( "[DHT] File = %s\n", path);
}
else {
OS_TPrintf( "[DHT] Error: NAM_GetTitleBootContentPathFast titleID = 0x%08x0x%08x\n",titleID_hi, titleID_lo);
return FALSE;
}
return TRUE;
}
static void PrepareDHTDatabase(void)
{
char path[256];
if ( GetDatabaseFilepath( path ) )
{
FSFile file;
if ( FS_OpenFileEx(&file, path, FS_FILEMODE_R) )
{
#if 0 // 1 if using attach_dummyromheader
if ( FS_SeekFile(&file, sizeof(ROM_Header), FS_SEEK_SET) )
#endif
{
DHT_PrepareDatabase(dht, &file);
DC_FlushRange(dht, DHT_GetDatabaseLength(dht));
}
FS_CloseFile(&file);
}
}
else
{
MI_CpuClear8(dht, sizeof(DHTHeader));
}
}
static BOOL WrapperFunc_ReadCardData(void* dest, s32 offset, s32 length, void* arg)
{
#pragma unused(arg)
HOTSW_ReadCardData( (void *)offset, dest, (u32)length);
return TRUE;
}
//================================================================================
// for register SCFG_OP
//================================================================================
@ -831,7 +919,7 @@ static AuthResult SYSMi_AuthenticateHeaderWithSign( TitleProperty *pBootTitle, R
);
}
// アプリ種別とボンディングオプションによって使う鍵を分ける
// #define LNC_PDTKEY_DBG
//#define LNC_PDTKEY_DBG
#ifdef LNC_PDTKEY_DBG
{
// 注:デバグ用コード。
@ -886,7 +974,7 @@ static AuthResult SYSMi_AuthenticateHeaderWithSign( TitleProperty *pBootTitle, R
}
}else
{
OS_TPrintf("Authenticate_Header failed: Sign check failed.\n");
OS_TPrintf("Authenticate_Header failed: Sign calc failed.\n");
if(!b_dev) return AUTH_RESULT_AUTHENTICATE_FAILED;
}
OS_TPrintf("Authenticate_Header : total %d ms.\n", OS_TicksToMilliSeconds(OS_GetTick() - start) );
@ -1099,28 +1187,43 @@ static AuthResult SYSMi_AuthenticateNTRDownloadTitle( TitleProperty *pBootTitle)
// NTR版カードアプリのヘッダ認証処理
static AuthResult SYSMi_AuthenticateNTRCardAppHeader( TitleProperty *pBootTitle, ROM_Header *head )
{
AuthResult ret;
AuthResult ret = AUTH_RESULT_SUCCEEDED;
// デバッガで読み込むROMには適用しない
if( SYSM_IsRunOnDebugger() )
{
return AUTH_RESULT_SUCCEEDED;
}
if( head->s.enable_nitro_whitelist_signature )
{
// マスタリング済みNTRカードアプリの署名チェック実はTWLアプリと同じ
ret = SYSMi_AuthenticateHeaderWithSign( pBootTitle, head );
if( ret == AUTH_RESULT_SUCCEEDED )
{
#ifdef DHT_TEST
// [TODO:]retを捕まえてOKならhash値をstatic変数に保存しておき、DHTのphase1とphase2で使う
#endif
hash0 = head->s.nitro_whitelist_phase1_digest;
hash1 = head->s.nitro_whitelist_phase2_diegst;
}
}else
{
// [TODO:]NTRカード ホワイトリスト検索
// ホワイトリスト検索
ret = AUTH_RESULT_SUCCEEDED;
if( ret == AUTH_RESULT_SUCCEEDED )
const DHTDatabase* db;
PrepareDHTDatabase();// [TODO:]遅ければ場所を変えることも検討
if(!dht)
{
#ifdef DHT_TEST
// [TODO:]retを捕まえてOKならhash値をstatic変数に保存しておき、DHTのphase1とphase2で使う
#endif
OS_TPrintf(" Search DHT : database init Failed.\n");
return AUTH_RESULT_AUTHENTICATE_FAILED;
}
OS_TPrintf("Searching DHT for %.4s(%02X)...", head->s.game_code, head->s.rom_version);
db = DHT_GetDatabase(dht, &head->s);
if ( !db )
{
OS_TPrintf(" Search DHT : Failed.\n");
return AUTH_RESULT_AUTHENTICATE_FAILED;
}
hash0 = db->hash[0];
hash1 = db->hash[1];
ret = AUTH_RESULT_SUCCEEDED;
}
return ret;
}
@ -1129,10 +1232,38 @@ static AuthResult SYSMi_AuthenticateNTRCardAppHeader( TitleProperty *pBootTitle,
static AuthResult SYSMi_AuthenticateNTRCardTitle( TitleProperty *pBootTitle)
{
#pragma unused(pBootTitle)
// [TODO:]DHTチェックphase2phase1はstaticの読み込み時に平行処理
#ifdef DHT_TEST
#endif
DHTPhase2Work* p2work;
SVCHMACSHA1Context ctx;
ROM_Header_Short *hs = ( ROM_Header_Short *)SYSM_APP_ROM_HEADER_BUF;
// デバッガで読み込むROMには適用しない
if( SYSM_IsRunOnDebugger() )
{
return AUTH_RESULT_SUCCEEDED;
}
// べた書きphase1テスト([TODO:]実際にはstaticの読み込み時に平行処理)
OS_TPrintf("DHT Phase1...");
DHT_CheckHashPhase1Init(&ctx, hs);
DHT_CheckHashPhase1Update(&ctx, hs->main_ram_address, (s32)hs->main_size);
DHT_CheckHashPhase1Update(&ctx, hs->sub_ram_address, (s32)hs->sub_size);
if ( !DHT_CheckHashPhase1Final(&ctx, hash0) )
{
OS_TPrintf(" DHT Phase1 : Failed.\n");
return AUTH_RESULT_AUTHENTICATE_FAILED;
}
// DHTチェックphase2phase1はstaticの読み込み時に平行処理
OS_TPrintf("DHT Phase2...");
p2work = SYSM_Alloc( sizeof(DHTPhase2Work) );
if ( !DHT_CheckHashPhase2(hash1, hs, p2work, WrapperFunc_ReadCardData, NULL) )
{
OS_TPrintf(" DHT Phase2 : Failed.\n");
SYSM_Free(p2work);
return AUTH_RESULT_AUTHENTICATE_FAILED;
}
SYSM_Free(p2work);
return AUTH_RESULT_SUCCEEDED;
}

View File

@ -129,10 +129,6 @@ void TwlMain( void )
// 各種パラメータの取得------------
pBootTitle = SYSM_ReadParameters(); // 本体設定データ、リセットパラメータのリード、検査用オート起動カード判定、量産ライン用キーショートカット起動判定等のリード
#ifdef DHT_TEST
SYSMi_PrepareDatabase();
#endif
if( SYSM_IsFatalError() ) {
// FATALエラー処理
}