Static領域がAES領域の境界をまたいでいる場合をサポート

git-svn-id: file:///Users/lillianskinner/Downloads/platinum/twl/TwlIPL/trunk@84 b08762b0-b915-fc4b-9d8c-17b2551a87ff
This commit is contained in:
yutaka 2007-10-31 06:50:02 +00:00
parent 6f7c91a75f
commit 5ddf21e9f9
2 changed files with 208 additions and 157 deletions

View File

@ -294,36 +294,85 @@ static AESCounter* FATFSi_GetCounter( u32 offset )
AES領域をまたぐ場合は (
)
makerom.TWLまたはIPLの使用に依存します
Arguments: offset offset of region from head of ROM_Header
size size of region (for check only)
size size of region
Returns: counter
Returns: size to transfer once
*---------------------------------------------------------------------------*/
static void FATFSi_SetupAES( u32 offset, u32 size )
static u32 FATFSi_SetupAES( u32 offset, u32 size )
{
u32 aes_end = rh->s.aes_target_rom_offset + RoundUpModuleSize(rh->s.aes_target_size);
u32 arg_end = offset + RoundUpModuleSize(size);
if ( rh->s.enable_aes && offset >= rh->s.aes_target_rom_offset && arg_end <= aes_end )
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 )
{
AESi_WaitKey();
if (rh->s.developer_encrypt)
if ( offset >= aes_offset && offset < aes_end )
{
AESi_LoadKey( AES_KEY_SLOT_C );
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 );
}
FATFS_EnableAES( FATFSi_GetCounter( offset ) );
}
else
{
AESi_LoadKey( AES_KEY_SLOT_A );
if ( offset < aes_offset && offset + size > aes_offset )
{
size = aes_offset - offset;
}
FATFS_DisableAES();
}
FATFS_EnableAES( FATFSi_GetCounter( offset ) );
}
else
{
FATFS_DisableAES();
}
return size;
}
/*---------------------------------------------------------------------------*
Name: FATFSi_LoadModule
Description: transfer module to ARM9 via WRAM[B]
FATFSi_LoadBufferの上位APIです
AES境界をまたぐときに2回に分けるだけです
Arguments: offset offset from head of ROM_Header
size size to load
Returns: TRUE if success
*---------------------------------------------------------------------------*/
static /*inline*/ BOOL FATFSi_LoadModule(u32 offset, u32 size)
{
size = RoundUpModuleSize( size ); // アラインメント調整
while ( size > 0 )
{
u32 unit = FATFSi_SetupAES( offset, size ); // 一度の転送サイズ
if ( !FATFS_LoadBuffer( offset, unit ) )
{
return FALSE;
}
offset += unit;
size -= unit;
}
return TRUE;
}
/*---------------------------------------------------------------------------*
Name: FATFS_LoadStatic
@ -347,98 +396,77 @@ static void FATFSi_SetupAES( u32 offset, u32 size )
*---------------------------------------------------------------------------*/
BOOL FATFS_LoadStatic( void )
{
#ifdef PROFILE_ENABLE
// 30: LoadStatic
pf_cnt = 0x30;
profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick());
profile[pf_cnt++] = (u32)PROFILE_PXI_SEND | FIRM_PXI_ID_LOAD_STATIC; // checkpoint
#endif
PXI_NotifyID( FIRM_PXI_ID_LOAD_STATIC );
// load ARM9 static region without AES
if ( rh->s.main_size > 0 )
{
u32 aligned = RoundUpModuleSize(rh->s.main_size);
#ifdef PROFILE_ENABLE
// 30: before PXI
pf_cnt = 0x30;
// 31: before PXI
profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick());
profile[pf_cnt++] = (u32)PROFILE_PXI_SEND | FIRM_PXI_ID_LOAD_ARM9_STATIC; // checkpoint
#endif
PXI_NotifyID( FIRM_PXI_ID_LOAD_ARM9_STATIC );
FATFSi_SetupAES( rh->s.main_rom_offset, aligned );
if ( !FATFS_LoadBuffer( rh->s.main_rom_offset, aligned ) ||
PXI_RecvID() != FIRM_PXI_ID_AUTH_ARM9_STATIC )
if ( !FATFSi_LoadModule( rh->s.main_rom_offset, rh->s.main_size ) )
{
return FALSE;
}
#ifdef PROFILE_ENABLE
// 3x: after PXI
profile[pf_cnt++] = (u32)PROFILE_PXI_RECV | FIRM_PXI_ID_AUTH_ARM9_STATIC; // checkpoint
profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick());
#endif
}
// load ARM7 static region without AES
if ( rh->s.sub_size > 0 )
{
u32 aligned = RoundUpModuleSize(rh->s.sub_size);
#ifdef PROFILE_ENABLE
// 50: before PXI
pf_cnt = 0x50;
profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick());
profile[pf_cnt++] = (u32)PROFILE_PXI_SEND | FIRM_PXI_ID_LOAD_ARM7_STATIC; // checkpoint
#endif
PXI_NotifyID( FIRM_PXI_ID_LOAD_ARM7_STATIC );
FATFSi_SetupAES( rh->s.sub_rom_offset, aligned );
if ( !FATFS_LoadBuffer( rh->s.sub_rom_offset, aligned ) ||
PXI_RecvID() != FIRM_PXI_ID_AUTH_ARM7_STATIC )
if ( !FATFSi_LoadModule( rh->s.sub_rom_offset, rh->s.sub_size ) )
{
return FALSE;
}
#ifdef PROFILE_ENABLE
// 5x: after PXI
profile[pf_cnt++] = (u32)PROFILE_PXI_RECV | FIRM_PXI_ID_AUTH_ARM7_STATIC; // checkpoint
profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick());
#endif
}
// load ARM9 extended static region with AES
if ( rh->s.main_ltd_size > 0 )
{
u32 aligned = RoundUpModuleSize(rh->s.main_ltd_size);
#ifdef PROFILE_ENABLE
// 70: before PXI
pf_cnt = 0x70;
profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick());
profile[pf_cnt++] = (u32)PROFILE_PXI_SEND | FIRM_PXI_ID_LOAD_ARM9_LTD_STATIC; // checkpoint
#endif
PXI_NotifyID( FIRM_PXI_ID_LOAD_ARM9_LTD_STATIC );
FATFSi_SetupAES( rh->s.main_ltd_rom_offset, aligned );
if ( !FATFS_LoadBuffer( rh->s.main_ltd_rom_offset, aligned ) ||
PXI_RecvID() != FIRM_PXI_ID_AUTH_ARM9_LTD_STATIC )
if ( !FATFSi_LoadModule( rh->s.main_ltd_rom_offset, rh->s.main_ltd_size ) )
{
return FALSE;
}
#ifdef PROFILE_ENABLE
// 7x: after PXI
profile[pf_cnt++] = (u32)PROFILE_PXI_RECV | FIRM_PXI_ID_AUTH_ARM9_LTD_STATIC; // checkpoint
profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick());
#endif
}
// load ARM7 extended static region with AES
if ( rh->s.sub_ltd_size > 0 )
{
u32 aligned = RoundUpModuleSize(rh->s.sub_ltd_size);
#ifdef PROFILE_ENABLE
// 90: before PXI
pf_cnt = 0x90;
profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick());
profile[pf_cnt++] = (u32)PROFILE_PXI_SEND | FIRM_PXI_ID_LOAD_ARM7_LTD_STATIC; // checkpoint
#endif
PXI_NotifyID( FIRM_PXI_ID_LOAD_ARM7_LTD_STATIC );
FATFSi_SetupAES( rh->s.sub_ltd_rom_offset, aligned );
if ( !FATFS_LoadBuffer( rh->s.sub_ltd_rom_offset, aligned ) ||
PXI_RecvID() != FIRM_PXI_ID_AUTH_ARM7_LTD_STATIC )
if ( !FATFSi_LoadModule( rh->s.sub_ltd_rom_offset, rh->s.sub_ltd_size ) )
{
return FALSE;
}
#ifdef PROFILE_ENABLE
// 9x: after PXI
profile[pf_cnt++] = (u32)PROFILE_PXI_RECV | FIRM_PXI_ID_AUTH_ARM7_LTD_STATIC; // checkpoint
profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick());
#endif
}
// waiting result
if ( PXI_RecvID() != FIRM_PXI_ID_AUTH_STATIC )
{
return FALSE;
}
#ifdef PROFILE_ENABLE
// 9x: after PXI
profile[pf_cnt++] = (u32)PROFILE_PXI_RECV | FIRM_PXI_ID_AUTH_STATIC; // checkpoint
profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick());
#endif
return TRUE;
}

