間違ってコミットしたので削除

git-svn-id: file:///Users/lillianskinner/Downloads/platinum/twl/TwlIPL/trunk@859 b08762b0-b915-fc4b-9d8c-17b2551a87ff
This commit is contained in:
yutaka 2008-03-11 10:18:13 +00:00
parent cb1539af2f
commit c28799559f
9 changed files with 0 additions and 1701 deletions

View File

@ -1,207 +0,0 @@
#----------------------------------------------------------------------------
# Project: TwlSDK - include
# File: ROM-TS.rsf
#
# Copyright 2007 Nintendo. All rights reserved.
#
# These coded insructions, statements, and computer programs contain
# proprietary information of Nintendo of America Inc. and/or Nintendo
# Company Ltd., and are protected by Federal copyright law. They may
# not be disclosed to third parties or copied or duplicated in any form,
# in whole or in part, without the prior written consent of Nintendo.
#
# $Date:: $
# $Rev$
# $Author$
#----------------------------------------------------------------------------
#
# TWL ROM SPEC FILE
#
Arm9
{
Static "$(MAKEROM_ARM9:r).TWL.FLX.sbin$(COMPSUFFIX9)"
OverlayDefs "$(MAKEROM_ARM9:r)_defs.TWL.FLX.sbin$(COMPSUFFIX9)"
OverlayTable "$(MAKEROM_ARM9:r)_table.TWL.FLX.sbin$(COMPSUFFIX9)"
Elf "$(MAKEROM_ARM9:r).tef"
}
Arm7
{
Static "$(MAKEROM_ARM7_BASE:r).TWL.FLX.sbin$(COMPSUFFIX7)"
OverlayDefs "$(MAKEROM_ARM7_BASE:r)_defs.TWL.FLX.sbin$(COMPSUFFIX7)"
OverlayTable "$(MAKEROM_ARM7_BASE:r)_table.TWL.FLX.sbin$(COMPSUFFIX7)"
Elf "$(MAKEROM_ARM7_BASE:r).tef"
}
Arm9.Ltd
{
Static "$(MAKEROM_ARM9:r).TWL.LTD.sbin$(COMPSUFFIX9)"
OverlayDefs "$(MAKEROM_ARM9:r)_defs.TWL.LTD.sbin$(COMPSUFFIX9)"
OverlayTable "$(MAKEROM_ARM9:r)_table.TWL.LTD.sbin$(COMPSUFFIX9)"
}
Arm7.Ltd
{
Static "$(MAKEROM_ARM7_BASE:r).TWL.LTD.sbin$(COMPSUFFIX7)"
OverlayDefs "$(MAKEROM_ARM7_BASE:r)_defs.TWL.LTD.sbin$(COMPSUFFIX7)"
OverlayTable "$(MAKEROM_ARM7_BASE:r)_table.TWL.LTD.sbin$(COMPSUFFIX7)"
}
Property
{
###
### Settings for FinalROM
###
#### BEGIN
#
# TITLE NAME: Your product name within 12bytes
#
#TitleName "YourAppName"
#
# MAKER CODE: Your company ID# in 2 ascii words
# issued by NINTENDO
#
#MakerCode "00"
#
# REMASTER VERSION: Mastering version
#
#RomVersion 0
#
# ROM SPEED TYPE: [MROM/1TROM/UNDEFINED]
#
RomSpeedType $(MAKEROM_ROMSPEED)
#
# ROM SIZE: in bit [64M/128M/256M/512M/1G/2G]
#
#RomSize 128M
#RomSize 256M
#
# ROM PADDING: TRUE if finalrom
#
#RomFootPadding TRUE
#
# ROM HEADER TEMPLATE: Provided to every product by NINTENDO
#
#RomHeaderTemplate ./etc/rom_header.template.sbin
#
# BANNER FILE: generated from Banner Spec File
#
#BannerFile ./etc/myGameBanner.bnr
BannerFile $(TWLSDK_ROOT)/include/twl/specfiles/default.bnr
#
# Permit TmpJump: for TWL "ApplicationJump" function
#
#PermitTmpJump FALSE
###
### Setting for TWL
###
#
# Digest parameters:
#
DigestParam 1024 32
#
# WRAM mapping: [MAP_BB_HYB/MAP_BB_LTD/MAP_TS_HYB/MAP_TS_LTD
# MAP2_BB_HYB/MAP2_BB_LTD/MAP2_TS_HYB/MAP2_TS_LTD]
# don't have to edit
#
WramMapping $(MAKEROM_WRAM_MAPPING)
#
# Codec mode:
# don't have to edit
#
CodecMode $(MAKEROM_CODEC_MODE)
#
# Enable Other Type Parental Controls
#OtherParentalControls FALSE
#
# Use WiFiConnection
#WiFiConnection TRUE
###
#### END
}
AppendProperty
{
#
# Publisher : "Nintendo"
# don't have to edit
Publisher Nintendo
#
# Application type : [USER/SYSTEM]
# don't have to edit
AppType User
#
# launch title on the launcher : [TRUE/FALSE]
# don't have to edit
Launch TRUE
#
# Boot allowed Media: [GameCard]
#
Media GameCard
#
# Data only title : [TRUE/FALSE]
# don't have to edit
DataOnly FALSE
#
# Secure title : [TRUE/FALSE]
# don't have to edit
Secure FALSE
#
# GameCode for TitleID : Your GameCode in 4 ascii words
#
#GameCode ABCJ
#
# Public save data size: [16K/32K/64K/128K/256K/512K/1M/2M/4M/8M]
#
#PublicSaveDataSize 32K
#
# Private save data size: [16K/32K/64K/128K/256K/512K/1M/2M/4M/8M]
#
#PrivateSaveDataSize 16K
#
# Enable SubBannerFile
#SubBannerFile TRUE
}
RomSpec
{
Offset 0x00000000
Segment ALL
HostRoot ../../tools/MakeDSHashTable
Root /sign
File DSHashTable.bin
HostRoot D:/SRL
Root /srl
# File NA22E0.035 # 1st
# File NA22J0.024 # 2nd
# File NYZYE0.E81 # last-1
# File NYZZJ0.L57 # last
File NYRVJ0.J30 # max number of overlaies
File NALKJ1.879 # max overlay size
File NA39J0.357 # mario kart
}

View File

@ -1,41 +0,0 @@
#! make -f
#----------------------------------------------------------------------------
# Project: TwlIPL - tests - CheckDSHashTable
# File: Makefile
#
# Copyright 2008 Nintendo. All rights reserved.
#
# These coded instructions, statements, and computer programs contain
# proprietary information of Nintendo of America Inc. and/or Nintendo
# Company Ltd., and are protected by Federal copyright law. They may
# not be disclosed to third parties or copied or duplicated in any form,
# in whole or in part, without the prior written consent of Nintendo.
#
# $Date:: $
# $Rev$
# $Author$
#----------------------------------------------------------------------------
TARGET_PLATFORM := TWL
TARGET_FIRM := SYSTEMMENU
override TWL_ARCHGEN := LIMITED
SRCS = main.c dht.c
LINCLUDES = include
TARGET_BIN = CheckDSHashTable.srl
ROM_SPEC = CheckDSHashTable.rsf
include $(TWL_IPL_RED_ROOT)/build/buildtools/commondefs
#----------------------------------------------------------------------------
SUBDIRS =
#----------------------------------------------------------------------------
do-build: $(TARGETS)
#----------------------------------------------------------------------------
include $(TWLSDK_ROOT)/build/buildtools/modulerules
#===== End of Makefile =====

View File

