FSライブラリの再構成

BOOTTYPEの設定タイミングの変更


git-svn-id: file:///Users/lillianskinner/Downloads/platinum/twl/TwlIPL/trunk@548 b08762b0-b915-fc4b-9d8c-17b2551a87ff
This commit is contained in:
yutaka 2008-01-30 07:18:03 +00:00
parent f73f99dff8
commit 0440a8ba65
21 changed files with 1663 additions and 1174 deletions

View File

@ -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:

View File

@ -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

View File

@ -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;
}

View 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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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;
}

View 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;
}

View 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;
}

View File

@ -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:

View File

@ -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
#----------------------------------------------------------------------------

View File

@ -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:

View File

@ -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:

View File

@ -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

View File

@ -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" */

View 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

View File

@ -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

View File

@ -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

View 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

View 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

View File

@ -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)