AES復号:WRAM経由ファイル読み込みへの対応開始

git-svn-id: file:///Users/lillianskinner/Downloads/platinum/twl/TwlIPL/trunk@1286 b08762b0-b915-fc4b-9d8c-17b2551a87ff
This commit is contained in:
yoshida_teruhisa 2008-05-07 07:54:59 +00:00
parent fe957af115
commit b9c925a653
3 changed files with 200 additions and 31 deletions

View File

@ -569,7 +569,7 @@ OS_TPrintf("RebootSystem failed: cant seek file(%d)\n", source[i]);
#ifdef LOAD_APP_VIA_WRAM
OS_TPrintf("RebootSystem : Load VIA WRAM %d.\n", i);
// [TODO:]ここで同時にハッシュ計算やAES処理もやってしまう予定
// [TODO:]ここで同時にAES処理もやってしまう予定
// 別スレッドで同じWRAM使おうとすると多分コケるので注意
// コールバック関数に与える引数を初期化してRead

View File

@ -20,15 +20,166 @@
#include <twl/aes/common/types.h>
// define data-----------------------------------------------------------------
#define PXI_FIFO_DATA_DECRYPTAES_W_INIT 0
#define PXI_FIFO_DATA_DECRYPTAES_W_TARGET1 1
#define PXI_FIFO_DATA_DECRYPTAES_W_TARGET2 2
#define PXI_FIFO_DATA_DECRYPTAES_NORMAL 3
// extern data-----------------------------------------------------------------
// function's prototype-------------------------------------------------------
// global variable-------------------------------------------------------------
// static variable-------------------------------------------------------------
#ifdef SDK_ARM9
static BOOL s_finished = FALSE;
void *s_Addr_AESregion[2];
u32 s_Size_AESregion[2];
BOOL s_initialized = FALSE;
#endif
// const data------------------------------------------------------------------
#ifdef SDK_ARM9
// WRAM経由ファイル読み込みのコールバックで使うAESデクリプト処理の初期化
BOOL SYSM_InitDecryptAESRegion_W( ROM_Header_Short *hs )
{
// AESデクリプト領域アドレスの算出と保存
// ヘッダ情報から、AESデクリプトが必要な領域のアドレスとサイズ
// (最終的な配置ではなく、ランチャーによってアプリがメモリにロードされた状態でのアドレス)
// を算出、保存する
// ここで保存したアドレスを使って、順次読み込んだ領域と比較しながらデクリプト処理を行う
// カードにも対応する場合、セキュア領域の退避についても考慮する必要あり
// ついでに7側に飛んで、鍵やらIDのセットも済ませておく
void *region_addr[2];
u32 region_size[2];
u32 region_offset[2];
u32 module_offset[4];
u32 module_size[4];
void *module_addr[4];
int l, m;
// AES有効
if( !hs->enable_aes )
{
OS_TPrintf( "SYSM_InitDecryptAESRegion(arm9):AES disabled.\n" );
s_initialized = FALSE;
return FALSE;
}
module_offset[0] = hs->main_rom_offset;
module_offset[1] = hs->sub_rom_offset;
module_offset[2] = hs->main_ltd_rom_offset;
module_offset[3] = hs->sub_ltd_rom_offset;
module_size[0] = hs->main_size;
module_size[1] = hs->sub_size;
module_size[2] = hs->main_ltd_size;
module_size[3] = hs->sub_ltd_size;
module_addr[0] = hs->main_ram_address;
module_addr[1] = hs->sub_ram_address;
module_addr[2] = hs->main_ltd_ram_address;
module_addr[3] = hs->sub_ltd_ram_address;
// 再配置情報があれば、モジュールは再配置情報のsrcのアドレスに格納されている
for( l=0; l<RELOCATE_INFO_NUM ; l++ )
{
if( SYSMi_GetWork()->romRelocateInfo[l].src != NULL )
{
module_addr[l] = (void *)SYSMi_GetWork()->romRelocateInfo[l].src;
}
}
// デクリプト情報算出&格納処理
region_offset[0] = hs->aes_target_rom_offset;
region_offset[1] = hs->aes_target2_rom_offset;
region_size[0] = hs->aes_target_size;
region_size[1] = hs->aes_target2_size;
s_Addr_AESregion[0] = NULL;
s_Addr_AESregion[1] = NULL;
for( m=0; m<2; m++ )
{
// デクリプトする暗号化領域の判定とオフセット計算ARM9flx, ARM9ltd, ARM7flx, ARM7ltdのどれか
region_addr[m] = NULL;
if( region_size[m] == 0 )
{
continue;
}
for( l=0; l<4; l++ )
{
// モジュール配置先の領域サイズは32バイト単位に補正に、復号指定領域が含まれているか
if( module_offset[l] <= region_offset[m] &&
region_offset[m] + region_size[m] <= module_offset[l] + MATH_ROUNDUP( module_size[l], SYSM_ALIGNMENT_LOAD_MODULE ) )
{
region_addr[m] = (void *)( (u32)module_addr[l] + (region_offset[m] - module_offset[l]) );
break;
}
}
if( region_addr[m] == NULL )
{
continue;
}
// Workに暗号化領域情報を格納
s_Addr_AESregion[m] = region_addr[m];
s_Size_AESregion[m] = region_size[m];
}
if(region_addr[0] == NULL && region_addr[1] == NULL)
{
// ターゲットも存在しないor設定オフセットがおかしい
OS_TPrintf( "SYSM_InitDecryptAESRegion(arm9):No targets.\n" );
s_initialized = FALSE;
return FALSE;
}
// Workに開発/製品情報を格納
SYSMi_GetWork()->isDeveloperAESMode = ( hs->developer_encrypt ? TRUE : FALSE );
// Workに「鍵」or「シードとゲームコード」をセット
if( hs->developer_encrypt )
{
MI_CpuCopy8( hs->title_name, SYSMi_GetWork()->keyAES, AES_KEY_SIZE );
}else
{
MI_CpuCopy8( hs->main_ltd_static_digest, SYSMi_GetWork()->seedAES, AES_KEY_SIZE );
MI_CpuCopy8( hs->game_code, SYSMi_GetWork()->idAES, GAME_CODE_MAX );
}
// ARM7に開始通知
s_finished = FALSE;
while( PXI_SendWordByFifo(PXI_FIFO_TAG_DECRYPTAES, PXI_FIFO_DATA_DECRYPTAES_W_INIT, FALSE) != PXI_FIFO_SUCCESS )
{
OS_TPrintf( "SYSM_InitDecryptAESRegion(arm9):ARM9 PXI send error.\n" );
}
// ARM7からの完了通知を受け取って完了
while( !s_finished )
{
OS_WaitAnyIrq();
}
OS_TPrintf( "SYSM_InitDecryptAESRegion(arm9):Init finished.\n" );
s_initialized = TRUE;
return TRUE;
}
// WRAM経由ファイル読み込みのコールバックで使うAESデクリプト処理関数
void SYSM_StartDecryptAESRegion_W( void *wram_addr, 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で送ると良いかも
if( !s_initialized )
{
return;
}
}
// べた書きAESデクリプト処理
void SYSM_StartDecryptAESRegion( ROM_Header_Short *hs )
{
void *region_addr[2];
@ -132,7 +283,7 @@ void SYSM_StartDecryptAESRegion( ROM_Header_Short *hs )
// ARM7ÉŠJŽnÊm
s_finished = FALSE;
while( PXI_SendWordByFifo(PXI_FIFO_TAG_DECRYPTAES, 0, FALSE) != PXI_FIFO_SUCCESS )
while( PXI_SendWordByFifo(PXI_FIFO_TAG_DECRYPTAES, PXI_FIFO_DATA_DECRYPTAES_NORMAL, FALSE) != PXI_FIFO_SUCCESS )
{
OS_TPrintf( "SYSM_StartDecryptAESRegion(arm9):ARM9 PXI send error.\n" );
}
@ -173,20 +324,8 @@ static void ReplaceWithAes( void* ptr, u32 size )
AES_Unlock();
}
#endif //ifdef SDK_ARM9
static void SYSMi_CallbackDecryptAESRegion(PXIFifoTag tag, u32 data, BOOL err)
static void SYSMi_SetKeys( void )
{
#pragma unused(tag)
#pragma unused(data)
#pragma unused(err)
#ifdef SDK_ARM9
s_finished = TRUE;
#else //SDK_ARM7
int l;
// 製品ならIDセット
if ( !SYSMi_GetWork()->isDeveloperAESMode )
{
AESi_InitKeysForApp( SYSMi_GetWork()->idAES );
@ -204,23 +343,49 @@ static void SYSMi_CallbackDecryptAESRegion(PXIFifoTag tag, u32 data, BOOL err)
AES_SetKeySeedA( (AESKeySeed*)SYSMi_GetWork()->seedAES );
}
AES_Unlock();
for( l=0; l<2; l++ )
{
if( SYSMi_GetWork()->addr_AESregion[l]==NULL )
{
OS_TPrintf( "SYSM_StartDecryptAESRegion(arm7):Region %d skip.\n", (l+1) );
continue;
}
static void SYSMi_DecryptAESRegion_sub( int target )
{
if( SYSMi_GetWork()->addr_AESregion[target]==NULL )
{
OS_TPrintf( "SYSMi_DecryptAESRegion_sub(arm7):Target Addr Error!\n" );
return;
}
// カウンタの初期値セット
MI_CpuCopy8( SYSMi_GetWork()->counterAES[target], &aesCounter, AES_BLOCK_SIZE );
// 鍵ロードして暗号化領域の復号開始
ReplaceWithAes( SYSMi_GetWork()->addr_AESregion[target], SYSMi_GetWork()->size_AESregion[target] );
}
#endif //ifdef SDK_ARM9
static void SYSMi_CallbackDecryptAESRegion(PXIFifoTag tag, u32 data, BOOL err)
{
#pragma unused(tag)
#pragma unused(data)
#pragma unused(err)
#ifdef SDK_ARM9
s_finished = TRUE;
#else //SDK_ARM7
if(data == PXI_FIFO_DATA_DECRYPTAES_W_INIT)
{
SYSMi_SetKeys();
}else if(data == PXI_FIFO_DATA_DECRYPTAES_W_TARGET1 || data == PXI_FIFO_DATA_DECRYPTAES_W_TARGET2)
{
int target = (int)(data - PXI_FIFO_DATA_DECRYPTAES_W_TARGET1);
SYSMi_DecryptAESRegion_sub( target );
}else if(data == PXI_FIFO_DATA_DECRYPTAES_NORMAL)
{
int l;
SYSMi_SetKeys();
for( l=0; l<2; l++ )
{
SYSMi_DecryptAESRegion_sub( l );
}
// カウンタの初期値セット
MI_CpuCopy8( SYSMi_GetWork()->counterAES[l], &aesCounter, AES_BLOCK_SIZE );
// 鍵ロードして暗号化領域の復号開始
ReplaceWithAes( SYSMi_GetWork()->addr_AESregion[l], SYSMi_GetWork()->size_AESregion[l] );
OS_TPrintf( "SYSM_StartDecryptAESRegion(arm7):Region %d decryption finished.\n", (l+1) );
// DMA転送なのでARM9のためのキャッシュフラッシュは不要のはず
// もうARM7側でも再配置まで触らないのでキャッシュ破棄する必要もないはず
}
// ARM9ÉŠ®—¹Êm

View File

@ -102,7 +102,11 @@ extern BOOL SYSM_IsLoadTitleFinished( void ); // SYSM_StartLoadTitle
extern void SYSM_StartAuthenticateTitle( TitleProperty *pBootTitle ); // 指定したTitlePropertyを別スレッドで検証開始
extern BOOL SYSM_IsAuthenticateTitleFinished( void ); // SYSM_StartAuthenticateTitleで起動したスレッドが終了したかどうかを確認
extern AuthResult SYSM_TryToBootTitle( TitleProperty *pBootTitle ); // pBootTitleで指定したタイトルをブート。成功時は、never return.
// 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_CaribrateTP( void ); // タッチパネルキャリブレーション