TwlIPL/build/libraries_sysmenu/sysmenu/common/src/decryptAES.c
yoshida_teruhisa 6299d449e8 NAM の種置き場が間違っていたので修正
git-svn-id: file:///Users/lillianskinner/Downloads/platinum/twl/TwlIPL/branches/20090601_test_sd_boot@2836 b08762b0-b915-fc4b-9d8c-17b2551a87ff
2009-06-04 02:24:19 +00:00

554 lines
18 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: 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
}