TwlIPL/build/systemMenu_RED/HWInfoWriter/ARM9/src/hwi.c
kamikawa 4d072fd20a NandInitializer では内部的に HWInfoWriter とまったく同様のコードを実行していましたが、
両方をメンテナンスすることが手間であるため、HWInfoWriterのコードの一部をライブラリ化し、
一元管理できるようにしました。ただ、Makefileの記述も合わせる必要があることに注意が必要です。

git-svn-id: file:///Users/lillianskinner/Downloads/platinum/twl/TwlIPL/trunk@652 b08762b0-b915-fc4b-9d8c-17b2551a87ff
2008-02-14 03:06:18 +00:00

400 lines
11 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*---------------------------------------------------------------------------*
Project: TwlIPL
File: HWInfoWriterLib.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.h>
#include "TWLHWInfo_api.h"
#include "TWLSettings_api.h"
#include "hwi.h"
// define data------------------------------------------
// extern data------------------------------------------
const LCFGTWLHWNormalInfo *LCFG_THW_GetDefaultNormalInfo( void );
const LCFGTWLHWSecureInfo *LCFG_THW_GetDefaultSecureInfo( void );
const LCFGTWLHWNormalInfo *LCFG_THW_GetNormalInfo( void );
const LCFGTWLHWSecureInfo *LCFG_THW_GetSecureInfo( void );
// function's prototype declaration---------------------
static void ReadTWLSettings( void );
static HwiInitResult ReadPrivateKey( void );
static void ReadHWInfoFile( void );
static void VerifyHWInfo( void );
static BOOL VerifyData( const u8 *pTgt, const u8 *pOrg, u32 len );
// global variable -------------------------------------
// static variable -------------------------------------
static u8 *s_pPrivKeyBuffer = NULL;
static LCFGReadResult (*s_pReadSecureInfoFunc)( void );
static BOOL s_isReadTSD;
static void *(*spAlloc)( u32 length );
static void (*spFree)( void *ptr );
// const data -----------------------------------------
static const u32 s_langBitmapList[ LCFG_TWL_REGION_MAX ] = {
LCFG_TWL_LANG_BITMAP_JAPAN,
LCFG_TWL_LANG_BITMAP_AMERICA,
LCFG_TWL_LANG_BITMAP_EUROPE,
LCFG_TWL_LANG_BITMAP_AUSTRALIA,
LCFG_TWL_LANG_BITMAP_CHINA,
LCFG_TWL_LANG_BITMAP_KOREA,
};
static char *strLanguage[] = {
(char *)"LANG_JAPANESE",
(char *)"LANG_ENGLISH",
(char *)"LANG_FRENCH",
(char *)"LANG_GERMAN",
(char *)"LANG_ITALIAN",
(char *)"LANG_SPANISH",
(char *)"LANG_CHINESE",
(char *)"LANG_KOREAN",
};
static const char *strLauncherGameCode[] = {
"LNCJ",
"LNCE",
"LNCP",
"LNCO",
"LNCC",
"LNCK",
};
//======================================================
// HW<48><57><EFBFBD>񃉃C<F1838983>^<5E>[
//======================================================
/*---------------------------------------------------------------------------*
Name: HWI_Init
Description: HW<48><57><EFBFBD>񃉃C<F1838983>^<5E>[<5B>̏<EFBFBD><CC8F><EFBFBD><EFBFBD><EFBFBD>
Arguments:
Returns: None.
*---------------------------------------------------------------------------*/
HwiInitResult HWI_Init( void *(*pAlloc)( u32 ), void (*pFree)( void * ) )
{
HwiInitResult result;
spAlloc = pAlloc;
spFree = pFree;
ACSign_SetAllocFunc( pAlloc, pFree );
ReadTWLSettings();
result = ReadPrivateKey();
ReadHWInfoFile();
// VerifyHWInfo();
return result;
}
// TWL<57>ݒ<EFBFBD><DD92>f<EFBFBD>[<5B>^<5E>̃<EFBFBD><CC83>[<5B>h
static void ReadTWLSettings( void )
{
s_isReadTSD = LCFGi_TSD_ReadSettings();
if( s_isReadTSD ) {
OS_TPrintf( "TSD read succeeded.\n" );
}else {
OS_TPrintf( "TSD read failed.\n" );
}
}
// <20><EFBFBD><E996A7><EFBFBD>̃<EFBFBD><CC83>[<5B>h
HwiInitResult ReadPrivateKey( void )
{
BOOL result = FALSE;
u32 keyLength;
FSFile file;
OSTick start = OS_GetTick();
FS_InitFile( &file );
if( !FS_OpenFileEx( &file, "rom:key/private_HWInfo.der", FS_FILEMODE_R ) )
{
OS_TPrintf( "PrivateKey read failed.\n" );
}
else
{
keyLength = FS_GetFileLength( &file );
if( keyLength > 0 ) {
s_pPrivKeyBuffer = spAlloc( keyLength );
if( FS_ReadFile( &file, s_pPrivKeyBuffer, (s32)keyLength ) == keyLength ) {
OS_TPrintf( "PrivateKey read succeeded.\n" );
result = TRUE;
}else {
OS_TPrintf( "PrivateKey read failed.\n" );
}
}
FS_CloseFile( &file );
}
if( !result && s_pPrivKeyBuffer ) {
spFree( s_pPrivKeyBuffer );
s_pPrivKeyBuffer = NULL;
}
OS_TPrintf( "PrivKey read time = %dms\n", OS_TicksToMilliSeconds( OS_GetTick() - start ) );
#ifdef USE_PRODUCT_KEY
// <20><><EFBFBD>i<EFBFBD>p<EFBFBD><EFBFBD><E996A7><EFBFBD><EFBFBD><EFBFBD>L<EFBFBD><4C><EFBFBD>Ȃ<EFBFBD><C882>A<EFBFBD><41><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̃A<CC83>N<EFBFBD>Z<EFBFBD>X
s_pReadSecureInfoFunc = LCFGi_THW_ReadSecureInfo;
if (result) { return HWI_INIT_SUCCESS_SIGNATURE_MODE; }
else { return HWI_INIT_FAILURE; }
#else
// <20><><EFBFBD><EFBFBD><EFBFBD>łȂ<C582><C882>Ȃ<EFBFBD><C882>A<EFBFBD><41><EFBFBD><EFBFBD><EFBFBD>Ȃ<EFBFBD><C882>̃A<CC83>N<EFBFBD>Z<EFBFBD>X
s_pReadSecureInfoFunc = LCFGi_THW_ReadSecureInfo_NoCheck;
if (result) { return HWI_INIT_SUCCESS_NO_SIGNATRUE_MODE; }
else { return HWI_INIT_FAILURE; }
#endif
}
// HW<48><57><EFBFBD><EFBFBD><EFBFBD>S<EFBFBD>̂̃<CC82><CC83>[<5B>h
static void ReadHWInfoFile( void )
{
LCFGReadResult retval;
OSTick start = OS_GetTick();
retval = LCFGi_THW_ReadNormalInfo();
if( retval == LCFG_TSF_READ_RESULT_SUCCEEDED ) {
OS_TPrintf( "HW Normal Info read succeeded.\n" );
}else {
OS_TPrintf( "HW Normal Info read failed.\n" );
}
OS_TPrintf( "HW Normal Info read time = %dms\n", OS_TicksToMilliSeconds( OS_GetTick() - start ) );
start = OS_GetTick();
retval = s_pReadSecureInfoFunc();
if( retval == LCFG_TSF_READ_RESULT_SUCCEEDED ) {
OS_TPrintf( "HW Secure Info read succeeded.\n" );
}else {
OS_TPrintf( "HW Secure Info read failed.\n" );
}
OS_TPrintf( "HW Secure Info read time = %dms\n", OS_TicksToMilliSeconds( OS_GetTick() - start ) );
}
// HWInfo<66>t<EFBFBD>@<40>C<EFBFBD><43><EFBFBD>̃x<CC83><78><EFBFBD>t<EFBFBD>@<40>C
static void VerifyHWInfo( void )
{
if( VerifyData( (const u8 *)LCFG_THW_GetNormalInfo(), (const u8 *)LCFG_THW_GetDefaultNormalInfo(), sizeof(LCFGTWLHWNormalInfo) ) ) {
OS_TPrintf( "HW normal Info verify succeeded.\n" );
}else {
OS_TPrintf( "HW normal Info verify failed.\n" );
}
if( VerifyData( (const u8 *)LCFG_THW_GetSecureInfo(), (const u8 *)LCFG_THW_GetDefaultSecureInfo(), sizeof(LCFGTWLHWSecureInfo) ) ) {
OS_TPrintf( "HW secure Info verify succeeded.\n" );
}else {
OS_TPrintf( "HW secure Info verify failed.\n" );
}
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̃f<CC83>[<5B>^<5E>x<EFBFBD><78><EFBFBD>t<EFBFBD>@<40>C
static BOOL VerifyData( const u8 *pTgt, const u8 *pOrg, u32 len )
{
while( len-- ) {
if( *pTgt++ != *pOrg++ ) {
return FALSE;
}
}
return TRUE;
}
/*---------------------------------------------------------------------------*
Name: HWI_ModifyLanguage
Description: <20><><EFBFBD><EFBFBD><EFBFBD>R<EFBFBD>[<5B>h<EFBFBD><68><EFBFBD><EFBFBD><EFBFBD>[<5B>W<EFBFBD><57><EFBFBD><EFBFBD><EFBFBD>l<EFBFBD>ɍ<EFBFBD><C98D><EFBFBD>ďC<C48F><43><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>B
Arguments:
Returns: None.
*---------------------------------------------------------------------------*/
void HWI_ModifyLanguage( u8 region )
{
u32 langBitmap = s_langBitmapList[ region ];
u8 nowLanguage = LCFG_TSD_GetLanguage();
// TSD<53><44><EFBFBD>ǂݍ<C782><DD8D>߂Ă<DF82><C482>Ȃ<EFBFBD><C882>Ȃ<EFBFBD><C882>A<EFBFBD><41><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>^<5E>[<5B><>
if( !s_isReadTSD ) {
return;
}
if( langBitmap & ( 0x0001 << nowLanguage ) ) {
OS_TPrintf( "Language no change.\n" );
}else {
int i;
for( i = 0; i < LCFG_TWL_LANG_CODE_MAX; i++ ) {
if( langBitmap & ( 0x0001 << i ) ) {
break;
}
}
LCFG_TSD_SetLanguage( (LCFGTWLLangCode)i );
LCFG_TSD_SetFlagCountry( FALSE ); // <20><><EFBFBD>‚<EFBFBD><C282>łɍ<C582><C98D>R<EFBFBD>[<5B>h<EFBFBD><68><EFBFBD>N<EFBFBD><4E><EFBFBD>A<EFBFBD><41><EFBFBD>Ă<EFBFBD><C482><EFBFBD><EFBFBD>B
LCFG_TSD_SetCountry( LCFG_TWL_COUNTRY_UNDEFINED );
LCFGi_TSD_WriteSettings();
OS_TPrintf( "Language Change \"%s\" -> \"%s\"\n",
strLanguage[ nowLanguage ], strLanguage[ LCFG_TSD_GetLanguage() ] );
}
}
/*---------------------------------------------------------------------------*
Name: HWI_WriteHWNormalInfoFile
Description: HW<48>m<EFBFBD>[<5B>}<7D><>Info<66>t<EFBFBD>@<40>C<EFBFBD><43><EFBFBD>̃<EFBFBD><CC83>C<EFBFBD>g
Arguments:
Returns: None.
*---------------------------------------------------------------------------*/
BOOL HWI_WriteHWNormalInfoFile( void )
{
BOOL isWrite = TRUE;
LCFGReadResult result;
result = LCFGi_THW_ReadNormalInfo();
if( result != LCFG_TSF_READ_RESULT_SUCCEEDED ) {
if( !LCFGi_THW_RecoveryNormalInfo( result ) ) {
OS_TPrintf( "HW Normal Info Recovery failed.\n" );
isWrite = FALSE;
}
}
if( isWrite &&
!LCFGi_THW_WriteNormalInfo() ) {
OS_TPrintf( "HW Normal Info Write failed.\n" );
}
return isWrite;
}
/*---------------------------------------------------------------------------*
Name: HWI_WriteHWSecureInfoFile
Description: HW<48>Z<EFBFBD>L<EFBFBD><4C><EFBFBD>AInfo<66>t<EFBFBD>@<40>C<EFBFBD><43><EFBFBD>̃<EFBFBD><CC83>C<EFBFBD>g
Arguments:
Returns: None.
*---------------------------------------------------------------------------*/
BOOL HWI_WriteHWSecureInfoFile( u8 region )
{
BOOL isWrite = TRUE;
LCFGReadResult result;
// <20>t<EFBFBD>@<40>C<EFBFBD><43><EFBFBD>̃<EFBFBD><CC83>[<5B>h
result = s_pReadSecureInfoFunc();
// <20><><EFBFBD>[<5B>h<EFBFBD>Ɏ<EFBFBD><C98E>s<EFBFBD><73><EFBFBD><EFBFBD><EFBFBD><EFBFBD>J<EFBFBD>o<EFBFBD><6F>
if( result != LCFG_TSF_READ_RESULT_SUCCEEDED ) {
if( !LCFGi_THW_RecoverySecureInfo( result ) ) {
OS_TPrintf( "HW Secure Info Recovery failed.\n" );
isWrite = FALSE;
}
}
// <20><><EFBFBD>[<5B>W<EFBFBD><57><EFBFBD><EFBFBD><EFBFBD>̃Z<CC83>b<EFBFBD>g
LCFG_THW_SetRegion( region );
// <20>Ή<EFBFBD><CE89><EFBFBD><EFBFBD><EFBFBD><EFBFBD>r<EFBFBD>b<EFBFBD>g<EFBFBD>}<7D>b<EFBFBD>v<EFBFBD>̃Z<CC83>b<EFBFBD>g
LCFG_THW_SetValidLanguageBitmap( s_langBitmapList[ region ] );
// [TODO:]<5D>ʎY<CA8E>H<EFBFBD><48><EFBFBD>łȂ<C582><C882>ƃV<C683><56><EFBFBD>A<EFBFBD><41>No.<2E>͗p<CD97>ӂł<D382><C582>Ȃ<EFBFBD><C882>̂ŁA<C581><41><EFBFBD><EFBFBD><EFBFBD>ł<EFBFBD>MAC<41>A<EFBFBD>h<EFBFBD><68><EFBFBD>X<EFBFBD><58><EFBFBD><EFBFBD><EFBFBD>ƂɓK<C993><4B><EFBFBD>Ȓl<C892><6C><EFBFBD>Z<EFBFBD>b<EFBFBD>g<EFBFBD><67><EFBFBD><EFBFBD><EFBFBD>B
// <20>V<EFBFBD><56><EFBFBD>A<EFBFBD><41>No.<2E>̃Z<CC83>b<EFBFBD>g
{
u8 buffer[ 12 ] = "SERIAL"; // <20>K<EFBFBD><4B><EFBFBD>ȕ<EFBFBD><C895><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>MAC<41>A<EFBFBD>h<EFBFBD><68><EFBFBD>X<EFBFBD>ƌ<EFBFBD><C68C><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>SHA1<41><31><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>A<EFBFBD><41>SerialNo<4E>Ƃ<EFBFBD><C682><EFBFBD><EFBFBD>B
u8 serialNo[ SVC_SHA1_DIGEST_SIZE ];
int i;
int len = ( LCFG_THW_GetRegion() == LCFG_TWL_REGION_AMERICA ) ?
LCFG_TWL_HWINFO_SERIALNO_LEN_AMERICA : LCFG_TWL_HWINFO_SERIALNO_LEN_OTHERS;
OS_GetMacAddress( buffer + 6 );
SVC_CalcSHA1( serialNo, buffer, sizeof(buffer) );
for( i = 3; i < SVC_SHA1_DIGEST_SIZE; i++ ) {
serialNo[ i ] = (u8)( ( serialNo[ i ] % 10 ) + 0x30 );
}
MI_CpuCopy8( "SRN", serialNo, 3 );
MI_CpuClear8( &serialNo[ len ], sizeof(serialNo) - len );
OS_TPrintf( "serialNo : %s\n", serialNo );
LCFG_THW_SetSerialNo( serialNo );
}
// <20><><EFBFBD><EFBFBD><EFBFBD>`<60><><EFBFBD>[TitleID_Lo<4C>̃Z<CC83>b<EFBFBD>g
{
int i;
u8 titleID_Lo[4];
for( i = 0; i < 4; i++ ) titleID_Lo[ i ] = (u8)strLauncherGameCode[ region ][ 4 - i - 1 ];
LCFG_THW_SetLauncherTitleID_Lo( (const u8 *)titleID_Lo );
}
// <20><><EFBFBD>C<EFBFBD>g
if( isWrite &&
!LCFGi_THW_WriteSecureInfo( s_pPrivKeyBuffer ) ) {
isWrite = FALSE;
OS_TPrintf( "HW Secure Info Write failed.\n" );
}
return isWrite;
}
/*---------------------------------------------------------------------------*
Name: HWI_DeleteHWNormalInfoFile
Description: HW<48>m<EFBFBD>[<5B>}<7D><>Info<66>t<EFBFBD>@<40>C<EFBFBD><43><EFBFBD>̏<EFBFBD><CC8F><EFBFBD>
Arguments: None
Returns: BOOL
*---------------------------------------------------------------------------*/
BOOL HWI_DeleteHWNormalInfoFile( void )
{
if (FS_DeleteFile( (char *)LCFG_TWL_HWINFO_NORMAL_PATH ))
{
OS_TPrintf( "%s delete succeeded.\n", (char *)LCFG_TWL_HWINFO_NORMAL_PATH );
return TRUE;
}
else
{
OS_TPrintf( "%s delete failed.\n", (char *)LCFG_TWL_HWINFO_NORMAL_PATH );
return FALSE;
}
}
/*---------------------------------------------------------------------------*
Name: HWI_DeleteHWSecureInfoFile
Description: HW<48>Z<EFBFBD>L<EFBFBD><4C><EFBFBD>AInfo<66>t<EFBFBD>@<40>C<EFBFBD><43><EFBFBD>̏<EFBFBD><CC8F><EFBFBD>
Arguments: None
Returns: BOOL
*---------------------------------------------------------------------------*/
BOOL HWI_DeleteHWSecureInfoFile( void )
{
if (FS_DeleteFile( (char *)LCFG_TWL_HWINFO_SECURE_PATH ))
{
OS_TPrintf( "%s delete succeeded.\n", (char *)LCFG_TWL_HWINFO_SECURE_PATH );
return TRUE;
}
else
{
OS_TPrintf( "%s delete failed.\n", (char *)LCFG_TWL_HWINFO_SECURE_PATH );
return FALSE;
}
}