From b17524a88a4b42e816e188d50d3feb7be4325a27 Mon Sep 17 00:00:00 2001 From: "(no author)" <(no author)@b08762b0-b915-fc4b-9d8c-17b2551a87ff> Date: Tue, 8 Apr 2008 10:05:48 +0000 Subject: [PATCH] =?UTF-8?q?(=E6=9B=B4=E6=96=B0:Akabane=20Jumpei)=20?= =?UTF-8?q?=E3=83=BBTWL=E3=82=AB=E3=83=BC=E3=83=89=E5=AF=BE=E5=BF=9C(KeyTa?= =?UTF-8?q?ble2=E3=81=AF=E4=B8=80=E6=99=82=E7=9A=84=E3=81=AA=E3=82=82?= =?UTF-8?q?=E3=81=AE=E3=82=92=E3=83=AD=E3=83=BC=E3=82=AB=E3=83=AB=E3=81=AB?= =?UTF-8?q?=E6=8C=81=E3=81=A4)=20=E3=83=BB=E7=AC=A6=E5=8F=B7=E7=94=9F?= =?UTF-8?q?=E6=88=90=E5=9B=9E=E8=B7=AF=E5=88=9D=E6=9C=9F=E5=80=A4=E3=82=92?= =?UTF-8?q?Rom=E3=83=98=E3=83=83=E3=83=80=E3=82=92=E8=A6=8B=E3=81=A6?= =?UTF-8?q?=E5=A4=89=E6=9B=B4=E3=81=99=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB?= =?UTF-8?q?=E3=81=97=E3=81=9F?= 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@1082 b08762b0-b915-fc4b-9d8c-17b2551a87ff --- build/libraries_sysmenu/hotsw/ARM7/Makefile | 1 + .../hotsw/ARM7/include/blowfish.h | 3 +- .../hotsw/ARM7/include/hotswTypes.h | 16 +- .../hotsw/ARM7/src/blowfish.c | 86 +-- .../libraries_sysmenu/hotsw/ARM7/src/hotsw.c | 534 +++++++++++------- .../hotsw/ARM7/src/twl_blowfish_table.c | 282 +++++++++ 6 files changed, 683 insertions(+), 239 deletions(-) create mode 100644 build/libraries_sysmenu/hotsw/ARM7/src/twl_blowfish_table.c diff --git a/build/libraries_sysmenu/hotsw/ARM7/Makefile b/build/libraries_sysmenu/hotsw/ARM7/Makefile index e3a6af27..092ee1f6 100644 --- a/build/libraries_sysmenu/hotsw/ARM7/Makefile +++ b/build/libraries_sysmenu/hotsw/ARM7/Makefile @@ -33,6 +33,7 @@ SRCS = blowfish.c \ hotsw.c \ dsCardCommon.c \ romEmulation.c \ + twl_blowfish_table.c \ customNDma.c TARGET_LIB = libhotsw_sp$(TWL_LIBSUFFIX).a diff --git a/build/libraries_sysmenu/hotsw/ARM7/include/blowfish.h b/build/libraries_sysmenu/hotsw/ARM7/include/blowfish.h index 8323aeac..b3d5abea 100644 --- a/build/libraries_sysmenu/hotsw/ARM7/include/blowfish.h +++ b/build/libraries_sysmenu/hotsw/ARM7/include/blowfish.h @@ -22,7 +22,8 @@ extern "C" { #endif /*************************************************************************/ -extern BLOWFISH_CTX GCDi_BlowfishInitTableBufDS; +extern BLOWFISH_CTX HotSwBlowfishInitTableBufDS; +extern BLOWFISH_CTX HotSwBlowfishInitTableTWL; // Function Prototype ------------------------------------------------------------------------ // Blowfish 初期化 diff --git a/build/libraries_sysmenu/hotsw/ARM7/include/hotswTypes.h b/build/libraries_sysmenu/hotsw/ARM7/include/hotswTypes.h index 39e5b52b..5fdb62cb 100644 --- a/build/libraries_sysmenu/hotsw/ARM7/include/hotswTypes.h +++ b/build/libraries_sysmenu/hotsw/ARM7/include/hotswTypes.h @@ -16,6 +16,7 @@ #include #include #include +#include #include "romSpec.h" #ifdef __cplusplus @@ -261,10 +262,10 @@ typedef union BootSegmentData } BootSegmentData; // struct ------------------------------------------------------------------- -typedef struct BLOWFISH_CTX{ +/*typedef struct BLOWFISH_CTX{ u32 P[16 + 2]; u32 S[4][256]; -} BLOWFISH_CTX; +} BLOWFISH_CTX;*/ // カードブート時に必要な変数一式をまとめた構造体 typedef struct CardBootData{ @@ -279,21 +280,20 @@ typedef struct CardBootData{ u32 id_scr2; u32 id_gam; - u32 arm9StcSize; - u32 arm7StcSize; - u32 arm9LtdSize; - u32 arm7LtdSize; - u32 arm9Stc; u32 arm7Stc; u32 arm9Ltd; u32 arm7Ltd; BOOL twlFlg; - + BOOL debuggerFlg; + BOOL illegalCardFlg; + BOOL isLoadTypeTwl; + u32 romStatus; u32 keyBuf[KEY_BUF_SIZE]; + u32 keyBuf2[KEY_BUF_SIZE]; CardTypeEx cardType; ModeType modeType; diff --git a/build/libraries_sysmenu/hotsw/ARM7/src/blowfish.c b/build/libraries_sysmenu/hotsw/ARM7/src/blowfish.c index 609e7fa2..e8b8ca39 100644 --- a/build/libraries_sysmenu/hotsw/ARM7/src/blowfish.c +++ b/build/libraries_sysmenu/hotsw/ARM7/src/blowfish.c @@ -1,5 +1,5 @@ /*---------------------------------------------------------------------------* - Project: TwlBrom - libraries - GCD + Project: TwlIPL File: blowfish.c Copyright 2007 Nintendo. All rights reserved. @@ -12,6 +12,8 @@ *---------------------------------------------------------------------------*/ #include #include +#include +#include #define MAXKEYBYTES 56 /* 448 bits */ #define N 16 @@ -19,14 +21,15 @@ // Function Prototype ------------------------------------------------------- static u32 F(const BLOWFISH_CTX *ctx, u32 x); -//***************************************** -// -// GCDm_MakeBlowfishTableDS関数 -// -//***************************************** + +/*---------------------------------------------------------------------------* + Name: GCDm_MakeBlowfishTableDS + + Description: KeyTableの生成 + *---------------------------------------------------------------------------*/ void GCDm_MakeBlowfishTableDS(CardBootData *cbd, s32 keyLen) { - const BLOWFISH_CTX *initTable = &GCDi_BlowfishInitTableBufDS; + const BLOWFISH_CTX *initTable = &HotSwBlowfishInitTableBufDS; u32 blowfishedKey[2]; @@ -35,7 +38,17 @@ void GCDm_MakeBlowfishTableDS(CardBootData *cbd, s32 keyLen) u32 *keyBuf = cbd->keyBuf; BLOWFISH_CTX *ctx = &cbd->keyTable; - MI_CpuCopyFast((void *)initTable, (void *)ctx, sizeof(BLOWFISH_CTX)); + if(cbd->modeType == HOTSW_MODE1){ + MI_CpuCopyFast((void *)initTable, (void *)ctx, sizeof(BLOWFISH_CTX)); + } + else{ + keyBuf = cbd->keyBuf2; + + MI_CpuCopyFast(&HotSwBlowfishInitTableTWL, (void *)ctx, sizeof(BLOWFISH_CTX)); +// MI_CpuCopyFast((void *)((OSFromFirm7Buf *)HW_FIRM_FROM_FIRM_BUF)->twl_blowfish, (void *)ctx, sizeof(BLOWFISH_CTX)); + + return; + } keyBuf[0] = *RomHeaderGameCode; keyBuf[1] = *RomHeaderGameCode >> 1; @@ -51,11 +64,12 @@ void GCDm_MakeBlowfishTableDS(CardBootData *cbd, s32 keyLen) InitBlowfishKeyAndTableDS(ctx, keyBuf, keyLen); } -//***************************************** -// -// InitBlowfishKeyAndTableDS関数 -// -//***************************************** + +/*---------------------------------------------------------------------------* + Name: InitBlowfishKeyAndTableDS + + Description: + *---------------------------------------------------------------------------*/ void InitBlowfishKeyAndTableDS(BLOWFISH_CTX *ctx, u32 *keyBufp, s32 keyLen) { EncryptByBlowfish(ctx, &(keyBufp)[2], &(keyBufp)[1]); @@ -63,11 +77,12 @@ void InitBlowfishKeyAndTableDS(BLOWFISH_CTX *ctx, u32 *keyBufp, s32 keyLen) InitBlowfish(ctx, (u8 *)keyBufp, keyLen); } -//***************************************** -// -// InitBlowfish関数 -// -//***************************************** + +/*---------------------------------------------------------------------------* + Name: InitBlowfish + + Description: + *---------------------------------------------------------------------------*/ void InitBlowfish(BLOWFISH_CTX *ctx, const unsigned char *key, int keyLen) { int i, j, k; @@ -104,11 +119,12 @@ void InitBlowfish(BLOWFISH_CTX *ctx, const unsigned char *key, int keyLen) } -//***************************************** -// -// EncryptByBlowfish関数 -// -//***************************************** + +/*---------------------------------------------------------------------------* + Name: EncryptByBlowfish + + Description: + *---------------------------------------------------------------------------*/ void EncryptByBlowfish(const BLOWFISH_CTX *ctx, u32 *xl, u32 *xr) { u32 Xl; @@ -140,11 +156,12 @@ void EncryptByBlowfish(const BLOWFISH_CTX *ctx, u32 *xl, u32 *xr) *xr = Xr; } -//***************************************** -// -// DecryptByBlowfish関数 -// -//***************************************** + +/*---------------------------------------------------------------------------* + Name: DecryptByBlowfish + + Description: + *---------------------------------------------------------------------------*/ void DecryptByBlowfish(const BLOWFISH_CTX *ctx, u32 *xl, u32 *xr) { u32 Xl; @@ -178,11 +195,12 @@ void DecryptByBlowfish(const BLOWFISH_CTX *ctx, u32 *xl, u32 *xr) *xr = Xr; } -//***************************************** -// -// F関数 -// -//***************************************** + +/*---------------------------------------------------------------------------* + Name: F + + Description: + *---------------------------------------------------------------------------*/ static u32 F(const BLOWFISH_CTX *ctx, u32 x) { u32 a, b, c, d; u32 y; @@ -205,5 +223,3 @@ static u32 F(const BLOWFISH_CTX *ctx, u32 x) { return y; } - - diff --git a/build/libraries_sysmenu/hotsw/ARM7/src/hotsw.c b/build/libraries_sysmenu/hotsw/ARM7/src/hotsw.c index b09e9f05..71edadea 100644 --- a/build/libraries_sysmenu/hotsw/ARM7/src/hotsw.c +++ b/build/libraries_sysmenu/hotsw/ARM7/src/hotsw.c @@ -29,8 +29,8 @@ //#define HOWSW_TRY_DEEP_SLEEP_WHILE_INSERT_CARD // define ------------------------------------------------------------------- -#define CHATTERING_COUNTER 0x600 -#define COUNTER_A 0x100 +#define CHATTERING_COUNTER 0x1988 // 100ms分 (0x1988 * 15.3us = 100000us) +#define COUNTER_A 0x51C // 20ms分 ( 0x51C * 15.3us = 20012us) #define UNDEF_CODE 0xe7ffdeff // 未定義コード #define ENCRYPT_DEF_SIZE 0x800 // 2KB ※ ARM9常駐モジュール先頭2KB @@ -75,6 +75,8 @@ static void McPowerOn(void); static void McPowerOff(void); static void SetMCSCR(void); +static BOOL isTwlModeLoad(void); + static void GenVA_VB_VD(void); static HotSwState DecryptObjectFile(void); static HotSwState LoadBannerData(void); @@ -82,6 +84,8 @@ static HotSwState LoadStaticModule(void); static HotSwState LoadCardData(void); static HotSwState CheckCardAuthCode(void); +static HotSwState CheckStaticModuleHash(void); + static s32 LockExCard(u16 lockID); static s32 UnlockExCard(u16 lockID); @@ -103,6 +107,7 @@ static char encrypt_object_key[] ATTRIBUTE_ALIGN(4) = "encryObj"; static u16 s_RscLockID; static u16 s_CardLockID; +static u16 s_bondingOp; static u32 s_BootSegBufSize, s_SecureSegBufSize, s_Secure2SegBufSize; @@ -114,6 +119,9 @@ static CardBootData s_cbData; static SYSMRomEmuInfo s_romEmuInfo; static BOOL debuggerFlg; +static BOOL s_IsPulledOut = TRUE; +static BOOL s_isHotSwBusy = FALSE; + // HMACSHA1の鍵 static u8 s_digestDefaultKey[ DIGEST_HASH_BLOCK_SIZE_SHA1 ] = { 0x21, 0x06, 0xc0, 0xde, @@ -157,7 +165,7 @@ static CardBootFunction s_funcTable[] = { }; // Global Values ------------------------------------------------------------ -BLOWFISH_CTX GCDi_BlowfishInitTableBufDS; +BLOWFISH_CTX HotSwBlowfishInitTableBufDS; CardThreadData HotSwThreadData; #include @@ -165,10 +173,11 @@ CardThreadData HotSwThreadData; // =========================================================================== // Function Describe // =========================================================================== + /*---------------------------------------------------------------------------* Name: HOTSW_Init - Arguments: None. - Returns: None. + + Description: *---------------------------------------------------------------------------*/ void HOTSW_Init(u32 threadPrio) { @@ -177,7 +186,7 @@ void HOTSW_Init(u32 threadPrio) #ifndef USE_LOCAL_KEYTABLE // 初期化後に他の用途でWRAM_0を使用できるようにローカルバッファへコピーしておく - MI_CpuCopyFast((void *)HW_WRAM_0_LTD, &GCDi_BlowfishInitTableBufDS, sizeof(BLOWFISH_CTX)); + MI_CpuCopyFast((void *)HW_WRAM_0_LTD, &HotSwBlowfishInitTableBufDS, sizeof(BLOWFISH_CTX)); #endif // PXI初期化 PXI_Init(); @@ -190,17 +199,12 @@ void HOTSW_Init(u32 threadPrio) (void)OS_EnableIrq(); (void)OS_EnableInterrupts(); -#ifdef SDK_ARM7 // チャッタリングカウンタの値を設定 reg_MI_MC1 = (u32)((reg_MI_MC1 & ~REG_MI_MC1_CC_MASK) | (CHATTERING_COUNTER << REG_MI_MC1_CC_SHIFT)); // Counter-Aの値を設定 reg_MI_MC2 = COUNTER_A; -#else - // PXI経由でARM7にチャッタリングカウンタ・カウンタAの値を設定してもらう。設定されるまで待つ。 - -#endif // カードブート用構造体の初期化 MI_CpuClear8(&s_cbData, sizeof(CardBootData)); @@ -264,14 +268,15 @@ void HOTSW_Init(u32 threadPrio) } } -/* ----------------------------------------------------------------- - * LoadCardData関数 - * - * カードからデータをロードする - * - * ※BootSegmentBuffer SecureSegmentBufferの設定を行ってから - * この関数を呼んでください。 - * ----------------------------------------------------------------- */ + +/*---------------------------------------------------------------------------* + Name: LoadCardData + + Description: カードからデータをロードする + + ※BootSegmentBuffer SecureSegmentBufferの設定を行ってから + この関数を呼んでください。 + *---------------------------------------------------------------------------*/ static HotSwState LoadCardData(void) { OSTick start; @@ -289,20 +294,16 @@ static HotSwState LoadCardData(void) #endif // カード電源リセット -#ifdef SDK_ARM7 McPowerOff(); #ifndef HOWSW_TRY_DEEP_SLEEP_WHILE_INSERT_CARD MCU_EnableDeepSleepToPowerLine( MCU_PWR_LINE_33, FALSE ); #endif McPowerOn(); -#else // SDK_ARM9 - // ARM7にPXI経由でカード電源ONをお願い。ONになるまで待つ。 - -#endif // バッファを設定 s_cbData.pBootSegBuf = s_pBootSegBuffer; s_cbData.pSecureSegBuf = s_pSecureSegBuffer; + s_cbData.pSecure2SegBuf= s_pSecure2SegBuffer; // ロード処理開始 if(HOTSW_IsCardAccessible()){ @@ -430,6 +431,53 @@ static HotSwState LoadCardData(void) retval = (retval == HOTSW_SUCCESS) ? state : retval; } + // ★TWLカード対応 一旦リセット後Secure2モードに移行 + // SCFG + if((s_cbData.isLoadTypeTwl = isTwlModeLoad()) == TRUE){ + OS_PutString("Read Mode : TwlCard\n"); + + // Mode2に移行する準備 + s_cbData.modeType = HOTSW_MODE2; + + // ---------------------- Reset ---------------------- + McPowerOff(); + McPowerOn(); + + // ---------------------- Normal Mode ---------------------- + state = ReadIDNormal(&s_cbData); + retval = (retval == HOTSW_SUCCESS) ? state : retval; + + // 先頭1Page分だけでOK。データは読み捨てバッファに + state = ReadBootSegNormal(&s_cbData); + retval = (retval == HOTSW_SUCCESS) ? state : retval; + + // Key Table初期化 + GCDm_MakeBlowfishTableDS(&s_cbData, 8); + + // コマンド認証値・コマンドカウンタ初期値・PNジェネレータ初期値の生成 + GenVA_VB_VD(); + + // セキュア2モードに移行 + state = ChangeModeNormal2(&s_cbData); + retval = (retval == HOTSW_SUCCESS) ? state : retval; + + // ---------------------- Secure2 Mode ---------------------- + // PNG設定 + state = s_funcTable[s_cbData.cardType].SetPNG_S(&s_cbData); + retval = (retval == HOTSW_SUCCESS) ? state : retval; + + // DS側符号生成回路初期値設定 (レジスタ設定) + SetMCSCR(); + + // セキュア2カードID読み込み + state = s_funcTable[s_cbData.cardType].ReadID_S(&s_cbData); + retval = (retval == HOTSW_SUCCESS) ? state : retval; + + // Secure2領域のSegment読み込み + state = s_funcTable[s_cbData.cardType].ReadSegment_S(&s_cbData); + retval = (retval == HOTSW_SUCCESS) ? state : retval; + } + // ゲームモードに移行 state = s_funcTable[s_cbData.cardType].ChangeMode_S(&s_cbData); retval = (retval == HOTSW_SUCCESS) ? state : retval; @@ -486,10 +534,10 @@ end: } // カードDMA終了確認 - while( MI_IsNDmaBusy(HOTSW_NDMA_NO) == TRUE ){} + HOTSW_WaitDmaCtrl(HOTSW_NDMA_NO); // カードアクセス終了確認 - while( reg_HOTSW_MCCNT1 & REG_MI_MCCNT1_START_MASK ){} + HOTSW_WaitCardCtrl(); // カードのロック開放(※ロックIDは開放せずに持ち続ける) #ifndef DEBUG_USED_CARD_SLOT_B_ @@ -503,11 +551,74 @@ end: return retval; } -/* ----------------------------------------------------------------- - * HOTSWi_RefreshBadBlock関数 - * - * ノーマルモードまたはゲームモードでバッドブロックを置換 - * ----------------------------------------------------------------- */ + +/*---------------------------------------------------------------------------* + Name: isTwlModeLoad + + Description: カードのロードをTWLモードで行うかDSモードで行うかを決める + + + ■ Bonding Op = 0 (製品版) + ソフトウェア |     DSカード | TWLカード + ------------------------------------------------------------------------ + DS用 | DSカード読みシーケンス | DSカード読みシーケンス(※1) + TWL用 | 不正カードフラグ立て | TWLカード読みシーケンス + ハイブリット | 不正カードフラグ立て | TWLカード読みシーケンス + + ■ Bonding Op = 0以外 (開発用) + ソフトウェア |     DSカード | TWLカード + ------------------------------------------------------------------------ + DS用 | DSカード読みシーケンス | DSカード読みシーケンス(※1) + TWL用 | DSカード読みシーケンス | TWLカード読みシーケンス + ハイブリット | DSカード読みシーケンス | TWLカード読みシーケンス + + + ※1 [TODO] 動作に関してはカードGと相談して決める + *---------------------------------------------------------------------------*/ +static BOOL isTwlModeLoad(void) +{ + // TWLカード + if(s_cbData.id_nml & HOTSW_ROMID_TWLROM_MASK){ + // PlatformCodeがTwl or Hybridの場合 + if(s_cbData.pBootSegBuf->rh.s.platform_code & 0x02){ + OS_PutString("TWL Card : TWL Application : Read Sequence -> TWL\n"); + return TRUE; + } + else{ + // [TODO] 仕様確認 + OS_PutString("TWL Card : NTR Application : Read Sequence -> NTR\n"); + return FALSE; + } + } + // DSカード + else{ + // 製品版の場合 + if(s_bondingOp == SCFG_OP_PRODUCT){ + // PlatformCodeがTwl or Hybridの場合 + if(s_cbData.pBootSegBuf->rh.s.platform_code & 0x02){ + OS_PutString("NTR Card : TWL Application : Illegal Card\n"); + s_cbData.illegalCardFlg = TRUE; + return FALSE; + } + else{ + OS_PutString("NTR Card : NTR Application : Read Sequence -> NTR\n"); + return FALSE; + } + } + // 開発用の場合 + else{ + OS_PutString("Bonding Option Development : NTR Card : Read Sequence -> NTR\n"); + return FALSE; + } + } +} + + +/*---------------------------------------------------------------------------* + Name: HOTSWi_RefreshBadBlock + + Description: ノーマルモードまたはゲームモードでバッドブロックを置換 + *---------------------------------------------------------------------------*/ HotSwState HOTSWi_RefreshBadBlock(u32 romMode) { HotSwState retval = HOTSW_SUCCESS; @@ -549,11 +660,12 @@ HotSwState HOTSWi_RefreshBadBlock(u32 romMode) return retval; } -/* ----------------------------------------------------------------- - * HOTSW_GetRomEmulationBuffer関数 - * - * Romエミュレーション情報を格納しているバッファへのポインタを返す - * ----------------------------------------------------------------- */ + +/*---------------------------------------------------------------------------* + Name: HOTSW_GetRomEmulationBuffer + + Description: Romエミュレーション情報を格納しているバッファへのポインタを返す + *---------------------------------------------------------------------------*/ void* HOTSW_GetRomEmulationBuffer(void) { return &s_romEmuInfo; @@ -635,18 +747,21 @@ static HotSwState LoadBannerData(void) return retval; } -/* ----------------------------------------------------------------- - * LoadStaticModule関数 - * - * ARM7,9の常駐モジュールを展開する関数 - * - * 注:一度カードブートしてゲームモードになってから呼び出してください - * ----------------------------------------------------------------- */ + +/*---------------------------------------------------------------------------* + Name: LoadStaticModule + + Description: ARM7,9の常駐モジュールを展開する関数 + + 注:ゲームモードになってから呼び出してください + *---------------------------------------------------------------------------*/ static HotSwState LoadStaticModule(void) { HotSwState retval = HOTSW_SUCCESS; HotSwState state = HOTSW_SUCCESS; - u32 arm9StcEnd = s_cbData.pBootSegBuf->rh.s.main_rom_offset + s_cbData.pBootSegBuf->rh.s.main_size; + u32 arm9StcEnd = s_cbData.pBootSegBuf->rh.s.main_rom_offset + s_cbData.pBootSegBuf->rh.s.main_size; + u32 arm9LtdStcEnd = s_cbData.pBootSegBuf->rh.s.main_ltd_rom_offset + s_cbData.pBootSegBuf->rh.s.main_ltd_size; + u32 secure2SegEnd = (u32)(s_cbData.pBootSegBuf->rh.s.twl_card_keytable_area_rom_offset * TWLCARD_BORDER_OFFSET + SECURE_SEGMENT_SIZE); // 配置先と再配置情報を取得 & Arm9の常駐モジュール残りを指定先に転送 s_cbData.arm9Stc = (u32)s_cbData.pBootSegBuf->rh.s.main_ram_address; @@ -657,7 +772,7 @@ static HotSwState LoadStaticModule(void) } } else{ - retval = HOTSW_BUFFER_OVERRUN_ERROR; + retval = (retval == HOTSW_SUCCESS) ? HOTSW_BUFFER_OVERRUN_ERROR : retval; } if(retval != HOTSW_SUCCESS){ return retval; @@ -670,22 +785,26 @@ static HotSwState LoadStaticModule(void) retval = (retval == HOTSW_SUCCESS) ? state : retval; } else{ - retval = HOTSW_BUFFER_OVERRUN_ERROR; + retval = (retval == HOTSW_SUCCESS) ? HOTSW_BUFFER_OVERRUN_ERROR : retval; } if(retval != HOTSW_SUCCESS){ return retval; } - // [TODO] TWLカード対応 (※ 拡張領域の境界はRomHeaderの値で計算する) + // 拡張常駐モジュールの読み込み if( s_cbData.twlFlg ) { u32 size = ( s_cbData.pBootSegBuf->rh.s.main_ltd_size < SECURE_SEGMENT_SIZE ) ? s_cbData.pBootSegBuf->rh.s.main_ltd_size : SECURE_SEGMENT_SIZE; s_cbData.arm9Ltd = (u32)s_cbData.pBootSegBuf->rh.s.main_ltd_ram_address; // 配置先と再配置情報を取得 & Arm9の常駐モジュールを指定先に転送 if(SYSM_CheckLoadRegionAndSetRelocateInfo( ARM9_LTD_STATIC, &s_cbData.arm9Ltd, s_cbData.pBootSegBuf->rh.s.main_ltd_size, &SYSMi_GetWork()->romRelocateInfo[ARM9_LTD_STATIC] , TRUE)){ - state = ReadPageGame(&s_cbData, s_cbData.pBootSegBuf->rh.s.main_ltd_rom_offset, (u32 *)SYSM_CARD_TWL_SECURE_BUF, MATH_ROUNDUP( size, 16 ) ); - retval = (retval == HOTSW_SUCCESS) ? state : retval; + if(!s_cbData.isLoadTypeTwl){ + // Secure2領域読み + state = ReadPageGame(&s_cbData, s_cbData.pBootSegBuf->rh.s.main_ltd_rom_offset, (u32 *)SYSM_CARD_TWL_SECURE_BUF, MATH_ROUNDUP( size, 16 )); + retval = (retval == HOTSW_SUCCESS) ? state : retval; + } + // (Arm9Ltd領域 - Secure2領域)分の読み込み if( s_cbData.pBootSegBuf->rh.s.main_ltd_size > SECURE_SEGMENT_SIZE ) { state = ReadPageGame(&s_cbData, s_cbData.pBootSegBuf->rh.s.main_ltd_rom_offset + SECURE_SEGMENT_SIZE, (u32 *)(s_cbData.arm9Ltd + SECURE_SEGMENT_SIZE), @@ -694,7 +813,7 @@ static HotSwState LoadStaticModule(void) } } else{ - retval = HOTSW_BUFFER_OVERRUN_ERROR; + retval = (retval == HOTSW_SUCCESS) ? HOTSW_BUFFER_OVERRUN_ERROR : retval; } if(retval != HOTSW_SUCCESS){ @@ -708,7 +827,7 @@ static HotSwState LoadStaticModule(void) retval = (retval == HOTSW_SUCCESS) ? state : retval; } else{ - retval = HOTSW_BUFFER_OVERRUN_ERROR; + retval = (retval == HOTSW_SUCCESS) ? HOTSW_BUFFER_OVERRUN_ERROR : retval; } if(retval != HOTSW_SUCCESS){ return retval; @@ -734,45 +853,21 @@ static HotSwState LoadStaticModule(void) UnlockHotSwRsc(&SYSMi_GetWork()->lockHotSW); } -//#define MY_DEBUG +#define MY_DEBUG #ifdef MY_DEBUG - // Arm9常駐モジュール Hash値のチェック - if(!CheckArm9HashValue()){ - state = HOTSW_HASH_CHECK_ERROR; - OS_PutString("×Arm9 Static Module Hash Check Error...\n"); - } - - // Arm7常駐モジュール Hash値のチェック - if(!CheckArm7HashValue()){ - state = HOTSW_HASH_CHECK_ERROR; - OS_PutString("×Arm7 Static Module Hash Check Error...\n"); - } - - // Arm9拡張常駐モジュール Hash値のチェック - if(!CheckExtArm9HashValue()){ - state = HOTSW_HASH_CHECK_ERROR; - OS_PutString("×Arm9 Ltd Static Module Hash Check Error...\n"); - } - - // Arm7拡張常駐モジュール Hash値のチェック - if(!CheckExtArm7HashValue()){ - state = HOTSW_HASH_CHECK_ERROR; - OS_PutString("×Arm7 Ltd Static Module Hash Check Error...\n"); - } - retval = (retval == HOTSW_SUCCESS) ? state : retval; + (void)CheckStaticModuleHash(); #endif } return retval; } -/* ----------------------------------------------------------------- - * CheckCardAuthCode関数 - * - * Rom Headerの認証コードアドレスを読んで、クローンブート対応か判定する - * - * 注:カードブート処理中は呼び出さないようにする - * ----------------------------------------------------------------- */ + +/*---------------------------------------------------------------------------* + Name: CheckCardAuthCode + + Description: Rom Headerの認証コードアドレスを読んで、クローンブート対応か判定する + *---------------------------------------------------------------------------*/ static HotSwState CheckCardAuthCode(void) { u32 authBuf[PAGE_SIZE/sizeof(u32)]; @@ -851,11 +946,12 @@ void HOTSW_SetSecureSegmentBuffer(ModeType type ,void* buf, u32 size) } } -/* ----------------------------------------------------------------- - * GenVA_VB_VD関数 - * - * コマンド認証値・コマンドカウンタ・PNジェネレータ初期値の生成 - * ----------------------------------------------------------------- */ + +/*---------------------------------------------------------------------------* + Name: GenVA_VB_VD + + Description: コマンド認証値・コマンドカウンタ・PNジェネレータ初期値の生成 + *---------------------------------------------------------------------------*/ static void GenVA_VB_VD(void) { u32 dummy = 0; @@ -880,14 +976,14 @@ static void GenVA_VB_VD(void) s_cbData.vd &= 0xffffff; } -/* ----------------------------------------------------------------- - * DecryptObjectFile関数 - * - * セキュア領域先頭2KBの暗号化領域を復号化 - * - * 注:セキュアモード中、またはセキュアモード前にこの関数を呼ぶと、 - *   正常にコマンドの暗号化が行えなくなります。 - * ----------------------------------------------------------------- */ + +/*---------------------------------------------------------------------------* + Name: DecryptObjectFile + + Description: セキュア領域先頭2KBの暗号化領域を復号化 + + 注:セキュア領域を読み込んでからこの関数を呼び出してください + *---------------------------------------------------------------------------*/ static u32 encDestBuf[ENCRYPT_DEF_SIZE/sizeof(u32)]; static HotSwState DecryptObjectFile(void) @@ -960,23 +1056,23 @@ static void LockHotSwRsc(OSLockWord* word) } } -/* ----------------------------------------------------------------- - * UnlockHotSwRsc関数 - * - * 共有ワークのリソースの排他制御用 Unlockを行う - * ----------------------------------------------------------------- */ + +/*---------------------------------------------------------------------------* + Name: UnlockHotSwRsc + + Description: 共有ワークのリソースの排他制御用 Unlockを行う + *---------------------------------------------------------------------------*/ static void UnlockHotSwRsc(OSLockWord* word) { OS_UnlockByWord( s_RscLockID, word, NULL ); } -/* ----------------------------------------------------------------- - * HOTSW_IsCardExist関数 - * - * カードの存在判定 - * - * ※SCFG_MC1のCDETフラグを見ている - * ----------------------------------------------------------------- */ + +/*---------------------------------------------------------------------------* + Name: HOTSW_IsCardExist + + Description: SCFG_MC1のCDETフラグを見て、カードの存在判定を行う + *---------------------------------------------------------------------------*/ BOOL HOTSW_IsCardExist(void) { #ifndef DEBUG_USED_CARD_SLOT_B_ @@ -993,13 +1089,12 @@ static void UnlockHotSwRsc(OSLockWord* word) } } -/* ----------------------------------------------------------------- - * HOTSW_IsCardAccessible関数 - * - * カードスロットにアクセスできる状態か判定する - * - * ※SCFG_MC1のCDETフラグとM(モード)を見ている - * ----------------------------------------------------------------- */ + +/*---------------------------------------------------------------------------* + Name: HOTSW_IsCardAccessible + + Description: SCFG_MC1のCDETフラグとM(モード)を見て、カードスロットにアクセスできる状態か判定する + *---------------------------------------------------------------------------*/ BOOL HOTSW_IsCardAccessible(void) { if( HOTSW_IsCardExist() && CmpMcSlotMode(SLOT_STATUS_MODE_10) == TRUE){ @@ -1010,13 +1105,12 @@ BOOL HOTSW_IsCardAccessible(void) } } -/* ----------------------------------------------------------------- - * IsSwap関数 - * - * カードのスワップ判定 - * - * ※SCFG_MC1のSWPフラグを見ている - * ----------------------------------------------------------------- */ + +/*---------------------------------------------------------------------------* + Name: IsSwap + + Description: SCFG_MC1のSWPフラグを見て、スロットがスワップされているか判定する + *---------------------------------------------------------------------------*/ static BOOL IsSwap(void) { if( reg_MI_MC1 & REG_MI_MC1_SWP_MASK ){ @@ -1027,20 +1121,23 @@ static BOOL IsSwap(void) } } -/* ----------------------------------------------------------------- - * GetMcSlotShift関数 - * - * カードスロットのシフトビット数の取得 - * ----------------------------------------------------------------- */ + +/*---------------------------------------------------------------------------* + Name: GetMcSlotShift + + Description: カードスロットのシフトビット数の取得 + *---------------------------------------------------------------------------*/ static u32 GetMcSlotShift(void) { return (u32)(IsSwap() * REG_MI_MC_SL2_CDET_SHIFT); } -/* ----------------------------------------------------------------- - * GetMcSlotMask関数 - * - * カードスロットのシフトビット数の取得 - * ----------------------------------------------------------------- */ + + +/*---------------------------------------------------------------------------* + Name: GetMcSlotMask + + Description: カードスロットのシフトビット数の取得 + *---------------------------------------------------------------------------*/ static u32 GetMcSlotMask(void) { #ifndef DEBUG_USED_CARD_SLOT_B_ @@ -1050,11 +1147,12 @@ static u32 GetMcSlotMask(void) #endif } -/* ----------------------------------------------------------------- - * SetMcSlotMode関数 - * - * カードスロットのモード設定 - * ----------------------------------------------------------------- */ + +/*---------------------------------------------------------------------------* + Name: SetMcSlotMode + + Description: カードスロットのモード設定 + *---------------------------------------------------------------------------*/ static void SetMcSlotMode(u32 mode) { #ifndef DEBUG_USED_CARD_SLOT_B_ @@ -1064,11 +1162,12 @@ static void SetMcSlotMode(u32 mode) #endif } -/* ----------------------------------------------------------------- - * CmpMcSlotMode関数 - * - * カードスロットのモード比較 - * ----------------------------------------------------------------- */ + +/*---------------------------------------------------------------------------* + Name: CmpMcSlotMode + + Description: 引数で与えられてモードと現在のカードスロットのモードを比較 + *---------------------------------------------------------------------------*/ static BOOL CmpMcSlotMode(u32 mode) { #ifndef DEBUG_USED_CARD_SLOT_B_ @@ -1083,10 +1182,11 @@ static BOOL CmpMcSlotMode(u32 mode) } } + /*---------------------------------------------------------------------------* Name: McPowerOn - Description: スロット電源ON関数 + Description: スロット電源ON *---------------------------------------------------------------------------*/ static void McPowerOn(void) { @@ -1098,12 +1198,12 @@ static void McPowerOn(void) if(CmpMcSlotMode(SLOT_STATUS_MODE_00) == TRUE){ // [TODO:]待ち時間は暫定値。金子さんに数値を測定してもらう。 // VDDの安定期間待ち - OS_Sleep(100); +// OS_Sleep(100); // SCFG_MC1 の Slot Status の M1,M0 を 01 にする SetMcSlotMode(SLOT_STATUS_MODE_01); - // 1ms待ち - OS_Sleep(1); + // 3ms待ち + OS_Sleep(3); // SCFG_MC1 の Slot Status の M1,M0 を 10 にする SetMcSlotMode(SLOT_STATUS_MODE_10); @@ -1117,14 +1217,15 @@ static void McPowerOn(void) // [TODO:]待ち時間は暫定値。金子さんに数値を測定してもらう。 // カードへ最初のコマンドを送るまでの待ち時間 - OS_Sleep(100); + OS_Sleep(120); } } + /*---------------------------------------------------------------------------* Name: McPowerOff - Description: スロット電源OFF関数 + Description: スロット電源OFF *---------------------------------------------------------------------------*/ static void McPowerOff(void) { @@ -1195,24 +1296,28 @@ void HOTSWi_TurnCardPowerOn(u32 slot) Description: 符号生成回路初期値設定レジスタを設定する - ※注:この関数はセキュアモードで、 - sPNG_ONコマンドを実行してから呼び出してください。 + ※注:この関数はセキュアモードで、sPNG_ONコマンドを実行してから呼び出してください。 *---------------------------------------------------------------------------*/ static void SetMCSCR(void) { - u32 pna_l = (u32)(PNA_BASE_VALUE | (s_cbData.vd << 15)); - u32 pna_h = (u32)(s_cbData.vd >> 17); - + static u32 pnbL = 0x879b9b05; + static u8 pnbH = 0x5c; + static u8 pnaL1 = 0x60; + static u8 pnaL0Table[8] = { 0xe8, 0x4d, 0x5a, 0xb1, 0x17, 0x8f, 0x99, 0xd5 }; + + u32 pnaL = s_cbData.vd << 15 | pnaL1 << 8 | pnaL0Table[(s_cbData.pBootSegBuf->rh.s.rom_type & 0x7)]; + u8 pnaH = (u8)((s_cbData.vd >> 17) & 0x7f); + // SCR A - reg_HOTSW_MCSCR0 = pna_l; + reg_HOTSW_MCSCR0 = pnaL; // SCR B - reg_HOTSW_MCSCR1 = PNB_L_VALUE; + reg_HOTSW_MCSCR1 = pnbL; // [d0 -d6 ] -> SCR A // [d16-d22] -> SCR B - reg_HOTSW_MCSCR2 = (u32)(pna_h | PNB_H_VALUE << 16); - + reg_HOTSW_MCSCR2 = (u32)(pnaH | pnbH << 16); + // MCCNT1 レジスタ設定 (SCR = 1に) reg_HOTSW_MCCNT1 = SCR_MASK; } @@ -1360,6 +1465,7 @@ static void InterruptCallbackCard(void) OS_PutString("○\n"); } + /*---------------------------------------------------------------------------* Name: InterruptCallbackCardDet @@ -1380,21 +1486,6 @@ static void InterruptCallbackCardDet(void) OS_PutString("●\n"); } -/*---------------------------------------------------------------------------* - Name: InterruptCallbackNDma - - Description: カードB データ転送終了割り込みハンドラ - *---------------------------------------------------------------------------*/ -static void InterruptCallbackNDma(void) -{ - // メッセージ送信 -// OS_SendMessage(&HotSwThreadData.hotswDmaQueue, (OSMessage *)&HotSwThreadData.hotswDmaMsg[HotSwThreadData.idx_dma], OS_MESSAGE_NOBLOCK); - - // メッセージインデックスをインクリメント -// HotSwThreadData.idx_dma = (HotSwThreadData.idx_dma+1) % HOTSW_DMA_MSG_NUM; - - OS_PutString("▽\n"); -} /*---------------------------------------------------------------------------* Name: InterruptCallbackPxi @@ -1420,6 +1511,7 @@ static void InterruptCallbackPxi(PXIFifoTag tag, u32 data, BOOL err) HotSwThreadData.idx_ctrl = (HotSwThreadData.idx_ctrl+1) % HOTSW_CTRL_MSG_NUM; } + /*---------------------------------------------------------------------------* Name: AllocateExCardBus @@ -1433,6 +1525,7 @@ static inline void SetExCardProcessor(MIProcessor proc) } #endif + /*---------------------------------------------------------------------------* Name: AllocateExCardBus @@ -1450,6 +1543,7 @@ static void AllocateExCardBus(void) #endif } + /*---------------------------------------------------------------------------* Name: FreeExCardBus @@ -1462,6 +1556,7 @@ static void FreeExCardBus(void) #endif } + /*---------------------------------------------------------------------------* Name: LockSlotB @@ -1472,6 +1567,7 @@ static s32 LockExCard(u16 lockID) return OS_LockByWord(lockID, (OSLockWord *)SLOT_B_LOCK_BUF, AllocateExCardBus); } + /*---------------------------------------------------------------------------* Name: UnlockSlotB @@ -1482,6 +1578,7 @@ static s32 UnlockExCard(u16 lockID) return OS_UnlockByWord(lockID, (OSLockWord *)SLOT_B_LOCK_BUF, FreeExCardBus); } + /*---------------------------------------------------------------------------* Name: SetInterruptCallback SetInterruptCallbackEx @@ -1500,6 +1597,7 @@ static void SetInterruptCallbackEx( OSIrqMask intr_bit, void *func ) (void)OS_EnableIrqMaskEx(intr_bit); } + /*---------------------------------------------------------------------------* Name: SetInterrupt @@ -1510,25 +1608,62 @@ static void SetInterrupt(void) #ifndef DEBUG_USED_CARD_SLOT_B_ SetInterruptCallback( OS_IE_CARD_A_IREQ , InterruptCallbackCard ); SetInterruptCallback( OS_IE_CARD_A_DET , InterruptCallbackCardDet ); - SetInterruptCallback( OS_IE_NDMA2 , InterruptCallbackNDma ); + (void)OS_EnableIrqMask(OS_IE_NDMA2); #else SetInterruptCallback( OS_IE_CARD_B_IREQ , InterruptCallbackCard ); SetInterruptCallback( OS_IE_CARD_B_DET , InterruptCallbackCardDet ); - SetInterruptCallback( OS_IE_NDMA2 , InterruptCallbackNDma ); + (void)OS_EnableIrqMask(OS_IE_NDMA2); #endif } -/* ----------------------------------------------------------------- - * CheckHashValue関数 - * - * 常駐モジュール・拡張常駐モジュールのハッシュを計算して、 - * カード内のハッシュ値と比べる。 - * ----------------------------------------------------------------- */ -#include -// ---------------------------------------------------------------------- -// Arm7常駐モジュールのハッシュチェック -// ---------------------------------------------------------------------- +#include +/*---------------------------------------------------------------------------* + Name: CheckStaticModuleHash + + Description: 常駐モジュールのハッシュチェックを行う + *---------------------------------------------------------------------------*/ +static HotSwState CheckStaticModuleHash(void) +{ + BOOL flg = TRUE; + + // Arm9常駐モジュール Hash値のチェック + if(!CheckArm9HashValue()){ + flg = FALSE; + OS_PutString("×Arm9 Static Module Hash Check Error...\n"); + } + + // Arm7常駐モジュール Hash値のチェック + if(!CheckArm7HashValue()){ + flg = FALSE; + OS_PutString("×Arm7 Static Module Hash Check Error...\n"); + } + + // Arm9拡張常駐モジュール Hash値のチェック + if(!CheckExtArm9HashValue()){ + flg = FALSE; + OS_PutString("×Arm9 Ltd Static Module Hash Check Error...\n"); + } + + // Arm7拡張常駐モジュール Hash値のチェック + if(!CheckExtArm7HashValue()){ + flg = FALSE; + OS_PutString("×Arm7 Ltd Static Module Hash Check Error...\n"); + } + + if(flg){ + OS_PutString("*** Static Module Load was Completed!!\n"); + } + + return flg ? HOTSW_SUCCESS : HOTSW_HASH_CHECK_ERROR; +} + + +/*---------------------------------------------------------------------------* + Name: CheckArm7HashValue + + Description: Arm7常駐モジュールのハッシュチェック + *---------------------------------------------------------------------------*/ static BOOL CheckArm7HashValue(void) { u8 sha1data[DIGEST_SIZE_SHA1]; @@ -1547,11 +1682,14 @@ static BOOL CheckArm7HashValue(void) return SVC_CompareSHA1( sha1data, s_cbData.pBootSegBuf->rh.s.sub_static_digest ); } -// ---------------------------------------------------------------------- -// Arm9常駐モジュールのハッシュチェック -// -// ※ 先頭2Kの復号化が行われる前のデータのハッシュを比べる -// ---------------------------------------------------------------------- + +/*---------------------------------------------------------------------------* + Name: CheckArm9HashValue + + Description: Arm9常駐モジュールのハッシュチェック + + ※ 先頭2Kの復号化が行われる前のデータのハッシュを比べる + *---------------------------------------------------------------------------*/ static BOOL CheckArm9HashValue(void) { u8 sha1data[DIGEST_SIZE_SHA1]; @@ -1576,9 +1714,12 @@ static BOOL CheckArm9HashValue(void) return SVC_CompareSHA1( sha1data, s_cbData.pBootSegBuf->rh.s.main_static_digest ); } -// ---------------------------------------------------------------------- -// Arm7拡張常駐モジュールのハッシュチェック -// ---------------------------------------------------------------------- + +/*---------------------------------------------------------------------------* + Name: CheckExtArm7HashValue + + Description: Arm7拡張常駐モジュールのハッシュチェック + *---------------------------------------------------------------------------*/ static BOOL CheckExtArm7HashValue(void) { u8 sha1data[DIGEST_SIZE_SHA1]; @@ -1597,9 +1738,12 @@ static BOOL CheckExtArm7HashValue(void) return SVC_CompareSHA1( sha1data, s_cbData.pBootSegBuf->rh.s.sub_ltd_static_digest ); } -// ---------------------------------------------------------------------- -// Arm9拡張常駐モジュールのハッシュチェック -// ---------------------------------------------------------------------- + +/*---------------------------------------------------------------------------* + Name: CheckExtArm9HashValue + + Description: Arm9拡張常駐モジュールのハッシュチェック + *---------------------------------------------------------------------------*/ static BOOL CheckExtArm9HashValue(void) { u8 sha1data[DIGEST_SIZE_SHA1]; diff --git a/build/libraries_sysmenu/hotsw/ARM7/src/twl_blowfish_table.c b/build/libraries_sysmenu/hotsw/ARM7/src/twl_blowfish_table.c new file mode 100644 index 00000000..0b990fc3 --- /dev/null +++ b/build/libraries_sysmenu/hotsw/ARM7/src/twl_blowfish_table.c @@ -0,0 +1,282 @@ +/*---------------------------------------------------------------------------* + Project: TwlIPL + File: twl_blowfish_table.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. + *---------------------------------------------------------------------------*/ +#include + + +const BLOWFISH_CTX HotSwBlowfishInitTableTWL = { + 0x05526369, 0x040B421F, 0x04DAE16B, 0x03222EFA, + 0x05EB3557, 0x0089EBE1, 0x03E13C75, 0x02BD8B6D, + 0x071E6069, 0x0406B0C5, 0x0737814E, 0x04357C20, + 0x06E70543, 0x02D6B325, 0x05F42EDC, 0x075FA408, + 0x058CB61F, 0x0005B115, + + 0x04FB84D7, 0x00835937, 0x074D69B0, 0x03092EF8, + 0x02C477AA, 0x02633C66, 0x021479EB, 0x02BE7290, + 0x04254FE3, 0x041A18DE, 0x0011129E, 0x019209F3, + 0x053751A3, 0x02B46D10, 0x02819FB4, 0x008B2FA5, + 0x0720D1F8, 0x0314C7A2, 0x04B9AE7B, 0x04168028, + 0x01AD742F, 0x02AA9574, 0x05A95800, 0x047A0DA5, + 0x0279F093, 0x06FAA890, 0x06A3A9BD, 0x061142AB, + 0x02D36BB5, 0x07D5B8CB, 0x01D5147F, 0x0185B4F2, + 0x04329CCE, 0x04B1B5D8, 0x06E13A40, 0x04F0898C, + 0x059B5707, 0x072D9FD8, 0x04A6A963, 0x0571C044, + 0x050B1D95, 0x06B8DE98, 0x0253CAFF, 0x040F93D5, + 0x024DE9A5, 0x016159BD, 0x04164C1E, 0x06039C0F, + 0x0162BB3A, 0x037A6F5F, 0x023E1F80, 0x01BEDC47, + 0x02E42CC4, 0x02BA1AD3, 0x009FCD4A, 0x01A09A64, + 0x03D5F72F, 0x002F16F7, 0x061523C2, 0x019EDE98, + 0x02FB4E21, 0x024ABA82, 0x035F324B, 0x043B186D, + 0x046FD0BA, 0x03D84F7D, 0x01519C5F, 0x054FC637, + 0x06443165, 0x00591465, 0x07D4856A, 0x05C847F1, + 0x0749E7A2, 0x017D80EC, 0x0111BF2F, 0x02C920BE, + 0x06D85623, 0x064ADF93, 0x03260CCC, 0x02C0F28D, + 0x005BBE0C, 0x0371F35E, 0x00407119, 0x06075C7B, + 0x06CB6DC2, 0x0031CB12, 0x05220DB5, 0x03D235D9, + 0x0736EB35, 0x0716448C, 0x02B9E4E9, 0x06C408D8, + 0x0282D902, 0x052586A3, 0x0775A47F, 0x056CA10B, + 0x028F164F, 0x03365948, 0x07BBDB4D, 0x034217C7, + 0x00FDF4DB, 0x0278BE82, 0x056B2EE3, 0x003A57F4, + 0x026E44DA, 0x0587D6DF, 0x0699B381, 0x05DD58DD, + 0x0099C34B, 0x07FE334F, 0x061682A1, 0x075F48DC, + 0x05A95910, 0x07C8D2F2, 0x0701F13E, 0x01F92114, + 0x051F55EB, 0x03158B95, 0x06A4CBEB, 0x0688C7D5, + 0x0439631E, 0x006448FE, 0x01AB7B3F, 0x03DCD3B0, + 0x0735B15D, 0x01045A14, 0x047CF4D0, 0x01BFE119, + 0x065976D4, 0x06BF4287, 0x0054D2BF, 0x037E281A, + 0x0474DC3E, 0x01DDF533, 0x07FD249E, 0x0696FF5C, + 0x06FC83EF, 0x00895986, 0x077FAD53, 0x02A0D475, + 0x0589CF47, 0x0463060D, 0x04F58C53, 0x018C0184, + 0x0416EF7F, 0x0148B8E7, 0x00665F46, 0x06B15F0E, + 0x07DD76B3, 0x07592BBE, 0x02C752F9, 0x035B639A, + 0x07B561AB, 0x055A02C1, 0x032C87F4, 0x074DF8C9, + 0x04DE7E08, 0x01779DD0, 0x04B0A183, 0x02CD73F1, + 0x015C106E, 0x070EEBBC, 0x0055BB03, 0x02651FA2, + 0x06CE6DD3, 0x065B3BAC, 0x05B18A61, 0x01843559, + 0x00F1600A, 0x035B2893, 0x0119BA0F, 0x0311E24C, + 0x0076A1DC, 0x075E5486, 0x02651C67, 0x02B0FAB2, + 0x029CED3A, 0x03E9DDAB, 0x03B35437, 0x03D30D6D, + 0x03629908, 0x070B253C, 0x0403FD6E, 0x0631AE1B, + 0x04C6E55B, 0x05CFEA46, 0x00F78239, 0x04C31E56, + 0x02AC48EA, 0x02DA5793, 0x07D7EE80, 0x01A58DD0, + 0x0440BC8E, 0x047FA958, 0x04A120AE, 0x07A48C2F, + 0x0490D631, 0x04205C1B, 0x074491E1, 0x03DC8737, + 0x05AA7B91, 0x028149A0, 0x02D15368, 0x02B857B2, + 0x03352071, 0x013F2B3F, 0x02A32234, 0x00AD5A5F, + 0x02C1BB07, 0x0746B1A8, 0x016F1BC5, 0x008EEC53, + 0x011F6374, 0x0236DEF8, 0x01F5F136, 0x015E1206, + 0x07E815F6, 0x042879C6, 0x033AD57D, 0x0558442A, + 0x0243F9F1, 0x00B50791, 0x04632BED, 0x008CE746, + 0x02BA47B9, 0x04DC953D, 0x0230C520, 0x028B8A44, + 0x034E4AAD, 0x05F4404A, 0x05C02F9A, 0x049C2098, + 0x05738F11, 0x07341FBB, 0x01845FDA, 0x043ED01F, + 0x0497A307, 0x055FF998, 0x04DDD428, 0x05DDFDA4, + 0x07442F72, 0x0607229D, 0x052FD116, 0x00E528D3, + 0x01E3D7AA, 0x02EBBA09, 0x06E3C252, 0x04F17067, + 0x070622BB, 0x0308860B, 0x039D045B, 0x04DD8848, + 0x01D9105D, 0x0389C9AA, 0x00B06AAE, 0x034DCAAC, + + 0x01C5E8E5, 0x02834663, 0x07BC04DB, 0x046C0F43, + 0x05795C2C, 0x00C3A9D0, 0x0698646D, 0x0441E7DA, + 0x0104EC07, 0x04CF09C4, 0x01FA3B1F, 0x07A3A818, + 0x00C3492F, 0x059E41C5, 0x020C91CC, 0x04F45D15, + 0x0462532F, 0x05B0B06B, 0x03B77F77, 0x071208FD, + 0x00BDB01C, 0x068A9386, 0x047F4C10, 0x0028A7F0, + 0x06A27510, 0x056F2B43, 0x0005764C, 0x056E9195, + 0x0267997F, 0x04018898, 0x0535EE95, 0x07027559, + 0x067491B6, 0x02F34209, 0x034E47BB, 0x02E492E6, + 0x013A1C03, 0x0253A5C4, 0x0664E84A, 0x0069A5E6, + 0x000D2E8F, 0x06C4DAA8, 0x06FA8774, 0x04D3A4C8, + 0x02ABC317, 0x05144060, 0x021120E9, 0x072E4B71, + 0x073C25AF, 0x0591407E, 0x00D96350, 0x02DF7B1D, + 0x0025231F, 0x03D6E660, 0x03DC62BF, 0x06F28B61, + 0x02AF873D, 0x077DBF4C, 0x06BC320E, 0x07D9B25B, + 0x079FF100, 0x035304BC, 0x06FB6C25, 0x017E04F0, + 0x04B879DA, 0x02472768, 0x06B05478, 0x07F9296D, + 0x06D3A241, 0x00E9D0EE, 0x06C4FF27, 0x055F65D9, + 0x02551093, 0x04067917, 0x038B524D, 0x07405D23, + 0x053FDCBE, 0x04A6A73D, 0x03529F18, 0x041DCA50, + 0x069A923E, 0x06564436, 0x003CA4E0, 0x07E422B6, + 0x059D37DA, 0x06E48164, 0x0137BA88, 0x038B9355, + 0x008E1D46, 0x005426EA, 0x06B67424, 0x02C58519, + 0x04AF2FE5, 0x0032FC6F, 0x006ED904, 0x0596BDC2, + 0x061A29F2, 0x023A9D03, 0x00439E06, 0x00348DD2, + 0x01DCF8CE, 0x075688E9, 0x04D29E0A, 0x03BD448C, + 0x05AB97F3, 0x050BE3BB, 0x05C07374, 0x01BEB46C, + 0x035D666C, 0x05A7A7FF, 0x0327E38A, 0x05802A3D, + 0x0145D043, 0x0444FF08, 0x03C2E090, 0x042EF1AB, + 0x0620D57B, 0x07F6E013, 0x06FBA530, 0x030C14A8, + 0x01215A38, 0x03BE914A, 0x05FFB3D2, 0x028478DC, + 0x0726564B, 0x00537D65, 0x006161DE, 0x07AEB02B, + 0x020D6D8E, 0x01C4FA66, 0x05F12500, 0x046868EF, + 0x02174F3B, 0x02255533, 0x071AE436, 0x014A54F7, + 0x07DB3334, 0x041BDA53, 0x0283D946, 0x053130DA, + 0x01ABA660, 0x07360D56, 0x0056855C, 0x00CE94BD, + 0x0406CDD9, 0x06E6E008, 0x004D36E0, 0x051C6286, + 0x0270346E, 0x05AD0969, 0x07D0E274, 0x00E5991E, + 0x0286B221, 0x056319CA, 0x0084E10B, 0x050CBD59, + 0x0683D539, 0x034B03AA, 0x069ADBB5, 0x013F16D2, + 0x01EA112A, 0x037C0DB8, 0x070F9266, 0x026BE5C1, + 0x04E4E47C, 0x021DC174, 0x049F4368, 0x030BA52B, + 0x04A7E825, 0x02869122, 0x02986850, 0x02501755, + 0x03B99C06, 0x00960EB8, 0x07DAFE1F, 0x03C1F644, + 0x0423E828, 0x032C4A38, 0x0602F748, 0x06AA625E, + 0x07587950, 0x02964BF0, 0x03A6B633, 0x03627E34, + 0x03BF74E4, 0x03DA2A2F, 0x04AAB440, 0x01028113, + 0x03860A5C, 0x04874576, 0x078C31ED, 0x0048BC9C, + 0x01544842, 0x019922EA, 0x03D13432, 0x072E4602, + 0x05947F38, 0x045059D9, 0x03BCB4B1, 0x04D1196E, + 0x003EA37F, 0x031AB679, 0x049F4941, 0x03B29D99, + 0x048F5356, 0x0776CD4B, 0x0313BA85, 0x0200BBA3, + 0x00B8AB81, 0x005AC364, 0x0454D94F, 0x0097FA8A, + 0x06CF6FF2, 0x02596050, 0x0542E364, 0x00CBF046, + 0x03D9624A, 0x05B68507, 0x04FC61A1, 0x05BE5A73, + 0x023ACFF7, 0x06CFCFE3, 0x02639FBA, 0x057B3C8F, + 0x017CFE6C, 0x01CB94D3, 0x0328D69B, 0x02ECFEE7, + 0x070258F0, 0x021799B6, 0x02FEB4CB, 0x0511A362, + 0x0089C6AB, 0x06A305D4, 0x05B8A852, 0x0231138C, + 0x03C30AB5, 0x043E510D, 0x06565249, 0x0421DCF4, + 0x04D58857, 0x05D10658, 0x05EEA869, 0x04404D1D, + 0x010E0C8F, 0x04B64F11, 0x005E881E, 0x0683A890, + 0x031B0717, 0x02A38461, 0x01EB6C9B, 0x055CE3B8, + 0x0414733D, 0x060C602F, 0x00F033FF, 0x05167B33, + + 0x04A9DC78, 0x0077F324, 0x03791527, 0x062A6309, + 0x03291611, 0x022F9818, 0x07452BDE, 0x06F92768, + 0x010C5DA6, 0x07675065, 0x0332B09A, 0x00856009, + 0x02993788, 0x06F81E49, 0x0036CA92, 0x07AA2EEA, + 0x0458BD2F, 0x004DD8AC, 0x026BEC7E, 0x03278664, + 0x075581CF, 0x01E96321, 0x0113EE6C, 0x04303FCB, + 0x0242F3CA, 0x00B08BDD, 0x050F5CF8, 0x0504A197, + 0x07FE5BFB, 0x07BDF90B, 0x01C65BB1, 0x00921436, + 0x007202F5, 0x04CA4249, 0x034FB69E, 0x0283DB7B, + 0x03C7C61A, 0x06B3EA14, 0x077B885A, 0x07752D31, + 0x037ED1C8, 0x04A5CE3D, 0x06D3F995, 0x00DCC24B, + 0x047072D0, 0x01C166DB, 0x01860647, 0x07489365, + 0x00EE5F88, 0x063F8882, 0x06D77198, 0x0145A590, + 0x0291187A, 0x006E4606, 0x069550A6, 0x06224C8C, + 0x068BB1CE, 0x01519F5D, 0x01F1A883, 0x06309385, + 0x06C653E2, 0x01AB6E47, 0x0541D01E, 0x00A21869, + 0x038F42FA, 0x04F8BCE5, 0x07AC3407, 0x049FC3B5, + 0x07F4902B, 0x03CF9275, 0x05526F3D, 0x05E28B23, + 0x00EEEA3A, 0x03982C33, 0x04124282, 0x0396F250, + 0x0195A14C, 0x072E5EAE, 0x00E6E717, 0x003DC85E, + 0x038B6FF8, 0x04C7B6FE, 0x076F853B, 0x05BAA978, + 0x030EDF53, 0x04F1AEAB, 0x03A3D1B0, 0x0207BA9D, + 0x03928189, 0x006E3DFD, 0x012EDB63, 0x062116C3, + 0x0786305B, 0x065C3FAD, 0x044AE49B, 0x0431138D, + 0x068963C6, 0x07CDC08C, 0x0179CBEE, 0x04E823B2, + 0x03F919C6, 0x04B360F1, 0x06E5AC3C, 0x0540C334, + 0x06A9102C, 0x061CB509, 0x013B8536, 0x00D5B3D6, + 0x04838C80, 0x066308A8, 0x076AE7EA, 0x0613968A, + 0x054EC14E, 0x05BC0854, 0x034602A9, 0x068FB55C, + 0x04D5A55B, 0x02FC18B0, 0x044B9B70, 0x05BF28AF, + 0x07FE89F2, 0x0452207A, 0x03AFAA4F, 0x0288FEA8, + 0x0426C60C, 0x034D6F1D, 0x053EA274, 0x06F5631E, + 0x0349AF3E, 0x048ABC15, 0x026E0937, 0x03C69B8B, + 0x03CA94DE, 0x02F36D84, 0x01ABC96A, 0x01C5C9E1, + 0x05B3C1A6, 0x0025E14B, 0x033E0FD8, 0x07BABDEF, + 0x06FFC780, 0x02ED1E95, 0x04B92564, 0x075B4238, + 0x078FEF49, 0x04A1024B, 0x00AA6C24, 0x01310C32, + 0x067B8D0D, 0x059D38EC, 0x06411603, 0x039D4F50, + 0x0003471B, 0x002F1F45, 0x027AF1F8, 0x061E6850, + 0x055AB734, 0x036E99E3, 0x07014475, 0x069B10C3, + 0x068BE51A, 0x02C006C5, 0x0288E7B8, 0x075B45DB, + 0x016F1C65, 0x03465E48, 0x043C68CA, 0x05E77E8D, + 0x0051F731, 0x012DC2FF, 0x01C11914, 0x02ADA6A1, + 0x02456B10, 0x0365049F, 0x013F80A6, 0x03B4AD28, + 0x01C480E2, 0x06C2F6DB, 0x06512084, 0x00E5DC11, + 0x02DC1915, 0x01840696, 0x034087A0, 0x07C40C20, + 0x03963E03, 0x062BAEE1, 0x07BC9556, 0x02DF2044, + 0x009823EE, 0x027671B0, 0x051C0806, 0x0479E463, + 0x0241414B, 0x0524582B, 0x06077E70, 0x02969905, + 0x01480578, 0x02AF230F, 0x07A9D824, 0x03955F39, + 0x04416164, 0x035E768D, 0x02DBEB41, 0x031AC25E, + 0x01B43DA1, 0x040FF3CC, 0x02B93B42, 0x00D0CD63, + 0x05C34037, 0x05E17F9D, 0x06D4006B, 0x06216274, + 0x00536CF2, 0x003C9402, 0x006B6BCA, 0x02C4975A, + 0x022B10A4, 0x05711925, 0x0155CE98, 0x038C6B67, + 0x02A06A0C, 0x060FAC1C, 0x02AB5B25, 0x038FB9A3, + 0x011261EC, 0x00A391B5, 0x07DB8671, 0x04FA631C, + 0x0739EFBE, 0x06EDC12A, 0x04F4C770, 0x003DD114, + 0x00888C03, 0x00FFF95C, 0x02EFBD4E, 0x029C2CCC, + 0x02D3F3C3, 0x029B853C, 0x02603C10, 0x00F8431D, + 0x03250BE4, 0x0460FEF8, 0x0250E2D5, 0x0439722E, + 0x02513A6E, 0x05D82FCD, 0x064894C2, 0x05492769, + 0x03266680, 0x047E0475, 0x02FA0EB6, 0x06BA3C61, + 0x047FA9A9, 0x02C1A9FE, 0x025ACFB7, 0x02985ED2, + + 0x04441BAC, 0x060D6E18, 0x04D5A4D7, 0x042A7F2E, + 0x06902DAB, 0x00E87B20, 0x017F6ECE, 0x0134312A, + 0x054D7CCE, 0x04C49F48, 0x03E33BA0, 0x00990CF1, + 0x00BD21BD, 0x01466B0D, 0x0702E278, 0x038ED06C, + 0x04BC7EB9, 0x07D59BF7, 0x04572039, 0x02C0EF14, + 0x00B3DEDC, 0x0560B71B, 0x04EE3D97, 0x018816E1, + 0x06185D9B, 0x01D91E3E, 0x0333A02E, 0x0287192F, + 0x02052CC5, 0x06E702F5, 0x044385D7, 0x03C0D8EC, + 0x03EAA772, 0x0495D684, 0x029CBCAD, 0x051DB4F4, + 0x0413BD8A, 0x057B06E4, 0x02650B62, 0x04683194, + 0x07CDCE28, 0x05815B81, 0x02BF630C, 0x0408C8CD, + 0x07F1D99C, 0x04D9DB4D, 0x07E2FCA1, 0x067F15BE, + 0x034C32D2, 0x07A5E06F, 0x0349D642, 0x06475323, + 0x05104EAB, 0x04FD4462, 0x03750461, 0x02B1D943, + 0x061EA9C7, 0x067BC97D, 0x02619A6B, 0x0654F1A7, + 0x0153E670, 0x00E597C0, 0x05F234AB, 0x04F7C459, + 0x026DD557, 0x06A0FC01, 0x0705E313, 0x05056DFE, + 0x018DD524, 0x033F7EBE, 0x02075A2E, 0x05BF99F2, + 0x00AA1078, 0x00C6B82E, 0x0194A559, 0x06AC62BB, + 0x03187480, 0x024316BE, 0x035B674C, 0x069C78DA, + 0x0698BE5B, 0x079353F3, 0x02AE3CD4, 0x00CAC9D4, + 0x006DBF93, 0x061BCE6F, 0x04B74C88, 0x07E0113E, + 0x013EC74C, 0x035AD6BE, 0x0360215D, 0x07F3B0E0, + 0x01B37B6A, 0x05B2A0CC, 0x03D32F5D, 0x016BB94D, + 0x01A374D1, 0x06A8F973, 0x0181AC19, 0x04176B01, + 0x0785C98E, 0x0013DB53, 0x075247CE, 0x0767FF49, + 0x00B29434, 0x061FDEB3, 0x05C57CF0, 0x07D1FDA2, + 0x030968E5, 0x01C01BA4, 0x03BAC374, 0x0744CDE1, + 0x07E9CDBA, 0x0199E71A, 0x012481EA, 0x07D1712E, + 0x01CD4CCB, 0x01377B6D, 0x05605B0E, 0x002FEAD2, + 0x02B2337B, 0x07622D30, 0x00A04AD9, 0x02D3BE46, + 0x07F02949, 0x0424A261, 0x076585B5, 0x078816BE, + 0x07154117, 0x01C11842, 0x050029F9, 0x07928B4E, + 0x04F89976, 0x0458082C, 0x0119CF5D, 0x01B54C8A, + 0x04F5282C, 0x02095F82, 0x01DFDB26, 0x06B7BC89, + 0x0582A656, 0x075A623D, 0x04BDB794, 0x0637A962, + 0x057A662D, 0x046B8EC7, 0x0621680F, 0x025175A7, + 0x0021CB4A, 0x009B3215, 0x015F1CAD, 0x06589BDD, + 0x06C0168B, 0x0362B7F9, 0x07300782, 0x06B22353, + 0x06540788, 0x01160327, 0x023E8711, 0x05014033, + 0x000405D7, 0x028C4AD2, 0x0236D242, 0x05F2E721, + 0x067CF60A, 0x05BB8ACD, 0x0060EF1A, 0x05AC708E, + 0x07E2BC7D, 0x07C99786, 0x00E49260, 0x01E5411A, + 0x047D51FB, 0x05CD01A8, 0x071081EB, 0x04CD0F64, + 0x039818D2, 0x0333096C, 0x04B686D1, 0x0399D633, + 0x0774C73D, 0x07CE7E4A, 0x03E8FB45, 0x07F00496, + 0x07909622, 0x047701B7, 0x0527C8D1, 0x07E9318D, + 0x00629C06, 0x00C79873, 0x024C1C1C, 0x0743B797, + 0x05B1E662, 0x01542F00, 0x02AC058C, 0x0178AE04, + 0x0153DC07, 0x07D617F5, 0x05BC22B3, 0x054658D6, + 0x07E328D1, 0x04769750, 0x041DCC6A, 0x04C55E9F, + 0x025F562F, 0x012AD3D9, 0x07E16C24, 0x079177C2, + 0x04FCA8EF, 0x02D93386, 0x05161E69, 0x06B39D9D, + 0x008699E0, 0x0405519F, 0x029FB6BA, 0x038F33FF, + 0x0443ED1D, 0x04608C08, 0x02426B87, 0x0662A078, + 0x05A748EC, 0x0305A6CE, 0x04E1841B, 0x0171FE26, + 0x057ADCFA, 0x00F46C0A, 0x00052EC8, 0x051F0984, + 0x06E385FF, 0x01173F10, 0x05166DF2, 0x07793AE8, + 0x013C3393, 0x006135F5, 0x06C00900, 0x04D5F763, + 0x02C7993D, 0x07049AEE, 0x0272F2BD, 0x021D5CB5, + 0x05A53EFE, 0x06466AB1, 0x077FDD2B, 0x03976DA3, + 0x05EEBAC3, 0x0315E29B, 0x000D8D97, 0x00E0292F, + 0x01AC4A30, 0x05D468EA, 0x07F92E7A, 0x04790EB8, + 0x00416DE1, 0x01C0269C, 0x06564FC0, 0x064D8FD1 +};