(更新:Akabane Jumpei)

・TWLカード対応(KeyTable2は一時的なものをローカルに持つ)
・符号生成回路初期値をRomヘッダを見て変更するようにした

git-svn-id: file:///Users/lillianskinner/Downloads/platinum/twl/TwlIPL/trunk@1082 b08762b0-b915-fc4b-9d8c-17b2551a87ff
This commit is contained in:
(no author) 2008-04-08 10:05:48 +00:00
parent c6817bba98
commit b17524a88a
6 changed files with 683 additions and 239 deletions

View File

@ -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

View File

@ -22,7 +22,8 @@ extern "C" {
#endif
/*************************************************************************/
extern BLOWFISH_CTX GCDi_BlowfishInitTableBufDS;
extern BLOWFISH_CTX HotSwBlowfishInitTableBufDS;
extern BLOWFISH_CTX HotSwBlowfishInitTableTWL;
// Function Prototype ------------------------------------------------------------------------
// Blowfish <20>‰Šú‰»

View File

@ -16,6 +16,7 @@
#include <twl.h>
#include <twl/os/common/format_rom.h>
#include <sysmenu.h>
#include <firm/gcd/blowfish.h>
#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;

View File

@ -1,5 +1,5 @@
/*---------------------------------------------------------------------------*
Project: TwlBrom - libraries - GCD
Project: TwlIPL
File: blowfish.c
Copyright 2007 Nintendo. All rights reserved.
@ -12,6 +12,8 @@
*---------------------------------------------------------------------------*/
#include <twl.h>
#include <blowfish.h>
#include <firm/format/from_firm.h>
#include <firm/hw/ARM7/mmap_firm.h>
#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ŠÖ<C5A0>
//
//*****************************************
/*---------------------------------------------------------------------------*
Name: GCDm_MakeBlowfishTableDS
Description: KeyTableÌ<EFBFBD><EFBFBD>¬
*---------------------------------------------------------------------------*/
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ŠÖ<C5A0>
//
//*****************************************
/*---------------------------------------------------------------------------*
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ŠÖ<C5A0>
//
//*****************************************
/*---------------------------------------------------------------------------*
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ŠÖ<C5A0>
//
//*****************************************
/*---------------------------------------------------------------------------*
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ŠÖ<C5A0>
//
//*****************************************
/*---------------------------------------------------------------------------*
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ŠÖ<C5A0>
//
//*****************************************
/*---------------------------------------------------------------------------*
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;
}

View File

@ -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 <twl/ltdwram_end.h>
@ -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();
// セキュアカードID読み込み
state = s_funcTable[s_cbData.cardType].ReadID_S(&s_cbData);
retval = (retval == HOTSW_SUCCESS) ? state : retval;
// Secure領域の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 <twl/os/common/systemCall.h>
// ----------------------------------------------------------------------
// Arm7常駐モジュールのハッシュチェック
// ----------------------------------------------------------------------
#include <twl/os/common/systemCall.h>
/*---------------------------------------------------------------------------*
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];

View File

@ -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 <hotswTypes.h>
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
};