WRAM経由ロード実装(不具合アリ)

git-svn-id: file:///Users/lillianskinner/Downloads/platinum/twl/TwlIPL/trunk@1291 b08762b0-b915-fc4b-9d8c-17b2551a87ff
This commit is contained in:
yoshida_teruhisa 2008-05-08 07:37:23 +00:00
parent ec06975d51
commit 16a895d5df
7 changed files with 82 additions and 28 deletions

View File

@ -30,10 +30,13 @@ extern "C" {
Read/Write中のWRAMにデータがある状態で呼び出されるAPI Read/Write中のWRAMにデータがある状態で呼び出されるAPI
addr addr
orig_addr Read格納先/Write元アドレス
len len
wram 使WRAM
slot 使
arg APIに渡した引数 arg APIに渡した引数
*/ */
typedef void (*FSWramCallback)(const void* addr, u32 len, void* arg); typedef void (*FSWramCallback)(const void* addr, const void* orig_addr, u32 len, MIWramPos wram, s32 slot, void* arg);
/* /*
FS_InitWramTransfer FS_InitWramTransfer

View File

@ -265,7 +265,7 @@ static BOOL FSi_ReadWram(u8* dest, u32 len, MIWramPos wram, s32 slot, FSWramCall
const u8* s = src + done; const u8* s = src + done;
u8* d = dest + done; u8* d = dest + done;
u32 u = unit - done < FS_WRAM_CALLBACK_UNIT ? unit - done : FS_WRAM_CALLBACK_UNIT; u32 u = unit - done < FS_WRAM_CALLBACK_UNIT ? unit - done : FS_WRAM_CALLBACK_UNIT;
callback(s, u, arg); callback(s, d, u, wram, slot + ret, arg);
MI_CpuCopyFast( s, d, u ); MI_CpuCopyFast( s, d, u );
} }
} }
@ -326,7 +326,7 @@ static BOOL FSi_WriteWram(const u8* src, u32 len, MIWramPos wram, s32 slot, FSWr
u8* d = dest + done; u8* d = dest + done;
u32 u = unit - done < FS_WRAM_CALLBACK_UNIT ? unit - done : FS_WRAM_CALLBACK_UNIT; u32 u = unit - done < FS_WRAM_CALLBACK_UNIT ? unit - done : FS_WRAM_CALLBACK_UNIT;
MI_CpuCopyFast( s, d, u ); MI_CpuCopyFast( s, d, u );
callback(d, u, arg); callback(d, s, u, wram, slot + ret, arg);
} }
} }
else else

View File

@ -369,19 +369,25 @@ static s32 ReadFile(FSFile* pf, void* buffer, s32 size)
// //
// ============================================================================ // ============================================================================
static void SYSMi_CalcHMACSHA1Callback(const void* addr, u32 len, void* arg) static void SYSMi_CalcHMACSHA1Callback(const void* addr, const void* orig_addr, u32 len, MIWramPos wram, s32 slot, void* arg)
{ {
CalcHMACSHA1CallbackArg *cba = (CalcHMACSHA1CallbackArg *)arg; CalcHMACSHA1CallbackArg *cba = (CalcHMACSHA1CallbackArg *)arg;
u32 calc_len = ( cba->hash_length < len ? cba->hash_length : len ); u32 calc_len = ( cba->hash_length < len ? cba->hash_length : len );
MI_SwitchWramSlot( wram, slot, MI_WRAM_SIZE_32KB, MI_WRAM_ARM9, MI_WRAM_ARM7 );// Wramを7にスイッチ
SYSM_StartDecryptAESRegion_W( addr, orig_addr, len ); // AES領域デクリプト
MI_SwitchWramSlot( wram, slot, MI_WRAM_SIZE_32KB, MI_WRAM_ARM7, MI_WRAM_ARM9 );// Wramが7にスイッチしてしまっているので戻す
if( calc_len == 0 ) return; if( calc_len == 0 ) return;
cba->hash_length -= calc_len; cba->hash_length -= calc_len;
SVC_HMACSHA1Update( &cba->ctx, addr, calc_len ); SVC_HMACSHA1Update( &cba->ctx, addr, calc_len );
} }
static void SYSMi_CalcSHA1Callback(const void* addr, u32 len, void* arg) static void SYSMi_CalcSHA1Callback(const void* addr, const void* orig_addr, u32 len, MIWramPos wram, s32 slot, void* arg)
{ {
CalcSHA1CallbackArg *cba = (CalcSHA1CallbackArg *)arg; CalcSHA1CallbackArg *cba = (CalcSHA1CallbackArg *)arg;
u32 calc_len = ( cba->hash_length < len ? cba->hash_length : len ); u32 calc_len = ( cba->hash_length < len ? cba->hash_length : len );
MI_SwitchWramSlot( wram, slot, MI_WRAM_SIZE_32KB, MI_WRAM_ARM9, MI_WRAM_ARM7 );// Wramを7にスイッチ
SYSM_StartDecryptAESRegion_W( addr, orig_addr, len ); // AES領域デクリプト
MI_SwitchWramSlot( wram, slot, MI_WRAM_SIZE_32KB, MI_WRAM_ARM7, MI_WRAM_ARM9 );// Wramが7にスイッチしてしまっているので戻す
if( calc_len == 0 ) return; if( calc_len == 0 ) return;
cba->hash_length -= calc_len; cba->hash_length -= calc_len;
SVC_SHA1Update( &cba->ctx, addr, calc_len ); SVC_SHA1Update( &cba->ctx, addr, calc_len );
@ -609,10 +615,15 @@ OS_TPrintf("RebootSystem failed: cant read file(%d, %d)\n", source[i], len);
} }
#endif // LOAD_APP_VIA_WRAM #endif // LOAD_APP_VIA_WRAM
// ヘッダ読み込み完了フラグ // ヘッダ読み込み完了
if( i == region_header ) if( i == region_header )
{ {
// ヘッダ読み込み完了フラグを立てる
SYSMi_GetWork()->flags.common.isHeaderLoadCompleted = TRUE; SYSMi_GetWork()->flags.common.isHeaderLoadCompleted = TRUE;
#ifdef LOAD_APP_VIA_WRAM
// WRAM経由ロードの場合はAES初期化
(void)SYSM_InitDecryptAESRegion_W( (ROM_Header_Short *)destaddr[region_header] );
#endif // LOAD_APP_VIA_WRAM
} }
} }
@ -867,12 +878,15 @@ static AuthResult SYSMi_AuthenticateTWLHeader( TitleProperty *pBootTitle )
#endif #endif
#ifdef LOAD_APP_VIA_WRAM #ifdef LOAD_APP_VIA_WRAM
// NANDアプリをWRAM経由でロードする場合は、転送時にチェックしてしまうので、ここではCARDアプリのみ必要
if( pBootTitle->flags.bootType == LAUNCHER_BOOTTYPE_ROM ) if( pBootTitle->flags.bootType == LAUNCHER_BOOTTYPE_ROM )
#endif #endif
{ {
prev = OS_GetTick();
// TWL以降のアプリはモジュールの特定領域がAES暗号化されているので、ハッシュチェック前にデクリプトする必要がある。 // TWL以降のアプリはモジュールの特定領域がAES暗号化されているので、ハッシュチェック前にデクリプトする必要がある。
// ヘッダのデータを使うので、署名チェック後が望ましい。よってこのタイミング。 // ヘッダのデータを使うので、署名チェック後が望ましい。よってこのタイミング。
SYSM_StartDecryptAESRegion( &(head->s) ); SYSM_StartDecryptAESRegion( &(head->s) );
OS_TPrintf("Authenticate : DecryptAESRegion %d ms.\n", OS_TicksToMilliSeconds(OS_GetTick() - prev) );
} }
// それぞれARM9,7のFLXおよびLTDについてハッシュを計算してヘッダに格納されているハッシュと比較 // それぞれARM9,7のFLXおよびLTDについてハッシュを計算してヘッダに格納されているハッシュと比較

View File

@ -30,13 +30,15 @@
// static variable------------------------------------------------------------- // static variable-------------------------------------------------------------
#ifdef SDK_ARM9 #ifdef SDK_ARM9
static BOOL s_finished = FALSE; static BOOL s_finished = FALSE;
void *s_Addr_AESregion[2]; static void *s_Addr_AESregion[2];
u32 s_Size_AESregion[2]; static u32 s_Size_AESregion[2];
BOOL s_initialized = FALSE; static BOOL s_initialized = FALSE;
static u8 s_initCounterAES[2][AES_BLOCK_SIZE];
#endif #endif
// const data------------------------------------------------------------------ // const data------------------------------------------------------------------
#ifdef SDK_ARM9 #ifdef SDK_ARM9
#include <twl/aes/ARM9/aes_internal.h>
// WRAM経由ファイル読み込みのコールバックで使うAESデクリプト処理の初期化 // WRAM経由ファイル読み込みのコールバックで使うAESデクリプト処理の初期化
BOOL SYSM_InitDecryptAESRegion_W( ROM_Header_Short *hs ) BOOL SYSM_InitDecryptAESRegion_W( ROM_Header_Short *hs )
@ -131,6 +133,10 @@ BOOL SYSM_InitDecryptAESRegion_W( ROM_Header_Short *hs )
// Workに開発/製品情報を格納 // Workに開発/製品情報を格納
SYSMi_GetWork()->isDeveloperAESMode = ( hs->developer_encrypt ? TRUE : FALSE ); SYSMi_GetWork()->isDeveloperAESMode = ( hs->developer_encrypt ? TRUE : FALSE );
// カウンタの初期値記録
MI_CpuCopy8( hs->main_static_digest, s_initCounterAES[0], AES_BLOCK_SIZE ); // 領域1初期値
MI_CpuCopy8( hs->sub_static_digest, s_initCounterAES[1], AES_BLOCK_SIZE ); // 領域2初期値
// Workに「鍵」or「シードとゲームコード」をセット // Workに「鍵」or「シードとゲームコード」をセット
if( hs->developer_encrypt ) if( hs->developer_encrypt )
@ -161,22 +167,57 @@ BOOL SYSM_InitDecryptAESRegion_W( ROM_Header_Short *hs )
} }
// WRAM経由ファイル読み込みのコールバックで使うAESデクリプト処理関数 // WRAM経由ファイル読み込みのコールバックで使うAESデクリプト処理関数
void SYSM_StartDecryptAESRegion_W( void *wram_addr, void *orig_addr, u32 size ) // 注意キャッシュケア済み、WRAMが7に倒れ済みである事を前提とする
void SYSM_StartDecryptAESRegion_W( const void *wram_addr, const void *orig_addr, u32 size )
{ {
#pragma unused(wram_addr) int l;
#pragma unused(orig_addr)
#pragma unused(size)
// [TODO:]
// AESデクリプト領域と、ファイルからWRAMに読み込んできた領域の目的地の比較
// 共通部分となる領域のアドレスとサイズWRAMでのアドレスをWORKに記録し、7で該当領域をデクリプトしてもらう
// 対象となる領域をデクリプトする際に必要なカウンタの値も算出してWORKに入れておく
// 一応、デクリプトする領域のキャッシュもケアしておく
// ついでにtarget1なのか2なのかもFIFOで送ると良いかも
if( !s_initialized ) if( !s_initialized )
{ {
return; return;
} }
SYSMi_GetWork()->addr_AESregion[0] = NULL;
SYSMi_GetWork()->addr_AESregion[1] = NULL;
// target1と2について両方調べる
for( l=0;l<2;l++ )
{
u32 start;
u32 end;
// AESデクリプト領域と、ファイルからWRAMに読み込んできた領域の目的地の比較
if( ( ((u32)orig_addr + size) < (u32)s_Addr_AESregion[l] ) ||
( ((u32)s_Addr_AESregion[l] + s_Size_AESregion[l]) < (u32)orig_addr )
)
{
continue;
}
// 上で比較した結果、共通部分があればデクリプトする領域なので括り出す
start = ( orig_addr < s_Addr_AESregion[l] ) ? (u32)s_Addr_AESregion[l] : (u32)orig_addr;
end = ( (u32)orig_addr + size < (u32)s_Addr_AESregion[l] + s_Size_AESregion[l] ) ?
(u32)orig_addr + size : (u32)s_Addr_AESregion[l] + s_Size_AESregion[l];
// デクリプトする領域のアドレスとサイズWRAMに読み込んだ状態でのアドレスとサイズをWORKに記録
SYSMi_GetWork()->addr_AESregion[l] = (void *)( (s32)wram_addr + (start - (u32)orig_addr) );
SYSMi_GetWork()->size_AESregion[l] = end - start;
// 対象となる領域をデクリプトする際に必要なカウンタの値も算出してWORKに入れておく
MI_CpuCopy8( s_initCounterAES[l], SYSMi_GetWork()->counterAES[l], AES_BLOCK_SIZE );
AESi_AddToCounter( (AESCounter *)SYSMi_GetWork()->counterAES[l], (start - (u32)s_Addr_AESregion[l]) / AES_BLOCK_SIZE );
// OS_TPrintf( "SYSM_StartDecryptAESRegion_W(arm9):wramaddr:0x%0.8x start:0x%0.8x end:0x%0.8x counter offset: %d.\n",wram_addr, start,end,(start - (u32)s_Addr_AESregion[l]) / AES_BLOCK_SIZE );
// 7にデクリプトしてもらうtarget1なのか2なのかFIFOで送る
s_finished = FALSE;
while( PXI_SendWordByFifo(PXI_FIFO_TAG_DECRYPTAES, (u32)(PXI_FIFO_DATA_DECRYPTAES_W_TARGET1 + l), FALSE) != PXI_FIFO_SUCCESS )
{
OS_TPrintf( "SYSM_StartDecryptAESRegion_W(arm9):ARM9 PXI send error.\n" );
}
// ARM7からの完了通知を受け取って完了
while( !s_finished )
{
OS_WaitAnyIrq();
}
}
} }
// べた書きAESデクリプト処理 // べた書きAESデクリプト処理
@ -349,7 +390,7 @@ static void SYSMi_DecryptAESRegion_sub( int target )
{ {
if( SYSMi_GetWork()->addr_AESregion[target]==NULL ) if( SYSMi_GetWork()->addr_AESregion[target]==NULL )
{ {
OS_TPrintf( "SYSMi_DecryptAESRegion_sub(arm7):Target Addr Error!\n" ); OS_TPrintf( "SYSMi_DecryptAESRegion_sub(arm7):Target%d Addr Error!\n",target+1 );
return; return;
} }
@ -358,6 +399,7 @@ static void SYSMi_DecryptAESRegion_sub( int target )
// 鍵ロードして暗号化領域の復号開始 // 鍵ロードして暗号化領域の復号開始
ReplaceWithAes( SYSMi_GetWork()->addr_AESregion[target], SYSMi_GetWork()->size_AESregion[target] ); ReplaceWithAes( SYSMi_GetWork()->addr_AESregion[target], SYSMi_GetWork()->size_AESregion[target] );
// OS_TPrintf( "SYSMi_DecryptAESRegion_sub(arm7):target:%d addr:0x%0.8x size:0x%x\n",target+1, SYSMi_GetWork()->addr_AESregion[target], SYSMi_GetWork()->size_AESregion[target] );
} }
#endif //ifdef SDK_ARM9 #endif //ifdef SDK_ARM9

View File

@ -147,12 +147,9 @@ TwlSpMain(void)
(void)OS_EnableInterrupts(); (void)OS_EnableInterrupts();
// ファイルシステム初期化 // ファイルシステム初期化
FS_Init(FS_DMA_NOT_USE);
FS_CreateReadServerThread(THREAD_PRIO_FS);
if (OS_IsRunOnTwl() == TRUE) if (OS_IsRunOnTwl() == TRUE)
{ {
InitializeFatfs(); // FATFS <20>‰Šú‰»
#ifndef SDK_NOCRYPTO #ifndef SDK_NOCRYPTO
AES_Init(); // AES 初期化 AES_Init(); // AES 初期化
#endif #endif
@ -170,8 +167,6 @@ TwlSpMain(void)
// SPI 初期化 // SPI 初期化
SPI_Init(THREAD_PRIO_SPI); SPI_Init(THREAD_PRIO_SPI);
BOOT_Init();
while (TRUE) while (TRUE)
{ {
OS_Halt(); OS_Halt();
@ -180,7 +175,6 @@ TwlSpMain(void)
{ {
OS_ResetSystem(); OS_ResetSystem();
} }
BOOT_WaitStart();
} }
} }

View File

@ -57,7 +57,7 @@ LLIBRARY_DIRS += ../crt/ARM9/obj/ARM9-TS.HYB/$(TWL_BUILD_DIR)
CRT0_O = crt0_rc.FLX.TWL.o CRT0_O = crt0_rc.FLX.TWL.o
//MAKEROM_FLAGS += -DTITLEID_LO='$(TITLEID_LO)' //MAKEROM_FLAGS += -DTITLEID_LO='$(TITLEID_LO)'
MAKEROM_FLAGS += -F -DTITLEID_LO='$(TITLEID_LO)' MAKEROM_FLAGS += -F -DTITLEID_LO='$(TITLEID_LO)' -a
include $(TWL_IPL_RED_ROOT)/build/tests/RelocateChecker/buildtools/commondefs include $(TWL_IPL_RED_ROOT)/build/tests/RelocateChecker/buildtools/commondefs

View File

@ -106,7 +106,8 @@ extern AuthResult SYSM_TryToBootTitle( TitleProperty *pBootTitle ); // pBootT
// AES領域デクリプト // AES領域デクリプト
extern void SYSM_StartDecryptAESRegion( ROM_Header_Short *hs ); // 起動するROMのAES暗号化領域のデクリプト開始 extern void SYSM_StartDecryptAESRegion( ROM_Header_Short *hs ); // 起動するROMのAES暗号化領域のデクリプト開始
extern BOOL SYSM_InitDecryptAESRegion_W( ROM_Header_Short *hs ); // WRAM経由ファイル読み込みのコールバックで使うAESデクリプト処理の初期化 extern BOOL SYSM_InitDecryptAESRegion_W( ROM_Header_Short *hs ); // WRAM経由ファイル読み込みのコールバックで使うAESデクリプト処理の初期化
extern void SYSM_StartDecryptAESRegion_W( void *wram_addr, void *orig_addr, u32 size ); // WRAM経由ファイル読み込みのコールバックで使うAESデクリプト処理関数 extern void SYSM_StartDecryptAESRegion_W( const void *wram_addr, const void *orig_addr, u32 size );
// WRAM経由ファイル読み込みのコールバックで使うAESデクリプト処理関数
// デバイス制御 // デバイス制御
extern void SYSM_CaribrateTP( void ); // タッチパネルキャリブレーション extern void SYSM_CaribrateTP( void ); // タッチパネルキャリブレーション