diff --git a/build/libraries_sysmenu/sysmenu/ARM9/include/fs_wram.h b/build/libraries_sysmenu/sysmenu/ARM9/include/fs_wram.h index bf1a5955..2031a60e 100644 --- a/build/libraries_sysmenu/sysmenu/ARM9/include/fs_wram.h +++ b/build/libraries_sysmenu/sysmenu/ARM9/include/fs_wram.h @@ -30,10 +30,13 @@ extern "C" { Read/Write中のWRAMにデータがある状態で呼び出されるAPI 改ざんした場合は、改ざん後のデータが有効となることに注意 addr データがあるアドレス + orig_addr 本来のRead格納先/Write元アドレス len 有効なデータサイズ + wram 使用しているWRAM + slot 使用しているスロット 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 diff --git a/build/libraries_sysmenu/sysmenu/ARM9/src/fs_wram.c b/build/libraries_sysmenu/sysmenu/ARM9/src/fs_wram.c index c12c3bfc..0bd57ae3 100644 --- a/build/libraries_sysmenu/sysmenu/ARM9/src/fs_wram.c +++ b/build/libraries_sysmenu/sysmenu/ARM9/src/fs_wram.c @@ -265,7 +265,7 @@ static BOOL FSi_ReadWram(u8* dest, u32 len, MIWramPos wram, s32 slot, FSWramCall const u8* s = src + done; u8* d = dest + done; 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 ); } } @@ -326,7 +326,7 @@ static BOOL FSi_WriteWram(const u8* src, u32 len, MIWramPos wram, s32 slot, FSWr u8* d = dest + done; u32 u = unit - done < FS_WRAM_CALLBACK_UNIT ? unit - done : FS_WRAM_CALLBACK_UNIT; MI_CpuCopyFast( s, d, u ); - callback(d, u, arg); + callback(d, s, u, wram, slot + ret, arg); } } else diff --git a/build/libraries_sysmenu/sysmenu/ARM9/src/title.c b/build/libraries_sysmenu/sysmenu/ARM9/src/title.c index b8fa17fb..5c09dc25 100644 --- a/build/libraries_sysmenu/sysmenu/ARM9/src/title.c +++ b/build/libraries_sysmenu/sysmenu/ARM9/src/title.c @@ -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; 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; cba->hash_length -= 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; 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; cba->hash_length -= 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 - // ヘッダ読み込み完了フラグ + // ヘッダ読み込み完了 if( i == region_header ) { + // ヘッダ読み込み完了フラグを立てる 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 #ifdef LOAD_APP_VIA_WRAM + // NANDアプリをWRAM経由でロードする場合は、転送時にチェックしてしまうので、ここではCARDアプリのみ必要 if( pBootTitle->flags.bootType == LAUNCHER_BOOTTYPE_ROM ) #endif { + prev = OS_GetTick(); // TWL以降のアプリはモジュールの特定領域がAES暗号化されているので、ハッシュチェック前にデクリプトする必要がある。 // ヘッダのデータを使うので、署名チェック後が望ましい。よってこのタイミング。 SYSM_StartDecryptAESRegion( &(head->s) ); + OS_TPrintf("Authenticate : DecryptAESRegion %d ms.\n", OS_TicksToMilliSeconds(OS_GetTick() - prev) ); } // それぞれARM9,7のFLXおよびLTDについてハッシュを計算してヘッダに格納されているハッシュと比較 diff --git a/build/libraries_sysmenu/sysmenu/common/src/decodeAES.c b/build/libraries_sysmenu/sysmenu/common/src/decodeAES.c index 902a1754..bd796f6c 100644 --- a/build/libraries_sysmenu/sysmenu/common/src/decodeAES.c +++ b/build/libraries_sysmenu/sysmenu/common/src/decodeAES.c @@ -30,13 +30,15 @@ // static variable------------------------------------------------------------- #ifdef SDK_ARM9 static BOOL s_finished = FALSE; -void *s_Addr_AESregion[2]; -u32 s_Size_AESregion[2]; -BOOL s_initialized = FALSE; +static void *s_Addr_AESregion[2]; +static u32 s_Size_AESregion[2]; +static BOOL s_initialized = FALSE; +static u8 s_initCounterAES[2][AES_BLOCK_SIZE]; #endif // const data------------------------------------------------------------------ #ifdef SDK_ARM9 +#include // WRAM経由ファイル読み込みのコールバックで使うAESデクリプト処理の初期化 BOOL SYSM_InitDecryptAESRegion_W( ROM_Header_Short *hs ) @@ -131,6 +133,10 @@ BOOL SYSM_InitDecryptAESRegion_W( ROM_Header_Short *hs ) // Workに開発/製品情報を格納 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「シードとゲームコード」をセット if( hs->developer_encrypt ) @@ -161,22 +167,57 @@ BOOL SYSM_InitDecryptAESRegion_W( ROM_Header_Short *hs ) } // 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) -#pragma unused(orig_addr) -#pragma unused(size) - // [TODO:] - // AESデクリプト領域と、ファイルからWRAMに読み込んできた領域の目的地の比較 - // 共通部分となる領域のアドレスとサイズ(WRAMでのアドレス)をWORKに記録し、7で該当領域をデクリプトしてもらう - // 対象となる領域をデクリプトする際に必要なカウンタの値も算出してWORKに入れておく - // 一応、デクリプトする領域のキャッシュもケアしておく - // ついでにtarget1なのか2なのかもFIFOで送ると良いかも + int l; if( !s_initialized ) { 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デクリプト処理 @@ -349,7 +390,7 @@ static void SYSMi_DecryptAESRegion_sub( int target ) { 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; } @@ -358,6 +399,7 @@ static void SYSMi_DecryptAESRegion_sub( int 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 diff --git a/build/tests/RelocateChecker/ARM7/src/main.c b/build/tests/RelocateChecker/ARM7/src/main.c index 11c379dd..4f4db021 100644 --- a/build/tests/RelocateChecker/ARM7/src/main.c +++ b/build/tests/RelocateChecker/ARM7/src/main.c @@ -147,12 +147,9 @@ TwlSpMain(void) (void)OS_EnableInterrupts(); // ファイルシステム初期化 - FS_Init(FS_DMA_NOT_USE); - FS_CreateReadServerThread(THREAD_PRIO_FS); if (OS_IsRunOnTwl() == TRUE) { - InitializeFatfs(); // FATFS 初期化 #ifndef SDK_NOCRYPTO AES_Init(); // AES 初期化 #endif @@ -170,8 +167,6 @@ TwlSpMain(void) // SPI 初期化 SPI_Init(THREAD_PRIO_SPI); - BOOT_Init(); - while (TRUE) { OS_Halt(); @@ -180,7 +175,6 @@ TwlSpMain(void) { OS_ResetSystem(); } - BOOT_WaitStart(); } } diff --git a/build/tests/RelocateChecker/ARM9/Makefile.1 b/build/tests/RelocateChecker/ARM9/Makefile.1 index ef9f131a..9ae825da 100644 --- a/build/tests/RelocateChecker/ARM9/Makefile.1 +++ b/build/tests/RelocateChecker/ARM9/Makefile.1 @@ -57,7 +57,7 @@ LLIBRARY_DIRS += ../crt/ARM9/obj/ARM9-TS.HYB/$(TWL_BUILD_DIR) CRT0_O = crt0_rc.FLX.TWL.o //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 diff --git a/include/sysmenu/sysmenu_lib/common/sysmenu_api.h b/include/sysmenu/sysmenu_lib/common/sysmenu_api.h index 3688cbed..8886c38d 100644 --- a/include/sysmenu/sysmenu_lib/common/sysmenu_api.h +++ b/include/sysmenu/sysmenu_lib/common/sysmenu_api.h @@ -106,7 +106,8 @@ extern AuthResult SYSM_TryToBootTitle( TitleProperty *pBootTitle ); // pBootT // AES領域デクリプト extern void SYSM_StartDecryptAESRegion( ROM_Header_Short *hs ); // 起動するROMの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 ); // タッチパネルキャリブレーション