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/branches/20090601_test_sd_boot@2836 b08762b0-b915-fc4b-9d8c-17b2551a87ff
554 lines
18 KiB
C
554 lines
18 KiB
C
/*---------------------------------------------------------------------------*
|
||
Project: TwlIPL
|
||
File: decryptAES.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>
|
||
#include <firm/os/common/boot.h>
|
||
#include "internal_api.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
|
||
#define PXI_FIFO_DATA_DECRYPTAES_SET_JPEG_KEY 4
|
||
#define PXI_FIFO_DATA_DECRYPTAES_SET_SDCOPY_KEY 5
|
||
|
||
#define SYSM_DECODE_AES_MESSAGE_ARRAY_MAX 8
|
||
// extern data-----------------------------------------------------------------
|
||
extern void SDK_SEA_KEY_STORE(void);
|
||
|
||
// function's prototype-------------------------------------------------------
|
||
// global variable-------------------------------------------------------------
|
||
// static variable-------------------------------------------------------------
|
||
#ifdef SDK_ARM9
|
||
static BOOL s_finished = 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];
|
||
static OSMessageQueue msgQ4arm9;
|
||
static OSMessage msgArray4arm9[SYSM_DECODE_AES_MESSAGE_ARRAY_MAX];
|
||
#else
|
||
static OSMessageQueue msgQ4arm7;
|
||
static OSMessage msgArray4arm7[SYSM_DECODE_AES_MESSAGE_ARRAY_MAX];
|
||
#endif
|
||
// const data------------------------------------------------------------------
|
||
|
||
|
||
#ifdef SDK_ARM9
|
||
#include <twl/aes/ARM9/aes_internal.h>
|
||
|
||
// WRAM<41>o<EFBFBD>R<EFBFBD>t<EFBFBD>@<40>C<EFBFBD><43><EFBFBD>ǂݍ<C782><DD8D>݂̃R<CC83>[<5B><><EFBFBD>o<EFBFBD>b<EFBFBD>N<EFBFBD>Ŏg<C58E><67>AES<45>f<EFBFBD>N<EFBFBD><4E><EFBFBD>v<EFBFBD>g<EFBFBD><67><EFBFBD><EFBFBD><EFBFBD>̏<EFBFBD><CC8F><EFBFBD><EFBFBD><EFBFBD>
|
||
BOOL SYSM_InitDecryptAESRegion_W( ROM_Header_Short *hs )
|
||
{
|
||
// AES<45>f<EFBFBD>N<EFBFBD><4E><EFBFBD>v<EFBFBD>g<EFBFBD>̈<EFBFBD><CC88>A<EFBFBD>h<EFBFBD><68><EFBFBD>X<EFBFBD>̎Z<CC8E>o<EFBFBD>ƕۑ<C695>
|
||
// <20>w<EFBFBD>b<EFBFBD>_<EFBFBD><5F><EFBFBD><EFBFBD><F182A982>AAES<45>f<EFBFBD>N<EFBFBD><4E><EFBFBD>v<EFBFBD>g<EFBFBD><67><EFBFBD>K<EFBFBD>v<EFBFBD>ȗ̈<C897><CC88>̃A<CC83>h<EFBFBD><68><EFBFBD>X<EFBFBD>ƃT<C683>C<EFBFBD>Y
|
||
// <20>i<EFBFBD>ŏI<C58F>I<EFBFBD>Ȕz<C894>u<EFBFBD>ł͂Ȃ<CD82><C882>A<EFBFBD><41><EFBFBD><EFBFBD><EFBFBD>`<60><><EFBFBD>[<5B>ɂ<EFBFBD><C982><EFBFBD><EFBFBD>ăA<C483>v<EFBFBD><76><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƀ<EFBFBD><C983>[<5B>h<EFBFBD><68><EFBFBD>ꂽ<EFBFBD><EA82BD><EFBFBD>Ԃł̃A<CC83>h<EFBFBD><68><EFBFBD>X<EFBFBD>j
|
||
// <20><><EFBFBD>Z<EFBFBD>o<EFBFBD>A<EFBFBD>ۑ<EFBFBD><DB91><EFBFBD><EFBFBD><EFBFBD>
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD>ŕۑ<C595><DB91><EFBFBD><EFBFBD><EFBFBD><EFBFBD>A<EFBFBD>h<EFBFBD><68><EFBFBD>X<EFBFBD><58><EFBFBD>g<EFBFBD><67><EFBFBD>āA<C481><41><EFBFBD><EFBFBD><EFBFBD>ǂݍ<C782><DD8D>̈<F182BE97><CC88>Ɣ<EFBFBD><C694>r<EFBFBD><72><EFBFBD>Ȃ<EFBFBD><C882><EFBFBD><EFBFBD>f<EFBFBD>N<EFBFBD><4E><EFBFBD>v<EFBFBD>g<EFBFBD><67><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>s<EFBFBD><73>
|
||
// <20>J<EFBFBD>[<5B>h<EFBFBD>ɂ<EFBFBD><C982>Ή<EFBFBD><CE89><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ꍇ<EFBFBD>A<EFBFBD>Z<EFBFBD>L<EFBFBD><4C><EFBFBD>A<EFBFBD>̈<EFBFBD><CC88>̑ޔ<CC91><DE94>ɂ<C982><C282>Ă<EFBFBD><C482>l<EFBFBD><6C><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>K<EFBFBD>v<EFBFBD><76><EFBFBD><EFBFBD>
|
||
// <20><EFBFBD><C282>ł<EFBFBD>7<EFBFBD><37><EFBFBD>ɔ<EFBFBD><C994><EFBFBD><EFBFBD>ŁA<C581><41><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ID<49>̃Z<CC83>b<EFBFBD>g<EFBFBD><67><EFBFBD>ς܂<CF82><DC82>Ă<EFBFBD><C482><EFBFBD>
|
||
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<45>L<EFBFBD><4C><EFBFBD>H
|
||
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;
|
||
|
||
// <20>Ĕz<C494>u<EFBFBD><75><EFBFBD><EFBFBD><F182AA82><EFBFBD><EFBFBD>A<CE81><41><EFBFBD>W<EFBFBD><57><EFBFBD>[<5B><><EFBFBD>͍Ĕz<C494>u<EFBFBD><75><EFBFBD><EFBFBD><EFBFBD><EFBFBD>src<72>̃A<CC83>h<EFBFBD><68><EFBFBD>X<EFBFBD>Ɋi<C98A>[<5B><><EFBFBD><EFBFBD><EFBFBD>Ă<EFBFBD><C482><EFBFBD>
|
||
for( l=0; l<RELOCATE_INFO_NUM ; l++ )
|
||
{
|
||
if( SYSMi_GetWork()->romRelocateInfo[l].src != NULL )
|
||
{
|
||
module_addr[l] = (void *)SYSMi_GetWork()->romRelocateInfo[l].src;
|
||
}
|
||
}
|
||
|
||
// <20>f<EFBFBD>N<EFBFBD><4E><EFBFBD>v<EFBFBD>g<EFBFBD><67><EFBFBD><EFBFBD><EFBFBD>Z<EFBFBD>o<EFBFBD><6F><EFBFBD>i<EFBFBD>[<5B><><EFBFBD><EFBFBD>
|
||
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++ )
|
||
{
|
||
// <20>f<EFBFBD>N<EFBFBD><4E><EFBFBD>v<EFBFBD>g<EFBFBD><67><EFBFBD><EFBFBD><EFBFBD>Í<EFBFBD><C38D><EFBFBD><EFBFBD>̈<EFBFBD><CC88>̔<EFBFBD><CC94><EFBFBD><EFBFBD>ƃI<C683>t<EFBFBD>Z<EFBFBD>b<EFBFBD>g<EFBFBD>v<EFBFBD>Z<EFBFBD>iARM9flx, ARM9ltd, ARM7flx, ARM7ltd<74>̂ǂꂩ<C782>j
|
||
region_addr[m] = NULL;
|
||
if( region_size[m] == 0 )
|
||
{
|
||
continue;
|
||
}
|
||
for( l=0; l<4; l++ )
|
||
{
|
||
// <20><><EFBFBD>W<EFBFBD><57><EFBFBD>[<5B><><EFBFBD>z<EFBFBD>u<EFBFBD><75><EFBFBD>̗̈<CC97><CC88>i<EFBFBD>T<EFBFBD>C<EFBFBD>Y<EFBFBD><59>32<33>o<EFBFBD>C<EFBFBD>g<EFBFBD>P<EFBFBD>ʂɕ<C995>j<EFBFBD>ɁA<C981><41><EFBFBD><EFBFBD><EFBFBD>w<EFBFBD><77><EFBFBD>̈悪<CC88>܂܂<DC82><DC82>Ă<EFBFBD><C482>邩<EFBFBD>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;
|
||
}
|
||
|
||
// Work<72>ɈÍ<C988><C38D><EFBFBD><EFBFBD>̈<EFBFBD><CC88><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>i<EFBFBD>[
|
||
s_Addr_AESregion[m] = region_addr[m];
|
||
s_Size_AESregion[m] = region_size[m];
|
||
}
|
||
|
||
if(region_addr[0] == NULL && region_addr[1] == NULL)
|
||
{
|
||
// <20>^<5E>[<5B>Q<EFBFBD>b<EFBFBD>g<EFBFBD>P<EFBFBD><50><EFBFBD>Q<EFBFBD><51><EFBFBD><EFBFBD><EFBFBD>݂<EFBFBD><DD82>Ȃ<EFBFBD>or<6F>ݒ<EFBFBD><DD92>I<EFBFBD>t<EFBFBD>Z<EFBFBD>b<EFBFBD>g<EFBFBD><67><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
OS_TPrintf( "SYSM_InitDecryptAESRegion(arm9):No targets.\n" );
|
||
s_initialized = FALSE;
|
||
return FALSE;
|
||
}
|
||
|
||
// Work<72>ɊJ<C98A><4A>/<2F><><EFBFBD>i<EFBFBD><69><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>i<EFBFBD>[
|
||
SYSMi_GetWork()->isDeveloperAESMode = ( hs->developer_encrypt_old || hs->exFlags.developer_encrypt ) ? TRUE : FALSE;
|
||
|
||
// <20>J<EFBFBD>E<EFBFBD><45><EFBFBD>^<5E>̏<EFBFBD><CC8F><EFBFBD><EFBFBD>l<EFBFBD>L<EFBFBD>^
|
||
MI_CpuCopy8( hs->main_static_digest, s_initCounterAES[0], AES_BLOCK_SIZE ); // <20>̈<EFBFBD>1<EFBFBD><31><EFBFBD><EFBFBD><EFBFBD>l
|
||
MI_CpuCopy8( hs->sub_static_digest, s_initCounterAES[1], AES_BLOCK_SIZE ); // <20>̈<EFBFBD>2<EFBFBD><32><EFBFBD><EFBFBD><EFBFBD>l
|
||
|
||
// Work<72>Ɂu<C981><75><EFBFBD>vor<6F>u<EFBFBD>V<EFBFBD>[<5B>h<EFBFBD>ƃQ<C683>[<5B><><EFBFBD>R<EFBFBD>[<5B>h<EFBFBD>v<EFBFBD><76><EFBFBD>Z<EFBFBD>b<EFBFBD>g
|
||
if( hs->developer_encrypt_old || hs->exFlags.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<4D>ɊJ<C98A>n<EFBFBD>ʒm
|
||
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<4D><37><EFBFBD><EFBFBD><EFBFBD>̊<EFBFBD><CC8A><EFBFBD><EFBFBD>ʒm<CA92><6D><EFBFBD><EFBFBD><F382AF8E><EFBFBD><EFBFBD>Ċ<EFBFBD><C48A><EFBFBD>
|
||
OS_ReceiveMessage(&msgQ4arm9, (OSMessage*)&s_finished, OS_MESSAGE_BLOCK);
|
||
|
||
OS_TPrintf( "SYSM_InitDecryptAESRegion(arm9):Init finished.\n" );
|
||
s_initialized = TRUE;
|
||
return TRUE;
|
||
}
|
||
|
||
// WRAM<41>o<EFBFBD>R<EFBFBD>t<EFBFBD>@<40>C<EFBFBD><43><EFBFBD>ǂݍ<C782><DD8D>݂̃R<CC83>[<5B><><EFBFBD>o<EFBFBD>b<EFBFBD>N<EFBFBD>Ŏg<C58E><67>AES<45>f<EFBFBD>N<EFBFBD><4E><EFBFBD>v<EFBFBD>g<EFBFBD><67><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
// <20><><EFBFBD>ӁF<D381>L<EFBFBD><4C><EFBFBD>b<EFBFBD>V<EFBFBD><56><EFBFBD>P<EFBFBD>A<EFBFBD>ς݁AWRAM<41><4D>7<EFBFBD>ɓ|<7C><><EFBFBD>ς݂ł<DD82><C582>鎖<EFBFBD><E98E96><EFBFBD>O<EFBFBD><4F><EFBFBD>Ƃ<EFBFBD><C682><EFBFBD>
|
||
void SYSM_StartDecryptAESRegion_W( const void *wram_addr, const void *orig_addr, u32 size )
|
||
{
|
||
int l;
|
||
if( !s_initialized )
|
||
{
|
||
return;
|
||
}
|
||
|
||
SYSMi_GetWork()->addr_AESregion[0] = NULL;
|
||
SYSMi_GetWork()->addr_AESregion[1] = NULL;
|
||
// target1<74><31>2<EFBFBD>ɂ<C982><C282>ė<EFBFBD><C497><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ׂ<EFBFBD>
|
||
for( l=0;l<2;l++ )
|
||
{
|
||
u32 start;
|
||
u32 end;
|
||
|
||
// AES<45>f<EFBFBD>N<EFBFBD><4E><EFBFBD>v<EFBFBD>g<EFBFBD>̈<EFBFBD><CC88>ƁA<C681>t<EFBFBD>@<40>C<EFBFBD><43><EFBFBD><EFBFBD><EFBFBD><EFBFBD>WRAM<41>ɓǂݍ<C782><DD8D><EFBFBD><EFBFBD>ł<EFBFBD><C582><EFBFBD><EFBFBD>̈<EFBFBD><CC88>̖ړI<DA93>n<EFBFBD>̔<EFBFBD><CC94>r
|
||
if( ( ((u32)orig_addr + size) < (u32)s_Addr_AESregion[l] ) ||
|
||
( ((u32)s_Addr_AESregion[l] + s_Size_AESregion[l]) < (u32)orig_addr )
|
||
)
|
||
{
|
||
continue;
|
||
}
|
||
|
||
// <20><><EFBFBD>Ŕ<EFBFBD><C594>r<EFBFBD><72><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʁA<CA81><41><EFBFBD>ʕ<EFBFBD><CA95><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>f<CE83>N<EFBFBD><4E><EFBFBD>v<EFBFBD>g<EFBFBD><67><EFBFBD><EFBFBD><EFBFBD>̈<EFBFBD><CC88>Ȃ̂Ŋ<CC82><C58A><EFBFBD><EFBFBD>o<EFBFBD><6F>
|
||
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];
|
||
|
||
// <20>f<EFBFBD>N<EFBFBD><4E><EFBFBD>v<EFBFBD>g<EFBFBD><67><EFBFBD><EFBFBD><EFBFBD>̈<EFBFBD><CC88>̃A<CC83>h<EFBFBD><68><EFBFBD>X<EFBFBD>ƃT<C683>C<EFBFBD>Y<EFBFBD>iWRAM<41>ɓǂݍ<C782><DD8D><EFBFBD><F182BE8F>Ԃł̃A<CC83>h<EFBFBD><68><EFBFBD>X<EFBFBD>ƃT<C683>C<EFBFBD>Y<EFBFBD>j<EFBFBD><6A>WORK<52>ɋL<C98B>^
|
||
SYSMi_GetWork()->addr_AESregion[l] = (void *)( (s32)wram_addr + (start - (u32)orig_addr) );
|
||
SYSMi_GetWork()->size_AESregion[l] = end - start;
|
||
|
||
// <20>ΏۂƂȂ<C682><C882>̈<EFBFBD><CC88><EFBFBD><EFBFBD>f<EFBFBD>N<EFBFBD><4E><EFBFBD>v<EFBFBD>g<EFBFBD><67><EFBFBD><EFBFBD><EFBFBD>ۂɕK<C995>v<EFBFBD>ȃJ<C883>E<EFBFBD><45><EFBFBD>^<5E>̒l<CC92><6C><EFBFBD>Z<EFBFBD>o<EFBFBD><6F><EFBFBD><EFBFBD>WORK<52>ɓ<EFBFBD><C993><EFBFBD><EFBFBD>Ă<EFBFBD><C482><EFBFBD>
|
||
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<>Ƀf<C983>N<EFBFBD><4E><EFBFBD>v<EFBFBD>g<EFBFBD><67><EFBFBD>Ă<EFBFBD><C482>炤<EFBFBD>itarget1<74>Ȃ̂<C882>2<EFBFBD>Ȃ̂<C882>FIFO<46>ő<EFBFBD><C591><EFBFBD><EFBFBD>j
|
||
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<4D><37><EFBFBD><EFBFBD><EFBFBD>̊<EFBFBD><CC8A><EFBFBD><EFBFBD>ʒm<CA92><6D><EFBFBD><EFBFBD><F382AF8E><EFBFBD><EFBFBD>Ċ<EFBFBD><C48A><EFBFBD>
|
||
OS_ReceiveMessage(&msgQ4arm9, (OSMessage*)&s_finished, OS_MESSAGE_BLOCK);
|
||
}
|
||
}
|
||
|
||
// <20>ׂ<EFBFBD><D782><EFBFBD><EFBFBD><EFBFBD>AES<45>f<EFBFBD>N<EFBFBD><4E><EFBFBD>v<EFBFBD>g<EFBFBD><67><EFBFBD><EFBFBD>
|
||
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<45>L<EFBFBD><4C><EFBFBD>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<C494>u<EFBFBD><75><EFBFBD><EFBFBD><F182AA82><EFBFBD><EFBFBD>A<CE81><41><EFBFBD>W<EFBFBD><57><EFBFBD>[<5B><><EFBFBD>͍Ĕz<C494>u<EFBFBD><75><EFBFBD><EFBFBD><EFBFBD><EFBFBD>src<72>̃A<CC83>h<EFBFBD><68><EFBFBD>X<EFBFBD>Ɋi<C98A>[<5B><><EFBFBD><EFBFBD><EFBFBD>Ă<EFBFBD><C482><EFBFBD>
|
||
for( l=0; l<RELOCATE_INFO_NUM ; l++ )
|
||
{
|
||
if( SYSMi_GetWork()->romRelocateInfo[l].src != NULL )
|
||
{
|
||
module_addr[l] = (void *)SYSMi_GetWork()->romRelocateInfo[l].src;
|
||
}
|
||
}
|
||
|
||
// <20>f<EFBFBD>N<EFBFBD><4E><EFBFBD>v<EFBFBD>g<EFBFBD><67><EFBFBD><EFBFBD><EFBFBD>Z<EFBFBD>o<EFBFBD><6F><EFBFBD>i<EFBFBD>[<5B><><EFBFBD><EFBFBD>
|
||
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++ )
|
||
{
|
||
// <20>f<EFBFBD>N<EFBFBD><4E><EFBFBD>v<EFBFBD>g<EFBFBD><67><EFBFBD><EFBFBD><EFBFBD>Í<EFBFBD><C38D><EFBFBD><EFBFBD>̈<EFBFBD><CC88>̔<EFBFBD><CC94><EFBFBD><EFBFBD>ƃI<C683>t<EFBFBD>Z<EFBFBD>b<EFBFBD>g<EFBFBD>v<EFBFBD>Z<EFBFBD>iARM9flx, ARM9ltd, ARM7flx, ARM7ltd<74>̂ǂꂩ<C782>j
|
||
region_addr[m] = NULL;
|
||
if( region_size[m] == 0 )
|
||
{
|
||
continue;
|
||
}
|
||
for( l=0; l<4; l++ )
|
||
{
|
||
// <20><><EFBFBD>W<EFBFBD><57><EFBFBD>[<5B><><EFBFBD>z<EFBFBD>u<EFBFBD><75><EFBFBD>̗̈<CC97><CC88>i<EFBFBD>T<EFBFBD>C<EFBFBD>Y<EFBFBD><59>32<33>o<EFBFBD>C<EFBFBD>g<EFBFBD>P<EFBFBD>ʂɕ<C995>j<EFBFBD>ɁA<C981><41><EFBFBD><EFBFBD><EFBFBD>w<EFBFBD><77><EFBFBD>̈悪<CC88>܂܂<DC82><DC82>Ă<EFBFBD><C482>邩<EFBFBD>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;
|
||
}
|
||
|
||
// <20>̈<EFBFBD><CC88>̃L<CC83><4C><EFBFBD>b<EFBFBD>V<EFBFBD><56><EFBFBD><EFBFBD><EFBFBD>t<EFBFBD><74><EFBFBD>b<EFBFBD>V<EFBFBD><56>
|
||
DC_FlushRange( region_addr[m], region_size[m] );
|
||
|
||
// Work<72>ɈÍ<C988><C38D><EFBFBD><EFBFBD>̈<EFBFBD><CC88><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>i<EFBFBD>[
|
||
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)
|
||
{
|
||
// <20>^<5E>[<5B>Q<EFBFBD>b<EFBFBD>g<EFBFBD>P<EFBFBD><50><EFBFBD>Q<EFBFBD><51><EFBFBD><EFBFBD><EFBFBD>݂<EFBFBD><DD82>Ȃ<EFBFBD>or<6F>ݒ<EFBFBD><DD92>I<EFBFBD>t<EFBFBD>Z<EFBFBD>b<EFBFBD>g<EFBFBD><67><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
OS_TPrintf( "SYSM_StartDecryptAESRegion(arm9):No targets.\n" );
|
||
return;
|
||
}
|
||
|
||
// Work<72>ɊJ<C98A><4A>/<2F><><EFBFBD>i<EFBFBD><69><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>i<EFBFBD>[
|
||
SYSMi_GetWork()->isDeveloperAESMode = ( hs->developer_encrypt_old || hs->exFlags.developer_encrypt ) ? TRUE : FALSE;
|
||
|
||
// Work<72>ɃJ<C983>E<EFBFBD><45><EFBFBD>^<5E>̏<EFBFBD><CC8F><EFBFBD><EFBFBD>l<EFBFBD>Z<EFBFBD>b<EFBFBD>g
|
||
MI_CpuCopy8( hs->main_static_digest, SYSMi_GetWork()->counterAES[0], AES_BLOCK_SIZE ); // <20>̈<EFBFBD>1<EFBFBD><31><EFBFBD><EFBFBD><EFBFBD>l
|
||
MI_CpuCopy8( hs->sub_static_digest, SYSMi_GetWork()->counterAES[1], AES_BLOCK_SIZE ); // <20>̈<EFBFBD>2<EFBFBD><32><EFBFBD><EFBFBD><EFBFBD>l
|
||
|
||
// Work<72>Ɂu<C981><75><EFBFBD>vor<6F>u<EFBFBD>V<EFBFBD>[<5B>h<EFBFBD>ƃQ<C683>[<5B><><EFBFBD>R<EFBFBD>[<5B>h<EFBFBD>v<EFBFBD><76><EFBFBD>Z<EFBFBD>b<EFBFBD>g
|
||
if( hs->developer_encrypt_old || hs->exFlags.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<4D>ɊJ<C98A>n<EFBFBD>ʒm
|
||
s_finished = FALSE;
|
||
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" );
|
||
}
|
||
|
||
// ARM7<4D><37><EFBFBD><EFBFBD><EFBFBD>̊<EFBFBD><CC8A><EFBFBD><EFBFBD>ʒm<CA92><6D><EFBFBD><EFBFBD><F382AF8E><EFBFBD><EFBFBD>Ċ<EFBFBD><C48A><EFBFBD>
|
||
OS_ReceiveMessage(&msgQ4arm9, (OSMessage*)&s_finished, OS_MESSAGE_BLOCK);
|
||
|
||
OS_TPrintf( "SYSM_StartDecryptAESRegion(arm9):AES decryption finished.\n" );
|
||
}
|
||
|
||
|
||
void SYSMi_setJPEGKeyToAESSlotC( void )
|
||
{
|
||
// ARM7<4D>ɊJ<C98A>n<EFBFBD>ʒm
|
||
s_finished = FALSE;
|
||
while( PXI_SendWordByFifo(PXI_FIFO_TAG_DECRYPTAES, PXI_FIFO_DATA_DECRYPTAES_SET_JPEG_KEY, FALSE) != PXI_FIFO_SUCCESS )
|
||
{
|
||
OS_TPrintf( "SYSMi_setJPEGKeyToAESSlotC(arm9):ARM9 PXI send error.\n" );
|
||
}
|
||
|
||
// ARM7<4D><37><EFBFBD><EFBFBD><EFBFBD>̊<EFBFBD><CC8A><EFBFBD><EFBFBD>ʒm<CA92><6D><EFBFBD><EFBFBD><F382AF8E><EFBFBD><EFBFBD>Ċ<EFBFBD><C48A><EFBFBD>
|
||
OS_ReceiveMessage(&msgQ4arm9, (OSMessage*)&s_finished, OS_MESSAGE_BLOCK);
|
||
|
||
OS_TPrintf( "SYSMi_setJPEGKeyToAESSlotC(arm9):AES decryption finished.\n" );
|
||
}
|
||
|
||
void SYSMi_setSDCopyKeyToAESSlotC( void )
|
||
{
|
||
// ARM7<4D>ɊJ<C98A>n<EFBFBD>ʒm
|
||
s_finished = FALSE;
|
||
while( PXI_SendWordByFifo(PXI_FIFO_TAG_DECRYPTAES, PXI_FIFO_DATA_DECRYPTAES_SET_SDCOPY_KEY, FALSE) != PXI_FIFO_SUCCESS )
|
||
{
|
||
OS_TPrintf( "SYSMi_setSDCopyKeyToAESSlotC(arm9):ARM9 PXI send error.\n" );
|
||
}
|
||
|
||
// ARM7<4D><37><EFBFBD><EFBFBD><EFBFBD>̊<EFBFBD><CC8A><EFBFBD><EFBFBD>ʒm<CA92><6D><EFBFBD><EFBFBD><F382AF8E><EFBFBD><EFBFBD>Ċ<EFBFBD><C48A><EFBFBD>
|
||
OS_ReceiveMessage(&msgQ4arm9, (OSMessage*)&s_finished, OS_MESSAGE_BLOCK);
|
||
|
||
OS_TPrintf( "SYSMi_setSDCopyKeyToAESSlotC(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;
|
||
|
||
// dev_commonKey<65>̓x<CD83>^<5E>Ŏ<EFBFBD><C58E><EFBFBD><EFBFBD>Ă<EFBFBD><C482><EFBFBD><EFBFBD>B
|
||
static const u8 dev_seedNAM[] ATTRIBUTE_ALIGN(4) = {
|
||
0x4D, 0x04, 0xA4, 0x7F, 0xE3, 0x02, 0x30, 0x2E,
|
||
0x2A, 0x07, 0x06, 0xE6, 0xD9, 0x06, 0x47, 0x76,
|
||
};
|
||
|
||
static const u8 dev_seedSlotC[] ATTRIBUTE_ALIGN(4) = {
|
||
0x3B, 0x06, 0x86, 0x57, 0x33, 0x04, 0x88, 0x11,
|
||
0x49, 0x04, 0x6B, 0x33, 0x12, 0x02, 0xAC, 0xF3,
|
||
};
|
||
|
||
#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();
|
||
}
|
||
|
||
static void SYSMi_SetKeys( void )
|
||
{
|
||
if ( !SYSMi_GetWork()->isDeveloperAESMode )
|
||
{
|
||
AESi_InitKeysForApp( SYSMi_GetWork()->idAES );
|
||
}
|
||
|
||
// <20>J<EFBFBD><4A><EFBFBD>Ȃ献<C882>Z<EFBFBD>b<EFBFBD>g<EFBFBD>A<EFBFBD><41><EFBFBD>i<EFBFBD>Ȃ<EFBFBD><C882>V<EFBFBD>[<5B>h<EFBFBD>Z<EFBFBD>b<EFBFBD>g
|
||
AES_Lock();
|
||
AES_WaitKey();
|
||
if ( SYSMi_GetWork()->isDeveloperAESMode )
|
||
{
|
||
AES_SetKeyA( (AESKey*)SYSMi_GetWork()->keyAES );
|
||
}
|
||
else
|
||
{
|
||
AES_SetKeySeedA( (AESKeySeed*)SYSMi_GetWork()->seedAES );
|
||
}
|
||
AES_Unlock();
|
||
}
|
||
|
||
static void SYSMi_DecryptAESRegion_sub( int target )
|
||
{
|
||
if( SYSMi_GetWork()->addr_AESregion[target]==NULL )
|
||
{
|
||
OS_TPrintf( "SYSMi_DecryptAESRegion_sub(arm7):Target%d Addr Error!\n",target+1 );
|
||
return;
|
||
}
|
||
|
||
// <20>J<EFBFBD>E<EFBFBD><45><EFBFBD>^<5E>̏<EFBFBD><CC8F><EFBFBD><EFBFBD>l<EFBFBD>Z<EFBFBD>b<EFBFBD>g
|
||
MI_CpuCopy8( SYSMi_GetWork()->counterAES[target], &aesCounter, AES_BLOCK_SIZE );
|
||
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD>[<5B>h<EFBFBD><68><EFBFBD>ĈÍ<C488><C38D><EFBFBD><EFBFBD>̈<EFBFBD><CC88>̕<EFBFBD><CC95><EFBFBD><EFBFBD>J<EFBFBD>n
|
||
ReplaceWithAes( SYSMi_GetWork()->addr_AESregion[target], MATH_ROUNDUP( SYSMi_GetWork()->size_AESregion[target] ,32 ) );
|
||
// 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] );
|
||
}
|
||
|
||
static void SYSMi_setSDCopyKeyToAESSlotC( void )
|
||
{
|
||
void *pSeedNAM = ( SCFG_GetBondingOption() == SCFG_OP_PRODUCT ) ?
|
||
&( OSi_GetFromFirmAddr()->rsa_pubkey[ 3 ][ 0x10 ] ) : (void *)dev_seedNAM;
|
||
void *pSeedSlotC = ( SCFG_GetBondingOption() == SCFG_OP_PRODUCT ) ?
|
||
&( OSi_GetFromFirmAddr()->rsa_pubkey[ 3 ][ 0x20 ] ) : (void *)dev_seedSlotC;
|
||
MI_CpuCopy8( pSeedNAM, (u8 *)SDK_SEA_KEY_STORE + 0x20, AES_BLOCK_SIZE );
|
||
|
||
// AES<45>X<EFBFBD><58><EFBFBD>b<EFBFBD>g<EFBFBD>̃f<CC83>t<EFBFBD>H<EFBFBD><48><EFBFBD>g<EFBFBD>l<EFBFBD>Z<EFBFBD>b<EFBFBD>g
|
||
AES_Lock();
|
||
AES_SetKeySeedC( pSeedSlotC );
|
||
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
|
||
if(!OS_SendMessage(&msgQ4arm9, (OSMessage)TRUE, OS_MESSAGE_NOBLOCK))
|
||
{
|
||
OS_TPrintf( "SYSMi_CallbackDecryptAESRegion(arm9):Message send error.\n" );
|
||
}
|
||
#else //SDK_ARM7
|
||
if(!OS_SendMessage(&msgQ4arm7, (OSMessage)data, OS_MESSAGE_NOBLOCK))
|
||
{
|
||
OS_TPrintf( "SYSMi_CallbackDecryptAESRegion(arm7):Message send error.\n" );
|
||
}
|
||
#endif //ifdef SDK_ARM9
|
||
}
|
||
|
||
#ifdef SDK_ARM7
|
||
#define SYSM_AES_THREAD_STACK_SIZE 512
|
||
#define AES_THREAD_PRIORITY 5
|
||
static OSThread aes_thread;
|
||
static u64 aes_thread_stack[SYSM_AES_THREAD_STACK_SIZE/sizeof(u64)];
|
||
|
||
static void SYSMi_DecryptAESThread(void* arg)
|
||
{
|
||
#pragma unused(arg)
|
||
int aes_start;
|
||
while(1)
|
||
{
|
||
OS_ReceiveMessage(&msgQ4arm7, (OSMessage*)&aes_start, OS_MESSAGE_BLOCK);
|
||
|
||
if(aes_start == PXI_FIFO_DATA_DECRYPTAES_W_INIT)
|
||
{
|
||
SYSMi_SetKeys();
|
||
}else if(aes_start == PXI_FIFO_DATA_DECRYPTAES_W_TARGET1 || aes_start == PXI_FIFO_DATA_DECRYPTAES_W_TARGET2)
|
||
{
|
||
int target = (int)(aes_start - PXI_FIFO_DATA_DECRYPTAES_W_TARGET1);
|
||
SYSMi_DecryptAESRegion_sub( target );
|
||
}else if(aes_start == PXI_FIFO_DATA_DECRYPTAES_NORMAL)
|
||
{
|
||
int l;
|
||
SYSMi_SetKeys();
|
||
for( l=0; l<2; l++ )
|
||
{
|
||
SYSMi_DecryptAESRegion_sub( l );
|
||
}
|
||
// PXI <20>p<EFBFBD>^<5E>O<EFBFBD><4F><EFBFBD><EFBFBD><EFBFBD>L<EFBFBD><4C><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̂<EFBFBD><CC82>A<EFBFBD><41><EFBFBD>Ȃ̂ŁAAES <20><><EFBFBD>Z<EFBFBD>b<EFBFBD>g<EFBFBD>̏<EFBFBD><CC8F><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ł<EFBFBD><C582><EFBFBD><EFBFBD>ɒlj<C992><C789><EFBFBD><EFBFBD>Ă<EFBFBD><C482><EFBFBD>
|
||
}else if(aes_start == PXI_FIFO_DATA_DECRYPTAES_SET_JPEG_KEY)
|
||
{
|
||
SYSMi_SetAESKeysForSignJPEG( (ROM_Header *)HW_TWL_ROM_HEADER_BUF, NULL, NULL );
|
||
}else if(aes_start == PXI_FIFO_DATA_DECRYPTAES_SET_SDCOPY_KEY)
|
||
{
|
||
SYSMi_setSDCopyKeyToAESSlotC();
|
||
}
|
||
|
||
// ARM9<4D>Ɋ<EFBFBD><C98A><EFBFBD><EFBFBD>ʒm
|
||
while( PXI_SendWordByFifo(PXI_FIFO_TAG_DECRYPTAES, 0, FALSE) != PXI_FIFO_SUCCESS )
|
||
{
|
||
OS_TPrintf( "SYSMi_DecryptAESThread(arm7):ARM7 PXI send error.\n" );
|
||
}
|
||
}
|
||
}
|
||
#endif
|
||
|
||
void SYSM_InitDecryptAESPXICallback( void )
|
||
{
|
||
PXI_SetFifoRecvCallback(PXI_FIFO_TAG_DECRYPTAES, SYSMi_CallbackDecryptAESRegion);
|
||
#ifdef SDK_ARM9
|
||
while(!PXI_IsCallbackReady(PXI_FIFO_TAG_DECRYPTAES, PXI_PROC_ARM7))
|
||
{
|
||
// do nothing
|
||
}
|
||
OS_InitMessageQueue(&msgQ4arm9, msgArray4arm9, SYSM_DECODE_AES_MESSAGE_ARRAY_MAX);
|
||
#else
|
||
OS_InitMessageQueue(&msgQ4arm7, msgArray4arm7, SYSM_DECODE_AES_MESSAGE_ARRAY_MAX);
|
||
// ARM7<4D><37><EFBFBD>̏<EFBFBD><CC8F><EFBFBD><EFBFBD><EFBFBD><EFBFBD>s<EFBFBD><73><EFBFBD><EFBFBD><EFBFBD>߂̃X<CC83><58><EFBFBD>b<EFBFBD>h<EFBFBD>J<EFBFBD>n
|
||
OS_CreateThread(&aes_thread, SYSMi_DecryptAESThread, 0,
|
||
(void*)(aes_thread_stack + (SYSM_AES_THREAD_STACK_SIZE/sizeof(u64))),
|
||
SYSM_AES_THREAD_STACK_SIZE, AES_THREAD_PRIORITY);
|
||
OS_WakeupThreadDirect(&aes_thread);
|
||
#endif
|
||
} |