diff --git a/build/libraries/fatfs/ARM7/src/fatfs_loader.c b/build/libraries/fatfs/ARM7/src/fatfs_loader.c index a60b5ab3..a3d141d8 100644 --- a/build/libraries/fatfs/ARM7/src/fatfs_loader.c +++ b/build/libraries/fatfs/ARM7/src/fatfs_loader.c @@ -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; } diff --git a/build/libraries/mi/ARM9/mi_loader.c b/build/libraries/mi/ARM9/mi_loader.c index e9b7ba7e..803976cd 100644 --- a/build/libraries/mi/ARM9/mi_loader.c +++ b/build/libraries/mi/ARM9/mi_loader.c @@ -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境界をまたぐ場合は、2回のLoadBufferに分割します。 + + すでにハッシュ値が分かっていて、ちょうど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; }