@ -1,40 +0,0 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL - DHT
File: dht.h
Copyright 2008 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
#ifndef _DHT_H_
#define _DHT_H_
#include <twl/types.h>
#include <twl/os/common/format_rom.h>
#include <firm/dshashtable.h>
#ifdef __cplusplus
extern "C" {
#endif
BOOL DHT_PrepareDatabase(DHTFile* pDHT);
const DHTDatabase* DHT_GetDatabase(const DHTFile* pDHT, const ROM_Header_Short* pROMHeader);
BOOL DHT_CheckHashPhase1(const DHTDatabase *db, const ROM_Header_Short* pROMHeader, const void* pARM9, const void* pARM7);
BOOL DHT_CheckHashPhase2(const DHTDatabase *db, const ROM_Header_Short* pROMHeader, FSFile* fp, void* buffer);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif // _DHT_H_

View File

@ -1,407 +0,0 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL - DHT
File: dht.c
Copyright 2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
#include <twl.h>
#include <sysmenu/dht/dht.h>
#define HASH_PATH "/sign/DSHashTable.bin"
/*
*/
#define PRINT_PROFILE
#ifdef PRINT_PROFILE
static int count;
static OSTick profile[0x10];
#define PROFILE_INIT() (count = 0)
#define PROFILE_COUNT() (profile[count++] = OS_GetTick())
#else
#define PROFILE_INIT() ((void)0)
#define PROFILE_COUNT() ((void)0)
#define
#endif
static const u8 g_pubkey_DER[ 0xa2 ] = {
0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01,
0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xc7, 0xf4, 0x1d,
0x27, 0x3f, 0xe8, 0xae, 0x7f, 0x7c, 0xbc, 0x9a, 0xae, 0x09, 0x8d, 0x19, 0x26, 0x2e, 0x90, 0x04,
0x03, 0x13, 0x93, 0xbc, 0xb2, 0xe0, 0x8b, 0x1f, 0x85, 0x48, 0xf5, 0xf6, 0x94, 0x69, 0x3e, 0x05,
0x1b, 0x97, 0x85, 0x44, 0x6d, 0xa3, 0xcd, 0xa8, 0x01, 0xfe, 0xdc, 0x77, 0x5d, 0xd1, 0xb1, 0x36,
0x21, 0xfc, 0x80, 0xe8, 0xa6, 0x0e, 0xde, 0x59, 0x76, 0xca, 0x96, 0xcc, 0x87, 0x4c, 0xc3, 0x90,
0xc6, 0x3b, 0xc8, 0x17, 0x9d, 0x2d, 0xac, 0x45, 0xbc, 0xa7, 0x15, 0xb2, 0xe3, 0xd7, 0x76, 0xfa,
0x09, 0x8c, 0x55, 0x09, 0x22, 0x95, 0x4b, 0xe7, 0xde, 0xc0, 0x82, 0xf2, 0x02, 0x1a, 0x8a, 0x42,
0x38, 0x7f, 0xbb, 0x31, 0xd6, 0xa8, 0x36, 0xdc, 0x8d, 0x2c, 0x42, 0x56, 0x51, 0xc1, 0xa3, 0x30,
0x21, 0x30, 0xef, 0x06, 0x72, 0x0c, 0xa6, 0x55, 0xb7, 0x4f, 0x30, 0x35, 0x1b, 0x02, 0x03, 0x01,
0x00, 0x01
};
static const u8 hmac_key[] = DHT_HMAC_KEY;
/*
bsearch
*/
static void *bsearch(const void *key, const void *base,
size_t nmemb, size_t size,
int (*compar)(const void *, const void *))
{
u32 left = 0;
u32 right = nmemb;
if ( compar((u8*)base + size * (right - 1), key) < 0 )
{
return NULL;
}
if ( compar((u8*)base + size * left, key) > 0 )
{
return NULL;
}
while (left <= right)
{
u32 mid = (left + right) >> 1;
const void* data = (u8*)base + size * mid;
int result = compar(data, key);
//OS_TPrintf("left = %d, mid = %d, right = %d\n", left, mid, right);
if ( !result )
{
return (void*)data;
}
if ( result < 0 )
{
left = mid + 1;
}
else
{
right = mid - 1;
}
}
return NULL;
}
static int CompareGameCodeAndVersion(const void* a, const void* b)
{
return MI_CpuComp8(a, b, 5);
}
/*
()
*/
BOOL DHT_PrepareDatabase(DHTFile* pDHT)
{
FSFile file;
u32 length;
s32 result;
SVCSignHeapContext pool;
u8 heap[4*1024];
u8 md1[20];
u8 md2[20];
PROFILE_INIT();
// ファイルオープン
PROFILE_COUNT();
if (!FS_OpenFileEx(&file, HASH_PATH, FS_FILEMODE_R))
{
OS_TPrintf("Cannot open " HASH_PATH ".\n");
return FALSE;
}
// ヘッダ読み込み
PROFILE_COUNT();
result = FS_ReadFile(&file, &pDHT->header, sizeof(DHTHeader));
if ( result != sizeof(DHTHeader) )
{
OS_TPrintf("Cannot read the header of " HASH_PATH " (result=%d).\n", result);
return FALSE;
}
if ( pDHT->header.magic_code != DHT_MAGIC_CODE )
{
OS_TPrintf("Invalid " HASH_PATH " magic code (magic=0x%08X).\n", pDHT->header.magic_code);
return FALSE;
}
// サイズチェック
PROFILE_COUNT();
length = FS_GetFileLength(&file);
if ( length != sizeof(DHTHeader) + pDHT->header.nums * sizeof(DHTDatabase) )
{
OS_TPrintf("Invalid " HASH_PATH " size (%d != %d).\n", length, sizeof(DHTHeader) + pDHT->header.nums * sizeof(DHTDatabase));
return FALSE;
}
// databaseサイズの保存
length = pDHT->header.nums * sizeof(DHTDatabase);
// データベース読み込み
PROFILE_COUNT();
result = FS_ReadFile(&file, pDHT->database, (s32)length);
if ( result != length )
{
OS_TPrintf("Cannot read the database of " HASH_PATH " (result=%d).\n", result);
return FALSE;
}
FS_CloseFile(&file);
// ファイル署名取り出し
PROFILE_COUNT();
SVC_InitSignHeap(&pool, heap, sizeof(heap));
SVC_DecryptSign(&pool, md1, pDHT->header.sign, &g_pubkey_DER[29]);
// ハッシュ計算
PROFILE_COUNT();
SVC_CalcSHA1(md2, DHT_GET_SIGN_TARGET_ADDR(&pDHT->header), DHT_GET_SIGN_TARGET_SIZE(&pDHT->header));
// 検証
PROFILE_COUNT();
result = SVC_CompareSHA1(md1, md2);
if ( !result )
{
OS_TPrintfEx("SIGN = % 20B\n", md1);
OS_TPrintfEx("HASH = % 20B\n", md2);
OS_TPrintf("Signature is not valid.\n");
return FALSE;
}
// 結果報告
#ifdef PRINT_PROFILE
PROFILE_COUNT();
OS_TPrintf("\nDone to prepare the database.\n");
OS_TPrintf("%10d msec for file open.\n", (int)OS_TicksToMilliSeconds(profile[1]-profile[0]));
OS_TPrintf("%10d msec for reading header.\n", (int)OS_TicksToMilliSeconds(profile[2]-profile[1]));
OS_TPrintf("%10d msec for size check.\n", (int)OS_TicksToMilliSeconds(profile[3]-profile[2]));
OS_TPrintf("%10d msec for reading database.\n", (int)OS_TicksToMilliSeconds(profile[4]-profile[3]));
OS_TPrintf("%10d msec for decrypt sign.\n", (int)OS_TicksToMilliSeconds(profile[5]-profile[4]));
OS_TPrintf("%10d msec for hashing database.\n", (int)OS_TicksToMilliSeconds(profile[6]-profile[5]));
OS_TPrintf("%10d msec for comparing hash.\n", (int)OS_TicksToMilliSeconds(profile[7]-profile[6]));
OS_TPrintf("\nTotal: %10d msec.\n", (int)OS_TicksToMilliSeconds(profile[7]-profile[0]));
#endif
return TRUE;
}
/*
ROMヘッダに対応するデータベースを手に入れる
*/
const DHTDatabase* DHT_GetDatabase(const DHTFile* pDHT, const ROM_Header_Short* pROMHeader)
{
u8 data[5];
DHTDatabase* db;
PROFILE_INIT();
// 準備
PROFILE_COUNT();
MI_CpuCopy8( pROMHeader->game_code, data, 4 );
data[4] = pROMHeader->rom_version;
db = (DHTDatabase*)bsearch(data, pDHT->database, pDHT->header.nums, sizeof(DHTDatabase), CompareGameCodeAndVersion);
if ( !db )
{
OS_TPrintf("Cannot find the database.\n");
}
#ifdef PRINT_PROFILE
PROFILE_COUNT();
OS_TPrintf("%10d msec for searching database.\n", (int)OS_TicksToMilliSeconds(profile[1]-profile[0]));
#endif
return db;
}
/*
(1)
*/
BOOL DHT_CheckHashPhase1(const DHTDatabase *db, const ROM_Header_Short* pROMHeader, const void* pARM9, const void* pARM7)
{
SVCHMACSHA1Context ctx;
u8 md[20];
BOOL result;
PROFILE_INIT();
// 準備
PROFILE_COUNT();
SVC_HMACSHA1Init(&ctx, hmac_key, sizeof(hmac_key));
// ヘッダ
PROFILE_COUNT();
SVC_HMACSHA1Update(&ctx, pROMHeader, DHT_DS_HEADER_SIZE);
// ARM9 Static
PROFILE_COUNT();
SVC_HMACSHA1Update(&ctx, pARM9, pROMHeader->main_size);
// ARM7 Static
PROFILE_COUNT();
SVC_HMACSHA1Update(&ctx, pARM7, pROMHeader->sub_size);
// 検証
PROFILE_COUNT();
SVC_HMACSHA1GetHash(&ctx, md);
result = SVC_CompareSHA1(db->hash[0], md);
if ( !result )
{
OS_TPrintfEx("DB = % 20B\n", db->hash[0]);
OS_TPrintfEx("HASH = % 20B\n", md);
OS_TPrintf("%s: hash[0] is not valid.\n", __func__);
}
// 結果報告
#ifdef PRINT_PROFILE
PROFILE_COUNT();
OS_TPrintf("\nDone to chekc the hash (phase 1).\n");
OS_TPrintf("%10d msec for preparing hash.\n", (int)OS_TicksToMilliSeconds(profile[1]-profile[0]));
OS_TPrintf("%10d msec for scanning header.\n", (int)OS_TicksToMilliSeconds(profile[2]-profile[1]));
OS_TPrintf("%10d msec for scanning ARM9.\n", (int)OS_TicksToMilliSeconds(profile[3]-profile[2]));
OS_TPrintf("%10d msec for scanning ARM7.\n", (int)OS_TicksToMilliSeconds(profile[4]-profile[3]));
OS_TPrintf("%10d msec for comparing hash.\n", (int)OS_TicksToMilliSeconds(profile[5]-profile[4]));
OS_TPrintf("\nTotal: %10d msec.\n", (int)OS_TicksToMilliSeconds(profile[5]-profile[0]));
#endif
return result;
}
/*
(2)
FSを用いたテストの場合とCARDアプリの場合で異なる
*/
#if 1
// FS版 (fctx == FSFile*)
static BOOL ReadImage(void* fctx, void* dest, s32 offset, s32 length)
{
FSFile* fp = fctx;
s32 result;
if ( !FS_SeekFile(fp, offset, FS_SEEK_SET) )
{
OS_TPrintf("Cannot seek to the offset (%d bytes).\n", offset);
return FALSE;
}
result = FS_ReadFile(fp, dest, length);
if ( result != length )
{
OS_TPrintf("Cannot read the data (%d bytes).\n", length);
return FALSE;
}
return TRUE;
}
#else
// CARD版 (fctx == dma no)
static BOOL ReadImage(void* fctx, void* dest, s32 offset, s32 length)
{
u32 dma = (u32)fctx;
CARD_ReadRom(dma, (void*)offset, dest, (u32)length);
return TRUE;
}
#endif
static BOOL ImageHMACSHA1Update(SVCHMACSHA1Context* ctx, void* fctx, s32 offset, s32 length, void* buffer)
{
if ( !ReadImage(fctx, buffer, offset, length) )
{
return FALSE;
}
SVC_HMACSHA1Update(ctx, buffer, (u32)length);
return TRUE;
}
static BOOL GetOverlayInfo(int no, void* fctx, int fat_offset, int* pOffset, int* pLength)
{
ROM_FAT fat;
if ( !ReadImage(fctx, &fat, fat_offset + no * (s32)sizeof(ROM_FAT), sizeof(ROM_FAT)) )
{
return FALSE;
}
if ( pOffset )
{
*pOffset = (s32)fat.top.offset;
}
if ( pLength )
{
*pLength = (s32)(fat.bottom.offset - fat.top.offset);
}
return TRUE;
}
BOOL DHT_CheckHashPhase2(const DHTDatabase *db, const ROM_Header_Short* pROMHeader, void* fctx, void* buffer)
{
int overlay_nums = (int)(pROMHeader->main_ovt_size / sizeof(ROM_OVT));
u8 md[20];
PROFILE_INIT();
if ( overlay_nums )
{
SVCHMACSHA1Context ctx;
int total_sectors;
int i;
// 準備
PROFILE_COUNT();
SVC_HMACSHA1Init(&ctx, hmac_key, sizeof(hmac_key));
// OVT
PROFILE_COUNT();
if ( !ImageHMACSHA1Update(&ctx, fctx, (s32)pROMHeader->main_ovt_offset, (s32)pROMHeader->main_ovt_size, buffer) )
{
OS_TPrintf("Cannot calc HMAC-SHA1 for OVT.\n");
return FALSE;
}
// FAT
PROFILE_COUNT();
if ( !ImageHMACSHA1Update(&ctx, fctx, (s32)pROMHeader->fat_offset, overlay_nums * (s32)sizeof(ROM_FAT), buffer) )
{
OS_TPrintf("Cannot calc HMAC-SHA1 for %d of FAT.\n", overlay_nums);
return FALSE;
}
// 各オーバーレイ
PROFILE_COUNT();
total_sectors = 0;
for (i = 0; i < overlay_nums; i++)
{
int max_sectors = (DHT_OVERLAY_MAX/512 - total_sectors) / (overlay_nums - i);
int offset;
int length;
if ( !GetOverlayInfo(i, fctx, (s32)pROMHeader->fat_offset, &offset, &length) )
{
OS_TPrintf("Cannot get %d of overlay info.\n", i);
return FALSE;
}
length = (length + 511) / 512; // bytes -> sectors
if ( length > max_sectors )
{
length = max_sectors;
}
if ( !ImageHMACSHA1Update(&ctx, fctx, offset, length * 512, buffer) )
{
OS_TPrintf("Cannot calc HMAC-SHA1 for %d of overlay.\n", i);
return FALSE;
}
total_sectors += length;
}
// 検証
PROFILE_COUNT();
SVC_HMACSHA1GetHash(&ctx, md);
}
else
{
PROFILE_COUNT();
PROFILE_COUNT();
PROFILE_COUNT();
PROFILE_COUNT();
PROFILE_COUNT();
MI_CpuClear8(md, sizeof(md));
}
if ( !SVC_CompareSHA1(md, db->hash[1]) )
{
OS_TPrintfEx("DB = % 20B\n", db->hash[1]);
OS_TPrintfEx("HASH = % 20B\n", md);
OS_TPrintf("%s: hash[1] is not valid.\n", __func__);
return FALSE;
}
// 結果報告
#ifdef PRINT_PROFILE
PROFILE_COUNT();
OS_TPrintf("\nDone to chekc the hash (phase 2).\n");
OS_TPrintf("%10d msec for preparing hash.\n", (int)OS_TicksToMilliSeconds(profile[1]-profile[0]));
OS_TPrintf("%10d msec for scanning OVT.\n", (int)OS_TicksToMilliSeconds(profile[2]-profile[1]));
OS_TPrintf("%10d msec for scanning FAT.\n", (int)OS_TicksToMilliSeconds(profile[3]-profile[2]));
OS_TPrintf("%10d msec for scanning every overlays.\n", (int)OS_TicksToMilliSeconds(profile[4]-profile[3]));
OS_TPrintf("%10d msec for comparing hash.\n", (int)OS_TicksToMilliSeconds(profile[5]-profile[4]));
OS_TPrintf("\nTotal: %10d msec.\n", (int)OS_TicksToMilliSeconds(profile[5]-profile[0]));
#endif
return TRUE;
}

View File

@ -1,193 +0,0 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL - tests - CheckDSHashTable
File: main.c
Copyright 2008 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
#include <twl.h>
#include <sysmenu/dht/dht.h>
/*
CARD関数の代わりにFS関数で
DHTライブラリが実装されている前提である
*/
#define ROM_PATH "/srl"
#define DS_HASH_TABLE_NUMS 3000
#define DS_HASH_TABLE_SIZE (sizeof(DHTHeader) + DS_HASH_TABLE_NUMS * sizeof(DHTDatabase))
/*
DHTファイル読み込み先
*/
static u8 dht_buffer[DS_HASH_TABLE_SIZE] ATTRIBUTE_ALIGN(32);
static DHTFile *const dht = (DHTFile*)dht_buffer;
/*
Phase2用バッファ
*/
static u8 ov_buffer[DHT_OVERLAY_MAX];
/*
*/
#include <twl/ltdmain_begin.h>
static ROM_Header_Short rom_header ATTRIBUTE_ALIGN(32); // 使うのは DHT_DS_HEADER_SIZE だけ
static u8 rom_arm9[3*1024*1024] ATTRIBUTE_ALIGN(32);
static u8 rom_arm7[1024*1024] ATTRIBUTE_ALIGN(32);
#include <twl/ltdmain_end.h>
static void VBlankIntr( void )
{
OS_SetIrqCheckFlag(OS_IE_V_BLANK);
}
/*
*/
static BOOL CheckValidation(FSFile* fp)
{
const DHTDatabase *db;
s32 result;
// ヘッダの読み込み
result = FS_ReadFile(fp, &rom_header, DHT_DS_HEADER_SIZE);
if ( result != DHT_DS_HEADER_SIZE )
{
OS_TPrintf("Cannot read ROM header.\n");
return FALSE;
}
// ARM9部分
if ( rom_header.main_size > sizeof(rom_arm9) )
{
OS_TPrintf("Too large main size (%d > %d).\n", rom_header.main_size, sizeof(rom_arm9));
return FALSE;
}
if ( !FS_SeekFile(fp, (s32)rom_header.main_rom_offset, FS_SEEK_SET) )
{
OS_TPrintf("Cannot seek to ARM9 static.\n");
return FALSE;
}
result = FS_ReadFile(fp, rom_arm9, (s32)rom_header.main_size);
if ( result != rom_header.main_size )
{
OS_TPrintf("Cannot read ARM9 static.\n");
return FALSE;
}
// ARM7部分
if ( rom_header.sub_size > sizeof(rom_arm7) )
{
OS_TPrintf("Too large sub size (%d > %d).\n", rom_header.sub_size, sizeof(rom_arm7));
return FALSE;
}
if ( !FS_SeekFile(fp, (s32)rom_header.sub_rom_offset, FS_SEEK_SET) )
{
OS_TPrintf("Cannot seek to ARM7 static.\n");
return FALSE;
}
result = FS_ReadFile(fp, rom_arm7, (s32)rom_header.sub_size);
if ( result != rom_header.sub_size )
{
OS_TPrintf("Cannot read ARM7 static.\n");
return FALSE;
}
// データベースの検索
db = DHT_GetDatabase(dht, &rom_header);
if ( !db )
{
return FALSE;
}
//OS_TPrintf("FOUND: 0x%08X: %.4s(%d)\n", db, db->game_code, db->rom_version);
// ハッシュ計算 (1) - 隠蔽可能なはず
if ( !DHT_CheckHashPhase1(db, &rom_header, rom_arm9, rom_arm7) )
{
return FALSE;
}
// ハッシュ計算 (2) - 隠蔽は難しいか
if ( !DHT_CheckHashPhase2(db, &rom_header, fp, ov_buffer) )
{
return FALSE;
}
return TRUE;
}
void TwlMain(void)
{
OS_Init();
OS_InitTick();
(void)OS_EnableIrq();
(void)OS_EnableInterrupts();
// 割り込み許可----------------------------
(void)OS_SetIrqFunction(OS_IE_V_BLANK, VBlankIntr);
(void)OS_EnableIrqMask(OS_IE_V_BLANK);
(void)GX_VBlankIntr(TRUE);
FS_Init(FS_DMA_NOT_USE);
// 署名ロード
if ( !DHT_PrepareDatabase(dht) )
{
OS_TPanic("Cannot prepare the database.\n");
}
// 本番
{
FSFile dir;
FSDirectoryEntryInfo info;
BOOL result;
result = FS_OpenDirectory(&dir, ROM_PATH, FS_FILEMODE_R);
if ( !result )
{
OS_TPanic("Cannot open " ROM_PATH ".\n");
}
while ( FS_ReadDirectory(&dir, &info) )
{
FSFile file;
OSTick begin;
char path[FS_ENTRY_LONGNAME_MAX+sizeof(ROM_PATH)+1];
if ( info.attributes & FS_ATTRIBUTE_IS_DIRECTORY )
{
OS_TPrintf("%s is directory.\n", info.longname);
continue;
}
STD_CopyString(path, ROM_PATH "/");
STD_ConcatenateString(path, info.longname);
if (!FS_OpenFileEx(&file, path, FS_FILEMODE_R))
{
OS_TPrintf("Cannot open %s.\n", path);
continue;
}
OS_TPrintf("\nTrying %s...\n", path);
begin = OS_GetTick();
if ( !CheckValidation(&file) )
{
OS_TPrintf("Failed. %d msec (includes loading static data).\n", (int)OS_TicksToMilliSeconds(OS_GetTick()-begin));
}
else
{
OS_TPrintf("Success. %d msec (includes loading static data).\n", (int)OS_TicksToMilliSeconds(OS_GetTick()-begin));
}
FS_CloseFile(&file);
}
FS_CloseDirectory(&dir);
}
OS_TPrintf("\nDone.\n");
OS_Terminate();
}

View File

@ -1,592 +0,0 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL - tools - MakeDSHashTable
File: MakeDSHashTable.c
Copyright 2008 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <dirent.h>
#include <sys/stat.h>
#include <sysmenu/dht/dht_format.h>
#include <twl/os/common/format_rom.h>
#include <digest/include/sha1.h>
#include <acsign/include/acsign.h>
#define TARGET_DIR "."
#define OUTPUT_FILE "DSHashTable.bin"
const BOOL DebugMode = TRUE; // acsignで必要
// データベース署名用秘密鍵
const u8 g_privKey_DER[ 0x261 ] = {
0x30, 0x82, 0x02, 0x5d, 0x02, 0x01, 0x00, 0x02, 0x81, 0x81, 0x00, 0xc7, 0xf4, 0x1d, 0x27, 0x3f,
0xe8, 0xae, 0x7f, 0x7c, 0xbc, 0x9a, 0xae, 0x09, 0x8d, 0x19, 0x26, 0x2e, 0x90, 0x04, 0x03, 0x13,
0x93, 0xbc, 0xb2, 0xe0, 0x8b, 0x1f, 0x85, 0x48, 0xf5, 0xf6, 0x94, 0x69, 0x3e, 0x05, 0x1b, 0x97,
0x85, 0x44, 0x6d, 0xa3, 0xcd, 0xa8, 0x01, 0xfe, 0xdc, 0x77, 0x5d, 0xd1, 0xb1, 0x36, 0x21, 0xfc,
0x80, 0xe8, 0xa6, 0x0e, 0xde, 0x59, 0x76, 0xca, 0x96, 0xcc, 0x87, 0x4c, 0xc3, 0x90, 0xc6, 0x3b,
0xc8, 0x17, 0x9d, 0x2d, 0xac, 0x45, 0xbc, 0xa7, 0x15, 0xb2, 0xe3, 0xd7, 0x76, 0xfa, 0x09, 0x8c,
0x55, 0x09, 0x22, 0x95, 0x4b, 0xe7, 0xde, 0xc0, 0x82, 0xf2, 0x02, 0x1a, 0x8a, 0x42, 0x38, 0x7f,
0xbb, 0x31, 0xd6, 0xa8, 0x36, 0xdc, 0x8d, 0x2c, 0x42, 0x56, 0x51, 0xc1, 0xa3, 0x30, 0x21, 0x30,
0xef, 0x06, 0x72, 0x0c, 0xa6, 0x55, 0xb7, 0x4f, 0x30, 0x35, 0x1b, 0x02, 0x03, 0x01, 0x00, 0x01,
0x02, 0x81, 0x80, 0x17, 0x47, 0x76, 0x75, 0x71, 0x5d, 0x57, 0xa3, 0x84, 0x14, 0x39, 0x35, 0xf5,
0xea, 0xb5, 0x78, 0xda, 0x86, 0xed, 0xd0, 0xa5, 0xe0, 0xd7, 0x61, 0x43, 0xff, 0x2e, 0x86, 0x47,
0xfe, 0x4a, 0xdc, 0xf0, 0x7b, 0xc6, 0x00, 0x76, 0x5d, 0x8f, 0x9f, 0xec, 0x28, 0x2f, 0x5d, 0x3c,
0x1c, 0xd2, 0xd0, 0xdb, 0x6e, 0xf4, 0x4c, 0x74, 0xa7, 0x55, 0x6e, 0xaf, 0xe0, 0x77, 0x2d, 0xfb,
0x5c, 0x1f, 0x27, 0x94, 0xa1, 0x64, 0x4d, 0xaa, 0x17, 0x5f, 0x96, 0x55, 0x86, 0x23, 0x94, 0xf1,
0x46, 0x52, 0x91, 0x49, 0x8e, 0x47, 0x89, 0xf3, 0xa0, 0xe9, 0x71, 0xe4, 0x7f, 0x9a, 0x85, 0xf1,
0x20, 0xfd, 0x71, 0xf8, 0xc0, 0x97, 0x0d, 0x23, 0x16, 0xb0, 0x80, 0x1c, 0x57, 0xf1, 0xbd, 0x6d,
0xa0, 0x0f, 0xea, 0x34, 0xed, 0x98, 0xee, 0xf0, 0x38, 0xba, 0x92, 0x6b, 0x51, 0x21, 0xae, 0xf3,
0x6a, 0x75, 0x91, 0x02, 0x41, 0x00, 0xf0, 0xde, 0xc2, 0x64, 0x7f, 0xdc, 0x84, 0xc5, 0xf6, 0x36,
0x71, 0xa6, 0x12, 0x07, 0x14, 0x0c, 0xfa, 0x86, 0x4f, 0x2b, 0x37, 0xd6, 0x11, 0xdf, 0xac, 0xe7,
0xe6, 0xd3, 0x4c, 0x0c, 0xff, 0x70, 0x5f, 0x75, 0x18, 0x5d, 0xd4, 0xee, 0x25, 0xda, 0x66, 0xac,
0xe1, 0x51, 0x59, 0xe4, 0xc5, 0xcb, 0x6a, 0x87, 0xa6, 0x2e, 0x19, 0xb0, 0xca, 0x44, 0x4c, 0xac,
0xbf, 0x48, 0x2c, 0xb6, 0x6b, 0xc5, 0x02, 0x41, 0x00, 0xd4, 0x83, 0x68, 0x59, 0x55, 0x37, 0x8b,
0xab, 0xa1, 0x10, 0xbb, 0xc2, 0xac, 0x91, 0x69, 0x1a, 0x3b, 0x19, 0xd5, 0x11, 0xa0, 0x06, 0x8b,
0xcd, 0x35, 0xc7, 0x26, 0x19, 0xe4, 0xd3, 0xf0, 0xb9, 0xa6, 0x98, 0xe4, 0xf2, 0xaf, 0x81, 0x08,
0x44, 0x90, 0xb8, 0x25, 0x54, 0x22, 0x6f, 0xe6, 0x34, 0xfb, 0x84, 0x8f, 0x80, 0x4e, 0x13, 0xee,
0xe7, 0x6d, 0xda, 0xf4, 0x71, 0x83, 0x75, 0xcb, 0x5f, 0x02, 0x40, 0x2e, 0x3e, 0x36, 0x07, 0xe1,
0x5c, 0x4e, 0xc9, 0x4a, 0xb9, 0xad, 0x1b, 0xfa, 0xfe, 0x0c, 0xe5, 0x68, 0xfb, 0x7c, 0x1b, 0x89,
0xfe, 0xb9, 0x33, 0xbe, 0x18, 0x4f, 0x82, 0x65, 0x69, 0x61, 0x69, 0x0b, 0x8a, 0x89, 0x81, 0x0a,
0x2e, 0x26, 0x6a, 0x45, 0xa8, 0x0f, 0x21, 0xf5, 0x26, 0x2c, 0xab, 0x1e, 0xea, 0xa8, 0x06, 0xd5,
0xbb, 0xd1, 0x39, 0x47, 0x97, 0x2a, 0xaa, 0x0a, 0x9b, 0x83, 0x19, 0x02, 0x41, 0x00, 0xad, 0x53,
0x70, 0x2c, 0x4c, 0x40, 0xbd, 0x7e, 0x02, 0x23, 0xef, 0xbf, 0xdb, 0x97, 0xcd, 0xad, 0x43, 0x3e,
0xd2, 0x75, 0x49, 0x9b, 0x8d, 0x32, 0x96, 0x06, 0x13, 0xa1, 0x52, 0xed, 0x39, 0x8d, 0x71, 0xbf,
0x8a, 0x1c, 0x15, 0xe0, 0x9b, 0xa9, 0xb0, 0x8f, 0x40, 0x82, 0xda, 0x83, 0x81, 0xb2, 0xfc, 0xe1,
0x25, 0x59, 0x74, 0x54, 0xf5, 0xa9, 0x74, 0x03, 0xfd, 0x13, 0x08, 0x31, 0x6e, 0xe9, 0x02, 0x41,
0x00, 0xa9, 0xfa, 0xfc, 0x14, 0x12, 0x56, 0xf5, 0x27, 0xe7, 0xe6, 0x9e, 0x21, 0x21, 0xbc, 0x78,
0x30, 0xf8, 0xdc, 0x2a, 0xca, 0xbf, 0x5f, 0x2a, 0x48, 0x5b, 0x63, 0xe3, 0x55, 0xde, 0xb8, 0x96,
0x04, 0x2d, 0xfb, 0xda, 0x88, 0x74, 0x68, 0x7f, 0xb3, 0x69, 0xef, 0xe7, 0x7d, 0x7a, 0x6c, 0x0b,
0x07, 0x7f, 0x1b, 0x8e, 0xc1, 0xa7, 0x8a, 0xdb, 0x20, 0x6c, 0xea, 0xe9, 0xda, 0x88, 0x14, 0x6e,
0x95
};
/*
scandir
*/
static int alphasort( const struct dirent** a, const struct dirent** b )
{
return strcoll((*a)->d_name, (*b)->d_name);
}
static int scandir( const char* path, struct dirent ***plist, int (*filter)( const struct dirent* ), int(*compar)( const struct dirent**, const struct dirent** ) )
{
int nums;
DIR* dp;
struct dirent* entry;
chdir(path);
if ( !(dp = opendir( "." )) )
{
printf("Failed to open the target directory \"%s\".\n", path);
return -1;
}
if ( !plist || !compar )
{
printf("plist = %p, compar = %p\n", plist, compar);
return -1;
}
*plist = NULL;
nums = 0;
while ( (entry = readdir( dp )) != NULL )
{
if (filter && filter(entry) == 0)
{
continue;
}
*plist = realloc(*plist, ++nums * sizeof(struct dirent*));
if ( !(*plist) )
{
printf("Failed to realloc %d bytes.\n", nums * sizeof(struct dirent*));
return -1;
}
(*plist)[nums-1] = malloc(sizeof(struct dirent));
memcpy((*plist)[nums-1], entry, sizeof(struct dirent));
}
closedir( dp );
if ( nums && *plist && compar )
{
qsort( *plist, nums, sizeof(struct dirent*), (int(*)(const void *, const void *))compar );
}
return nums;
}
/*
HMAC-SHA1
*/
typedef struct HMACSHA1Context
{
SHA1Context sha1_ctx;
u8 key[64];
u32 keylen;
}
HMACSHA1Context;
void HMACSHA1Init( HMACSHA1Context *ctx, const void *key, u32 keylen )
{
u8 ipad[64];
int i;
if ( ctx == NULL || ( keylen > 0 && key == NULL ) ) // key == NULL && keylen == 0 を認める
return; // FAILED
/* 鍵がブロック長よりも長い場合、ハッシュ値を鍵とする. */
if ( keylen > 64 )
{
SHA1Context sha1_ctx;
SHA1Reset( &sha1_ctx );
SHA1Input( &sha1_ctx, key, keylen );
SHA1Result( &sha1_ctx, ctx->key );
ctx->keylen = 20;
}
else
{
memcpy( ctx->key, key, keylen );
ctx->keylen = keylen;
}
/* 鍵とipadのXOR */
for ( i = 0; i < ctx->keylen; i++ )
{
ipad[i] = (u8)(ctx->key[i] ^ 0x36);
}
/* 鍵のパディング部分とipadのXOR */
for ( ; i < 64; i++ )
{
ipad[i] = 0x00 ^ 0x36;
}
/* メッセージとの結合とハッシュ値の計算 */
SHA1Reset( &ctx->sha1_ctx );
SHA1Input( &ctx->sha1_ctx, ipad, 64 );
}
void HMACSHA1Update( HMACSHA1Context *ctx, const void *data, u32 len )
{
/*
if ( ctx == NULL || ( len > 0 && data == NULL ) )
return; // FAILED
if ( len == 0 && data == NULL ) // 何もすることはない
return; // SUCCESS
*/
if ( ctx == NULL || len == 0 || data == NULL ) // void型なのでまとめる
return;
/* メッセージとの結合とハッシュ値の計算 */
SHA1Input( &ctx->sha1_ctx, data, len );
}
void HMACSHA1GetHash( HMACSHA1Context *ctx, u8* md )
{
u8 opad[64];
u8 temp[20];
int i;
if ( ctx == NULL || md == NULL )
return; // FAILED
/* メッセージとの結合とハッシュ値の計算 */
SHA1Result( &ctx->sha1_ctx, temp );
/* 鍵とopadのXOR */
for ( i = 0; i < ctx->keylen; i++ )
{
opad[i] = (u8)(ctx->key[i] ^ 0x5c);
}
/* 鍵のパディング部分とopadのXOR */
for ( ; i < 64; i++ )
{
opad[i] = 0x00 ^ 0x5c;
}
/* ハッシュ値との結合とハッシュ値の計算 */
SHA1Reset( &ctx->sha1_ctx );
SHA1Input( &ctx->sha1_ctx, opad, 64 );
SHA1Input( &ctx->sha1_ctx, temp, 20 );
SHA1Result( &ctx->sha1_ctx, md );
}
/*
fpからsize分をHMAC-SHA1計算
*/
#define BUFSIZE 0x1000
static BOOL FileHMACSHA1( HMACSHA1Context *ctx, FILE* fp, int size )
{
while ( size > 0 )
{
int len = size < BUFSIZE ? size : BUFSIZE;
u8 buffer[BUFSIZE];
if ( fread(buffer, len, 1, fp) < 1 )
{
return FALSE;
}
HMACSHA1Update(ctx, buffer, len);
size -= len;
}
return TRUE;
}
/*
ROMファイルっぽいものかどうかの判定
*/
static int srl_filter( const struct dirent* dir )
{
struct stat buf;
if ( strlen( dir->d_name ) > 11 )
{
return 0;
}
if ( stat(dir->d_name, &buf) )
{
printf("Cannot stat \"%s\".\n", dir->d_name);
return 0;
}
if ( S_ISDIR(buf.st_mode) )
{
return 0;
}
if ( buf.st_size < sizeof(ROM_Header) )
{
return 0;
}
return 1;
}
/*
ROMヘッダhpがまともそうか判定する
*/
static BOOL check_code( const ROM_Header_Short* hp )
{
if ( !isprint(hp->game_code[0]) || !isprint(hp->game_code[1]) || !isprint(hp->game_code[2]) || !isprint(hp->game_code[3])
|| !isprint(hp->maker_code[0]) || !isprint(hp->maker_code[1]) )
{
return FALSE;
}
return TRUE;
}
/*
ROMヘッダhpからオーバーレイのサイズを計算する
*/
static int get_overlay_nums( const ROM_Header_Short* hp )
{
return hp->main_ovt_size / sizeof(struct ROM_OVT);
}
/*
ROMヘッダhpからオーバーレイのサイズを計算する
*/
static BOOL get_overlay_info( FILE* fp, int offset, int no, int* pOff, int* pLen )
{
struct ROM_FAT fat;
if ( !fp )
{
return FALSE;
}
if ( fseek( fp, offset + no * sizeof(ROM_FAT), SEEK_SET ) )
{
printf("Cannot seek No.%d of FAT\n", no);
return FALSE;
}
if ( fread( &fat, sizeof(struct ROM_FAT), 1, fp ) < 1 )
{
printf("Cannot read No.%d of FAT\n", no);
return FALSE;
}
if ( pOff )
{
*pOff = fat.top.offset;
}
if ( pLen )
{
*pLen = fat.bottom.offset - fat.top.offset;
}
return TRUE;
}
/*
filenameを解析して結果をfoutに書き出す
*/
static BOOL output_hash( FILE* fout, const char* filename )
{
FILE* fin = fopen(filename, "rb");
ROM_Header_Short header;
DHTDatabase db;
HMACSHA1Context ctx;
const u8 key[] = DHT_HMAC_KEY;
int nums;
if ( !fin )
{
printf("Cannot open the target file \"%s\".\n", filename);
return FALSE;
}
// まずヘッダを読む
if ( fread( &header, sizeof(ROM_Header_Short), 1, fin ) < 1 )
{
fseek( fin, 0, SEEK_SET );
printf("Cannot read the target file \"%s\". %d bytes only.\n", filename, fread( &header, 1, sizeof(ROM_Header_Short), fin ));
fclose(fin);
return FALSE;
}
// DSのROMか簡易チェック
if ( !check_code( &header ) )
{
fclose(fin);
return FALSE;
}
// db clear
memset(&db, 0, sizeof(db));
memcpy(db.game_code, header.game_code, sizeof(db.game_code));
db.rom_version = header.rom_version;
// ハッシュ準備 (その1)
HMACSHA1Init( &ctx, key, sizeof(key) );
// ヘッダのハッシュ計算
HMACSHA1Update( &ctx, (u8*)&header, DHT_DS_HEADER_SIZE );
// ARM9の読み込み
fseek(fin, header.main_rom_offset, SEEK_SET);
if ( !FileHMACSHA1( &ctx, fin, header.main_size ) )
{
printf("Cannot read the ARM9 Static for %.4s(%x).\n", header.game_code, header.rom_version);
fclose(fin);
return FALSE;
}
// ARM7の読み込み
fseek(fin, header.sub_rom_offset, SEEK_SET);
if ( !FileHMACSHA1( &ctx, fin, header.sub_size ) )
{
printf("Cannot read the ARM7 Static for %.4s(%x).\n", header.game_code, header.rom_version);
fclose(fin);
return FALSE;
}
// ハッシュ計算 (その1)
HMACSHA1GetHash( &ctx, db.hash[0] );
// オーバーレイ編
nums = get_overlay_nums(&header);
if (nums)
{
int i;
int total_sectors;
// ハッシュ準備 (その2)
HMACSHA1Init( &ctx, key, sizeof(key) );
// OVTの読み込み
fseek(fin, (long)header.main_ovt_offset, SEEK_SET);
if ( !FileHMACSHA1( &ctx, fin, header.main_ovt_size ) )
{
printf("Cannot read the OVT for %.4s(%x).\n", header.game_code, header.rom_version);
fclose(fin);
return FALSE;
}
// FAT(オーバーレイ部分)の読み込み
fseek(fin, (long)header.fat_offset, SEEK_SET);
if ( !FileHMACSHA1( &ctx, fin, nums * sizeof(ROM_FAT) ) )
{
printf("Cannot read the part of FAT for %.4s(%x).\n", header.game_code, header.rom_version);
fclose(fin);
return FALSE;
}
// 各オーバーレイの読み込み
total_sectors = 0;
for (i = 0; i < nums; i++)
{
int max_sectors = (DHT_OVERLAY_MAX/512 - total_sectors) / (nums-i);
int offset;
int length;
if ( !get_overlay_info( fin, (long)header.fat_offset, i, &offset, &length ) )
{
printf("Cannot get overlay info No.%d for %.4s(%x).\n", i, header.game_code, header.rom_version);
fclose(fin);
return FALSE;
}
length = (length + 511) / 512; // bytes -> sectors
if ( length > max_sectors )
{
length = max_sectors;
}
fseek(fin, offset, SEEK_SET);
if ( !FileHMACSHA1( &ctx, fin, length*512 ) )
{
printf("Cannot read the overlay No.%d for %.4s(%x).\n", i, header.game_code, header.rom_version);
fclose(fin);
return FALSE;
}
total_sectors += length;
if (total_sectors > DHT_OVERLAY_MAX/512)
{
printf("PROGRAM ERROR!!\n");
exit(1);
}
}
// ハッシュ計算 (その2)
HMACSHA1GetHash( &ctx, db.hash[1] );
}
else
{
memset(db.hash[1], 0, 20);
}
fclose(fin);
// 書き込み
if ( fwrite(&db, sizeof(db), 1, fout) < 1 )
{
printf("Cannot write the DHTDatabase for %.4s(%x).\n", header.game_code, header.rom_version);
return FALSE;
}
return TRUE;
}
/*
foutに書き出す
*/
static BOOL output_header( FILE* fp, int nums )
{
DHTHeader header;
header.magic_code = DHT_MAGIC_CODE;
header.nums = nums;
if (nums)
{
SHA1Context ctx;
u8 hash[20];
u8 sign[128];
int size = sizeof(DHTDatabase) * nums;
printf("Total hash size: %d bytes.\n", nums * sizeof(DHTDatabase));
if ( SHA1Reset( &ctx ) )
{
printf("Cannot reset SHA1 context.\n");
return FALSE;
}
SHA1Input(&ctx, (u8*)&header.nums, sizeof(header.nums));
fseek(fp, sizeof(DHTHeader), SEEK_SET);
while (size > 0)
{
int len = size < BUFSIZE ? size : BUFSIZE;
u8 buffer[BUFSIZE];
if ( fread(buffer, len, 1, fp) < 1 )
{
printf("Cannot calc SHA1 the while file.\n");
return FALSE;
}
SHA1Input(&ctx, buffer, len);
size -= len;
}
if ( SHA1Result( &ctx, hash ) )
{
printf("Cannot get SHA1 result for the whole file.\n");
return FALSE;
}
if( !ACSign_Encrypto( sign, g_privKey_DER, hash, sizeof(hash) ) )
{
printf("Cannot get signature.\n");
return FALSE;
}
memcpy(header.sign, sign, 128);
}
else
{
memset(header.sign, 0, 128);
}
rewind(fp);
if (fwrite(&header, sizeof(header), 1, fp) < 1)
{
printf("Cannot write the header. %d bytes only.\n", fwrite( &header, 1, sizeof(header), fp ));
return FALSE;
}
return TRUE;
}
/*
CSVファイルを作成する
*/
static BOOL make_hash( const char* path )
{
struct dirent **namelist;
int file_nums;
int i;
FILE* fp;
if ( !path )
{
return FALSE;
}
// 出力ファイルの作成
fp = fopen( OUTPUT_FILE, "w+b" );
if ( !fp )
{
printf("Cannot open the output file \"./%s\".\n", OUTPUT_FILE);
return FALSE;
}
printf("Ouptput file: ./%s\n", OUTPUT_FILE);
// ファイルリストの取得
file_nums = scandir( path, &namelist, srl_filter, alphasort );
if ( file_nums <= 0 )
{
printf("No target file.\n");
fclose(fp);
return FALSE;
}
printf("Found %d files.\n", file_nums);
// 仮ヘッダ作成
output_header( fp, 0 );
// ファイル解析&出力
for ( i = 0; i < file_nums; i++ )
{
output_hash( fp, namelist[i]->d_name );
free( namelist[i] );
if ( i % 500 == 0) printf("\n");
if ( i % 10 == 0) printf(".");
}
free( namelist );
printf("\n\n");
// 本ヘッダ作成
output_header( fp, file_nums );
fclose( fp );
return TRUE;
}
int main( int argc, char** argv )
{
printf("\n");
if (argc == 2 && argv[1] )
{
make_hash(argv[1]);
}
else
{
make_hash(TARGET_DIR);
}
printf("\nDone.\n");
return 0;
}

View File

@ -1,61 +0,0 @@
#! make -f
#---------------------------------------------------------------------------
# Project: TwlIPL - tools - MakeDSHashTalbe
# File: Makefile
#
# Copyright 2008 Nintendo. All rights reserved.
#
# These coded instructions, statements, and computer programs contain
# proprietary information of Nintendo of America Inc. and/or Nintendo
# Company Ltd., and are protected by Federal copyright law. They may
# not be disclosed to third parties or copied or duplicated in any form,
# in whole or in part, without the prior written consent of Nintendo.
#
# $Date:: $
# $Rev$
# $Author$
#---------------------------------------------------------------------------
TARGET_PLATFORM = TWL
TARGET_FIRM = SYSTEMMENU
SUBDIRS =
include $(TWL_IPL_RED_ROOT)/build/buildtools/commondefs
TARGETS = MakeDSHashTable.exe
SOURCES = MakeDSHashTable.c
OBJECTS = $(SOURCES:.c=.o)
LIBDIR = $(ROOT)/build/tools/makerom.TWL
LIBACSIGN = $(LIBDIR)/acsign/lib/X86/libacsign_x86.a
LIBDIGEST = $(LIBDIR)/digest/lib/X86/libdigest_x86.a
MACROS = -I$(LIBDIR) \
-I$(ROOT)/include \
-I$(SYSMENU_ROOT)/include
INSTALL_DIR = $(SYSMENU_INSTALL_TOOLSDIR)/bin
INSTALL_TARGETS = $(TARGETS)
LDIRT_CLEAN = depend $(OBJECTS)
include $(TWLSDK_ROOT)/build/buildtools/twl/modulerules.x86
#----------------------------------------------------------------------------
# build
#----------------------------------------------------------------------------
do-build: $(TARGETS)
$(TARGETS): $(OBJECTS) $(LIBACSIGN) $(LIBDIGEST)
$(CC_X86) $+ -o $@
depend: $(SOURCES)
-@ $(RM) depend
-@ for i in $(SOURCES); do\
$(CC_X86) $(MACROS) -MM -w -DSDK_WIN32 $(WARNING) -I. -c -I$(TWL_INCDIR) $$i >> depend;\
done
-include depend

View File

@ -1,84 +0,0 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL - DHT
File: dht.h
Copyright 2008 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: $
$Rev$
$Author$
*---------------------------------------------------------------------------*/
#ifndef SYSMENU_DHT_H_
#define SYSMENU_DHT_H_
#include <twl/types.h>
#include <twl/os/common/format_rom.h>
#include <sysmenu/dht/dht_format.h>
#ifdef __cplusplus
extern "C" {
#endif
/*---------------------------------------------------------------------------*
Name: DHT_PrepareDatabase
Description:
Arguments: pDHT
Returns: TRUE
*---------------------------------------------------------------------------*/
BOOL DHT_PrepareDatabase(DHTFile* pDHT);
/*---------------------------------------------------------------------------*
Name: DHT_GetDatabase
Description: ROMヘッダに対応するデータベースを検索する
Arguments: pDHT
pROMHeader ROMヘッダ格納先
Returns:
*---------------------------------------------------------------------------*/
const DHTDatabase* DHT_GetDatabase(const DHTFile* pDHT, const ROM_Header_Short* pROMHeader);
/*---------------------------------------------------------------------------*
Name: DHT_CheckHashPhase1
Description: ROMヘッダおよびARM9/ARM7スタティック領域の検証
Arguments: db
pROMHeader ROMヘッダ格納先
pARM9 ARM9スタティック格納先
pARM7 ARM7スタティック格納先
Returns: TRUE
*---------------------------------------------------------------------------*/
BOOL DHT_CheckHashPhase1(const DHTDatabase *db, const ROM_Header_Short* pROMHeader, const void* pARM9, const void* pARM7);
/*---------------------------------------------------------------------------*
Name: DHT_CheckHashPhase2
Description:
Arguments: db
pROMHeader ROMヘッダ格納先
fctx (FS版) FSFile構造体へのポインタ
(CARD版) dma番号をvoid*
buffer APIで使用するワーク (DHT_OVERLAY_MAXだけ必要)
Returns: TRUE
*---------------------------------------------------------------------------*/
BOOL DHT_CheckHashPhase2(const DHTDatabase *db, const ROM_Header_Short* pROMHeader, void* fctx, void* buffer);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif // SYSMENU_DHT_H_

View File

@ -1,76 +0,0 @@
/*---------------------------------------------------------------------------*
Project: TwlIPL - DHT
File: dht_format.h
Copyright 2008 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Date:: 2007-09-06$
$Rev$
$Author$
*---------------------------------------------------------------------------*/
#ifndef SYSMENU_DHT_FORMAT_H_
#define SYSMENU_DHT_FORMAT_H_
#define DHT_MAGIC_CODE (('N' << 0)|('D' << 8)|('H' << 16)|('T' << 24))
#define DHT_DS_HEADER_SIZE 0x160
#define DHT_OVERLAY_MAX (512*1024)
#include <twl/types.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct DHTHeader
{
u32 magic_code; // fixed
u8 sign[128]; // for nums member and whole DHTDatabase array
u32 nums; // number of subsequent DHTDatabase array
}
DHTHeader;
typedef struct DHTDatabase
{
u8 game_code[4];
u8 rom_version;
u8 reserved[3]; // for 4B alignment DHTDatabase array
u8 hash[2][20];
}
DHTDatabase;
typedef struct DHTFile
{
DHTHeader header;
DHTDatabase database[];
}
DHTFile;
#define DHT_HMAC_KEY { \
0x61, 0xbd, 0xdd, 0x72, 0x7e, 0x72, 0xbe, 0xde, 0xad, 0x3a, 0xdf, 0x7f, 0x3d, 0x2d, 0xf7, 0xa5, \
0x16, 0x7e, 0xb4, 0xc9, 0x7c, 0x6c, 0x00, 0x7c, 0x57, 0xbb, 0x94, 0x8a, 0x64, 0xcd, 0x4e, 0x1c, \
0x51, 0x6b, 0xbd, 0xdb, 0x1d, 0xeb, 0x54, 0xe9, 0x34, 0x27, 0xf9, 0x31, 0x51, 0x5e, 0x89, 0x4e, \
0x7f, 0xd9, 0x7c, 0xe9, 0x92, 0x44, 0x0f, 0xef, 0x6b, 0xb6, 0x12, 0x21, 0x68, 0x88, 0xd8, 0xee \
}
/*
hp:
*/
#define DHT_GET_SIGN_TARGET_ADDR(hp) (&((DHTHeader*)hp)->nums)
#define DHT_GET_SIGN_TARGET_SIZE(hp) (((DHTHeader*)hp)->nums * sizeof(DHTDatabase) + sizeof(u32))
#define DHT_GET_SIGN_TARGET_OFFSET (int)DHT_GET_SIGN_TARGET_ADDR(0)
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif //SYSMENU_DHT_FORMAT_H_