TwlIPL/build/libraries_sysmenu/sysmenu/common/src/decodeAES.c
yoshida_teruhisa 4e63f543f8 AESデクリプト処理のタイミングを変更(署名チェック直後)
デクリプト範囲判定の厳密化

git-svn-id: file:///Users/lillianskinner/Downloads/platinum/twl/TwlIPL/trunk@1088 b08762b0-b915-fc4b-9d8c-17b2551a87ff
2008-04-09 02:05:11 +00:00

238 lines
7.2 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*---------------------------------------------------------------------------*
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>Ä”zu<E28099>î•ñª êÎ<E2809A>ƒWƒ…<C692>Í<E2809A>Ä”zu<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>”zu<E28099>æÌ—̈æ<CB86>iƒTƒCƒYÍ32ƒoƒCƒgPˆÊÉ•â<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ƒgPà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>Ä”zuÜÅ<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);
}