mirror of
https://github.com/rvtr/TwlIPL.git
synced 2025-10-31 06:01:12 -04:00
本番用MI/FATFSをFSに統合
git-svn-id: file:///Users/lillianskinner/Downloads/platinum/twl/TwlIPL/trunk@275 b08762b0-b915-fc4b-9d8c-17b2551a87ff
This commit is contained in:
parent
7068897306
commit
042bbc08d3
54
build/libraries/fs/ARM7/Makefile
Normal file
54
build/libraries/fs/ARM7/Makefile
Normal file
@ -0,0 +1,54 @@
|
||||
#! make -f
|
||||
#----------------------------------------------------------------------------
|
||||
# Project: TwlFirm - libraries - fs
|
||||
# File: Makefile
|
||||
#
|
||||
# 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:$
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
SUBDIRS =
|
||||
SUBMAKES =
|
||||
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
# build ARM & THUMB libraries
|
||||
TWL_CODEGEN_ALL ?= TRUE
|
||||
|
||||
# Codegen for sub processer
|
||||
TWL_PROC = ARM7
|
||||
|
||||
LINCLUDES = \
|
||||
$(TWLSDK_ROOT)/build/libraries/fatfs/ARM7.TWL/include \
|
||||
$(TWLSDK_ROOT)/build/libraries/fatfs/ARM7.TWL/include/twl/fatfs/ARM7
|
||||
|
||||
SRCS = fs_firm.c
|
||||
|
||||
|
||||
TARGET_LIB = libfs_sp$(FIRM_LIBSUFFIX).a
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
include $(TWLIPL_ROOT)/build/buildtools/commondefs
|
||||
|
||||
INSTALL_TARGETS = $(TARGETS)
|
||||
INSTALL_DIR = $(FIRM_INSTALL_LIBDIR)
|
||||
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
do-build: $(TARGETS)
|
||||
|
||||
include $(TWLIPL_ROOT)/build/buildtools/modulerules
|
||||
|
||||
#===== End of Makefile =====
|
||||
320
build/libraries/fs/ARM7/src/fs_firm.c
Normal file
320
build/libraries/fs/ARM7/src/fs_firm.c
Normal file
@ -0,0 +1,320 @@
|
||||
/*---------------------------------------------------------------------------*
|
||||
Project: TwlIPL - libraries - fs
|
||||
File: fs_firm.c
|
||||
|
||||
Copyright 2007 Nintendo. All rights reserved.
|
||||
|
||||
These coded instructions, statements, and computer programs contain
|
||||
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||
Company Ltd., and are protected by Federal copyright law. They may
|
||||
not be disclosed to third parties or copied or duplicated in any form,
|
||||
in whole or in part, without the prior written consent of Nintendo.
|
||||
|
||||
$Date:: $
|
||||
$Rev$
|
||||
$Author$
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#include <symbols.h>
|
||||
#include <firm.h>
|
||||
#include <rtfs.h>
|
||||
|
||||
#define WORKAROUND_NAND_2KB_BUG
|
||||
|
||||
#define FS_HEADER_AUTH_SIZE 0xe00
|
||||
|
||||
#define MODULE_ALIGNMENT 0x10 // 16バイト単位で読み込む
|
||||
//#define MODULE_ALIGNMENT 0x200 // 512バイト単位で読み込む
|
||||
#define RoundUpModuleSize(value) (((value) + MODULE_ALIGNMENT - 1) & -MODULE_ALIGNMENT)
|
||||
|
||||
static ROM_Header* const rh= (ROM_Header*)HW_TWL_ROM_HEADER_BUF;
|
||||
|
||||
static void ConvertPath( u16* dest, const char* src, u32 max)
|
||||
{
|
||||
dest[0] = 0;
|
||||
{
|
||||
const OSMountInfo *info;
|
||||
int len;
|
||||
// デバイス部分を取得
|
||||
for (len = 0; src[len] && src[len] != ':'; len++)
|
||||
{
|
||||
if (len >= max) // もっと手前で止めても良い?
|
||||
{
|
||||
OS_TPanic("%s: Cannot detect ':' in %d charactors.\n", __func__, len);
|
||||
}
|
||||
}
|
||||
|
||||
// ドライブ名の解決
|
||||
for (info = OS_GetMountInfo(); *info->drive; ++info)
|
||||
{
|
||||
if ((STD_CompareNString(src, info->archiveName, len) == 0) &&
|
||||
(info->archiveName[len] == 0))
|
||||
{
|
||||
if (info->target != OS_MOUNT_TGT_ROOT) // 多重マウント未対応
|
||||
{
|
||||
return;
|
||||
}
|
||||
dest[0] = (u16)*info->drive;
|
||||
break;
|
||||
}
|
||||
}
|
||||
max --;
|
||||
dest++;
|
||||
src += len;
|
||||
}
|
||||
{
|
||||
int len;
|
||||
// 残りunicode化 (ASCIIのみ)
|
||||
for (len = 0; len < max && src[len]; len++)
|
||||
{
|
||||
if (src[len] == '/')
|
||||
{
|
||||
dest[len] = L'\\';
|
||||
}
|
||||
#ifndef SDK_FINALROM
|
||||
else if (src[len] & 0x80)
|
||||
{
|
||||
OS_TPanic("%s: Multi-byte charactor was detected (0x%02X).\n", __func__, src[len]);
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
dest[len] = (u16)src[len];
|
||||
}
|
||||
}
|
||||
if (len < max)
|
||||
{
|
||||
dest[len] = 0;
|
||||
}
|
||||
else // l type (ensure to terminate zero)
|
||||
{
|
||||
dest[max-1] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FS_OpenSrl
|
||||
|
||||
Description: open srl file named in HW_TWL_FS_BOOT_SRL_PATH_BUF
|
||||
|
||||
Arguments: None
|
||||
|
||||
Returns: file discriptor
|
||||
*---------------------------------------------------------------------------*/
|
||||
int FS_OpenSrl( void )
|
||||
{
|
||||
const char *fspath = (char*)HW_TWL_FS_BOOT_SRL_PATH_BUF;
|
||||
u16 fatpath[OS_MOUNT_PATH_LEN];
|
||||
ConvertPath(fatpath, fspath, OS_MOUNT_PATH_LEN);
|
||||
return FATFSi_rtfs_po_open((u8*)fatpath, 0, 0);
|
||||
}
|
||||
|
||||
static void EnableAes( AESCounter* pCounter ) // ドライバAPIと置き換える
|
||||
{
|
||||
(void)pCounter;
|
||||
}
|
||||
static void DisableAes( void ) // ドライバAPIと置き換える
|
||||
{
|
||||
}
|
||||
|
||||
static void GetAesCounter( AESCounter* pCounter, u32 offset )
|
||||
{
|
||||
MI_CpuCopy32( rh->s.main_static_digest, pCounter, AES_BLOCK_SIZE );
|
||||
AESi_AddCounter( pCounter, offset - rh->s.aes_target_rom_offset );
|
||||
}
|
||||
|
||||
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 )
|
||||
{
|
||||
AESCounter counter;
|
||||
if ( end > aes_end )
|
||||
{
|
||||
size = aes_end - offset;
|
||||
}
|
||||
AESi_WaitKey();
|
||||
if (rh->s.developer_encrypt)
|
||||
{
|
||||
AESi_LoadKey( AES_KEY_SLOT_C );
|
||||
}
|
||||
else
|
||||
{
|
||||
AESi_LoadKey( AES_KEY_SLOT_A );
|
||||
}
|
||||
GetAesCounter( &counter, offset );
|
||||
EnableAes( &counter );
|
||||
}
|
||||
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, (s32)offset, PSEEK_SET) < 0 )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
while ( size > 0 )
|
||||
{
|
||||
u8* dest = (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) < 0 )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
if ( FATFSi_rtfs_po_read(fd, (u8*)dest, (int)unit) < 0 )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
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;
|
||||
}
|
||||
|
||||
47
build/libraries/fs/ARM9/Makefile
Normal file
47
build/libraries/fs/ARM9/Makefile
Normal file
@ -0,0 +1,47 @@
|
||||
#! make -f
|
||||
#----------------------------------------------------------------------------
|
||||
# Project: TwlFirm - libraries - fs
|
||||
# File: Makefile
|
||||
#
|
||||
# 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:$
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
SUBDIRS =
|
||||
SUBMAKES =
|
||||
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
LINCLUDES = $(ES_ROOT)/include
|
||||
|
||||
SRCS = fs_firm.c
|
||||
|
||||
|
||||
TARGET_LIB = libfs$(FIRM_LIBSUFFIX).a
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
include $(TWLIPL_ROOT)/build/buildtools/commondefs
|
||||
include $(TWLSDK_ROOT)/add-ins/es/commondefs.es
|
||||
|
||||
INSTALL_TARGETS = $(TARGETS)
|
||||
INSTALL_DIR = $(FIRM_INSTALL_LIBDIR)
|
||||
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
do-build: $(TARGETS)
|
||||
|
||||
include $(TWLIPL_ROOT)/build/buildtools/modulerules
|
||||
|
||||
#===== End of Makefile =====
|
||||
363
build/libraries/fs/ARM9/src/fs_firm.c
Normal file
363
build/libraries/fs/ARM9/src/fs_firm.c
Normal file
@ -0,0 +1,363 @@
|
||||
/*---------------------------------------------------------------------------*
|
||||
Project: TwlIPL - libraries - fs
|
||||
File: fs_firm.c
|
||||
|
||||
Copyright 2007 Nintendo. All rights reserved.
|
||||
|
||||
These coded instructions, statements, and computer programs contain
|
||||
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||
Company Ltd., and are protected by Federal copyright law. They may
|
||||
not be disclosed to third parties or copied or duplicated in any form,
|
||||
in whole or in part, without the prior written consent of Nintendo.
|
||||
|
||||
$Date:: $
|
||||
$Rev$
|
||||
$Author$
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#include <firm.h>
|
||||
#include <estypes.h>
|
||||
#include <es.h>
|
||||
|
||||
#define FS_HEADER_AUTH_SIZE 0xe00
|
||||
|
||||
#define CONTENT_INDEX_SRL 0
|
||||
#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,
|
||||
};
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
Name: FS_ResolveSrl
|
||||
|
||||
Description: resolve srl filename and store to HW_TWL_FS_BOOT_SRL_PATH_BUF
|
||||
|
||||
Arguments: titleId title id for srl file
|
||||
|
||||
Returns: TRUE if success
|
||||
*---------------------------------------------------------------------------*/
|
||||
BOOL FS_ResolveSrl( u64 titleId )
|
||||
{
|
||||
if ( ES_ERR_OK != ES_InitLib() ||
|
||||
ES_ERR_OK != ES_GetContentPath(titleId, CONTENT_INDEX_SRL, (char*)HW_TWL_FS_BOOT_SRL_PATH_BUF) ||
|
||||
ES_ERR_OK != ES_CloseLib() )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
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_BLOCK_SIZE; i++ )
|
||||
{
|
||||
if ( a[i] != b[i] )
|
||||
{
|
||||
result = FALSE;
|
||||
}
|
||||
}
|
||||
if ( aClr ) MI_CpuClear8(a, SVC_SHA1_BLOCK_SIZE);
|
||||
if ( bClr ) MI_CpuClear8(b, SVC_SHA1_BLOCK_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_BLOCK_SIZE];
|
||||
u8 md[SVC_SHA1_BLOCK_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 );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MI_CpuCopyFast( src, dest, unit );
|
||||
MI_CpuClearFast( src, unit );
|
||||
}
|
||||
DC_FlushRange( src, unit );
|
||||
MIi_SetWramBankMaster_B(count, MI_WRAM_ARM7);
|
||||
count = (count + 1) % HW_FIRM_LOAD_BUFFER_UNIT_NUMS;
|
||||
size -= unit;
|
||||
dest += unit;
|
||||
}
|
||||
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_BLOCK_SIZE] )
|
||||
{
|
||||
SVCHMACSHA1Context ctx;
|
||||
u8 md[SVC_SHA1_BLOCK_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_BLOCK_SIZE];
|
||||
u8 digest[SVC_SHA1_BLOCK_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 );
|
||||
MI_CpuCopy8( sd.digest, digest, SVC_SHA1_BLOCK_SIZE ); // ダイジェストの取り出し
|
||||
MI_CpuClear8( &sd, sizeof(sd) ); // 残り削除 (他に必要なものはない?)
|
||||
return CheckDigest( md, digest, TRUE, 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;
|
||||
}
|
||||
31
build/libraries/fs/Makefile
Normal file
31
build/libraries/fs/Makefile
Normal file
@ -0,0 +1,31 @@
|
||||
#! make -f
|
||||
#----------------------------------------------------------------------------
|
||||
# Project: TwlIPL - libraries - fatfs
|
||||
# File: Makefile
|
||||
#
|
||||
# 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 $(TWLIPL_ROOT)/build/buildtools/commondefs
|
||||
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
SUBDIRS = ARM7 ARM9
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
include $(TWLIPL_ROOT)/build/buildtools/modulerules
|
||||
|
||||
|
||||
#===== End of Makefile =====
|
||||
Loading…
Reference in New Issue
Block a user