mirror of
https://github.com/rvtr/TwlIPL.git
synced 2025-10-31 06:01:12 -04:00
FSライブラリの再構成
BOOTTYPEの設定タイミングの変更 git-svn-id: file:///Users/lillianskinner/Downloads/platinum/twl/TwlIPL/trunk@548 b08762b0-b915-fc4b-9d8c-17b2551a87ff
This commit is contained in:
parent
f73f99dff8
commit
0440a8ba65
@ -83,7 +83,12 @@ static void PreInit(void)
|
||||
{
|
||||
static const OSMountInfo firmSettings[] =
|
||||
{
|
||||
{ 'A', OS_MOUNT_DEVICE_SD, OS_MOUNT_TGT_ROOT, 0, OS_MOUNT_RSC_WRAM, (OS_MOUNT_USR_R|OS_MOUNT_USR_W), 0, 0, "sdmc", "/" },
|
||||
// drive device target pertitionIdx resource userPermission rsvA B archive path
|
||||
{ 'A', OS_MOUNT_DEVICE_SD, OS_MOUNT_TGT_ROOT, 0, OS_MOUNT_RSC_MMEM, (OS_MOUNT_USR_R|OS_MOUNT_USR_W), 0, 0, "sdmc", "/" },
|
||||
{ 'B', OS_MOUNT_DEVICE_NAND, OS_MOUNT_TGT_ROOT, 0, OS_MOUNT_RSC_WRAM, (OS_MOUNT_USR_R|OS_MOUNT_USR_W), 0, 0, "nand", "/" }, // ユーザーアプリはこのアーカイブではWrite不可
|
||||
{ 'C', OS_MOUNT_DEVICE_NAND, OS_MOUNT_TGT_ROOT, 1, OS_MOUNT_RSC_WRAM, (OS_MOUNT_USR_R|OS_MOUNT_USR_W), 0, 0, "nand2", "/" }, // ユーザーアプリはこのアーカイブではWrite不可
|
||||
{ 'D', OS_MOUNT_DEVICE_NAND, OS_MOUNT_TGT_DIR, 0, OS_MOUNT_RSC_MMEM, (OS_MOUNT_USR_R|OS_MOUNT_USR_W), 0, 0, "shared2", "nand2:/shared2" },
|
||||
{ 'E', OS_MOUNT_DEVICE_NAND, OS_MOUNT_TGT_DIR, 0, OS_MOUNT_RSC_MMEM, (OS_MOUNT_USR_R|OS_MOUNT_USR_W), 0, 0, "photo", "nand2:/photo" },
|
||||
{ 0 }
|
||||
};
|
||||
/*
|
||||
@ -105,6 +110,9 @@ static void PreInit(void)
|
||||
{
|
||||
OS_Terminate();
|
||||
}
|
||||
|
||||
// ブートタイプの変更
|
||||
( (OSBootInfo *)OS_GetBootInfo() )->boot_type = OS_BOOTTYPE_NAND;
|
||||
}
|
||||
|
||||
/***************************************************************
|
||||
@ -131,7 +139,7 @@ static BOOL CheckHeader(void)
|
||||
{
|
||||
static ROM_Header_Short* const rhs = (ROM_Header_Short*)HW_TWL_ROM_HEADER_BUF;
|
||||
// ƒCƒjƒVƒƒƒ‹ƒR<C692>[ƒh‚È‚Ç
|
||||
OS_TPrintf("Initial Code : %08X\n", *(u32*)rhs->game_code);
|
||||
OS_TPrintf("Initial Code : %08X (%.4s)\n", *(u32*)rhs->game_code, rhs->game_code);
|
||||
OS_TPrintf("Platform Code : %02X\n", rhs->platform_code);
|
||||
OS_TPrintf("Codec Mode : %s\n", rhs->codec_mode ? "TWL" : "NITRO");
|
||||
OS_TPrintf("Sigunature : %s\n", rhs->enable_signature ? "AVAILABLE" : "NOT AVAILABLE");
|
||||
@ -221,12 +229,12 @@ void TwlMain( void )
|
||||
OS_InitFIRM();
|
||||
OS_EnableIrq();
|
||||
OS_EnableInterrupts();
|
||||
|
||||
#ifdef PROFILE_ENABLE
|
||||
// 2: before OS_InitTick
|
||||
profile[pf_cnt++] = OS_TicksToMicroSecondsBROM32(OS_GetTick());
|
||||
|
||||
OS_InitTick();
|
||||
#endif
|
||||
// 2: after OS_InitTick
|
||||
PUSH_PROFILE();
|
||||
|
||||
PostInit();
|
||||
// 3: after PostInit
|
||||
@ -292,7 +300,7 @@ void TwlMain( void )
|
||||
}
|
||||
#endif
|
||||
|
||||
( (OSBootInfo *)OS_GetBootInfo() )->boot_type = OS_BOOTTYPE_NAND;
|
||||
MI_CpuClearFast( OSi_GetFromFirmAddr(), sizeof(OSFromFirmBuf) );
|
||||
OS_BootFromFIRM();
|
||||
|
||||
end:
|
||||
|
||||
@ -32,7 +32,7 @@ LINCLUDES = \
|
||||
$(ROOT)/build/libraries/fatfs/ARM7.TWL/include \
|
||||
$(ROOT)/build/libraries/fatfs/ARM7.TWL/include/twl/fatfs/ARM7
|
||||
|
||||
SRCS = fs_firm.c
|
||||
SRCS = fs_firm.c fs_loader.c
|
||||
|
||||
|
||||
TARGET_LIB = libfs_sp$(FIRM_LIBSUFFIX).a
|
||||
|
||||
@ -115,226 +115,3 @@ int FS_OpenSrl( void )
|
||||
ConvertPath(fatpath, fspath, OS_MOUNT_PATH_LEN);
|
||||
return FATFSi_rtfs_po_open((u8*)fatpath, 0, 0);
|
||||
}
|
||||
|
||||
#define DMA_SEND 2
|
||||
#define DMA_RECV 3
|
||||
static void CopyWithAes( const void* src, void* dest, u32 size )
|
||||
{
|
||||
AES_Lock();
|
||||
AES_Reset();
|
||||
AES_Reset();
|
||||
AES_WaitKey();
|
||||
AES_LoadKey( AES_KEY_SLOT_A );
|
||||
AES_WaitKey();
|
||||
AES_DmaSend( DMA_SEND, src, size, NULL, NULL );
|
||||
AES_DmaRecv( DMA_RECV, dest, 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 EnableAes( u32 offset )
|
||||
{
|
||||
aesFlag = TRUE;
|
||||
MI_CpuCopy8( rh->s.main_static_digest, &aesCounter, AES_BLOCK_SIZE );
|
||||
AES_AddToCounter( &aesCounter, (offset - rh->s.aes_target_rom_offset) / AES_BLOCK_SIZE );
|
||||
}
|
||||
static void DisableAes( void )
|
||||
{
|
||||
aesFlag = FALSE;
|
||||
}
|
||||
|
||||
static u32 GetTransferSize( u32 offset, u32 size )
|
||||
{
|
||||
u32 aes_offset = rh->s.aes_target_rom_offset;
|
||||
u32 aes_end = aes_offset + RoundUpModuleSize(rh->s.aes_target_size);
|
||||
u32 end = offset + RoundUpModuleSize(size);
|
||||
if ( rh->s.enable_aes )
|
||||
{
|
||||
if ( offset >= aes_offset && offset < aes_end )
|
||||
{
|
||||
if ( end > aes_end )
|
||||
{
|
||||
size = aes_end - offset;
|
||||
}
|
||||
EnableAes( offset );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( offset < aes_offset && offset + size > aes_offset )
|
||||
{
|
||||
size = aes_offset - offset;
|
||||
}
|
||||
DisableAes();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DisableAes();
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FS_LoadBuffer
|
||||
|
||||
Description: load data in file and pass to ARM9 via WRAM-B
|
||||
|
||||
Arguments: fd file discriptor to read
|
||||
offset offset to start to read in bytes
|
||||
size total length to read in bytes
|
||||
|
||||
Returns: TRUE if success
|
||||
*---------------------------------------------------------------------------*/
|
||||
BOOL FS_LoadBuffer( int fd, u32 offset, u32 size )
|
||||
{
|
||||
static int count = 0;
|
||||
|
||||
if ( fd < 0 )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
// seek
|
||||
if ( FATFSi_rtfs_po_lseek( fd, (long)offset, PSEEK_SET ) != (long)offset )
|
||||
{
|
||||
OS_TPrintf("Failed to seek file. (offset=0x%X)\n", offset);
|
||||
return FALSE;
|
||||
}
|
||||
while ( size > 0 )
|
||||
{
|
||||
u8* dest = aesFlag ? aesBuffer :
|
||||
(u8*)HW_FIRM_LOAD_BUFFER_BASE + count * HW_FIRM_LOAD_BUFFER_UNIT_SIZE;
|
||||
u32 unit = size < HW_FIRM_LOAD_BUFFER_UNIT_SIZE ? size : HW_FIRM_LOAD_BUFFER_UNIT_SIZE;
|
||||
while ( MI_GetWramBankMaster_B( count ) != MI_WRAM_ARM7 ) // wait to be ready
|
||||
{
|
||||
}
|
||||
#ifdef WORKAROUND_NAND_2KB_BUG
|
||||
{
|
||||
u32 done;
|
||||
for ( done = 0; done < unit; done += 2048 )
|
||||
{
|
||||
u8* d = dest + done;
|
||||
u32 u = unit - done < 2048 ? unit - done : 2048;
|
||||
if ( FATFSi_rtfs_po_read( fd, (u8*)d, (int)u ) != (int)u )
|
||||
{
|
||||
OS_TPrintf("Failed to read file. (dest=%p, size=0x%X)\n", d, u);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
if ( FATFSi_rtfs_po_read( fd, (u8*)dest, (int)unit ) != (int)unit )
|
||||
{
|
||||
OS_TPrintf("Failed to read file. (dest=%p, size=0x%X)\n", dest, unit);
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
if ( aesFlag )
|
||||
{
|
||||
CopyWithAes( dest, (u8*)HW_FIRM_LOAD_BUFFER_BASE + count * HW_FIRM_LOAD_BUFFER_UNIT_SIZE, unit );
|
||||
}
|
||||
PXI_NotifyID( FIRM_PXI_ID_LOAD_PIRIOD );
|
||||
count = ( count + 1 ) % HW_FIRM_LOAD_BUFFER_UNIT_NUMS;
|
||||
size -= unit;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FS_LoadModule
|
||||
|
||||
Description: load data in file and pass to ARM9 via WRAM-B in view of AES
|
||||
settings in the ROM header in HW_TWL_ROM_HEADER_BUF
|
||||
|
||||
Arguments: fd file discriptor to read
|
||||
offset offset to start to read in bytes
|
||||
length total length to read in bytes
|
||||
|
||||
Returns: TRUE if success
|
||||
*---------------------------------------------------------------------------*/
|
||||
BOOL FS_LoadModule( int fd, u32 offset, u32 size )
|
||||
{
|
||||
size = RoundUpModuleSize( size );
|
||||
while ( size > 0 )
|
||||
{
|
||||
u32 unit = GetTransferSize( offset, size );
|
||||
if ( !FS_LoadBuffer( fd, offset, unit ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
offset += unit;
|
||||
size -= unit;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FS_LoadHeader
|
||||
|
||||
Description: load ROM header in the head of file and pass to ARM9 via WRAM-B
|
||||
|
||||
Arguments: fd file discriptor to read
|
||||
|
||||
Returns: TRUE if success
|
||||
*---------------------------------------------------------------------------*/
|
||||
BOOL FS_LoadHeader( int fd )
|
||||
{
|
||||
if (fd < 0)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
DisableAes();
|
||||
if ( !FS_LoadBuffer(fd, 0, FS_HEADER_AUTH_SIZE) ||
|
||||
!FS_LoadBuffer(fd, FS_HEADER_AUTH_SIZE, HW_TWL_ROM_HEADER_BUF_SIZE - FS_HEADER_AUTH_SIZE) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FS_LoadStatic
|
||||
|
||||
Description: load static regions in file and pass to ARM9 via WRAM-B
|
||||
specified by ROM header at HW_TWL_ROM_HEADER_BUF
|
||||
|
||||
Arguments: fd file discriptor to read
|
||||
|
||||
Returns: TRUE if success
|
||||
*---------------------------------------------------------------------------*/
|
||||
BOOL FS_LoadStatic( int fd )
|
||||
{
|
||||
if ( rh->s.main_size > 0 )
|
||||
{
|
||||
if ( !FS_LoadModule( fd, rh->s.main_rom_offset, rh->s.main_size ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
if ( rh->s.sub_size > 0 )
|
||||
{
|
||||
if ( !FS_LoadModule( fd, rh->s.sub_rom_offset, rh->s.sub_size ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
if ( rh->s.main_ltd_size > 0 )
|
||||
{
|
||||
if ( !FS_LoadModule( fd, rh->s.main_ltd_rom_offset, rh->s.main_ltd_size ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
if ( rh->s.sub_ltd_size > 0 )
|
||||
{
|
||||
if ( !FS_LoadModule( fd, rh->s.sub_ltd_rom_offset, rh->s.sub_ltd_size ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
257
build/libraries/fs/ARM7/src/fs_loader.c
Normal file
257
build/libraries/fs/ARM7/src/fs_loader.c
Normal file
@ -0,0 +1,257 @@
|
||||
/*---------------------------------------------------------------------------*
|
||||
Project: TwlIPL - libraries - fs
|
||||
File: fs_loader.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 <symbols.h>
|
||||
#include <firm.h>
|
||||
#include <rtfs.h>
|
||||
|
||||
//#define WORKAROUND_NAND_2KB_BUG
|
||||
|
||||
#define FS_HEADER_AUTH_SIZE 0xe00
|
||||
|
||||
#define MODULE_ALIGNMENT 0x10 // 16バイト単位で読み込む
|
||||
//#define MODULE_ALIGNMENT 0x200 // 512バイト単位で読み込む
|
||||
#define RoundUpModuleSize(value) (((value) + MODULE_ALIGNMENT - 1) & -MODULE_ALIGNMENT)
|
||||
|
||||
static ROM_Header* const rh= (ROM_Header*)HW_TWL_ROM_HEADER_BUF;
|
||||
|
||||
static BOOL aesFlag;
|
||||
static AESCounter aesCounter;
|
||||
static u8 aesBuffer[HW_FIRM_LOAD_BUFFER_UNIT_SIZE] ATTRIBUTE_ALIGN(32);
|
||||
|
||||
#define DMA_SEND 2
|
||||
#define DMA_RECV 3
|
||||
static void CopyWithAes( const void* src, void* dest, u32 size )
|
||||
{
|
||||
AES_Lock();
|
||||
AES_Reset();
|
||||
AES_Reset();
|
||||
AES_WaitKey();
|
||||
AES_LoadKey( AES_KEY_SLOT_A );
|
||||
AES_WaitKey();
|
||||
AES_DmaSend( DMA_SEND, src, size, NULL, NULL );
|
||||
AES_DmaRecv( DMA_RECV, dest, 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 EnableAes( u32 offset )
|
||||
{
|
||||
aesFlag = TRUE;
|
||||
MI_CpuCopy8( rh->s.main_static_digest, &aesCounter, AES_BLOCK_SIZE );
|
||||
AES_AddToCounter( &aesCounter, (offset - rh->s.aes_target_rom_offset) / AES_BLOCK_SIZE );
|
||||
}
|
||||
static void DisableAes( void )
|
||||
{
|
||||
aesFlag = FALSE;
|
||||
}
|
||||
|
||||
static u32 GetTransferSize( u32 offset, u32 size )
|
||||
{
|
||||
u32 aes_offset = rh->s.aes_target_rom_offset;
|
||||
u32 aes_end = aes_offset + RoundUpModuleSize(rh->s.aes_target_size);
|
||||
u32 end = offset + RoundUpModuleSize(size);
|
||||
if ( rh->s.enable_aes )
|
||||
{
|
||||
if ( offset >= aes_offset && offset < aes_end )
|
||||
{
|
||||
if ( end > aes_end )
|
||||
{
|
||||
size = aes_end - offset;
|
||||
}
|
||||
EnableAes( offset );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( offset < aes_offset && offset + size > aes_offset )
|
||||
{
|
||||
size = aes_offset - offset;
|
||||
}
|
||||
DisableAes();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DisableAes();
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FS_LoadBuffer
|
||||
|
||||
Description: load data in file and pass to ARM9 via WRAM-B
|
||||
|
||||
Arguments: fd file discriptor to read
|
||||
offset offset to start to read in bytes
|
||||
size total length to read in bytes
|
||||
|
||||
Returns: TRUE if success
|
||||
*---------------------------------------------------------------------------*/
|
||||
BOOL FS_LoadBuffer( int fd, u32 offset, u32 size )
|
||||
{
|
||||
static int count = 0;
|
||||
|
||||
if ( fd < 0 )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
// seek
|
||||
if ( FATFSi_rtfs_po_lseek( fd, (long)offset, PSEEK_SET ) != (long)offset )
|
||||
{
|
||||
OS_TPrintf("Failed to seek file. (offset=0x%X)\n", offset);
|
||||
return FALSE;
|
||||
}
|
||||
while ( size > 0 )
|
||||
{
|
||||
u8* dest = aesFlag ? aesBuffer :
|
||||
(u8*)HW_FIRM_LOAD_BUFFER_BASE + count * HW_FIRM_LOAD_BUFFER_UNIT_SIZE;
|
||||
u32 unit = size < HW_FIRM_LOAD_BUFFER_UNIT_SIZE ? size : HW_FIRM_LOAD_BUFFER_UNIT_SIZE;
|
||||
while ( MI_GetWramBankMaster_B( count ) != MI_WRAM_ARM7 ) // wait to be ready
|
||||
{
|
||||
}
|
||||
#ifdef WORKAROUND_NAND_2KB_BUG
|
||||
{
|
||||
u32 done;
|
||||
for ( done = 0; done < unit; done += 2048 )
|
||||
{
|
||||
u8* d = dest + done;
|
||||
u32 u = unit - done < 2048 ? unit - done : 2048;
|
||||
if ( FATFSi_rtfs_po_read( fd, (u8*)d, (int)u ) != (int)u )
|
||||
{
|
||||
OS_TPrintf("Failed to read file. (dest=%p, size=0x%X)\n", d, u);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
if ( FATFSi_rtfs_po_read( fd, (u8*)dest, (int)unit ) != (int)unit )
|
||||
{
|
||||
OS_TPrintf("Failed to read file. (dest=%p, size=0x%X)\n", dest, unit);
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
if ( aesFlag )
|
||||
{
|
||||
CopyWithAes( dest, (u8*)HW_FIRM_LOAD_BUFFER_BASE + count * HW_FIRM_LOAD_BUFFER_UNIT_SIZE, unit );
|
||||
}
|
||||
PXI_NotifyID( FIRM_PXI_ID_LOAD_PIRIOD );
|
||||
count = ( count + 1 ) % HW_FIRM_LOAD_BUFFER_UNIT_NUMS;
|
||||
size -= unit;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FS_LoadModule
|
||||
|
||||
Description: load data in file and pass to ARM9 via WRAM-B in view of AES
|
||||
settings in the ROM header in HW_TWL_ROM_HEADER_BUF
|
||||
|
||||
Arguments: fd file discriptor to read
|
||||
offset offset to start to read in bytes
|
||||
length total length to read in bytes
|
||||
|
||||
Returns: TRUE if success
|
||||
*---------------------------------------------------------------------------*/
|
||||
BOOL FS_LoadModule( int fd, u32 offset, u32 size )
|
||||
{
|
||||
size = RoundUpModuleSize( size );
|
||||
while ( size > 0 )
|
||||
{
|
||||
u32 unit = GetTransferSize( offset, size );
|
||||
if ( !FS_LoadBuffer( fd, offset, unit ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
offset += unit;
|
||||
size -= unit;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FS_LoadHeader
|
||||
|
||||
Description: load ROM header in the head of file and pass to ARM9 via WRAM-B
|
||||
|
||||
Arguments: fd file discriptor to read
|
||||
|
||||
Returns: TRUE if success
|
||||
*---------------------------------------------------------------------------*/
|
||||
BOOL FS_LoadHeader( int fd )
|
||||
{
|
||||
if (fd < 0)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
DisableAes();
|
||||
if ( !FS_LoadBuffer(fd, 0, FS_HEADER_AUTH_SIZE) ||
|
||||
!FS_LoadBuffer(fd, FS_HEADER_AUTH_SIZE, HW_TWL_ROM_HEADER_BUF_SIZE - FS_HEADER_AUTH_SIZE) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FS_LoadStatic
|
||||
|
||||
Description: load static regions in file and pass to ARM9 via WRAM-B
|
||||
specified by ROM header at HW_TWL_ROM_HEADER_BUF
|
||||
|
||||
Arguments: fd file discriptor to read
|
||||
|
||||
Returns: TRUE if success
|
||||
*---------------------------------------------------------------------------*/
|
||||
BOOL FS_LoadStatic( int fd )
|
||||
{
|
||||
if ( rh->s.main_size > 0 )
|
||||
{
|
||||
if ( !FS_LoadModule( fd, rh->s.main_rom_offset, rh->s.main_size ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
if ( rh->s.sub_size > 0 )
|
||||
{
|
||||
if ( !FS_LoadModule( fd, rh->s.sub_rom_offset, rh->s.sub_size ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
if ( rh->s.main_ltd_size > 0 )
|
||||
{
|
||||
if ( !FS_LoadModule( fd, rh->s.main_ltd_rom_offset, rh->s.main_ltd_size ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
if ( rh->s.sub_ltd_size > 0 )
|
||||
{
|
||||
if ( !FS_LoadModule( fd, rh->s.sub_ltd_rom_offset, rh->s.sub_ltd_size ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -24,7 +24,7 @@ SUBMAKES =
|
||||
|
||||
LINCLUDES = $(ES_ROOT)/twl/include
|
||||
|
||||
SRCS = fs_firm.c fs_es.c
|
||||
SRCS = fs_firm.c fs_loader.c fs_loader2.c
|
||||
|
||||
|
||||
TARGET_LIB = libfs$(FIRM_LIBSUFFIX).a
|
||||
|
||||
@ -1,155 +0,0 @@
|
||||
/*---------------------------------------------------------------------------*
|
||||
Project: TwlIPL - libraries - fs
|
||||
File: fs_es.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 <firm.h>
|
||||
#include <es.h>
|
||||
|
||||
#define PATH_FORMAT_TMD "nand:/title/%08x/%08x/content/title.tmd"
|
||||
#define PATH_FORMAT_CONTENT "nand:/title/%08x/%08x/content/%08x.app"
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: LoadTMD
|
||||
|
||||
Description: 対象のタイトルの TMD ファイルをメモリに読み込みます。
|
||||
処理が正常に行われた場合に得られるバッファへのポインタは
|
||||
不要になったら NAMi_Free で解放する必要があります。
|
||||
|
||||
Arguments: titleId: 対象のタイトルの TitleID。
|
||||
|
||||
Returns: 処理が正常に行われたなら TRUEを返します。
|
||||
そうでなければ FALSE を返します。
|
||||
*---------------------------------------------------------------------------*/
|
||||
static BOOL LoadTMD(ESTitleMeta* pTmd, u64 titleId)
|
||||
{
|
||||
char path[64];
|
||||
FSFile f;
|
||||
BOOL bSuccess;
|
||||
u32 fileSize;
|
||||
s32 readSize;
|
||||
s32 readResult;
|
||||
|
||||
// TMD のパスを生成
|
||||
STD_TSPrintf(path, PATH_FORMAT_TMD, (u32)(titleId >> 32), (u32)titleId);
|
||||
|
||||
FS_InitFile(&f);
|
||||
bSuccess = FS_OpenFileEx(&f, path, FS_FILEMODE_R);
|
||||
|
||||
if( ! bSuccess )
|
||||
{
|
||||
// ファイルが開けなかった
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
fileSize = FS_GetFileLength(&f);
|
||||
|
||||
// ファイルサイズをチェック 1
|
||||
// 固定部分サイズ <= fileSize <= 固定部分サイズ + 可変長部分最大サイズ
|
||||
if( (fileSize < sizeof(IOSCSigRsa2048) + sizeof(ESTitleMetaHeader))
|
||||
|| (sizeof(ESTitleMeta) < fileSize) )
|
||||
{
|
||||
// ファイルサイズが異常
|
||||
FS_CloseFile(&f);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
readSize = (s32)fileSize;
|
||||
readResult = FS_ReadFile(&f, pTmd, readSize);
|
||||
FS_CloseFile(&f);
|
||||
|
||||
if( readResult != readSize )
|
||||
{
|
||||
// ファイルからの読み込みに失敗
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// ファイルサイズをチェック 2
|
||||
// 可変長部分を正しく考慮
|
||||
if( fileSize != sizeof(IOSCSigRsa2048)
|
||||
+ sizeof(ESTitleMetaHeader)
|
||||
+ sizeof(ESContentMeta) * MI_SwapEndian16(pTmd->head.numContents) )
|
||||
{
|
||||
// ファイルサイズが異常
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// タイトル ID の一致をチェック
|
||||
if( titleId != MI_SwapEndian64(pTmd->head.titleId) )
|
||||
{
|
||||
// タイトル ID が一致しない
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FS_GetTitleBootContentPathFast
|
||||
|
||||
Description: NAND にインストールされているアプリの実行ファイルのパスを
|
||||
取得します。
|
||||
取得する情報の正当性を検証しないため高速ですが、
|
||||
情報が改竄されている可能性があることに注意しなければなりません。
|
||||
|
||||
Arguments: buf: パスを格納するバッファへのポインタ。
|
||||
FS_ENTRY_LONGNAME_MAX 以上のサイズが必要です。
|
||||
titleId: パスを取得するアプリの Title ID。
|
||||
|
||||
Returns: 正常に処理が行われたなら TRUE を返します。
|
||||
*---------------------------------------------------------------------------*/
|
||||
BOOL FS_GetTitleBootContentPathFast(char* buf, u64 titleId)
|
||||
{
|
||||
ESTitleMeta tmd;
|
||||
u32 bootContentId;
|
||||
int bootContentIndex;
|
||||
int numContents;
|
||||
int i;
|
||||
|
||||
SDK_POINTER_ASSERT(buf);
|
||||
|
||||
|
||||
|
||||
if( !LoadTMD(&tmd, titleId) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// 生の TMD は BigEndian
|
||||
bootContentIndex = MI_SwapEndian16(tmd.head.bootIndex);
|
||||
numContents = MI_SwapEndian16(tmd.head.numContents);
|
||||
|
||||
// bootContentIndex に一致するコンテンツを探す
|
||||
for( i = 0; i < numContents; ++i )
|
||||
{
|
||||
const ESContentMeta* pContent = &tmd.contents[i];
|
||||
|
||||
if( MI_SwapEndian16(pContent->index) == bootContentIndex )
|
||||
{
|
||||
bootContentId = MI_SwapEndian32(pContent->cid);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( i >= numContents )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// コンテンツのパスを生成
|
||||
STD_TSPrintf(buf, PATH_FORMAT_CONTENT, (u32)(titleId >> 32), (u32)titleId, bootContentId);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
@ -14,50 +14,14 @@
|
||||
$Rev$
|
||||
$Author$
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#include <firm.h>
|
||||
#include <estypes.h>
|
||||
#include <es.h>
|
||||
|
||||
#define FS_HEADER_AUTH_SIZE 0xe00
|
||||
|
||||
#define MODULE_ALIGNMENT 0x10 // 16バイト単位で読み込む
|
||||
//#define MODULE_ALIGNMENT 0x200 // 512バイト単位で読み込む
|
||||
#define RoundUpModuleSize(value) (((value) + MODULE_ALIGNMENT - 1) & -MODULE_ALIGNMENT)
|
||||
|
||||
// bootContent ‚ð•\‚·“ÁŽê‚È contentIndex
|
||||
#define CONTENT_INDEX_BOOT 0xFFFF
|
||||
|
||||
#define HASH_UNIT 0x1000
|
||||
|
||||
static ROM_Header* const rh = (ROM_Header*)HW_TWL_ROM_HEADER_BUF;
|
||||
|
||||
static u8 currentKey[ SVC_SHA1_BLOCK_SIZE ];
|
||||
|
||||
static const u8 defaultKey[ SVC_SHA1_BLOCK_SIZE ] =
|
||||
{
|
||||
0x21, 0x06, 0xc0, 0xde,
|
||||
0xba, 0x98, 0xce, 0x3f,
|
||||
0xa6, 0x92, 0xe3, 0x9d,
|
||||
0x46, 0xf2, 0xed, 0x01,
|
||||
|
||||
0x76, 0xe3, 0xcc, 0x08,
|
||||
0x56, 0x23, 0x63, 0xfa,
|
||||
0xca, 0xd4, 0xec, 0xdf,
|
||||
0x9a, 0x62, 0x78, 0x34,
|
||||
|
||||
0x8f, 0x6d, 0x63, 0x3c,
|
||||
0xfe, 0x22, 0xca, 0x92,
|
||||
0x20, 0x88, 0x97, 0x23,
|
||||
0xd2, 0xcf, 0xae, 0xc2,
|
||||
|
||||
0x32, 0x67, 0x8d, 0xfe,
|
||||
0xca, 0x83, 0x64, 0x98,
|
||||
0xac, 0xfd, 0x3e, 0x37,
|
||||
0x87, 0x46, 0x58, 0x24,
|
||||
};
|
||||
|
||||
static AESKey FSiAesKeySeed;
|
||||
#define PATH_FORMAT_TMD "nand:/title/%08x/%08x/content/title.tmd"
|
||||
#define PATH_FORMAT_CONTENT "nand:/title/%08x/%08x/content/%08x.app"
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FS_InitFIRM
|
||||
@ -77,31 +41,135 @@ void FS_InitFIRM( void )
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FS_GetAesKeySeed
|
||||
Name: LoadTMD
|
||||
|
||||
Description: retreive aes key seed in the signature
|
||||
Description: 対象のタイトルの TMD ファイルをメモリに読み込みます。
|
||||
処理が正常に行われた場合に得られるバッファへのポインタは
|
||||
不要になったら NAMi_Free で解放する必要があります。
|
||||
|
||||
Arguments: None
|
||||
Arguments: titleId: 対象のタイトルの TitleID。
|
||||
|
||||
Returns: pointer to seed
|
||||
Returns: 処理が正常に行われたなら TRUEを返します。
|
||||
そうでなければ FALSE を返します。
|
||||
*---------------------------------------------------------------------------*/
|
||||
AESKey* const FS_GetAesKeySeed( void )
|
||||
static BOOL LoadTMD(ESTitleMeta* pTmd, u64 titleId)
|
||||
{
|
||||
return &FSiAesKeySeed;
|
||||
char path[64];
|
||||
FSFile f;
|
||||
BOOL bSuccess;
|
||||
u32 fileSize;
|
||||
s32 readSize;
|
||||
s32 readResult;
|
||||
|
||||
// TMD のパスを生成
|
||||
STD_TSPrintf(path, PATH_FORMAT_TMD, (u32)(titleId >> 32), (u32)titleId);
|
||||
|
||||
FS_InitFile(&f);
|
||||
bSuccess = FS_OpenFileEx(&f, path, FS_FILEMODE_R);
|
||||
|
||||
if( ! bSuccess )
|
||||
{
|
||||
// ファイルが開けなかった
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
fileSize = FS_GetFileLength(&f);
|
||||
|
||||
// ファイルサイズをチェック 1
|
||||
// 固定部分サイズ <= fileSize <= 固定部分サイズ + 可変長部分最大サイズ
|
||||
if( (fileSize < sizeof(IOSCSigRsa2048) + sizeof(ESTitleMetaHeader))
|
||||
|| (sizeof(ESTitleMeta) < fileSize) )
|
||||
{
|
||||
// ファイルサイズが異常
|
||||
FS_CloseFile(&f);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
readSize = (s32)fileSize;
|
||||
readResult = FS_ReadFile(&f, pTmd, readSize);
|
||||
FS_CloseFile(&f);
|
||||
|
||||
if( readResult != readSize )
|
||||
{
|
||||
// ファイルからの読み込みに失敗
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// ファイルサイズをチェック 2
|
||||
// 可変長部分を正しく考慮
|
||||
if( fileSize != sizeof(IOSCSigRsa2048)
|
||||
+ sizeof(ESTitleMetaHeader)
|
||||
+ sizeof(ESContentMeta) * MI_SwapEndian16(pTmd->head.numContents) )
|
||||
{
|
||||
// ファイルサイズが異常
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// タイトル ID の一致をチェック
|
||||
if( titleId != MI_SwapEndian64(pTmd->head.titleId) )
|
||||
{
|
||||
// タイトル ID が一致しない
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FS_DeleteAesKeySeed
|
||||
Name: FS_GetTitleBootContentPathFast
|
||||
|
||||
Description: delete aes key seed in the signature
|
||||
Description: NAND にインストールされているアプリの実行ファイルのパスを
|
||||
取得します。
|
||||
取得する情報の正当性を検証しないため高速ですが、
|
||||
情報が改竄されている可能性があることに注意しなければなりません。
|
||||
|
||||
Arguments: None
|
||||
Arguments: buf: パスを格納するバッファへのポインタ。
|
||||
FS_ENTRY_LONGNAME_MAX 以上のサイズが必要です。
|
||||
titleId: パスを取得するアプリの Title ID。
|
||||
|
||||
Returns: None
|
||||
Returns: 正常に処理が行われたなら TRUE を返します。
|
||||
*---------------------------------------------------------------------------*/
|
||||
void FS_DeleteAesKeySeed( void )
|
||||
BOOL FS_GetTitleBootContentPathFast(char* buf, u64 titleId)
|
||||
{
|
||||
MI_CpuClear8( &FSiAesKeySeed, sizeof(FSiAesKeySeed) );
|
||||
ESTitleMeta tmd;
|
||||
u32 bootContentId;
|
||||
int bootContentIndex;
|
||||
int numContents;
|
||||
int i;
|
||||
|
||||
SDK_POINTER_ASSERT(buf);
|
||||
|
||||
|
||||
|
||||
if( !LoadTMD(&tmd, titleId) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// 生の TMD は BigEndian
|
||||
bootContentIndex = MI_SwapEndian16(tmd.head.bootIndex);
|
||||
numContents = MI_SwapEndian16(tmd.head.numContents);
|
||||
|
||||
// bootContentIndex に一致するコンテンツを探す
|
||||
for( i = 0; i < numContents; ++i )
|
||||
{
|
||||
const ESContentMeta* pContent = &tmd.contents[i];
|
||||
|
||||
if( MI_SwapEndian16(pContent->index) == bootContentIndex )
|
||||
{
|
||||
bootContentId = MI_SwapEndian32(pContent->cid);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( i >= numContents )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// コンテンツのパスを生成
|
||||
STD_TSPrintf(buf, PATH_FORMAT_CONTENT, (u32)(titleId >> 32), (u32)titleId, bootContentId);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
@ -143,467 +211,4 @@ BOOL FS_ResolveSrlUnsecured( u64 titleId )
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FS_SetDigestKey
|
||||
|
||||
Description: set specified key or default key for HMAC-SHA-1
|
||||
|
||||
Arguments: digestKey pointer to key
|
||||
if NULL, use default key
|
||||
|
||||
Returns: TRUE if success
|
||||
*---------------------------------------------------------------------------*/
|
||||
void FS_SetDigestKey( const u8* digestKey )
|
||||
{
|
||||
if ( digestKey )
|
||||
{
|
||||
MI_CpuCopy8(digestKey, currentKey, SVC_SHA1_BLOCK_SIZE);
|
||||
}
|
||||
else
|
||||
{
|
||||
MI_CpuCopy8(defaultKey, currentKey, SVC_SHA1_BLOCK_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
static inline BOOL CheckDigest( u8* a, u8* b, BOOL aClr, BOOL bClr )
|
||||
{
|
||||
BOOL result = TRUE;
|
||||
int i;
|
||||
for ( i = 0; i < SVC_SHA1_DIGEST_SIZE; i++ )
|
||||
{
|
||||
if ( a[i] != b[i] )
|
||||
{
|
||||
result = FALSE;
|
||||
}
|
||||
}
|
||||
if ( aClr ) MI_CpuClear8(a, SVC_SHA1_DIGEST_SIZE);
|
||||
if ( bClr ) MI_CpuClear8(b, SVC_SHA1_DIGEST_SIZE);
|
||||
return result;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: CheckRomCertificate
|
||||
|
||||
Description: check the certification in the ROM
|
||||
|
||||
ROMヘッダに付加された証明書のチェックを行います。
|
||||
makerom.TWL内のコードに依存します。
|
||||
|
||||
Arguments: pool pointer to the SVCSignHeapContext
|
||||
pCert pointer to the certification
|
||||
pCAPubKey pointer to the public key for the certification
|
||||
gameCode initial code
|
||||
|
||||
Returns: TRUE if success
|
||||
*---------------------------------------------------------------------------*/
|
||||
static BOOL CheckRomCertificate( SVCSignHeapContext* pool, const RomCertificate *pCert, const void* pCAPubKey, u32 gameCode )
|
||||
{
|
||||
u8 digest[SVC_SHA1_DIGEST_SIZE];
|
||||
u8 md[SVC_SHA1_DIGEST_SIZE];
|
||||
|
||||
// 証明書ヘッダのマジックナンバーチェック
|
||||
if( pCert->header.magicNumber != TWL_ROM_CERT_MAGIC_NUMBER ||
|
||||
// 証明書ヘッダとROMヘッダのゲームコード一致チェック
|
||||
pCert->header.gameCode != gameCode )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
// 証明書署名チェック
|
||||
SVC_DecryptSign( pool, &digest, pCert->sign, pCAPubKey );
|
||||
|
||||
// ダイジェストの計算
|
||||
SVC_CalcSHA1( md, pCert, ROM_CERT_SIGN_OFFSET );
|
||||
|
||||
// 比較
|
||||
return CheckDigest(md, digest, TRUE, TRUE);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FS_LoadBuffer
|
||||
|
||||
Description: receive data from ARM7 via WRAM-B and store in destination address,
|
||||
calculate SHA1 in parallel if ctx is specified
|
||||
|
||||
Arguments: dest destination address to read
|
||||
size total length to read in bytes
|
||||
ctx pointer to SHA1 context or NULL
|
||||
|
||||
Returns: TRUE if success
|
||||
*---------------------------------------------------------------------------*/
|
||||
BOOL FS_LoadBuffer( u8* dest, u32 size, SVCSHA1Context *ctx )
|
||||
{
|
||||
static int count = 0;
|
||||
|
||||
while ( size > 0 )
|
||||
{
|
||||
u8* src = (u8*)HW_FIRM_LOAD_BUFFER_BASE + count * HW_FIRM_LOAD_BUFFER_UNIT_SIZE;
|
||||
u32 unit = size < HW_FIRM_LOAD_BUFFER_UNIT_SIZE ? size : HW_FIRM_LOAD_BUFFER_UNIT_SIZE;
|
||||
if ( PXI_RecvID() != FIRM_PXI_ID_LOAD_PIRIOD )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
MIi_SetWramBankMaster_B( count, MI_WRAM_ARM9 );
|
||||
if (ctx)
|
||||
{
|
||||
int done;
|
||||
for ( done = 0; done < unit; done += HASH_UNIT )
|
||||
{
|
||||
u8* s = src + done;
|
||||
u8* d = dest + done;
|
||||
u32 u = unit - done < HASH_UNIT ? unit - done : HASH_UNIT;
|
||||
SVC_SHA1Update( ctx, s, u );
|
||||
MI_CpuCopyFast( s, d, u );
|
||||
MI_CpuClearFast( s, u ); // OS_Bootでのクリアと比較する
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MI_CpuCopyFast( src, dest, unit );
|
||||
MI_CpuClearFast( src, unit ); // OS_Bootでのクリアと比較する
|
||||
}
|
||||
DC_FlushRange( src, unit );
|
||||
size -= unit;
|
||||
dest += unit;
|
||||
MIi_SetWramBankMaster_B( count, MI_WRAM_ARM7 );
|
||||
count = ( count + 1 ) % HW_FIRM_LOAD_BUFFER_UNIT_NUMS;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: GetTransferSize
|
||||
|
||||
Description: get size to transfer once
|
||||
|
||||
一度に受信するサイズを返します。
|
||||
|
||||
転送範囲がAES領域をまたぐ場合は、境界までのサイズ (引数より
|
||||
小さなサイズ) を返します。
|
||||
makerom.TWLまたはIPLの使用に依存します。
|
||||
|
||||
Arguments: offset offset of region from head of ROM_Header
|
||||
size size of region
|
||||
|
||||
Returns: size to transfer once
|
||||
*---------------------------------------------------------------------------*/
|
||||
static u32 GetTransferSize( u32 offset, u32 size )
|
||||
{
|
||||
u32 aes_offset = rh->s.aes_target_rom_offset;
|
||||
u32 aes_end = aes_offset + rh->s.aes_target_size;
|
||||
u32 end = offset + size;
|
||||
if ( rh->s.enable_aes )
|
||||
{
|
||||
if ( offset >= aes_offset && offset < aes_end )
|
||||
{
|
||||
if ( end > aes_end )
|
||||
{
|
||||
size = aes_end - offset;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( offset < aes_offset && offset + size > aes_offset )
|
||||
{
|
||||
size = aes_offset - offset;
|
||||
}
|
||||
}
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FS_LoadModule
|
||||
|
||||
Description: receive data from ARM7 via WRAM-B and store in destination address
|
||||
in view of AES settings in the ROM header at HW_TWL_ROM_HEADER_BUF,
|
||||
then verify the digest
|
||||
|
||||
Arguments: dest destination address to read
|
||||
offset file offset to start to read in bytes
|
||||
size total length to read in bytes
|
||||
digest digest to verify
|
||||
|
||||
Returns: TRUE if success
|
||||
*---------------------------------------------------------------------------*/
|
||||
BOOL FS_LoadModule( u8* dest, u32 offset, u32 size, const u8 digest[SVC_SHA1_DIGEST_SIZE] )
|
||||
{
|
||||
SVCHMACSHA1Context ctx;
|
||||
u8 md[SVC_SHA1_DIGEST_SIZE];
|
||||
|
||||
SVC_HMACSHA1Init(&ctx, currentKey, SVC_SHA1_BLOCK_SIZE );
|
||||
while ( size > 0 )
|
||||
{
|
||||
u32 unit = GetTransferSize( offset, size );
|
||||
if ( !FS_LoadBuffer( dest, unit, &ctx.sha1_ctx ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
dest += unit;
|
||||
offset += unit;
|
||||
size -= unit;
|
||||
}
|
||||
SVC_HMACSHA1GetHash(&ctx, md);
|
||||
return CheckDigest(md, (u8*)digest, TRUE, FALSE);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FS_LoadHeader
|
||||
|
||||
Description: receive ROM header, store to HW_TWL_ROM_HEADER_BUF,
|
||||
and verify signature
|
||||
|
||||
Arguments: pool heap context to call SVC_DecryptSign
|
||||
rsa_key public key to verify the signature
|
||||
|
||||
Returns: TRUE if success
|
||||
*---------------------------------------------------------------------------*/
|
||||
BOOL FS_LoadHeader( SVCSignHeapContext* pool, const void* rsa_key )
|
||||
{
|
||||
SVCSHA1Context ctx;
|
||||
u8 md[SVC_SHA1_DIGEST_SIZE];
|
||||
SignatureData sd;
|
||||
|
||||
SVC_SHA1Init( &ctx );
|
||||
if ( !FS_LoadBuffer( (u8*)rh, FS_HEADER_AUTH_SIZE, &ctx ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
SVC_SHA1GetHash( &ctx, md );
|
||||
if ( !FS_LoadBuffer( (u8*)rh + FS_HEADER_AUTH_SIZE, HW_TWL_ROM_HEADER_BUF_SIZE - FS_HEADER_AUTH_SIZE, NULL ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// コンテンツ証明書
|
||||
if ( CheckRomCertificate( pool, &rh->certificate, rsa_key, *(u32*)rh->s.game_code ) )
|
||||
{
|
||||
rsa_key = rh->certificate.pubKeyMod; // ヘッダ用の鍵の取り出し
|
||||
}
|
||||
else
|
||||
{
|
||||
// とりあえずコンテンツ証明書用の鍵がそのまま使えると仮定
|
||||
}
|
||||
|
||||
// ヘッダ署名チェック
|
||||
SVC_DecryptSign( pool, &sd, rh->signature, rsa_key );
|
||||
|
||||
if ( !CheckDigest( md, sd.digest, TRUE, FALSE ) )
|
||||
{
|
||||
MI_CpuClear8( &sd, sizeof(sd) ); // 残り削除 (他に必要なものはない?)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// ダイジェスト以外のデータのチェックが必要!!
|
||||
|
||||
// 鍵の保存
|
||||
MI_CpuCopy8( (AESKey*)sd.aes_key_seed, &FSiAesKeySeed, sizeof(FSiAesKeySeed) );
|
||||
|
||||
MI_CpuClear8( &sd, sizeof(sd) ); // 残り削除 (他に必要なものはない?)
|
||||
|
||||
// ROMヘッダのコピー
|
||||
MI_CpuCopyFast( rh, (void*)HW_ROM_HEADER_BUF, HW_ROM_HEADER_BUF_END-HW_ROM_HEADER_BUF );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FS_LoadStatic
|
||||
|
||||
Description: receive static regions from ARM6 via WRAM-B and store them
|
||||
specified by ROM header at HW_TWL_ROM_HEADER_BUF
|
||||
|
||||
Arguments: None
|
||||
|
||||
Returns: TRUE if success
|
||||
*---------------------------------------------------------------------------*/
|
||||
BOOL FS_LoadStatic( void )
|
||||
{
|
||||
if ( rh->s.main_size > 0 )
|
||||
{
|
||||
if ( !FS_LoadModule( rh->s.main_ram_address, rh->s.main_rom_offset, rh->s.main_size, rh->s.main_static_digest ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
if ( rh->s.sub_size > 0 )
|
||||
{
|
||||
if ( !FS_LoadModule( rh->s.sub_ram_address, rh->s.sub_rom_offset, rh->s.sub_size, rh->s.sub_static_digest ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
if ( rh->s.main_ltd_size > 0 )
|
||||
{
|
||||
if ( !FS_LoadModule( rh->s.main_ltd_ram_address, rh->s.main_ltd_rom_offset, rh->s.main_ltd_size, rh->s.main_ltd_static_digest ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
if ( rh->s.sub_ltd_size > 0 )
|
||||
{
|
||||
if ( !FS_LoadModule( rh->s.sub_ltd_ram_address, rh->s.sub_ltd_rom_offset, rh->s.sub_ltd_size, rh->s.sub_ltd_static_digest ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
以下、LoadBufferを使わない版 (通常FS APIを使用する)
|
||||
AES非対応!!
|
||||
*/
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FS_LoadSrlModule
|
||||
|
||||
Description: receive data from ARM7 via WRAM-B and store in destination address
|
||||
in view of AES settings in the ROM header at HW_TWL_ROM_HEADER_BUF,
|
||||
then verify the digest
|
||||
|
||||
Arguments: pFile pointer to FSFile streucture
|
||||
dest destination address to read
|
||||
offset file offset to start to read in bytes
|
||||
size total length to read in bytes
|
||||
digest digest to verify
|
||||
|
||||
Returns: TRUE if success
|
||||
*---------------------------------------------------------------------------*/
|
||||
BOOL FS_LoadSrlModule( FSFile *pFile, u8* dest, u32 offset, u32 size, const u8 digest[SVC_SHA1_DIGEST_SIZE] )
|
||||
{
|
||||
u8 md[SVC_SHA1_DIGEST_SIZE];
|
||||
u8* hmacDest = dest;
|
||||
u32 hmacSize = size;
|
||||
|
||||
if ( !FS_SeekFile( pFile, (s32)offset, FS_SEEK_SET ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
while ( size > 0 )
|
||||
{
|
||||
u32 unit = GetTransferSize( offset, size ); // AES対象ならうまく動かない
|
||||
if ( !FS_ReadFile( pFile, dest, (s32)unit ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
dest += unit;
|
||||
offset += unit;
|
||||
size -= unit;
|
||||
}
|
||||
SVC_CalcHMACSHA1( md, hmacDest, hmacSize, currentKey, SVC_SHA1_BLOCK_SIZE );
|
||||
return CheckDigest(md, (u8*)digest, TRUE, FALSE);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FS_OpenSrl
|
||||
|
||||
Description: open srl file named at HW_TWL_FS_BOOT_SRL_PATH_BUF
|
||||
|
||||
Arguments: pFile pointer to FSFile streucture
|
||||
|
||||
Returns: TRUE if success
|
||||
*---------------------------------------------------------------------------*/
|
||||
BOOL FS_OpenSrl( FSFile *pFile )
|
||||
{
|
||||
return FS_OpenFileEx( pFile, (char*)HW_TWL_FS_BOOT_SRL_PATH_BUF, FS_FILEMODE_R );
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FS_LoadSrlHeader
|
||||
|
||||
Description: load ROM header to HW_TWL_ROM_HEADER_BUF using normal FS,
|
||||
and verify signature
|
||||
|
||||
Arguments: pFile pointer to FSFile streucture
|
||||
pool heap context to call SVC_DecryptSign
|
||||
rsa_key public key to verify the signature
|
||||
|
||||
Returns: TRUE if success
|
||||
*---------------------------------------------------------------------------*/
|
||||
BOOL FS_LoadSrlHeader( FSFile *pFile, SVCSignHeapContext* pool, const void* rsa_key )
|
||||
{
|
||||
u8 md[SVC_SHA1_DIGEST_SIZE];
|
||||
SignatureData sd;
|
||||
|
||||
if ( !FS_SeekFile( pFile, 0, FS_SEEK_SET ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
if ( !FS_ReadFile( pFile, rh, HW_TWL_ROM_HEADER_BUF_SIZE ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
SVC_CalcSHA1( md, rh, FS_HEADER_AUTH_SIZE );
|
||||
|
||||
// コンテンツ証明書
|
||||
if ( CheckRomCertificate( pool, &rh->certificate, rsa_key, *(u32*)rh->s.game_code ) )
|
||||
{
|
||||
rsa_key = rh->certificate.pubKeyMod; // ヘッダ用の鍵の取り出し
|
||||
}
|
||||
else
|
||||
{
|
||||
// とりあえずコンテンツ証明書用の鍵がそのまま使えると仮定
|
||||
}
|
||||
|
||||
// ヘッダ署名チェック
|
||||
SVC_DecryptSign( pool, &sd, rh->signature, rsa_key );
|
||||
|
||||
if ( !CheckDigest( md, sd.digest, TRUE, FALSE ) )
|
||||
{
|
||||
MI_CpuClear8( &sd, sizeof(sd) ); // 残り削除 (他に必要なものはない?)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// ダイジェスト以外のデータのチェックが必要!!
|
||||
|
||||
// 鍵の保存
|
||||
MI_CpuCopy8( (AESKey*)sd.aes_key_seed, &FSiAesKeySeed, sizeof(FSiAesKeySeed) );
|
||||
|
||||
MI_CpuClear8( &sd, sizeof(sd) ); // 残り削除 (他に必要なものはない?)
|
||||
|
||||
// ROMヘッダのコピー
|
||||
MI_CpuCopyFast( rh, (void*)HW_ROM_HEADER_BUF, HW_ROM_HEADER_BUF_END-HW_ROM_HEADER_BUF );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FS_LoadSrlStatic
|
||||
|
||||
Description: receive static regions from ARM6 via WRAM-B and store them
|
||||
specified by ROM header at HW_TWL_ROM_HEADER_BUF
|
||||
|
||||
Arguments: pFile pointer to FSFile streucture
|
||||
|
||||
Returns: TRUE if success
|
||||
*---------------------------------------------------------------------------*/
|
||||
BOOL FS_LoadSrlStatic( FSFile *pFile )
|
||||
{
|
||||
if ( rh->s.main_size > 0 )
|
||||
{
|
||||
if ( !FS_LoadSrlModule( pFile, rh->s.main_ram_address, rh->s.main_rom_offset, rh->s.main_size, rh->s.main_static_digest ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
if ( rh->s.sub_size > 0 )
|
||||
{
|
||||
if ( !FS_LoadSrlModule( pFile, rh->s.sub_ram_address, rh->s.sub_rom_offset, rh->s.sub_size, rh->s.sub_static_digest ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
if ( rh->s.main_ltd_size > 0 )
|
||||
{
|
||||
if ( !FS_LoadSrlModule( pFile, rh->s.main_ltd_ram_address, rh->s.main_ltd_rom_offset, rh->s.main_ltd_size, rh->s.main_ltd_static_digest ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
if ( rh->s.sub_ltd_size > 0 )
|
||||
{
|
||||
if ( !FS_LoadSrlModule( pFile, rh->s.sub_ltd_ram_address, rh->s.sub_ltd_rom_offset, rh->s.sub_ltd_size, rh->s.sub_ltd_static_digest ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
390
build/libraries/fs/ARM9/src/fs_loader.c
Normal file
390
build/libraries/fs/ARM9/src/fs_loader.c
Normal file
@ -0,0 +1,390 @@
|
||||
/*---------------------------------------------------------------------------*
|
||||
Project: TwlIPL - libraries - fs
|
||||
File: fs_loader.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 <firm.h>
|
||||
#include <estypes.h>
|
||||
#include <es.h>
|
||||
|
||||
#define FS_HEADER_AUTH_SIZE 0xe00
|
||||
|
||||
#define MODULE_ALIGNMENT 0x10 // 16バイト単位で読み込む
|
||||
//#define MODULE_ALIGNMENT 0x200 // 512バイト単位で読み込む
|
||||
#define RoundUpModuleSize(value) (((value) + MODULE_ALIGNMENT - 1) & -MODULE_ALIGNMENT)
|
||||
|
||||
#define HASH_UNIT 0x1000
|
||||
|
||||
static ROM_Header* const rh = (ROM_Header*)HW_TWL_ROM_HEADER_BUF;
|
||||
|
||||
static u8 currentKey[ SVC_SHA1_BLOCK_SIZE ];
|
||||
|
||||
static const u8 defaultKey[ SVC_SHA1_BLOCK_SIZE ] =
|
||||
{
|
||||
0x21, 0x06, 0xc0, 0xde,
|
||||
0xba, 0x98, 0xce, 0x3f,
|
||||
0xa6, 0x92, 0xe3, 0x9d,
|
||||
0x46, 0xf2, 0xed, 0x01,
|
||||
|
||||
0x76, 0xe3, 0xcc, 0x08,
|
||||
0x56, 0x23, 0x63, 0xfa,
|
||||
0xca, 0xd4, 0xec, 0xdf,
|
||||
0x9a, 0x62, 0x78, 0x34,
|
||||
|
||||
0x8f, 0x6d, 0x63, 0x3c,
|
||||
0xfe, 0x22, 0xca, 0x92,
|
||||
0x20, 0x88, 0x97, 0x23,
|
||||
0xd2, 0xcf, 0xae, 0xc2,
|
||||
|
||||
0x32, 0x67, 0x8d, 0xfe,
|
||||
0xca, 0x83, 0x64, 0x98,
|
||||
0xac, 0xfd, 0x3e, 0x37,
|
||||
0x87, 0x46, 0x58, 0x24,
|
||||
};
|
||||
|
||||
static AESKey FSiAesKeySeed;
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FS_GetAesKeySeed
|
||||
|
||||
Description: retreive aes key seed in the signature
|
||||
|
||||
Arguments: None
|
||||
|
||||
Returns: pointer to seed
|
||||
*---------------------------------------------------------------------------*/
|
||||
AESKey* const FS_GetAesKeySeed( void )
|
||||
{
|
||||
return &FSiAesKeySeed;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FS_DeleteAesKeySeed
|
||||
|
||||
Description: delete aes key seed in the signature
|
||||
|
||||
Arguments: None
|
||||
|
||||
Returns: None
|
||||
*---------------------------------------------------------------------------*/
|
||||
void FS_DeleteAesKeySeed( void )
|
||||
{
|
||||
MI_CpuClear8( &FSiAesKeySeed, sizeof(FSiAesKeySeed) );
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FS_SetDigestKey
|
||||
|
||||
Description: set specified key or default key for HMAC-SHA-1
|
||||
|
||||
Arguments: digestKey pointer to key
|
||||
if NULL, use default key
|
||||
|
||||
Returns: TRUE if success
|
||||
*---------------------------------------------------------------------------*/
|
||||
void FS_SetDigestKey( const u8* digestKey )
|
||||
{
|
||||
if ( digestKey )
|
||||
{
|
||||
MI_CpuCopy8(digestKey, currentKey, SVC_SHA1_BLOCK_SIZE);
|
||||
}
|
||||
else
|
||||
{
|
||||
MI_CpuCopy8(defaultKey, currentKey, SVC_SHA1_BLOCK_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
static inline BOOL CheckDigest( u8* a, u8* b, BOOL aClr, BOOL bClr )
|
||||
{
|
||||
BOOL result = TRUE;
|
||||
int i;
|
||||
for ( i = 0; i < SVC_SHA1_DIGEST_SIZE; i++ )
|
||||
{
|
||||
if ( a[i] != b[i] )
|
||||
{
|
||||
result = FALSE;
|
||||
}
|
||||
}
|
||||
if ( aClr ) MI_CpuClear8(a, SVC_SHA1_DIGEST_SIZE);
|
||||
if ( bClr ) MI_CpuClear8(b, SVC_SHA1_DIGEST_SIZE);
|
||||
return result;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: CheckRomCertificate
|
||||
|
||||
Description: check the certification in the ROM
|
||||
|
||||
ROMヘッダに付加された証明書のチェックを行います。
|
||||
makerom.TWL内のコードに依存します。
|
||||
|
||||
Arguments: pool pointer to the SVCSignHeapContext
|
||||
pCert pointer to the certification
|
||||
pCAPubKey pointer to the public key for the certification
|
||||
gameCode initial code
|
||||
|
||||
Returns: TRUE if success
|
||||
*---------------------------------------------------------------------------*/
|
||||
static BOOL CheckRomCertificate( SVCSignHeapContext* pool, const RomCertificate *pCert, const void* pCAPubKey, u32 gameCode )
|
||||
{
|
||||
u8 digest[SVC_SHA1_DIGEST_SIZE];
|
||||
u8 md[SVC_SHA1_DIGEST_SIZE];
|
||||
|
||||
// 証明書ヘッダのマジックナンバーチェック
|
||||
if( pCert->header.magicNumber != TWL_ROM_CERT_MAGIC_NUMBER ||
|
||||
// 証明書ヘッダとROMヘッダのゲームコード一致チェック
|
||||
pCert->header.gameCode != gameCode )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
// 証明書署名チェック
|
||||
SVC_DecryptSign( pool, &digest, pCert->sign, pCAPubKey );
|
||||
|
||||
// ダイジェストの計算
|
||||
SVC_CalcSHA1( md, pCert, ROM_CERT_SIGN_OFFSET );
|
||||
|
||||
// 比較
|
||||
return CheckDigest(md, digest, TRUE, TRUE);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FS_LoadBuffer
|
||||
|
||||
Description: receive data from ARM7 via WRAM-B and store in destination address,
|
||||
calculate SHA1 in parallel if ctx is specified
|
||||
|
||||
Arguments: dest destination address to read
|
||||
size total length to read in bytes
|
||||
ctx pointer to SHA1 context or NULL
|
||||
|
||||
Returns: TRUE if success
|
||||
*---------------------------------------------------------------------------*/
|
||||
BOOL FS_LoadBuffer( u8* dest, u32 size, SVCSHA1Context *ctx )
|
||||
{
|
||||
static int count = 0;
|
||||
|
||||
while ( size > 0 )
|
||||
{
|
||||
u8* src = (u8*)HW_FIRM_LOAD_BUFFER_BASE + count * HW_FIRM_LOAD_BUFFER_UNIT_SIZE;
|
||||
u32 unit = size < HW_FIRM_LOAD_BUFFER_UNIT_SIZE ? size : HW_FIRM_LOAD_BUFFER_UNIT_SIZE;
|
||||
if ( PXI_RecvID() != FIRM_PXI_ID_LOAD_PIRIOD )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
MIi_SetWramBankMaster_B( count, MI_WRAM_ARM9 );
|
||||
if (ctx)
|
||||
{
|
||||
int done;
|
||||
for ( done = 0; done < unit; done += HASH_UNIT )
|
||||
{
|
||||
u8* s = src + done;
|
||||
u8* d = dest + done;
|
||||
u32 u = unit - done < HASH_UNIT ? unit - done : HASH_UNIT;
|
||||
SVC_SHA1Update( ctx, s, u );
|
||||
MI_CpuCopyFast( s, d, u );
|
||||
MI_CpuClearFast( s, u ); // OS_Bootでのクリアと比較する
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MI_CpuCopyFast( src, dest, unit );
|
||||
MI_CpuClearFast( src, unit ); // OS_Bootでのクリアと比較する
|
||||
}
|
||||
DC_FlushRange( src, unit );
|
||||
size -= unit;
|
||||
dest += unit;
|
||||
MIi_SetWramBankMaster_B( count, MI_WRAM_ARM7 );
|
||||
count = ( count + 1 ) % HW_FIRM_LOAD_BUFFER_UNIT_NUMS;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: GetTransferSize
|
||||
|
||||
Description: get size to transfer once
|
||||
|
||||
一度に受信するサイズを返します。
|
||||
|
||||
転送範囲がAES領域をまたぐ場合は、境界までのサイズ (引数より
|
||||
小さなサイズ) を返します。
|
||||
makerom.TWLまたはIPLの使用に依存します。
|
||||
|
||||
Arguments: offset offset of region from head of ROM_Header
|
||||
size size of region
|
||||
|
||||
Returns: size to transfer once
|
||||
*---------------------------------------------------------------------------*/
|
||||
static u32 GetTransferSize( u32 offset, u32 size )
|
||||
{
|
||||
u32 aes_offset = rh->s.aes_target_rom_offset;
|
||||
u32 aes_end = aes_offset + rh->s.aes_target_size;
|
||||
u32 end = offset + size;
|
||||
if ( rh->s.enable_aes )
|
||||
{
|
||||
if ( offset >= aes_offset && offset < aes_end )
|
||||
{
|
||||
if ( end > aes_end )
|
||||
{
|
||||
size = aes_end - offset;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( offset < aes_offset && offset + size > aes_offset )
|
||||
{
|
||||
size = aes_offset - offset;
|
||||
}
|
||||
}
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FS_LoadModule
|
||||
|
||||
Description: receive data from ARM7 via WRAM-B and store in destination address
|
||||
in view of AES settings in the ROM header at HW_TWL_ROM_HEADER_BUF,
|
||||
then verify the digest
|
||||
|
||||
Arguments: dest destination address to read
|
||||
offset file offset to start to read in bytes
|
||||
size total length to read in bytes
|
||||
digest digest to verify
|
||||
|
||||
Returns: TRUE if success
|
||||
*---------------------------------------------------------------------------*/
|
||||
BOOL FS_LoadModule( u8* dest, u32 offset, u32 size, const u8 digest[SVC_SHA1_DIGEST_SIZE] )
|
||||
{
|
||||
SVCHMACSHA1Context ctx;
|
||||
u8 md[SVC_SHA1_DIGEST_SIZE];
|
||||
|
||||
SVC_HMACSHA1Init(&ctx, currentKey, SVC_SHA1_BLOCK_SIZE );
|
||||
while ( size > 0 )
|
||||
{
|
||||
u32 unit = GetTransferSize( offset, size );
|
||||
if ( !FS_LoadBuffer( dest, unit, &ctx.sha1_ctx ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
dest += unit;
|
||||
offset += unit;
|
||||
size -= unit;
|
||||
}
|
||||
SVC_HMACSHA1GetHash(&ctx, md);
|
||||
return CheckDigest(md, (u8*)digest, TRUE, FALSE);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FS_LoadHeader
|
||||
|
||||
Description: receive ROM header, store to HW_TWL_ROM_HEADER_BUF,
|
||||
and verify signature
|
||||
|
||||
Arguments: pool heap context to call SVC_DecryptSign
|
||||
rsa_key public key to verify the signature
|
||||
|
||||
Returns: TRUE if success
|
||||
*---------------------------------------------------------------------------*/
|
||||
BOOL FS_LoadHeader( SVCSignHeapContext* pool, const void* rsa_key )
|
||||
{
|
||||
SVCSHA1Context ctx;
|
||||
u8 md[SVC_SHA1_DIGEST_SIZE];
|
||||
SignatureData sd;
|
||||
|
||||
SVC_SHA1Init( &ctx );
|
||||
if ( !FS_LoadBuffer( (u8*)rh, FS_HEADER_AUTH_SIZE, &ctx ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
SVC_SHA1GetHash( &ctx, md );
|
||||
if ( !FS_LoadBuffer( (u8*)rh + FS_HEADER_AUTH_SIZE, HW_TWL_ROM_HEADER_BUF_SIZE - FS_HEADER_AUTH_SIZE, NULL ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// コンテンツ証明書
|
||||
if ( CheckRomCertificate( pool, &rh->certificate, rsa_key, *(u32*)rh->s.game_code ) )
|
||||
{
|
||||
rsa_key = rh->certificate.pubKeyMod; // ヘッダ用の鍵の取り出し
|
||||
}
|
||||
else
|
||||
{
|
||||
// とりあえずコンテンツ証明書用の鍵がそのまま使えると仮定
|
||||
}
|
||||
|
||||
// ヘッダ署名チェック
|
||||
SVC_DecryptSign( pool, &sd, rh->signature, rsa_key );
|
||||
|
||||
if ( !CheckDigest( md, sd.digest, TRUE, FALSE ) )
|
||||
{
|
||||
MI_CpuClear8( &sd, sizeof(sd) ); // 残り削除 (他に必要なものはない?)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// ダイジェスト以外のデータのチェックが必要!!
|
||||
|
||||
// 鍵の保存
|
||||
MI_CpuCopy8( (AESKey*)sd.aes_key_seed, &FSiAesKeySeed, sizeof(FSiAesKeySeed) );
|
||||
|
||||
MI_CpuClear8( &sd, sizeof(sd) ); // 残り削除 (他に必要なものはない?)
|
||||
|
||||
// ROMヘッダのコピー
|
||||
MI_CpuCopyFast( rh, (void*)HW_ROM_HEADER_BUF, HW_ROM_HEADER_BUF_END-HW_ROM_HEADER_BUF );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FS_LoadStatic
|
||||
|
||||
Description: receive static regions from ARM6 via WRAM-B and store them
|
||||
specified by ROM header at HW_TWL_ROM_HEADER_BUF
|
||||
|
||||
Arguments: None
|
||||
|
||||
Returns: TRUE if success
|
||||
*---------------------------------------------------------------------------*/
|
||||
BOOL FS_LoadStatic( void )
|
||||
{
|
||||
if ( rh->s.main_size > 0 )
|
||||
{
|
||||
if ( !FS_LoadModule( rh->s.main_ram_address, rh->s.main_rom_offset, rh->s.main_size, rh->s.main_static_digest ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
if ( rh->s.sub_size > 0 )
|
||||
{
|
||||
if ( !FS_LoadModule( rh->s.sub_ram_address, rh->s.sub_rom_offset, rh->s.sub_size, rh->s.sub_static_digest ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
if ( rh->s.main_ltd_size > 0 )
|
||||
{
|
||||
if ( !FS_LoadModule( rh->s.main_ltd_ram_address, rh->s.main_ltd_rom_offset, rh->s.main_ltd_size, rh->s.main_ltd_static_digest ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
if ( rh->s.sub_ltd_size > 0 )
|
||||
{
|
||||
if ( !FS_LoadModule( rh->s.sub_ltd_ram_address, rh->s.sub_ltd_rom_offset, rh->s.sub_ltd_size, rh->s.sub_ltd_static_digest ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
474
build/libraries/fs/ARM9/src/fs_loader2.c
Normal file
474
build/libraries/fs/ARM9/src/fs_loader2.c
Normal file
@ -0,0 +1,474 @@
|
||||
/*---------------------------------------------------------------------------*
|
||||
Project: TwlIPL - libraries - fs
|
||||
File: fs_loader.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 <firm.h>
|
||||
#include <estypes.h>
|
||||
#include <es.h>
|
||||
#include <twl/aes.h>
|
||||
#include <twl/aes_private.h>
|
||||
|
||||
#define FS_HEADER_AUTH_SIZE 0xe00
|
||||
|
||||
#define MODULE_ALIGNMENT 0x10 // 16バイト単位で読み込む
|
||||
//#define MODULE_ALIGNMENT 0x200 // 512バイト単位で読み込む
|
||||
#define RoundUpModuleSize(value) (((value) + MODULE_ALIGNMENT - 1) & -MODULE_ALIGNMENT)
|
||||
|
||||
#define HASH_UNIT 0x1000
|
||||
|
||||
static ROM_Header* const rh = (ROM_Header*)HW_TWL_ROM_HEADER_BUF;
|
||||
|
||||
static u8 currentKey[ SVC_SHA1_BLOCK_SIZE ];
|
||||
|
||||
static const u8 defaultKey[ SVC_SHA1_BLOCK_SIZE ] =
|
||||
{
|
||||
0x21, 0x06, 0xc0, 0xde,
|
||||
0xba, 0x98, 0xce, 0x3f,
|
||||
0xa6, 0x92, 0xe3, 0x9d,
|
||||
0x46, 0xf2, 0xed, 0x01,
|
||||
|
||||
0x76, 0xe3, 0xcc, 0x08,
|
||||
0x56, 0x23, 0x63, 0xfa,
|
||||
0xca, 0xd4, 0xec, 0xdf,
|
||||
0x9a, 0x62, 0x78, 0x34,
|
||||
|
||||
0x8f, 0x6d, 0x63, 0x3c,
|
||||
0xfe, 0x22, 0xca, 0x92,
|
||||
0x20, 0x88, 0x97, 0x23,
|
||||
0xd2, 0xcf, 0xae, 0xc2,
|
||||
|
||||
0x32, 0x67, 0x8d, 0xfe,
|
||||
0xca, 0x83, 0x64, 0x98,
|
||||
0xac, 0xfd, 0x3e, 0x37,
|
||||
0x87, 0x46, 0x58, 0x24,
|
||||
};
|
||||
|
||||
static AESKey FSiAesKeySeed;
|
||||
|
||||
static BOOL aesFlag;
|
||||
static AESCounter aesCounter;
|
||||
static u8* const aesBuffer = (u8*)HW_FIRM_FS_AES_BUFFER; // 0x2ff3800
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FS2_GetAesKeySeed
|
||||
|
||||
Description: retreive aes key seed in the signature
|
||||
|
||||
Arguments: None
|
||||
|
||||
Returns: pointer to seed
|
||||
*---------------------------------------------------------------------------*/
|
||||
AESKey* const FS2_GetAesKeySeed( void )
|
||||
{
|
||||
return &FSiAesKeySeed;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FS2_DeleteAesKeySeed
|
||||
|
||||
Description: delete aes key seed in the signature
|
||||
|
||||
Arguments: None
|
||||
|
||||
Returns: None
|
||||
*---------------------------------------------------------------------------*/
|
||||
void FS2_DeleteAesKeySeed( void )
|
||||
{
|
||||
MI_CpuClear8( &FSiAesKeySeed, sizeof(FSiAesKeySeed) );
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FS2_SetDigestKey
|
||||
|
||||
Description: set specified key or default key for HMAC-SHA-1
|
||||
|
||||
Arguments: digestKey pointer to key
|
||||
if NULL, use default key
|
||||
|
||||
Returns: TRUE if success
|
||||
*---------------------------------------------------------------------------*/
|
||||
void FS2_SetDigestKey( const u8* digestKey )
|
||||
{
|
||||
if ( digestKey )
|
||||
{
|
||||
MI_CpuCopy8(digestKey, currentKey, SVC_SHA1_BLOCK_SIZE);
|
||||
}
|
||||
else
|
||||
{
|
||||
MI_CpuCopy8(defaultKey, currentKey, SVC_SHA1_BLOCK_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
static inline BOOL CheckDigest( u8* a, u8* b, BOOL aClr, BOOL bClr )
|
||||
{
|
||||
BOOL result = TRUE;
|
||||
int i;
|
||||
for ( i = 0; i < SVC_SHA1_DIGEST_SIZE; i++ )
|
||||
{
|
||||
if ( a[i] != b[i] )
|
||||
{
|
||||
result = FALSE;
|
||||
}
|
||||
}
|
||||
if ( aClr ) MI_CpuClear8(a, SVC_SHA1_DIGEST_SIZE);
|
||||
if ( bClr ) MI_CpuClear8(b, SVC_SHA1_DIGEST_SIZE);
|
||||
return result;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: CheckRomCertificate
|
||||
|
||||
Description: check the certification in the ROM
|
||||
|
||||
ROMヘッダに付加された証明書のチェックを行います。
|
||||
makerom.TWL内のコードに依存します。
|
||||
|
||||
Arguments: pool pointer to the SVCSignHeapContext
|
||||
pCert pointer to the certification
|
||||
pCAPubKey pointer to the public key for the certification
|
||||
gameCode initial code
|
||||
|
||||
Returns: TRUE if success
|
||||
*---------------------------------------------------------------------------*/
|
||||
static BOOL CheckRomCertificate( SVCSignHeapContext* pool, const RomCertificate *pCert, const void* pCAPubKey, u32 gameCode )
|
||||
{
|
||||
u8 digest[SVC_SHA1_DIGEST_SIZE];
|
||||
u8 md[SVC_SHA1_DIGEST_SIZE];
|
||||
|
||||
// 証明書ヘッダのマジックナンバーチェック
|
||||
if( pCert->header.magicNumber != TWL_ROM_CERT_MAGIC_NUMBER ||
|
||||
// 証明書ヘッダとROMヘッダのゲームコード一致チェック
|
||||
pCert->header.gameCode != gameCode )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
// 証明書署名チェック
|
||||
SVC_DecryptSign( pool, &digest, pCert->sign, pCAPubKey );
|
||||
|
||||
// ダイジェストの計算
|
||||
SVC_CalcSHA1( md, pCert, ROM_CERT_SIGN_OFFSET );
|
||||
|
||||
// 比較
|
||||
return CheckDigest(md, digest, TRUE, TRUE);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FS2_LoadBuffer
|
||||
|
||||
Description: receive data from ARM7 via WRAM-B and store in destination address,
|
||||
calculate SHA1 in parallel if ctx is specified
|
||||
|
||||
Arguments: dest destination address to read
|
||||
size total length to read in bytes
|
||||
ctx pointer to SHA1 context or NULL
|
||||
|
||||
Returns: TRUE if success
|
||||
*---------------------------------------------------------------------------*/
|
||||
BOOL FS2_LoadBuffer( u8* dest, u32 size, SVCSHA1Context *ctx )
|
||||
{
|
||||
static int count = 0;
|
||||
|
||||
while ( size > 0 )
|
||||
{
|
||||
u8* src = (u8*)HW_FIRM_LOAD_BUFFER_BASE + count * HW_FIRM_LOAD_BUFFER_UNIT_SIZE;
|
||||
u32 unit = size < HW_FIRM_LOAD_BUFFER_UNIT_SIZE ? size : HW_FIRM_LOAD_BUFFER_UNIT_SIZE;
|
||||
if ( PXI_RecvID() != FIRM_PXI_ID_LOAD_PIRIOD )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
MIi_SetWramBankMaster_B( count, MI_WRAM_ARM9 );
|
||||
if (ctx)
|
||||
{
|
||||
int done;
|
||||
for ( done = 0; done < unit; done += HASH_UNIT )
|
||||
{
|
||||
u8* s = src + done;
|
||||
u8* d = dest + done;
|
||||
u32 u = unit - done < HASH_UNIT ? unit - done : HASH_UNIT;
|
||||
SVC_SHA1Update( ctx, s, u );
|
||||
MI_CpuCopyFast( s, d, u );
|
||||
MI_CpuClearFast( s, u ); // OS_Bootでのクリアと比較する
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MI_CpuCopyFast( src, dest, unit );
|
||||
MI_CpuClearFast( src, unit ); // OS_Bootでのクリアと比較する
|
||||
}
|
||||
DC_FlushRange( src, unit );
|
||||
size -= unit;
|
||||
dest += unit;
|
||||
MIi_SetWramBankMaster_B( count, MI_WRAM_ARM7 );
|
||||
count = ( count + 1 ) % HW_FIRM_LOAD_BUFFER_UNIT_NUMS;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void AesCallback(AESResult result, void* arg)
|
||||
{
|
||||
volatile BOOL *pBusy = (BOOL*)arg;
|
||||
*pBusy = FALSE;
|
||||
if (result != AES_RESULT_SUCCESS)
|
||||
{
|
||||
OS_TPrintf("Failed to decrypt by AES (%d)\n", result);
|
||||
}
|
||||
}
|
||||
|
||||
static void CopyWithAes( const void* src, void* dest, u32 size )
|
||||
{
|
||||
volatile BOOL aesBusy = TRUE;
|
||||
|
||||
AES_SetKeySlot( AES_KEY_SLOT_A );
|
||||
aesBusy = TRUE;
|
||||
if ( AES_RESULT_SUCCESS == AES_Ctr( &aesCounter, src, size, dest, AesCallback, (void*)&aesBusy ) )
|
||||
{
|
||||
while ( aesBusy )
|
||||
{
|
||||
}
|
||||
}
|
||||
AES_AddToCounter( &aesCounter, size / AES_BLOCK_SIZE );
|
||||
}
|
||||
|
||||
static void EnableAes( u32 offset )
|
||||
{
|
||||
aesFlag = TRUE;
|
||||
MI_CpuCopy8( rh->s.main_static_digest, &aesCounter, AES_BLOCK_SIZE );
|
||||
AES_AddToCounter( &aesCounter, (offset - rh->s.aes_target_rom_offset) / AES_BLOCK_SIZE );
|
||||
}
|
||||
static void DisableAes( void )
|
||||
{
|
||||
aesFlag = FALSE;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: GetTransferSize
|
||||
|
||||
Description: get size to transfer once
|
||||
|
||||
一度に受信するサイズを返します。
|
||||
|
||||
転送範囲がAES領域をまたぐ場合は、境界までのサイズ (引数より
|
||||
小さなサイズ) を返します。
|
||||
makerom.TWLまたはIPLの使用に依存します。
|
||||
|
||||
Arguments: offset offset of region from head of ROM_Header
|
||||
size size of region
|
||||
|
||||
Returns: size to transfer once
|
||||
*---------------------------------------------------------------------------*/
|
||||
static u32 GetTransferSize( u32 offset, u32 size )
|
||||
{
|
||||
u32 aes_offset = rh->s.aes_target_rom_offset;
|
||||
u32 aes_end = aes_offset + RoundUpModuleSize(rh->s.aes_target_size);
|
||||
u32 end = offset + RoundUpModuleSize(size);
|
||||
if ( rh->s.enable_aes )
|
||||
{
|
||||
if ( offset >= aes_offset && offset < aes_end )
|
||||
{
|
||||
if ( end > aes_end )
|
||||
{
|
||||
size = aes_end - offset;
|
||||
}
|
||||
if ( size > HW_FIRM_FS_AES_BUFFER_SIZE )
|
||||
{
|
||||
size = HW_FIRM_FS_AES_BUFFER_SIZE;
|
||||
}
|
||||
EnableAes( offset );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( offset < aes_offset && offset + size > aes_offset )
|
||||
{
|
||||
size = aes_offset - offset;
|
||||
}
|
||||
DisableAes();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DisableAes();
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FS2_LoadModule
|
||||
|
||||
Description: receive data from ARM7 via WRAM-B and store in destination address
|
||||
in view of AES settings in the ROM header at HW_TWL_ROM_HEADER_BUF,
|
||||
then verify the digest
|
||||
|
||||
Arguments: pFile pointer to FSFile streucture
|
||||
dest destination address to read
|
||||
offset file offset to start to read in bytes
|
||||
size total length to read in bytes
|
||||
digest digest to verify
|
||||
|
||||
Returns: TRUE if success
|
||||
*---------------------------------------------------------------------------*/
|
||||
BOOL FS2_LoadModule( FSFile *pFile, u8* dest, u32 offset, u32 size, const u8 digest[SVC_SHA1_DIGEST_SIZE] )
|
||||
{
|
||||
u8 md[SVC_SHA1_DIGEST_SIZE];
|
||||
u8* hmacDest = dest;
|
||||
u32 hmacSize = size;
|
||||
|
||||
if ( !FS_SeekFile( pFile, (s32)offset, FS_SEEK_SET ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
size = RoundUpModuleSize( size );
|
||||
while ( size > 0 )
|
||||
{
|
||||
u32 unit = GetTransferSize( offset, size );
|
||||
if ( aesFlag )
|
||||
{
|
||||
if ( !FS_ReadFile( pFile, aesBuffer, (s32)unit ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
DC_FlushRange( aesBuffer, unit );
|
||||
CopyWithAes( aesBuffer, dest, unit );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !FS_ReadFile( pFile, dest, (s32)unit ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
dest += unit;
|
||||
offset += unit;
|
||||
size -= unit;
|
||||
}
|
||||
SVC_CalcHMACSHA1( md, hmacDest, hmacSize, currentKey, SVC_SHA1_BLOCK_SIZE );
|
||||
return CheckDigest(md, (u8*)digest, TRUE, FALSE);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FS2_OpenSrl
|
||||
|
||||
Description: open srl file named at HW_TWL_FS_BOOT_SRL_PATH_BUF
|
||||
|
||||
Arguments: pFile pointer to FSFile streucture
|
||||
|
||||
Returns: TRUE if success
|
||||
*---------------------------------------------------------------------------*/
|
||||
BOOL FS2_OpenSrl( FSFile *pFile )
|
||||
{
|
||||
return FS_OpenFileEx( pFile, (char*)HW_TWL_FS_BOOT_SRL_PATH_BUF, FS_FILEMODE_R );
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FS2_LoadHeader
|
||||
|
||||
Description: load ROM header to HW_TWL_ROM_HEADER_BUF using normal FS,
|
||||
and verify signature
|
||||
|
||||
Arguments: pFile pointer to FSFile streucture
|
||||
pool heap context to call SVC_DecryptSign
|
||||
rsa_key public key to verify the signature
|
||||
|
||||
Returns: TRUE if success
|
||||
*---------------------------------------------------------------------------*/
|
||||
BOOL FS2_LoadHeader( FSFile *pFile, SVCSignHeapContext* pool, const void* rsa_key )
|
||||
{
|
||||
u8 md[SVC_SHA1_DIGEST_SIZE];
|
||||
SignatureData sd;
|
||||
|
||||
if ( !FS_SeekFile( pFile, 0, FS_SEEK_SET ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
if ( !FS_ReadFile( pFile, rh, HW_TWL_ROM_HEADER_BUF_SIZE ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
SVC_CalcSHA1( md, rh, FS_HEADER_AUTH_SIZE );
|
||||
|
||||
// コンテンツ証明書
|
||||
if ( CheckRomCertificate( pool, &rh->certificate, rsa_key, *(u32*)rh->s.game_code ) )
|
||||
{
|
||||
rsa_key = rh->certificate.pubKeyMod; // ヘッダ用の鍵の取り出し
|
||||
}
|
||||
else
|
||||
{
|
||||
// とりあえずコンテンツ証明書用の鍵がそのまま使えると仮定
|
||||
}
|
||||
|
||||
// ヘッダ署名チェック
|
||||
SVC_DecryptSign( pool, &sd, rh->signature, rsa_key );
|
||||
|
||||
if ( !CheckDigest( md, sd.digest, TRUE, FALSE ) )
|
||||
{
|
||||
MI_CpuClear8( &sd, sizeof(sd) ); // 残り削除 (他に必要なものはない?)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// ダイジェスト以外のデータのチェックが必要!!
|
||||
|
||||
// 鍵の保存
|
||||
MI_CpuCopy8( (AESKey*)sd.aes_key_seed, &FSiAesKeySeed, sizeof(FSiAesKeySeed) );
|
||||
|
||||
MI_CpuClear8( &sd, sizeof(sd) ); // 残り削除 (他に必要なものはない?)
|
||||
|
||||
// ROMヘッダのコピー
|
||||
MI_CpuCopyFast( rh, (void*)HW_ROM_HEADER_BUF, HW_ROM_HEADER_BUF_END-HW_ROM_HEADER_BUF );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FS2_LoadStatic
|
||||
|
||||
Description: receive static regions from ARM6 via WRAM-B and store them
|
||||
specified by ROM header at HW_TWL_ROM_HEADER_BUF
|
||||
|
||||
Arguments: pFile pointer to FSFile streucture
|
||||
|
||||
Returns: TRUE if success
|
||||
*---------------------------------------------------------------------------*/
|
||||
BOOL FS2_LoadStatic( FSFile *pFile )
|
||||
{
|
||||
if ( rh->s.main_size > 0 )
|
||||
{
|
||||
if ( !FS2_LoadModule( pFile, rh->s.main_ram_address, rh->s.main_rom_offset, rh->s.main_size, rh->s.main_static_digest ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
if ( rh->s.sub_size > 0 )
|
||||
{
|
||||
if ( !FS2_LoadModule( pFile, rh->s.sub_ram_address, rh->s.sub_rom_offset, rh->s.sub_size, rh->s.sub_static_digest ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
if ( rh->s.main_ltd_size > 0 )
|
||||
{
|
||||
if ( !FS2_LoadModule( pFile, rh->s.main_ltd_ram_address, rh->s.main_ltd_rom_offset, rh->s.main_ltd_size, rh->s.main_ltd_static_digest ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
if ( rh->s.sub_ltd_size > 0 )
|
||||
{
|
||||
if ( !FS2_LoadModule( pFile, rh->s.sub_ltd_ram_address, rh->s.sub_ltd_rom_offset, rh->s.sub_ltd_size, rh->s.sub_ltd_static_digest ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
@ -108,6 +108,9 @@ static void PreInit(void)
|
||||
{
|
||||
OS_Terminate();
|
||||
}
|
||||
|
||||
// ブートタイプの変更
|
||||
( (OSBootInfo *)OS_GetBootInfo() )->boot_type = OS_BOOTTYPE_NAND;
|
||||
}
|
||||
|
||||
/***************************************************************
|
||||
@ -139,7 +142,6 @@ static BOOL TryResolveSrl(void)
|
||||
return FALSE;
|
||||
}
|
||||
LCFG_THW_GetLauncherTitleID_Lo( (u8*)&titleId );
|
||||
|
||||
// 4: after LCFG_ReadHWSecureInfo
|
||||
PUSH_PROFILE();
|
||||
|
||||
@ -176,7 +178,7 @@ static BOOL CheckHeader(void)
|
||||
{
|
||||
static ROM_Header_Short* const rhs = (ROM_Header_Short*)HW_TWL_ROM_HEADER_BUF;
|
||||
// ƒCƒjƒVƒƒƒ‹ƒR<C692>[ƒh‚È‚Ç
|
||||
OS_TPrintf("Initial Code : %08X\n", *(u32*)rhs->game_code);
|
||||
OS_TPrintf("Initial Code : %08X (%.4s)\n", *(u32*)rhs->game_code, rhs->game_code);
|
||||
OS_TPrintf("Platform Code : %02X\n", rhs->platform_code);
|
||||
OS_TPrintf("Codec Mode : %s\n", rhs->codec_mode ? "TWL" : "NITRO");
|
||||
OS_TPrintf("Sigunature : %s\n", rhs->enable_signature ? "AVAILABLE" : "NOT AVAILABLE");
|
||||
@ -262,12 +264,12 @@ void TwlMain( void )
|
||||
OS_InitFIRM();
|
||||
OS_EnableIrq();
|
||||
OS_EnableInterrupts();
|
||||
|
||||
#ifdef PROFILE_ENABLE
|
||||
// 2: before OS_InitTick
|
||||
profile[pf_cnt++] = OS_TicksToMicroSecondsBROM32(OS_GetTick());
|
||||
|
||||
OS_InitTick();
|
||||
#endif
|
||||
// 2: after PXI
|
||||
PUSH_PROFILE();
|
||||
|
||||
PostInit();
|
||||
// 3: after PostInit
|
||||
@ -337,7 +339,6 @@ void TwlMain( void )
|
||||
}
|
||||
#endif
|
||||
|
||||
( (OSBootInfo *)OS_GetBootInfo() )->boot_type = OS_BOOTTYPE_NAND;
|
||||
OS_BootFromFIRM();
|
||||
|
||||
end:
|
||||
|
||||
@ -45,7 +45,8 @@ LLIBRARIES += libes.TWL$(ARCHGEN_TYPE).a libboc.TWL$(ARCHGEN_TYPE).a
|
||||
else
|
||||
LLIBRARIES += ../Release/libes.TWL$(ARCHGEN_TYPE).a ../Release/libboc.TWL$(ARCHGEN_TYPE).a
|
||||
endif
|
||||
LLIBRARIES += liblcfg$(TWL_LIBSUFFIX).a
|
||||
LLIBRARIES += liblcfg$(TWL_LIBSUFFIX).a \
|
||||
libaes_private$(TWL_LIBSUFFIX).a
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
|
||||
@ -74,7 +74,8 @@ u32 pf_cnt = 0;
|
||||
#ifdef PRINT_MEMORY_ADDR
|
||||
static char* debugPtr = (char*)PRINT_MEMORY_ADDR;
|
||||
#undef OS_TPrintf
|
||||
#define OS_TPrintf(...) (debugPtr = (char*)((u32)(debugPtr + STD_TSPrintf(debugPtr, __VA_ARGS__) + 0xf) & ~0xf))
|
||||
//#define OS_TPrintf(...) (debugPtr = (char*)((u32)(debugPtr + STD_TSPrintf(debugPtr, __VA_ARGS__) + 0xf) & ~0xf))
|
||||
#define OS_TPrintf(...) (debugPtr += STD_TSPrintf(debugPtr, __VA_ARGS__))
|
||||
#endif
|
||||
|
||||
/***************************************************************
|
||||
@ -108,6 +109,9 @@ static void PreInit(void)
|
||||
{
|
||||
OS_Terminate();
|
||||
}
|
||||
|
||||
// ƒu<C692>[ƒgƒ^ƒCƒv‚Ì•Ï<E280A2>X
|
||||
( (OSBootInfo *)OS_GetBootInfo() )->boot_type = OS_BOOTTYPE_NAND;
|
||||
}
|
||||
|
||||
/***************************************************************
|
||||
@ -121,7 +125,7 @@ static void PostInit(void)
|
||||
// RSA用ヒープ設定
|
||||
SVC_InitSignHeap( &acPool, acHeap, sizeof(acHeap) );
|
||||
// HMAC用鍵準備
|
||||
FS_SetDigestKey( NULL );
|
||||
FS2_SetDigestKey( NULL );
|
||||
// FS/FATFS初期化
|
||||
FS_InitFIRM();
|
||||
}
|
||||
@ -176,7 +180,7 @@ static BOOL CheckHeader(void)
|
||||
{
|
||||
static ROM_Header_Short* const rhs = (ROM_Header_Short*)HW_TWL_ROM_HEADER_BUF;
|
||||
// イニシャルコードなど
|
||||
OS_TPrintf("Initial Code : %08X\n", *(u32*)rhs->game_code);
|
||||
OS_TPrintf("Initial Code : %08X (%.4s)\n", *(u32*)rhs->game_code, rhs->game_code);
|
||||
OS_TPrintf("Platform Code : %02X\n", rhs->platform_code);
|
||||
OS_TPrintf("Codec Mode : %s\n", rhs->codec_mode ? "TWL" : "NITRO");
|
||||
OS_TPrintf("Sigunature : %s\n", rhs->enable_signature ? "AVAILABLE" : "NOT AVAILABLE");
|
||||
@ -265,12 +269,12 @@ void TwlMain( void )
|
||||
OS_InitFIRM();
|
||||
OS_EnableIrq();
|
||||
OS_EnableInterrupts();
|
||||
|
||||
#ifdef PROFILE_ENABLE
|
||||
// 2: before OS_InitTick
|
||||
profile[pf_cnt++] = OS_TicksToMicroSecondsBROM32(OS_GetTick());
|
||||
|
||||
OS_InitTick();
|
||||
#endif
|
||||
// 2: after OS_InitTick
|
||||
PUSH_PROFILE();
|
||||
|
||||
PostInit();
|
||||
// 3: after PostInit
|
||||
@ -283,7 +287,7 @@ void TwlMain( void )
|
||||
// 5: after FS_ResolveSrl
|
||||
PUSH_PROFILE();
|
||||
|
||||
if ( !FS_OpenSrl( &file ) )
|
||||
if ( !FS2_OpenSrl( &file ) )
|
||||
{
|
||||
OS_TPrintf("Failed to call FS_OpenSrl().\n");
|
||||
goto end;
|
||||
@ -291,28 +295,28 @@ void TwlMain( void )
|
||||
// 6: after FS_OpenSrl
|
||||
PUSH_PROFILE();
|
||||
|
||||
if ( !FS_LoadSrlHeader( &file, &acPool, RSA_KEY_ADDR ) || !CheckHeader() )
|
||||
if ( !FS2_LoadHeader( &file, &acPool, RSA_KEY_ADDR ) || !CheckHeader() )
|
||||
{
|
||||
OS_TPrintf("Failed to call FS_LoadSrlHeader() and/or CheckHeader().\n");
|
||||
OS_TPrintf("Failed to call FS2_LoadHeader() and/or CheckHeader().\n");
|
||||
goto end;
|
||||
}
|
||||
// 7: after FS_LoadSrlHeader
|
||||
// 7: after FS2_LoadHeader
|
||||
PUSH_PROFILE();
|
||||
|
||||
PXI_NotifyID( FIRM_PXI_ID_DONE_HEADER );
|
||||
// 8: after PXI
|
||||
PUSH_PROFILE();
|
||||
|
||||
AESi_SendSeed( FS_GetAesKeySeed() );
|
||||
AESi_SendSeed( FS2_GetAesKeySeed() );
|
||||
// 9: after AESi_SendSeed
|
||||
PUSH_PROFILE();
|
||||
|
||||
if ( !FS_LoadSrlStatic( &file ) )
|
||||
if ( !FS2_LoadStatic( &file ) )
|
||||
{
|
||||
OS_TPrintf("Failed to call FS_LoadSrlStatic().\n");
|
||||
OS_TPrintf("Failed to call FS2_LoadStatic().\n");
|
||||
goto end;
|
||||
}
|
||||
// 10: after FS_LoadSrlStatic
|
||||
// 10: after FS2_LoadStatic
|
||||
PUSH_PROFILE();
|
||||
|
||||
PXI_NotifyID( FIRM_PXI_ID_DONE_STATIC );
|
||||
@ -339,10 +343,10 @@ void TwlMain( void )
|
||||
}
|
||||
OS_TPrintf("\n[ARM9] End\n");
|
||||
PXI_NotifyID( FIRM_PXI_ID_NULL );
|
||||
OS_SetTick(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
( (OSBootInfo *)OS_GetBootInfo() )->boot_type = OS_BOOTTYPE_NAND;
|
||||
OS_BootFromFIRM();
|
||||
|
||||
end:
|
||||
|
||||
@ -87,7 +87,12 @@ static void PreInit(void)
|
||||
{
|
||||
static const OSMountInfo firmSettings[] =
|
||||
{
|
||||
{ 'A', OS_MOUNT_DEVICE_SD, OS_MOUNT_TGT_ROOT, 0, OS_MOUNT_RSC_WRAM, (OS_MOUNT_USR_R|OS_MOUNT_USR_W), 0, 0, "sdmc", "/" },
|
||||
// drive device target pertitionIdx resource userPermission rsvA B archive path
|
||||
{ 'A', OS_MOUNT_DEVICE_SD, OS_MOUNT_TGT_ROOT, 0, OS_MOUNT_RSC_MMEM, (OS_MOUNT_USR_R|OS_MOUNT_USR_W), 0, 0, "sdmc", "/" },
|
||||
{ 'B', OS_MOUNT_DEVICE_NAND, OS_MOUNT_TGT_ROOT, 0, OS_MOUNT_RSC_WRAM, (OS_MOUNT_USR_R|OS_MOUNT_USR_W), 0, 0, "nand", "/" }, // ユーザーアプリはこのアーカイブではWrite不可
|
||||
{ 'C', OS_MOUNT_DEVICE_NAND, OS_MOUNT_TGT_ROOT, 1, OS_MOUNT_RSC_WRAM, (OS_MOUNT_USR_R|OS_MOUNT_USR_W), 0, 0, "nand2", "/" }, // ユーザーアプリはこのアーカイブではWrite不可
|
||||
{ 'D', OS_MOUNT_DEVICE_NAND, OS_MOUNT_TGT_DIR, 0, OS_MOUNT_RSC_MMEM, (OS_MOUNT_USR_R|OS_MOUNT_USR_W), 0, 0, "shared2", "nand2:/shared2" },
|
||||
{ 'E', OS_MOUNT_DEVICE_NAND, OS_MOUNT_TGT_DIR, 0, OS_MOUNT_RSC_MMEM, (OS_MOUNT_USR_R|OS_MOUNT_USR_W), 0, 0, "photo", "nand2:/photo" },
|
||||
{ 0 }
|
||||
};
|
||||
/*
|
||||
@ -109,6 +114,9 @@ static void PreInit(void)
|
||||
{
|
||||
OS_Terminate();
|
||||
}
|
||||
|
||||
// ブートタイプの変更
|
||||
( (OSBootInfo *)OS_GetBootInfo() )->boot_type = OS_BOOTTYPE_NAND;
|
||||
}
|
||||
|
||||
/***************************************************************
|
||||
@ -135,7 +143,7 @@ static BOOL CheckHeader(void)
|
||||
{
|
||||
static ROM_Header_Short* const rhs = (ROM_Header_Short*)HW_TWL_ROM_HEADER_BUF;
|
||||
// ƒCƒjƒVƒƒƒ‹ƒR<C692>[ƒh‚È‚Ç
|
||||
OS_TPrintf("Initial Code : %08X\n", *(u32*)rhs->game_code);
|
||||
OS_TPrintf("Initial Code : %08X (%.4s)\n", *(u32*)rhs->game_code, rhs->game_code);
|
||||
OS_TPrintf("Platform Code : %02X\n", rhs->platform_code);
|
||||
OS_TPrintf("Codec Mode : %s\n", rhs->codec_mode ? "TWL" : "NITRO");
|
||||
OS_TPrintf("Sigunature : %s\n", rhs->enable_signature ? "AVAILABLE" : "NOT AVAILABLE");
|
||||
@ -225,12 +233,12 @@ void TwlMain( void )
|
||||
OS_InitFIRM();
|
||||
OS_EnableIrq();
|
||||
OS_EnableInterrupts();
|
||||
|
||||
#ifdef PROFILE_ENABLE
|
||||
// 2: before OS_InitTick
|
||||
profile[pf_cnt++] = OS_TicksToMicroSecondsBROM32(OS_GetTick());
|
||||
|
||||
OS_InitTick();
|
||||
#endif
|
||||
// 2: after OS_InitTick
|
||||
PUSH_PROFILE();
|
||||
|
||||
PostInit();
|
||||
// 3: after PostInit
|
||||
@ -316,7 +324,7 @@ void TwlMain( void )
|
||||
}
|
||||
#endif
|
||||
|
||||
( (OSBootInfo *)OS_GetBootInfo() )->boot_type = OS_BOOTTYPE_NAND;
|
||||
MI_CpuClearFast( OSi_GetFromFirmAddr(), sizeof(OSFromFirmBuf) );
|
||||
OS_BootFromFIRM();
|
||||
|
||||
end:
|
||||
|
||||
@ -20,9 +20,11 @@
|
||||
|
||||
#ifdef SDK_ARM7
|
||||
#include <firm/fs/ARM7/fs_firm.h>
|
||||
#include <firm/fs/ARM7/fs_loader.h>
|
||||
#else
|
||||
#include <firm/fs/ARM9/fs_firm.h>
|
||||
#include <firm/fs/ARM9/fs_es.h>
|
||||
#include <firm/fs/ARM9/fs_loader.h>
|
||||
#include <firm/fs/ARM9/fs_loader2.h>
|
||||
#endif // SDK_ARM7
|
||||
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/*---------------------------------------------------------------------------*
|
||||
Project: TwlIPL - include - fs
|
||||
File: fs.h
|
||||
File: fs_firm.h
|
||||
|
||||
Copyright 2007 Nintendo. All rights reserved.
|
||||
|
||||
@ -18,9 +18,6 @@
|
||||
#ifndef FIRM_FS_FS_FIRM_H_
|
||||
#define FIRM_FS_FS_FIRM_H_
|
||||
|
||||
#include <twl/types.h>
|
||||
#include <twl/aes/ARM7/lo.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@ -36,56 +33,6 @@ extern "C" {
|
||||
*---------------------------------------------------------------------------*/
|
||||
int FS_OpenSrl( void );
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FS_LoadBuffer
|
||||
|
||||
Description: load data in file and pass to ARM9 via WRAM-B
|
||||
|
||||
Arguments: fd file discriptor to read
|
||||
offset offset to start to read in bytes
|
||||
size total length to read in bytes
|
||||
|
||||
Returns: TRUE if success
|
||||
*---------------------------------------------------------------------------*/
|
||||
BOOL FS_LoadBuffer( int fd, u32 offset, u32 size );
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FS_LoadModule
|
||||
|
||||
Description: load data in file and pass to ARM9 via WRAM-B in view of AES
|
||||
settings in the ROM header at HW_TWL_ROM_HEADER_BUF
|
||||
|
||||
Arguments: fd file discriptor to read
|
||||
offset offset to start to read in bytes
|
||||
size total length to read in bytes
|
||||
|
||||
Returns: TRUE if success
|
||||
*---------------------------------------------------------------------------*/
|
||||
BOOL FS_LoadModule( int fd, u32 offset, u32 size );
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FS_LoadHeader
|
||||
|
||||
Description: load ROM header in the head of file and pass to ARM9 via WRAM-B
|
||||
|
||||
Arguments: fd file discriptor to read
|
||||
|
||||
Returns: TRUE if success
|
||||
*---------------------------------------------------------------------------*/
|
||||
BOOL FS_LoadHeader( int fd );
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FS_LoadStatic
|
||||
|
||||
Description: load static regions in file and pass to ARM9 via WRAM-B
|
||||
specified by ROM header at HW_TWL_ROM_HEADER_BUF
|
||||
|
||||
Arguments: fd file discriptor to read
|
||||
|
||||
Returns: TRUE if success
|
||||
*---------------------------------------------------------------------------*/
|
||||
BOOL FS_LoadStatic( int fd );
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
||||
85
include/firm/fs/ARM7/fs_loader.h
Normal file
85
include/firm/fs/ARM7/fs_loader.h
Normal file
@ -0,0 +1,85 @@
|
||||
/*---------------------------------------------------------------------------*
|
||||
Project: TwlIPL - include - fs
|
||||
File: fs.h
|
||||
|
||||
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:: 2007-09-06$
|
||||
$Rev$
|
||||
$Author$
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef FIRM_FS_FS_LOADER_H_
|
||||
#define FIRM_FS_FS_LOADER_H_
|
||||
|
||||
#include <twl/types.h>
|
||||
#include <twl/aes/ARM7/lo.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FS_LoadBuffer
|
||||
|
||||
Description: load data in file and pass to ARM9 via WRAM-B
|
||||
|
||||
Arguments: fd file discriptor to read
|
||||
offset offset to start to read in bytes
|
||||
size total length to read in bytes
|
||||
|
||||
Returns: TRUE if success
|
||||
*---------------------------------------------------------------------------*/
|
||||
BOOL FS_LoadBuffer( int fd, u32 offset, u32 size );
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FS_LoadModule
|
||||
|
||||
Description: load data in file and pass to ARM9 via WRAM-B in view of AES
|
||||
settings in the ROM header at HW_TWL_ROM_HEADER_BUF
|
||||
|
||||
Arguments: fd file discriptor to read
|
||||
offset offset to start to read in bytes
|
||||
size total length to read in bytes
|
||||
|
||||
Returns: TRUE if success
|
||||
*---------------------------------------------------------------------------*/
|
||||
BOOL FS_LoadModule( int fd, u32 offset, u32 size );
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FS_LoadHeader
|
||||
|
||||
Description: load ROM header in the head of file and pass to ARM9 via WRAM-B
|
||||
|
||||
Arguments: fd file discriptor to read
|
||||
|
||||
Returns: TRUE if success
|
||||
*---------------------------------------------------------------------------*/
|
||||
BOOL FS_LoadHeader( int fd );
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FS_LoadStatic
|
||||
|
||||
Description: load static regions in file and pass to ARM9 via WRAM-B
|
||||
specified by ROM header at HW_TWL_ROM_HEADER_BUF
|
||||
|
||||
Arguments: fd file discriptor to read
|
||||
|
||||
Returns: TRUE if success
|
||||
*---------------------------------------------------------------------------*/
|
||||
BOOL FS_LoadStatic( int fd );
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
|
||||
/* FIRM_FS_FS_LOADER_H_ */
|
||||
#endif
|
||||
@ -1,50 +0,0 @@
|
||||
/*---------------------------------------------------------------------------*
|
||||
Project: TwlIPL - include - fs
|
||||
File: fs_es.h
|
||||
|
||||
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:: 2007-09-06$
|
||||
$Rev$
|
||||
$Author$
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef FIRM_FS_ES_FIRM_H_
|
||||
#define FIRM_FS_ES_FIRM_H_
|
||||
|
||||
#include <twl/types.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FS_GetTitleBootContentPathFast
|
||||
|
||||
Description: NAND にインストールされているアプリの実行ファイルのパスを
|
||||
取得します。
|
||||
取得する情報の正当性を検証しないため高速ですが、
|
||||
情報が改竄されている可能性があることに注意しなければなりません。
|
||||
|
||||
Arguments: buf: パスを格納するバッファへのポインタ。
|
||||
FS_ENTRY_LONGNAME_MAX 以上のサイズが必要です。
|
||||
titleId: パスを取得するアプリの Title ID。
|
||||
|
||||
Returns: 正常に処理が行われたなら TRUE を返します。
|
||||
*---------------------------------------------------------------------------*/
|
||||
BOOL FS_GetTitleBootContentPathFast(char* buf, u64 titleId);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
|
||||
/* FIRM_FS_ES_FIRM_H_ */
|
||||
#endif
|
||||
@ -1,6 +1,6 @@
|
||||
/*---------------------------------------------------------------------------*
|
||||
Project: TwlIPL - include - fs
|
||||
File: fs.h
|
||||
File: fs_firm.h
|
||||
|
||||
Copyright 2007 Nintendo. All rights reserved.
|
||||
|
||||
@ -36,26 +36,20 @@ extern "C" {
|
||||
void FS_InitFIRM( void );
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FS_GetAesKeySeed
|
||||
Name: FS_GetTitleBootContentPathFast
|
||||
|
||||
Description: retreive aes key seed in the signature
|
||||
Description: NAND にインストールされているアプリの実行ファイルのパスを
|
||||
取得します。
|
||||
取得する情報の正当性を検証しないため高速ですが、
|
||||
情報が改竄されている可能性があることに注意しなければなりません。
|
||||
|
||||
Arguments: None
|
||||
Arguments: buf: パスを格納するバッファへのポインタ。
|
||||
FS_ENTRY_LONGNAME_MAX 以上のサイズが必要です。
|
||||
titleId: パスを取得するアプリの Title ID。
|
||||
|
||||
Returns: pointer to seed
|
||||
Returns: 正常に処理が行われたなら TRUE を返します。
|
||||
*---------------------------------------------------------------------------*/
|
||||
AESKey* const FS_GetAesKeySeed( void );
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FS_DeleteAesKeySeed
|
||||
|
||||
Description: delete aes key seed in the signature
|
||||
|
||||
Arguments: None
|
||||
|
||||
Returns: None
|
||||
*---------------------------------------------------------------------------*/
|
||||
void FS_DeleteAesKeySeed( void );
|
||||
BOOL FS_GetTitleBootContentPathFast(char* buf, u64 titleId);
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FS_ResolveSrl
|
||||
@ -80,128 +74,6 @@ BOOL FS_ResolveSrl( u64 titleId );
|
||||
*---------------------------------------------------------------------------*/
|
||||
BOOL FS_ResolveSrlUnsecured( u64 titleId );
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FS_SetDigestKey
|
||||
|
||||
Description: set specified key or default key for HMAC-SHA-1
|
||||
|
||||
Arguments: digestKey pointer to key
|
||||
if NULL, use default key
|
||||
|
||||
Returns: TRUE if success
|
||||
*---------------------------------------------------------------------------*/
|
||||
void FS_SetDigestKey( const u8* digestKey );
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FS_LoadBuffer
|
||||
|
||||
Description: receive data from ARM7 via WRAM-B and store in destination address,
|
||||
calculate SHA1 in parallel if ctx is specified
|
||||
|
||||
Arguments: dest destination address to read
|
||||
size total length to read in bytes
|
||||
ctx pointer to SHA1 context or NULL
|
||||
|
||||
Returns: TRUE if success
|
||||
*---------------------------------------------------------------------------*/
|
||||
BOOL FS_LoadBuffer( u8* dest, u32 size, SVCSHA1Context *ctx );
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FS_LoadModule
|
||||
|
||||
Description: receive data from ARM7 via WRAM-B and store in destination address
|
||||
in view of AES settings in the ROM header at HW_TWL_ROM_HEADER_BUF,
|
||||
then verify the digest
|
||||
|
||||
Arguments: dest destination address to read
|
||||
offset file offset to start to read in bytes
|
||||
size total length to read in bytes
|
||||
digest digest to verify
|
||||
|
||||
Returns: TRUE if success
|
||||
*---------------------------------------------------------------------------*/
|
||||
BOOL FS_LoadModule( u8* dest, u32 offset, u32 size, const u8 digest[SVC_SHA1_BLOCK_SIZE] );
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FS_LoadHeader
|
||||
|
||||
Description: receive ROM header, store to HW_TWL_ROM_HEADER_BUF,
|
||||
and verify signature
|
||||
|
||||
Arguments: pool heap context to call SVC_DecryptSign
|
||||
rsa_key public key to verify the signature
|
||||
|
||||
Returns: TRUE if success
|
||||
*---------------------------------------------------------------------------*/
|
||||
BOOL FS_LoadHeader( SVCSignHeapContext* pool, const void* rsa_key );
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FS_LoadStatic
|
||||
|
||||
Description: receive static regions from ARM6 via WRAM-B and store them
|
||||
specified by ROM header at HW_TWL_ROM_HEADER_BUF
|
||||
|
||||
Arguments: None
|
||||
|
||||
Returns: TRUE if success
|
||||
*---------------------------------------------------------------------------*/
|
||||
BOOL FS_LoadStatic( void );
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FS_LoadSrlModule
|
||||
|
||||
Description: receive data from ARM7 via WRAM-B and store in destination address
|
||||
in view of AES settings in the ROM header at HW_TWL_ROM_HEADER_BUF,
|
||||
then verify the digest
|
||||
|
||||
Arguments: pFile pointer to FSFile streucture
|
||||
dest destination address to read
|
||||
offset file offset to start to read in bytes
|
||||
size total length to read in bytes
|
||||
digest digest to verify
|
||||
|
||||
Returns: TRUE if success
|
||||
*---------------------------------------------------------------------------*/
|
||||
BOOL FS_LoadSrlModule( FSFile *pFile, u8* dest, u32 offset, u32 size, const u8 digest[SVC_SHA1_BLOCK_SIZE] );
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FS_OpenSrl
|
||||
|
||||
Description: open srl file named at HW_TWL_FS_BOOT_SRL_PATH_BUF
|
||||
|
||||
Arguments: pFile pointer to FSFile streucture
|
||||
|
||||
Returns: TRUE if success
|
||||
*---------------------------------------------------------------------------*/
|
||||
BOOL FS_OpenSrl( FSFile *pFile );
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FS_LoadSrlHeader
|
||||
|
||||
Description: load ROM header to HW_TWL_ROM_HEADER_BUF using normal FS,
|
||||
and verify signature
|
||||
|
||||
Arguments: pFile pointer to FSFile streucture
|
||||
pool heap context to call SVC_DecryptSign
|
||||
rsa_key public key to verify the signature
|
||||
|
||||
Returns: TRUE if success
|
||||
*---------------------------------------------------------------------------*/
|
||||
BOOL FS_LoadSrlHeader( FSFile *pFile, SVCSignHeapContext* pool, const void* rsa_key );
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FS_LoadSrlStatic
|
||||
|
||||
Description: receive static regions from ARM6 via WRAM-B and store them
|
||||
specified by ROM header at HW_TWL_ROM_HEADER_BUF
|
||||
|
||||
Arguments: pFile pointer to FSFile streucture
|
||||
|
||||
Returns: TRUE if success
|
||||
*---------------------------------------------------------------------------*/
|
||||
BOOL FS_LoadSrlStatic( FSFile *pFile );
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
125
include/firm/fs/ARM9/fs_loader.h
Normal file
125
include/firm/fs/ARM9/fs_loader.h
Normal file
@ -0,0 +1,125 @@
|
||||
/*---------------------------------------------------------------------------*
|
||||
Project: TwlIPL - include - fs
|
||||
File: fs_loader.h
|
||||
|
||||
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:: 2007-09-06$
|
||||
$Rev$
|
||||
$Author$
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef FIRM_FS_FS_LOADER_H_
|
||||
#define FIRM_FS_FS_LOADER_H_
|
||||
|
||||
#include <twl/types.h>
|
||||
#include <twl/aes/common/types.h>
|
||||
#include <twl/os/common/systemCall.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FS_GetAesKeySeed
|
||||
|
||||
Description: retreive aes key seed in the signature
|
||||
|
||||
Arguments: None
|
||||
|
||||
Returns: pointer to seed
|
||||
*---------------------------------------------------------------------------*/
|
||||
AESKey* const FS_GetAesKeySeed( void );
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FS_DeleteAesKeySeed
|
||||
|
||||
Description: delete aes key seed in the signature
|
||||
|
||||
Arguments: None
|
||||
|
||||
Returns: None
|
||||
*---------------------------------------------------------------------------*/
|
||||
void FS_DeleteAesKeySeed( void );
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FS_SetDigestKey
|
||||
|
||||
Description: set specified key or default key for HMAC-SHA-1
|
||||
|
||||
Arguments: digestKey pointer to key
|
||||
if NULL, use default key
|
||||
|
||||
Returns: TRUE if success
|
||||
*---------------------------------------------------------------------------*/
|
||||
void FS_SetDigestKey( const u8* digestKey );
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FS_LoadBuffer
|
||||
|
||||
Description: receive data from ARM7 via WRAM-B and store in destination address,
|
||||
calculate SHA1 in parallel if ctx is specified
|
||||
|
||||
Arguments: dest destination address to read
|
||||
size total length to read in bytes
|
||||
ctx pointer to SHA1 context or NULL
|
||||
|
||||
Returns: TRUE if success
|
||||
*---------------------------------------------------------------------------*/
|
||||
BOOL FS_LoadBuffer( u8* dest, u32 size, SVCSHA1Context *ctx );
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FS_LoadModule
|
||||
|
||||
Description: receive data from ARM7 via WRAM-B and store in destination address
|
||||
in view of AES settings in the ROM header at HW_TWL_ROM_HEADER_BUF,
|
||||
then verify the digest
|
||||
|
||||
Arguments: dest destination address to read
|
||||
offset file offset to start to read in bytes
|
||||
size total length to read in bytes
|
||||
digest digest to verify
|
||||
|
||||
Returns: TRUE if success
|
||||
*---------------------------------------------------------------------------*/
|
||||
BOOL FS_LoadModule( u8* dest, u32 offset, u32 size, const u8 digest[SVC_SHA1_BLOCK_SIZE] );
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FS_LoadHeader
|
||||
|
||||
Description: receive ROM header, store to HW_TWL_ROM_HEADER_BUF,
|
||||
and verify signature
|
||||
|
||||
Arguments: pool heap context to call SVC_DecryptSign
|
||||
rsa_key public key to verify the signature
|
||||
|
||||
Returns: TRUE if success
|
||||
*---------------------------------------------------------------------------*/
|
||||
BOOL FS_LoadHeader( SVCSignHeapContext* pool, const void* rsa_key );
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FS_LoadStatic
|
||||
|
||||
Description: receive static regions from ARM6 via WRAM-B and store them
|
||||
specified by ROM header at HW_TWL_ROM_HEADER_BUF
|
||||
|
||||
Arguments: None
|
||||
|
||||
Returns: TRUE if success
|
||||
*---------------------------------------------------------------------------*/
|
||||
BOOL FS_LoadStatic( void );
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
|
||||
/* FIRM_FS_FS_LOADER_H_ */
|
||||
#endif
|
||||
138
include/firm/fs/ARM9/fs_loader2.h
Normal file
138
include/firm/fs/ARM9/fs_loader2.h
Normal file
@ -0,0 +1,138 @@
|
||||
/*---------------------------------------------------------------------------*
|
||||
Project: TwlIPL - include - fs
|
||||
File: fs_loader2.h
|
||||
|
||||
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:: 2007-09-06$
|
||||
$Rev$
|
||||
$Author$
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef FIRM_FS_FS_LOADER2_H_
|
||||
#define FIRM_FS_FS_LOADER2_H_
|
||||
|
||||
#include <twl/types.h>
|
||||
#include <twl/aes/common/types.h>
|
||||
#include <twl/os/common/systemCall.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FS2_GetAesKeySeed
|
||||
|
||||
Description: retreive aes key seed in the signature
|
||||
|
||||
Arguments: None
|
||||
|
||||
Returns: pointer to seed
|
||||
*---------------------------------------------------------------------------*/
|
||||
AESKey* const FS2_GetAesKeySeed( void );
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FS2_DeleteAesKeySeed
|
||||
|
||||
Description: delete aes key seed in the signature
|
||||
|
||||
Arguments: None
|
||||
|
||||
Returns: None
|
||||
*---------------------------------------------------------------------------*/
|
||||
void FS2_DeleteAesKeySeed( void );
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FS2_SetDigestKey
|
||||
|
||||
Description: set specified key or default key for HMAC-SHA-1
|
||||
|
||||
Arguments: digestKey pointer to key
|
||||
if NULL, use default key
|
||||
|
||||
Returns: TRUE if success
|
||||
*---------------------------------------------------------------------------*/
|
||||
void FS2_SetDigestKey( const u8* digestKey );
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FS2_LoadBuffer
|
||||
|
||||
Description: receive data from ARM7 via WRAM-B and store in destination address,
|
||||
calculate SHA1 in parallel if ctx is specified
|
||||
|
||||
Arguments: dest destination address to read
|
||||
size total length to read in bytes
|
||||
ctx pointer to SHA1 context or NULL
|
||||
|
||||
Returns: TRUE if success
|
||||
*---------------------------------------------------------------------------*/
|
||||
BOOL FS2_LoadBuffer( u8* dest, u32 size, SVCSHA1Context *ctx );
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FS2_LoadModule
|
||||
|
||||
Description: receive data from ARM7 via WRAM-B and store in destination address
|
||||
in view of AES settings in the ROM header at HW_TWL_ROM_HEADER_BUF,
|
||||
then verify the digest
|
||||
|
||||
Arguments: pFile pointer to FSFile streucture
|
||||
dest destination address to read
|
||||
offset file offset to start to read in bytes
|
||||
size total length to read in bytes
|
||||
digest digest to verify
|
||||
|
||||
Returns: TRUE if success
|
||||
*---------------------------------------------------------------------------*/
|
||||
BOOL FS2_LoadModule( FSFile *pFile, u8* dest, u32 offset, u32 size, const u8 digest[SVC_SHA1_DIGEST_SIZE] );
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FS2_OpenSrl
|
||||
|
||||
Description: open srl file named at HW_TWL_FS_BOOT_SRL_PATH_BUF
|
||||
|
||||
Arguments: pFile pointer to FSFile streucture
|
||||
|
||||
Returns: TRUE if success
|
||||
*---------------------------------------------------------------------------*/
|
||||
BOOL FS2_OpenSrl( FSFile *pFile );
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FS2_LoadHeader
|
||||
|
||||
Description: load ROM header to HW_TWL_ROM_HEADER_BUF using normal FS,
|
||||
and verify signature
|
||||
|
||||
Arguments: pFile pointer to FSFile streucture
|
||||
pool heap context to call SVC_DecryptSign
|
||||
rsa_key public key to verify the signature
|
||||
|
||||
Returns: TRUE if success
|
||||
*---------------------------------------------------------------------------*/
|
||||
BOOL FS2_LoadHeader( FSFile *pFile, SVCSignHeapContext* pool, const void* rsa_key );
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FS2_LoadStatic
|
||||
|
||||
Description: receive static regions from ARM6 via WRAM-B and store them
|
||||
specified by ROM header at HW_TWL_ROM_HEADER_BUF
|
||||
|
||||
Arguments: pFile pointer to FSFile streucture
|
||||
|
||||
Returns: TRUE if success
|
||||
*---------------------------------------------------------------------------*/
|
||||
BOOL FS2_LoadStatic( FSFile *pFile );
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
|
||||
/* FIRM_FS_FS_LOADER2_H_ */
|
||||
#endif
|
||||
@ -32,8 +32,8 @@ extern "C" {
|
||||
#define HW_FIRM_LOAD_BUFFER_END (HW_FIRM_LOAD_BUFFER_BASE + HW_FIRM_LOAD_BUFFER_SIZE)
|
||||
|
||||
//------------------------------------- FS/FATFS
|
||||
#define HW_FIRM_FS_AES_BUFFER 0x2ff0000
|
||||
#define HW_FIRM_FS_AES_BUFFER_SIZE (HW_FIRM_FS_AES_BUFFER_END - HW_FIRM_FS_AES_BUFFER)
|
||||
#define HW_FIRM_FS_AES_BUFFER (HW_FIRM_FS_AES_BUFFER_END - HW_FIRM_FS_AES_BUFFER_SIZE) // 0x02FF3800
|
||||
#define HW_FIRM_FS_AES_BUFFER_SIZE 0x4000
|
||||
#define HW_FIRM_FS_AES_BUFFER_END HW_FIRM_FATFS_COMMAND_BUFFER // 0x02ff7800
|
||||
|
||||
#define HW_FIRM_FATFS_COMMAND_BUFFER (HW_FIRM_FATFS_COMMAND_BUFFER_END - HW_FIRM_FATFS_COMMAND_BUFFER_SIZE)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user