From 0440a8ba65f354920195941de1507bf26494ef37 Mon Sep 17 00:00:00 2001 From: yutaka Date: Wed, 30 Jan 2008 07:18:03 +0000 Subject: [PATCH] =?UTF-8?q?FS=E3=83=A9=E3=82=A4=E3=83=96=E3=83=A9=E3=83=AA?= =?UTF-8?q?=E3=81=AE=E5=86=8D=E6=A7=8B=E6=88=90=20BOOTTYPE=E3=81=AE?= =?UTF-8?q?=E8=A8=AD=E5=AE=9A=E3=82=BF=E3=82=A4=E3=83=9F=E3=83=B3=E3=82=B0?= =?UTF-8?q?=E3=81=AE=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: file:///Users/lillianskinner/Downloads/platinum/twl/TwlIPL/trunk@548 b08762b0-b915-fc4b-9d8c-17b2551a87ff --- build/gcdfirm/sdmc-launcher/ARM9/main.c | 20 +- build/libraries/fs/ARM7/Makefile | 2 +- build/libraries/fs/ARM7/src/fs_firm.c | 223 ------- build/libraries/fs/ARM7/src/fs_loader.c | 257 ++++++++ build/libraries/fs/ARM9/Makefile | 2 +- build/libraries/fs/ARM9/src/fs_es.c | 155 ----- build/libraries/fs/ARM9/src/fs_firm.c | 633 ++++---------------- build/libraries/fs/ARM9/src/fs_loader.c | 390 ++++++++++++ build/libraries/fs/ARM9/src/fs_loader2.c | 474 +++++++++++++++ build/nandfirm/menu-launcher/ARM9/main.c | 13 +- build/nandfirm/menu-launcher2/ARM9/Makefile | 3 +- build/nandfirm/menu-launcher2/ARM9/main.c | 34 +- build/nandfirm/sdmc-launcher/ARM9/main.c | 20 +- include/firm/fs.h | 4 +- include/firm/fs/ARM7/fs_firm.h | 55 +- include/firm/fs/ARM7/fs_loader.h | 85 +++ include/firm/fs/ARM9/fs_es.h | 50 -- include/firm/fs/ARM9/fs_firm.h | 150 +---- include/firm/fs/ARM9/fs_loader.h | 125 ++++ include/firm/fs/ARM9/fs_loader2.h | 138 +++++ include/firm/hw/common/mmap_firm.h | 4 +- 21 files changed, 1663 insertions(+), 1174 deletions(-) create mode 100644 build/libraries/fs/ARM7/src/fs_loader.c delete mode 100644 build/libraries/fs/ARM9/src/fs_es.c create mode 100644 build/libraries/fs/ARM9/src/fs_loader.c create mode 100644 build/libraries/fs/ARM9/src/fs_loader2.c create mode 100644 include/firm/fs/ARM7/fs_loader.h delete mode 100644 include/firm/fs/ARM9/fs_es.h create mode 100644 include/firm/fs/ARM9/fs_loader.h create mode 100644 include/firm/fs/ARM9/fs_loader2.h diff --git a/build/gcdfirm/sdmc-launcher/ARM9/main.c b/build/gcdfirm/sdmc-launcher/ARM9/main.c index 7b86af06..c229b167 100644 --- a/build/gcdfirm/sdmc-launcher/ARM9/main.c +++ b/build/gcdfirm/sdmc-launcher/ARM9/main.c @@ -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; // イニシャルコードなど - 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: diff --git a/build/libraries/fs/ARM7/Makefile b/build/libraries/fs/ARM7/Makefile index e747ab21..a4bec5b3 100644 --- a/build/libraries/fs/ARM7/Makefile +++ b/build/libraries/fs/ARM7/Makefile @@ -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 diff --git a/build/libraries/fs/ARM7/src/fs_firm.c b/build/libraries/fs/ARM7/src/fs_firm.c index 0c94ba05..261ff699 100644 --- a/build/libraries/fs/ARM7/src/fs_firm.c +++ b/build/libraries/fs/ARM7/src/fs_firm.c @@ -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; -} - diff --git a/build/libraries/fs/ARM7/src/fs_loader.c b/build/libraries/fs/ARM7/src/fs_loader.c new file mode 100644 index 00000000..3ba74a87 --- /dev/null +++ b/build/libraries/fs/ARM7/src/fs_loader.c @@ -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 +#include +#include + +//#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; +} + diff --git a/build/libraries/fs/ARM9/Makefile b/build/libraries/fs/ARM9/Makefile index 69ad1688..4f7cd66a 100644 --- a/build/libraries/fs/ARM9/Makefile +++ b/build/libraries/fs/ARM9/Makefile @@ -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 diff --git a/build/libraries/fs/ARM9/src/fs_es.c b/build/libraries/fs/ARM9/src/fs_es.c deleted file mode 100644 index 2cb99a6e..00000000 --- a/build/libraries/fs/ARM9/src/fs_es.c +++ /dev/null @@ -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 -#include - -#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; -} - - diff --git a/build/libraries/fs/ARM9/src/fs_firm.c b/build/libraries/fs/ARM9/src/fs_firm.c index 534b3b66..c4828584 100644 --- a/build/libraries/fs/ARM9/src/fs_firm.c +++ b/build/libraries/fs/ARM9/src/fs_firm.c @@ -14,50 +14,14 @@ $Rev$ $Author$ *---------------------------------------------------------------------------*/ - #include -#include #include -#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; -} diff --git a/build/libraries/fs/ARM9/src/fs_loader.c b/build/libraries/fs/ARM9/src/fs_loader.c new file mode 100644 index 00000000..5e4d0229 --- /dev/null +++ b/build/libraries/fs/ARM9/src/fs_loader.c @@ -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 +#include +#include + +#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; +} diff --git a/build/libraries/fs/ARM9/src/fs_loader2.c b/build/libraries/fs/ARM9/src/fs_loader2.c new file mode 100644 index 00000000..79601beb --- /dev/null +++ b/build/libraries/fs/ARM9/src/fs_loader2.c @@ -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 +#include +#include +#include +#include + +#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; +} diff --git a/build/nandfirm/menu-launcher/ARM9/main.c b/build/nandfirm/menu-launcher/ARM9/main.c index 4db0966d..fd835dfa 100644 --- a/build/nandfirm/menu-launcher/ARM9/main.c +++ b/build/nandfirm/menu-launcher/ARM9/main.c @@ -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; // イニシャルコードなど - 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: diff --git a/build/nandfirm/menu-launcher2/ARM9/Makefile b/build/nandfirm/menu-launcher2/ARM9/Makefile index 47c43f07..0870f698 100644 --- a/build/nandfirm/menu-launcher2/ARM9/Makefile +++ b/build/nandfirm/menu-launcher2/ARM9/Makefile @@ -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 #---------------------------------------------------------------------------- diff --git a/build/nandfirm/menu-launcher2/ARM9/main.c b/build/nandfirm/menu-launcher2/ARM9/main.c index 64def192..8e2f4ba2 100644 --- a/build/nandfirm/menu-launcher2/ARM9/main.c +++ b/build/nandfirm/menu-launcher2/ARM9/main.c @@ -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(); } + + // ブートタイプの変更 + ( (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: diff --git a/build/nandfirm/sdmc-launcher/ARM9/main.c b/build/nandfirm/sdmc-launcher/ARM9/main.c index 4f18fd02..e9f1fd50 100644 --- a/build/nandfirm/sdmc-launcher/ARM9/main.c +++ b/build/nandfirm/sdmc-launcher/ARM9/main.c @@ -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; // イニシャルコードなど - 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: diff --git a/include/firm/fs.h b/include/firm/fs.h index c445fdac..cabe2145 100644 --- a/include/firm/fs.h +++ b/include/firm/fs.h @@ -20,9 +20,11 @@ #ifdef SDK_ARM7 #include +#include #else #include -#include +#include +#include #endif // SDK_ARM7 diff --git a/include/firm/fs/ARM7/fs_firm.h b/include/firm/fs/ARM7/fs_firm.h index 7752481c..c0e98a6c 100644 --- a/include/firm/fs/ARM7/fs_firm.h +++ b/include/firm/fs/ARM7/fs_firm.h @@ -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 -#include - #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" */ diff --git a/include/firm/fs/ARM7/fs_loader.h b/include/firm/fs/ARM7/fs_loader.h new file mode 100644 index 00000000..1ff82cc0 --- /dev/null +++ b/include/firm/fs/ARM7/fs_loader.h @@ -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 +#include + +#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 diff --git a/include/firm/fs/ARM9/fs_es.h b/include/firm/fs/ARM9/fs_es.h deleted file mode 100644 index baaf63a4..00000000 --- a/include/firm/fs/ARM9/fs_es.h +++ /dev/null @@ -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 - -#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 diff --git a/include/firm/fs/ARM9/fs_firm.h b/include/firm/fs/ARM9/fs_firm.h index 0e72127e..b88957ae 100644 --- a/include/firm/fs/ARM9/fs_firm.h +++ b/include/firm/fs/ARM9/fs_firm.h @@ -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 diff --git a/include/firm/fs/ARM9/fs_loader.h b/include/firm/fs/ARM9/fs_loader.h new file mode 100644 index 00000000..12c3b6b0 --- /dev/null +++ b/include/firm/fs/ARM9/fs_loader.h @@ -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 +#include +#include + +#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 diff --git a/include/firm/fs/ARM9/fs_loader2.h b/include/firm/fs/ARM9/fs_loader2.h new file mode 100644 index 00000000..a5228728 --- /dev/null +++ b/include/firm/fs/ARM9/fs_loader2.h @@ -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 +#include +#include + +#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 diff --git a/include/firm/hw/common/mmap_firm.h b/include/firm/hw/common/mmap_firm.h index 67c3d73c..dd22402e 100644 --- a/include/firm/hw/common/mmap_firm.h +++ b/include/firm/hw/common/mmap_firm.h @@ -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)