View File

@ -120,7 +120,7 @@ static BOOL CheckRomCertificate( SVCSignHeapContext* pool, const RomCertificate
}
/*---------------------------------------------------------------------------*
Name: MI_LoadBuffer
Name: MIi_LoadBuffer
Description: receive data from ARM7 and store(move) via WRAM[B]
@ -159,10 +159,11 @@ static BOOL CheckRomCertificate( SVCSignHeapContext* pool, const RomCertificate
Returns: TRUE if success
*---------------------------------------------------------------------------*/
static BOOL MI_LoadBuffer(u8* dest, u32 size, SVCSHA1Context *ctx)
static BOOL MIi_LoadBuffer(u8* dest, u32 size, SVCSHA1Context *ctx)
{
u8* base = (u8*)HW_FIRM_LOAD_BUFFER_BASE;
static int count = 0;
while (size > 0)
{
u8* src = base + count * HW_FIRM_LOAD_BUFFER_UNIT_SIZE;
@ -208,52 +209,6 @@ static BOOL MI_LoadBuffer(u8* dest, u32 size, SVCSHA1Context *ctx)
return TRUE;
}
/*---------------------------------------------------------------------------*
Name: MI_LoadModule
Description: receive module from ARM7 and store(move) via WRAM[B]
MI_LoadBufferの上位APIでSHA1のハッシュ値を渡すことで
SHA1ハッシュチェックを行います
SHA1の計算範囲全体を
便
Arguments: dest destination address for received data
size size to load
digest digest to compare
Returns: TRUE if success
*---------------------------------------------------------------------------*/
static /*inline*/ BOOL MI_LoadModule(void* dest, u32 size, const u8 digest[DIGEST_SIZE_SHA1])
{
SVCHMACSHA1Context ctx;
u8 md[DIGEST_SIZE_SHA1];
int i;
BOOL result = TRUE;
SVC_HMACSHA1Init(&ctx, s_digestDefaultKey, SVC_SHA1_BLOCK_SIZE );
if ( !MI_LoadBuffer( dest, size, &ctx.sha1_ctx ) ) // UpdateはSHA1と同じ処理
{
return FALSE;
}
SVC_HMACSHA1GetHash(&ctx, md);
#ifdef PROFILE_ENABLE
// xx: after SHA1
profile[pf_cnt++] = PROFILE_SHA1; // checkpoint
profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick());
#endif
for ( i = 0; i < DIGEST_SIZE_SHA1; i++ )
{
if ( md[i] != digest[i] )
{
result = FALSE;
}
}
return result;
}
/*---------------------------------------------------------------------------*
Name: MI_LoadHeader
@ -292,7 +247,7 @@ BOOL MI_LoadHeader( SVCSignHeapContext* pool, const void* rsa_key )
((profile[pf_cnt++] = PROFILE_PXI_RECV | FIRM_PXI_ID_LOAD_HEADER), FALSE) ||
((profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick())), FALSE) ||
#endif
!MI_LoadBuffer( (u8*)rh, AUTH_SIZE, &ctx ) )
!MIi_LoadBuffer( (u8*)rh, AUTH_SIZE, &ctx ) )
{
return FALSE;
}
@ -303,7 +258,7 @@ BOOL MI_LoadHeader( SVCSignHeapContext* pool, const void* rsa_key )
profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick());
#endif
// load header (remain)
if ( !MI_LoadBuffer( (u8*)rh + AUTH_SIZE, HEADER_SIZE - AUTH_SIZE, NULL ) )
if ( !MIi_LoadBuffer( (u8*)rh + AUTH_SIZE, HEADER_SIZE - AUTH_SIZE, NULL ) )
{
return FALSE;
}
@ -346,6 +301,102 @@ BOOL MI_LoadHeader( SVCSignHeapContext* pool, const void* rsa_key )
return result;
}
/*---------------------------------------------------------------------------*
Name: MIi_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 MIi_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: MIi_LoadModule
Description: receive module from ARM7 and store(move) via WRAM[B]
MIi_LoadBufferの上位APIです
AES境界をまたぐ場合は2LoadBufferに分割します
SHA1の計算範囲全体を
便
Arguments: dest destination address for received data
offset offset from head of ROM_Header
size size to load
digest digest to compare
Returns: TRUE if success
*---------------------------------------------------------------------------*/
static /*inline*/ BOOL MIi_LoadModule(void* dest, u32 offset, u32 size, const u8 digest[DIGEST_SIZE_SHA1])
{
SVCHMACSHA1Context ctx;
u8 md[DIGEST_SIZE_SHA1];
int i;
BOOL result = TRUE;
SVC_HMACSHA1Init(&ctx, s_digestDefaultKey, SVC_SHA1_BLOCK_SIZE );
while ( size > 0 )
{
u32 unit = MIi_GetTransferSize( offset, size );
if ( !MIi_LoadBuffer( dest, unit, &ctx.sha1_ctx ) ) // UpdateはSHA1と同じ処理
{
return FALSE;
}
dest = (u8*)dest + unit;
offset += unit;
size -= unit;
}
SVC_HMACSHA1GetHash(&ctx, md);
#ifdef PROFILE_ENABLE
// 3x: after SHA1
profile[pf_cnt++] = PROFILE_SHA1; // checkpoint
profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick());
#endif
for (i = 0; i < DIGEST_SIZE_SHA1; i++)
{
if (md[i] != digest[i])
{
result = FALSE;
}
}
MI_CpuClear8(md, DIGEST_SIZE_SHA1);
return result;
}
/*---------------------------------------------------------------------------*
Name: MI_LoadStatic
@ -365,29 +416,28 @@ BOOL MI_LoadHeader( SVCSignHeapContext* pool, const void* rsa_key )
*---------------------------------------------------------------------------*/
BOOL MI_LoadStatic( void )
{
// load static
if ( PXI_RecvID() != FIRM_PXI_ID_LOAD_STATIC )
{
return FALSE;
}
#ifdef PROFILE_ENABLE
// 30: after PXI
pf_cnt = 0x30;
profile[pf_cnt++] = PROFILE_PXI_RECV | FIRM_PXI_ID_LOAD_STATIC;
profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick());
#endif
// load ARM9 static region
if ( rh->s.main_size > 0 )
{
#ifdef PROFILE_ENABLE
// 30: before PXI
pf_cnt = 0x30;
// 31: before PXI
profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick());
#endif
if ( PXI_RecvID() != FIRM_PXI_ID_LOAD_ARM9_STATIC ||
#ifdef PROFILE_ENABLE
// 31: after PXI
((profile[pf_cnt++] = PROFILE_PXI_RECV | FIRM_PXI_ID_LOAD_ARM9_STATIC), FALSE) ||
((profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick())), FALSE) ||
#endif
!MI_LoadModule( rh->s.main_ram_address, rh->s.main_size, rh->s.main_static_digest ) )
if ( !MIi_LoadModule(rh->s.main_ram_address, rh->s.main_rom_offset, rh->s.main_size, rh->s.main_static_digest) )
{
return FALSE;
}
#ifdef PROFILE_ENABLE
// 3x: after PXI
profile[pf_cnt++] = (u32)PROFILE_PXI_SEND | FIRM_PXI_ID_AUTH_ARM9_STATIC; // checkpoint
#endif
PXI_NotifyID( FIRM_PXI_ID_AUTH_ARM9_STATIC );
}
// load ARM7 static region
@ -398,21 +448,10 @@ BOOL MI_LoadStatic( void )
pf_cnt = 0x50;
profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick());
#endif
if ( PXI_RecvID() != FIRM_PXI_ID_LOAD_ARM7_STATIC ||
#ifdef PROFILE_ENABLE
// 51: after PXI
((profile[pf_cnt++] = PROFILE_PXI_RECV | FIRM_PXI_ID_LOAD_ARM7_STATIC), FALSE) ||
((profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick())), FALSE) ||
#endif
!MI_LoadModule( rh->s.sub_ram_address, rh->s.sub_size, rh->s.sub_static_digest ) )
if ( !MIi_LoadModule( rh->s.sub_ram_address, rh->s.sub_rom_offset, rh->s.sub_size, rh->s.sub_static_digest ) )
{
return FALSE;
}
#ifdef PROFILE_ENABLE
// 5x: after PXI
profile[pf_cnt++] = (u32)PROFILE_PXI_SEND | FIRM_PXI_ID_AUTH_ARM7_STATIC; // checkpoint
#endif
PXI_NotifyID( FIRM_PXI_ID_AUTH_ARM7_STATIC );
}
// load ARM9 extended static region
@ -423,21 +462,10 @@ BOOL MI_LoadStatic( void )
pf_cnt = 0x70;
profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick());
#endif
if ( PXI_RecvID() != FIRM_PXI_ID_LOAD_ARM9_LTD_STATIC ||
#ifdef PROFILE_ENABLE
// 71: after PXI
((profile[pf_cnt++] = PROFILE_PXI_RECV | FIRM_PXI_ID_LOAD_ARM9_LTD_STATIC), FALSE) ||
((profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick())), FALSE) ||
#endif
!MI_LoadModule( rh->s.main_ltd_ram_address, rh->s.main_ltd_size, rh->s.main_ltd_static_digest ) )
if ( !MIi_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;
}
#ifdef PROFILE_ENABLE
// 7x: after PXI
profile[pf_cnt++] = (u32)PROFILE_PXI_SEND | FIRM_PXI_ID_AUTH_ARM9_LTD_STATIC; // checkpoint
#endif
PXI_NotifyID( FIRM_PXI_ID_AUTH_ARM9_LTD_STATIC );
}
// load ARM7 extended static region
if ( rh->s.sub_ltd_size > 0 )
@ -447,22 +475,17 @@ BOOL MI_LoadStatic( void )
pf_cnt = 0x90;
profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick());
#endif
if ( PXI_RecvID() != FIRM_PXI_ID_LOAD_ARM7_LTD_STATIC ||
#ifdef PROFILE_ENABLE
// 91: after PXI
((profile[pf_cnt++] = PROFILE_PXI_RECV | FIRM_PXI_ID_LOAD_ARM7_LTD_STATIC), FALSE) ||
((profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick())), FALSE) ||
#endif
!MI_LoadModule( rh->s.sub_ltd_ram_address, rh->s.sub_ltd_size, rh->s.sub_ltd_static_digest ) )
if ( !MIi_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;
}
#ifdef PROFILE_ENABLE
// 9x: before PXI
profile[pf_cnt++] = (u32)PROFILE_PXI_SEND | FIRM_PXI_ID_AUTH_ARM7_LTD_STATIC; // checkpoint
#endif
PXI_NotifyID( FIRM_PXI_ID_AUTH_ARM7_LTD_STATIC );
}
#ifdef PROFILE_ENABLE
// 9x: before PXI
profile[pf_cnt++] = (u32)OS_TicksToMicroSeconds(OS_GetTick());
profile[pf_cnt++] = (u32)PROFILE_PXI_SEND | FIRM_PXI_ID_AUTH_STATIC; // checkpoint
#endif
PXI_NotifyID( FIRM_PXI_ID_AUTH_STATIC );
return TRUE;
}