mirror of
https://github.com/rvtr/TwlIPL.git
synced 2025-10-31 06:01:12 -04:00
デクリプト範囲判定の厳密化 git-svn-id: file:///Users/lillianskinner/Downloads/platinum/twl/TwlIPL/trunk@1088 b08762b0-b915-fc4b-9d8c-17b2551a87ff
238 lines
7.2 KiB
C
238 lines
7.2 KiB
C
/*---------------------------------------------------------------------------*
|
||
Project: TwlIPL
|
||
File: decodeAES.c
|
||
|
||
Copyright 2007 Nintendo. All rights reserved.
|
||
|
||
These coded instructions, statements, and computer programs contain
|
||
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||
Company Ltd., and are protected by Federal copyright law. They may
|
||
not be disclosed to third parties or copied or duplicated in any form,
|
||
in whole or in part, without the prior written consent of Nintendo.
|
||
|
||
$Date:: #$
|
||
$Rev$
|
||
$Author$
|
||
*---------------------------------------------------------------------------*/
|
||
|
||
#include <twl.h>
|
||
#include <sysmenu.h>
|
||
#include <twl/aes/common/types.h>
|
||
|
||
// define data-----------------------------------------------------------------
|
||
// extern data-----------------------------------------------------------------
|
||
// function's prototype-------------------------------------------------------
|
||
// global variable-------------------------------------------------------------
|
||
// static variable-------------------------------------------------------------
|
||
static BOOL s_finished = FALSE;
|
||
// const data------------------------------------------------------------------
|
||
|
||
#ifdef SDK_ARM9
|
||
|
||
void SYSM_StartDecryptAESRegion( ROM_Header_Short *hs )
|
||
{
|
||
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—LŒø<C592>H
|
||
if( !hs->enable_aes )
|
||
{
|
||
OS_TPrintf( "SYSM_StartDecryptAESRegion(arm9):AES disabled.\n" );
|
||
return;
|
||
}
|
||
|
||
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;
|
||
|
||
// <20>Ä”z’u<E28099>î•ñ‚ª‚ ‚ê‚Î<E2809A>Aƒ‚ƒWƒ…<C692>[ƒ‹‚Í<E2809A>Ä”z’u<E28099>î•ñ‚Ìsrc‚̃AƒhƒŒƒX‚ÉŠi”[‚³‚ê‚Ä‚¢‚é
|
||
for( l=0; l<RELOCATE_INFO_NUM ; l++ )
|
||
{
|
||
if( SYSMi_GetWork()->romRelocateInfo[l].src != NULL )
|
||
{
|
||
module_addr[l] = (void *)SYSMi_GetWork()->romRelocateInfo[l].src;
|
||
}
|
||
}
|
||
|
||
// ƒfƒNƒŠƒvƒg<C692>î•ñŽZ<C5BD>o<EFBFBD>•Ši”[<5B>ˆ—<CB86>
|
||
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;
|
||
SYSMi_GetWork()->addr_AESregion[0] = NULL;
|
||
SYSMi_GetWork()->addr_AESregion[1] = NULL;
|
||
for( m=0; m<2; m++ )
|
||
{
|
||
// ƒfƒNƒŠƒvƒg‚·‚éˆÃ<CB86>†‰»—̈æ‚Ì”»’è‚ÆƒIƒtƒZƒbƒgŒvŽZ<C5BD>iARM9flx, ARM9ltd, ARM7flx, ARM7ltd‚̂ǂꂩ<E2809A>j
|
||
region_addr[m] = NULL;
|
||
if( region_size[m] == 0 )
|
||
{
|
||
continue;
|
||
}
|
||
for( l=0; l<4; l++ )
|
||
{
|
||
// ƒ‚ƒWƒ…<C692>[ƒ‹”z’u<E28099>æ‚̗̈æ<CB86>iƒTƒCƒY‚Í32ƒoƒCƒg’PˆÊ‚É•â<E280A2>³<EFBFBD>j‚É<E2809A>A•œ<E280A2>†Žw’è—̈悪ŠÜ‚Ü‚ê‚Ä‚¢‚é‚©<E2809A>H
|
||
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;
|
||
}
|
||
|
||
// —̈æ‚̃LƒƒƒbƒVƒ…‚ðƒtƒ‰ƒbƒVƒ…
|
||
DC_FlushRange( region_addr[m], region_size[m] );
|
||
|
||
// Work‚ɈÃ<CB86>†‰»—̈æ<CB86>î•ñ‚ðŠi”[
|
||
SYSMi_GetWork()->addr_AESregion[m] = region_addr[m];
|
||
SYSMi_GetWork()->size_AESregion[m] = region_size[m];
|
||
}
|
||
|
||
if(region_addr[0] == NULL && region_addr[1] == NULL)
|
||
{
|
||
// ƒ^<5E>[ƒQƒbƒg‚P‚à‚Q‚à‘¶<E28098>Ý‚µ‚È‚¢or<6F>Ý’èƒIƒtƒZƒbƒg‚ª‚¨‚©‚µ‚¢
|
||
OS_TPrintf( "SYSM_StartDecryptAESRegion(arm9):No targets.\n" );
|
||
return;
|
||
}
|
||
|
||
// Work‚ÉŠJ”/<2F>»•i<E280A2>î•ñ‚ðŠi”[
|
||
SYSMi_GetWork()->isDeveloperAESMode = ( hs->developer_encrypt ? TRUE : FALSE );
|
||
|
||
// Work‚ɃJƒEƒ“ƒ^‚Ì<E2809A>‰Šú’lƒZƒbƒg
|
||
MI_CpuCopy8( hs->main_static_digest, SYSMi_GetWork()->counterAES[0], AES_BLOCK_SIZE ); // —̈æ1<C3A6>‰Šú’l
|
||
MI_CpuCopy8( hs->sub_static_digest, SYSMi_GetWork()->counterAES[1], AES_BLOCK_SIZE ); // —̈æ2<C3A6>‰Šú’l
|
||
|
||
// Work‚É<E2809A>uŒ®<C592>vor<6F>uƒV<C692>[ƒh‚ƃQ<C692>[ƒ€ƒR<C692>[ƒh<C692>v‚ðƒZƒbƒg
|
||
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‚ÉŠJŽn’Ê’m
|
||
s_finished = FALSE;
|
||
while( PXI_SendWordByFifo(PXI_FIFO_TAG_DECRYPTAES, 0, FALSE) != PXI_FIFO_SUCCESS )
|
||
{
|
||
OS_TPrintf( "SYSM_StartDecryptAESRegion(arm9):ARM9 PXI send error.\n" );
|
||
}
|
||
|
||
// ARM7‚©‚ç‚ÌŠ®—¹’Ê’m‚ðŽó‚¯Žæ‚Á‚ÄŠ®—¹
|
||
while( !s_finished )
|
||
{
|
||
OS_WaitAnyIrq();
|
||
}
|
||
|
||
OS_TPrintf( "SYSM_StartDecryptAESRegion(arm9):AES decryption finished.\n" );
|
||
}
|
||
|
||
#else //SDK_ARM7
|
||
|
||
#include <twl/aes/ARM7/hi.h>
|
||
#include <twl/aes/ARM7/lo.h>
|
||
#include <firm/aes/ARM7/aes_init.h>
|
||
|
||
static AESCounter aesCounter;
|
||
|
||
#define DMA_SEND 2
|
||
#define DMA_RECV 3
|
||
static void ReplaceWithAes( void* ptr, u32 size )
|
||
{
|
||
AES_Lock();
|
||
AES_Reset();
|
||
AES_Reset();
|
||
AES_WaitKey();
|
||
AES_LoadKey( AES_KEY_SLOT_A );
|
||
AES_WaitKey();
|
||
AES_DmaSend( DMA_SEND, ptr, size, NULL, NULL );
|
||
AES_DmaRecv( DMA_RECV, ptr, size, NULL, NULL );
|
||
AES_SetCounter( &aesCounter );
|
||
AES_Run( AES_MODE_CTR, 0, size / AES_BLOCK_SIZE, NULL, NULL );
|
||
AES_AddToCounter( &aesCounter, size / AES_BLOCK_SIZE );
|
||
MI_WaitNDma( DMA_RECV );
|
||
AES_Unlock();
|
||
}
|
||
|
||
#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
|
||
int l;
|
||
|
||
// <20>»•i‚È‚çIDƒZƒbƒg
|
||
if ( !SYSMi_GetWork()->isDeveloperAESMode )
|
||
{
|
||
AESi_InitKeysForApp( SYSMi_GetWork()->idAES );
|
||
}
|
||
|
||
// ŠJ”‚Ȃ献ƒZƒbƒg<C692>A<EFBFBD>»•i‚È‚çƒV<C692>[ƒhƒZƒbƒg
|
||
AES_Lock();
|
||
AES_WaitKey();
|
||
if ( SYSMi_GetWork()->isDeveloperAESMode )
|
||
{
|
||
AES_SetKeyA( (AESKey*)SYSMi_GetWork()->keyAES );
|
||
}
|
||
else
|
||
{
|
||
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;
|
||
}
|
||
|
||
// ƒJƒEƒ“ƒ^‚Ì<E2809A>‰Šú’lƒZƒbƒg
|
||
MI_CpuCopy8( SYSMi_GetWork()->counterAES[l], &aesCounter, AES_BLOCK_SIZE );
|
||
|
||
// Œ®ƒ<C2AE><C692>[ƒh‚µ‚ĈÃ<CB86>†‰»—̈æ‚Ì•œ<E280A2>†ŠJŽn
|
||
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‚Ì‚½‚߂̃LƒƒƒbƒVƒ…ƒtƒ‰ƒbƒVƒ…‚Í•s—v‚̂͂¸
|
||
// ‚à‚¤ARM7‘¤‚Å‚à<E2809A>Ä”z’u‚Ü‚Å<E2809A>G‚ç‚È‚¢‚̂ŃLƒƒƒbƒVƒ…”jŠü‚·‚é•K—v‚à‚È‚¢‚Í‚¸
|
||
}
|
||
|
||
// ARM9‚ÉŠ®—¹’Ê’m
|
||
while( PXI_SendWordByFifo(PXI_FIFO_TAG_DECRYPTAES, 0, FALSE) != PXI_FIFO_SUCCESS )
|
||
{
|
||
OS_TPrintf( "SYSM_StartDecryptAESRegion(arm7):ARM7 PXI send error.\n" );
|
||
}
|
||
|
||
#endif //ifdef SDK_ARM9
|
||
}
|
||
|
||
void SYSM_InitDecryptAESPXICallback( void )
|
||
{
|
||
PXI_SetFifoRecvCallback(PXI_FIFO_TAG_DECRYPTAES, SYSMi_CallbackDecryptAESRegion);
|
||
} |