keys.bin support added.

Remove hollywood id from config.
Tidy HLE_Device_es.h (maybe)
Added const params to crypto stuff.
This commit is contained in:
Matthew Parlane 2013-01-29 01:18:53 +13:00
parent 2dd077028f
commit bca2cac640
9 changed files with 193 additions and 57 deletions

View File

@ -40,7 +40,7 @@ static u8 ec_G[60] =
printf("\n"); printf("\n");
}*/ }*/
static void elt_copy(u8 *d, u8 *a) static void elt_copy(u8 *d, const u8 *a)
{ {
memcpy(d, a, 30); memcpy(d, a, 30);
} }
@ -303,7 +303,7 @@ static void point_add(u8 *r, u8 *p, u8 *q)
elt_add(ry, s, rx); elt_add(ry, s, rx);
} }
void point_mul(u8 *d, u8 *a, u8 *b) // a is bignum void point_mul(u8 *d, const u8 *a, u8 *b) // a is bignum
{ {
u32 i; u32 i;
u8 mask; u8 mask;
@ -330,7 +330,7 @@ void silly_random(u8 * rndArea, u8 count)
} }
} }
void generate_ecdsa(u8 *R, u8 *S, u8 *k, u8 *hash) void generate_ecdsa(u8 *R, u8 *S, const u8 *k, u8 *hash)
{ {
u8 e[30]; u8 e[30];
u8 kk[30]; u8 kk[30];
@ -394,7 +394,7 @@ int check_ecdsa(u8 *Q, u8 *R, u8 *S, u8 *hash)
return (bn_compare(r1, R, 30) == 0); return (bn_compare(r1, R, 30) == 0);
} }
void ec_priv_to_pub(u8 *k, u8 *Q) void ec_priv_to_pub(const u8 *k, u8 *Q)
{ {
point_mul(Q, k, ec_G); point_mul(Q, k, ec_G);
} }

View File

@ -13,10 +13,10 @@ void bn_add(u8 *d, u8 *a, u8 *b, u8 *N, u32 n);
void bn_mul(u8 *d, u8 *a, u8 *b, u8 *N, u32 n); void bn_mul(u8 *d, u8 *a, u8 *b, u8 *N, u32 n);
void bn_inv(u8 *d, u8 *a, u8 *N, u32 n); // only for prime N void bn_inv(u8 *d, u8 *a, u8 *N, u32 n); // only for prime N
void bn_exp(u8 *d, u8 *a, u8 *N, u32 n, u8 *e, u32 en); void bn_exp(u8 *d, u8 *a, u8 *N, u32 n, u8 *e, u32 en);
void point_mul(u8 *d, u8 *a, u8 *b); void point_mul(u8 *d, const u8 *a, u8 *b);
void generate_ecdsa(u8 *R, u8 *S, u8 *k, u8 *hash); void generate_ecdsa(u8 *R, u8 *S, const u8 *k, u8 *hash);
void ec_priv_to_pub(u8 *k, u8 *Q); void ec_priv_to_pub(const u8 *k, u8 *Q);
#endif #endif

View File

@ -157,7 +157,6 @@ void SConfig::SaveSettings()
ini.Set("General", "RecursiveGCMPaths", m_RecursiveISOFolder); ini.Set("General", "RecursiveGCMPaths", m_RecursiveISOFolder);
ini.Set("General", "NANDRoot", m_NANDPath); ini.Set("General", "NANDRoot", m_NANDPath);
ini.Set("General", "WirelessMac", m_WirelessMac); ini.Set("General", "WirelessMac", m_WirelessMac);
ini.Set("General", "HollywoodID", m_HollywoodID);
#ifdef USE_GDBSTUB #ifdef USE_GDBSTUB
ini.Set("General", "GDBPort", m_LocalCoreStartupParameter.iGDBPort); ini.Set("General", "GDBPort", m_LocalCoreStartupParameter.iGDBPort);
#endif #endif
@ -307,7 +306,6 @@ void SConfig::LoadSettings()
DiscIO::cUIDsys::AccessInstance().UpdateLocation(); DiscIO::cUIDsys::AccessInstance().UpdateLocation();
DiscIO::CSharedContent::AccessInstance().UpdateLocation(); DiscIO::CSharedContent::AccessInstance().UpdateLocation();
ini.Get("General", "WirelessMac", &m_WirelessMac); ini.Get("General", "WirelessMac", &m_WirelessMac);
ini.Get("General", "HollywoodID", &m_HollywoodID, "0x21FFFFF");
} }
{ {

View File

@ -89,7 +89,6 @@ struct SConfig : NonCopyable
int m_ListSort2; int m_ListSort2;
std::string m_WirelessMac; std::string m_WirelessMac;
std::string m_HollywoodID;
bool m_PauseMovie; bool m_PauseMovie;
bool m_ShowLag; bool m_ShowLag;
std::string m_strMovieAuthor; std::string m_strMovieAuthor;

View File

@ -60,7 +60,8 @@
#include "IPC_HLE/WII_IPC_HLE_Device_usb.h" #include "IPC_HLE/WII_IPC_HLE_Device_usb.h"
#include "../Movie.h" #include "../Movie.h"
#include <ec_wii.h> #include "ec_wii.h"
#ifdef _WIN32 #ifdef _WIN32
#include <Windows.h> #include <Windows.h>
#endif #endif
@ -103,15 +104,6 @@ void CWII_IPC_HLE_Device_es::LoadWAD(const std::string& _rContentFile)
m_ContentFile = _rContentFile; m_ContentFile = _rContentFile;
} }
u32 CWII_IPC_HLE_Device_es::GetHollywoodID()
{
unsigned int HollywoodID = 0;
std::stringstream ss;
ss << std::hex << SConfig::GetInstance().m_HollywoodID;
ss >> HollywoodID;
return HollywoodID;
}
bool CWII_IPC_HLE_Device_es::Open(u32 _CommandAddress, u32 _Mode) bool CWII_IPC_HLE_Device_es::Open(u32 _CommandAddress, u32 _Mode)
{ {
m_pContentLoader = &DiscIO::CNANDContentManager::Access().GetNANDLoader(m_ContentFile); m_pContentLoader = &DiscIO::CNANDContentManager::Access().GetNANDLoader(m_ContentFile);
@ -185,8 +177,9 @@ bool CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress)
{ {
_dbg_assert_msg_(WII_IPC_ES, Buffer.NumberPayloadBuffer == 1, "IOCTL_ES_GETDEVICEID no out buffer"); _dbg_assert_msg_(WII_IPC_ES, Buffer.NumberPayloadBuffer == 1, "IOCTL_ES_GETDEVICEID no out buffer");
INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETDEVICEID %s", SConfig::GetInstance().m_HollywoodID.c_str()); EcWii &ec = EcWii::GetInstance();
Memory::Write_U32(GetHollywoodID(), Buffer.PayloadBuffer[0].m_Address); INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETDEVICEID %08X", ec.getNgId());
Memory::Write_U32(ec.getNgId(), Buffer.PayloadBuffer[0].m_Address);
Memory::Write_U32(0, _CommandAddress + 0x4); Memory::Write_U32(0, _CommandAddress + 0x4);
return true; return true;
} }
@ -859,36 +852,23 @@ bool CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress)
{ {
WARN_LOG(WII_IPC_ES, "IOCTL_ES_GETDEVICECERT"); WARN_LOG(WII_IPC_ES, "IOCTL_ES_GETDEVICECERT");
_dbg_assert_(WII_IPC_ES, Buffer.NumberPayloadBuffer == 1); _dbg_assert_(WII_IPC_ES, Buffer.NumberPayloadBuffer == 1);
std::string path = File::GetUserPath(D_WIIUSER_IDX) + "clientcert.bin";
u8* destination = Memory::GetPointer(Buffer.PayloadBuffer[0].m_Address); u8* destination = Memory::GetPointer(Buffer.PayloadBuffer[0].m_Address);
u32 size = Buffer.PayloadBuffer[0].m_Size;
if (File::Exists(path)) EcWii &ec = EcWii::GetInstance();
{ get_ng_cert(destination, ec.getNgId(), ec.getNgKeyId(), ec.getNgPriv(), ec.getNgSig());
File::IOFile(path, "rb").ReadBytes(destination, size);
}
else
{
ERROR_LOG(WII_IPC_ES, "IOCTL_ES_GETDEVICECERT failed: no cert found.");
}
Memory::Write_U32(0, _CommandAddress + 0x4);
break; break;
} }
case IOCTL_ES_SIGN: case IOCTL_ES_SIGN:
{ {
WARN_LOG(WII_IPC_ES, "IOCTL_ES_SIGN"); WARN_LOG(WII_IPC_ES, "IOCTL_ES_SIGN");
u8 *ap_cert_out = Memory::GetPointer(Buffer.PayloadBuffer[1].m_Address); u8 *ap_cert_out = Memory::GetPointer(Buffer.PayloadBuffer[1].m_Address);
u8 *data = Memory::GetPointer(Buffer.InBuffer[0].m_Address); u8 *data = Memory::GetPointer(Buffer.InBuffer[0].m_Address);
u32 data_size = Buffer.InBuffer[0].m_Size; u32 data_size = Buffer.InBuffer[0].m_Size;
u8 *sig_out = Memory::GetPointer(Buffer.PayloadBuffer[0].m_Address); u8 *sig_out = Memory::GetPointer(Buffer.PayloadBuffer[0].m_Address);
EcWii &ec = EcWii::GetInstance();
get_ap_sig_and_cert(sig_out, ap_cert_out, m_TitleID, data, data_size, key_ecc, GetHollywoodID()); get_ap_sig_and_cert(sig_out, ap_cert_out, m_TitleID, data, data_size, ec.getNgPriv(), ec.getNgId());
break; break;
} }

View File

@ -31,7 +31,6 @@ public:
virtual ~CWII_IPC_HLE_Device_es(); virtual ~CWII_IPC_HLE_Device_es();
void LoadWAD(const std::string& _rContentFile); void LoadWAD(const std::string& _rContentFile);
static u32 GetHollywoodID();
virtual bool Open(u32 _CommandAddress, u32 _Mode); virtual bool Open(u32 _CommandAddress, u32 _Mode);
@ -102,6 +101,7 @@ private:
IOCTL_ES_GETSHAREDCONTENTCNT = 0x36, IOCTL_ES_GETSHAREDCONTENTCNT = 0x36,
IOCTL_ES_GETSHAREDCONTENTS = 0x37, IOCTL_ES_GETSHAREDCONTENTS = 0x37,
IOCTL_ES_DELETESHAREDCONTENT = 0x38, IOCTL_ES_DELETESHAREDCONTENT = 0x38,
IOCTL_ES_CHECKKOREAREGION = 0x45, IOCTL_ES_CHECKKOREAREGION = 0x45,
}; };

View File

@ -55,6 +55,7 @@ it failed)
#include "ICMP.h" #include "ICMP.h"
#include "CommonPaths.h" #include "CommonPaths.h"
#include "SettingsHandler.h" #include "SettingsHandler.h"
#include "ec_wii.h"
#ifdef _WIN32 #ifdef _WIN32
@ -195,7 +196,9 @@ bool CWII_IPC_HLE_Device_net_kd_request::IOCtl(u32 _CommandAddress)
u8 area_code = GetAreaCode(area.c_str()); u8 area_code = GetAreaCode(area.c_str());
u8 id_ctr = config.IdGen(); u8 id_ctr = config.IdGen();
u8 hardware_model = GetHardwareModel(model.c_str()); u8 hardware_model = GetHardwareModel(model.c_str());
u32 HollywoodID = CWII_IPC_HLE_Device_es::GetHollywoodID();
EcWii &ec = EcWii::GetInstance();
u32 HollywoodID = ec.getNgId();
u64 UserID = 0; u64 UserID = 0;
s32 ret = NWC24MakeUserID(&UserID, HollywoodID, id_ctr, hardware_model, area_code); s32 ret = NWC24MakeUserID(&UserID, HollywoodID, id_ctr, hardware_model, area_code);

View File

@ -8,6 +8,7 @@
#include "Crypto/aes.h" #include "Crypto/aes.h"
#include "Crypto/sha1.h" #include "Crypto/sha1.h"
#include "Crypto/tools.h" #include "Crypto/tools.h"
#include "FileUtil.h"
#include "ec_wii.h" #include "ec_wii.h"
static u32 default_NG_id = 0x0403AC68; static u32 default_NG_id = 0x0403AC68;
@ -37,7 +38,7 @@ static u8 default_NG_sig[] = {
// NG_sig is the device-unique signature blob (from issuer) to use // NG_sig is the device-unique signature blob (from issuer) to use
// if NG_priv iis NULL or NG_sig is NULL or NG_id is 0 or NG_key_id is 0, default values // if NG_priv iis NULL or NG_sig is NULL or NG_id is 0 or NG_key_id is 0, default values
// will be used for all of them // will be used for all of them
void get_ng_cert(u8* ng_cert_out, u32 NG_id, u32 NG_key_id, u8* NG_priv, u8* NG_sig) void get_ng_cert(u8* ng_cert_out, u32 NG_id, u32 NG_key_id, const u8* NG_priv, const u8* NG_sig)
{ {
char name[64]; char name[64];
if((NG_id==0)||(NG_key_id==0)||(NG_priv==NULL)||(NG_sig==NULL)) if((NG_id==0)||(NG_key_id==0)||(NG_priv==NULL)||(NG_sig==NULL))
@ -64,7 +65,7 @@ void get_ng_cert(u8* ng_cert_out, u32 NG_id, u32 NG_key_id, u8* NG_priv, u8* NG_
// NG_priv is the device-unique private key to use // NG_priv is the device-unique private key to use
// NG_id is the device-unique id to use // NG_id is the device-unique id to use
// if NG_priv is NULL or NG_id is 0, it will use builtin defaults // if NG_priv is NULL or NG_id is 0, it will use builtin defaults
void get_ap_sig_and_cert(u8 *sig_out, u8 *ap_cert_out, u64 title_id, u8 *data, u32 data_size, u8 *NG_priv, u32 NG_id) void get_ap_sig_and_cert(u8 *sig_out, u8 *ap_cert_out, u64 title_id, u8 *data, u32 data_size, const u8 *NG_priv, u32 NG_id)
{ {
u8 hash[20]; u8 hash[20];
u8 ap_priv[30]; u8 ap_priv[30];
@ -97,7 +98,7 @@ void get_ap_sig_and_cert(u8 *sig_out, u8 *ap_cert_out, u64 title_id, u8 *data, u
generate_ecdsa(sig_out, sig_out + 30, ap_priv, hash); generate_ecdsa(sig_out, sig_out + 30, ap_priv, hash);
} }
void make_blanksig_ec_cert(u8 *cert_out, const char *signer, const char *name, u8 *private_key, u32 key_id) void make_blanksig_ec_cert(u8 *cert_out, const char *signer, const char *name, const u8 *private_key, u32 key_id)
{ {
memset(cert_out, 0, 0x180); memset(cert_out, 0, 0x180);
*(u32*)cert_out = Common::swap32(0x10002); *(u32*)cert_out = Common::swap32(0x10002);
@ -129,3 +130,58 @@ void get_shared_secret(u8* shared_secret_out, u8* remote_public_key, u8* NG_priv
point_mul(shared_secret_out, NG_priv, remote_public_key); point_mul(shared_secret_out, NG_priv, remote_public_key);
} }
EcWii::EcWii()
{
bool init = true;
std::string keys_path = File::GetUserPath(D_WIIUSER_IDX) + "keys.bin";
if (File::Exists(keys_path))
{
File::IOFile keys_f(keys_path, "rb");
if(keys_f.IsOpen())
{
if(keys_f.ReadBytes(&BootMiiKeysBin, sizeof(BootMiiKeysBin)))
{
init = false;
INFO_LOG(WII_IPC_ES, "Successfully loaded keys.bin created by: %s", BootMiiKeysBin.creator);
}
else
{
ERROR_LOG(WII_IPC_ES, "Failed to read keys.bin, check it is the correct size of %08lX bytes.", sizeof(BootMiiKeysBin));
}
}
else
{
ERROR_LOG(WII_IPC_ES, "Failed to open keys.bin, maybe a permissions error or it is in use?");
}
}
else
{
ERROR_LOG(WII_IPC_ES, "%s could not be found. Using default values. We recommend you grab keys.bin from BootMii.", keys_path.c_str());
}
if(init)
InitDefaults();
}
EcWii::~EcWii()
{
}
void EcWii::InitDefaults()
{
memset(&BootMiiKeysBin, 0, sizeof(BootMiiKeysBin));
BootMiiKeysBin.ng_id = Common::swap32(default_NG_id);
BootMiiKeysBin.ng_key_id = Common::swap32(default_NG_key_id);
memcpy(BootMiiKeysBin.ng_priv, default_NG_priv, sizeof(BootMiiKeysBin.ng_priv));
memcpy(BootMiiKeysBin.ng_sig, default_NG_sig, sizeof(BootMiiKeysBin.ng_sig));
}
EcWii& EcWii::GetInstance()
{
static EcWii m_Instance;
return(m_Instance);
}

View File

@ -3,8 +3,108 @@
// Licensed under the terms of the GNU GPL, version 2 // Licensed under the terms of the GNU GPL, version 2
// http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt // http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
void get_ng_cert(u8* ng_cert_out, u32 NG_id, u32 NG_key_id, u8* NG_priv, u8* NG_sig); /*
void get_ap_sig_and_cert(u8 *sig_out, u8 *ap_cert_out, u64 title_id, u8 *data, u32 data_size, u8 *NG_priv, u32 NG_id); *
* Structs for keys.bin taken from:
*
* mini - a Free Software replacement for the Nintendo/BroadOn IOS.
* crypto hardware support
*
* Copyright (C) 2008, 2009 Haxx Enterprises <bushing@gmail.com>
* Copyright (C) 2008, 2009 Sven Peter <svenpeter@gmail.com>
* Copyright (C) 2008, 2009 Hector Martin "marcan" <marcan@marcansoft.com>
*
* # This code is licensed to you under the terms of the GNU GPL, version 2;
* # see file COPYING or http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
*/
void make_blanksig_ec_cert(u8 *cert_out, const char *signer, const char *name, u8 *private_key, u32 key_id); #ifndef _ECWII_H
void get_shared_secret(u8* shared_secret_out, u8* remote_public_key, u8* NG_priv); #define _ECWII_H
#include "Common.h"
#include <lzoconf.h>
void get_ng_cert(u8* ng_cert_out, u32 NG_id, u32 NG_key_id, const u8* NG_priv, const u8* NG_sig);
void get_ap_sig_and_cert(u8 *sig_out, u8 *ap_cert_out, u64 title_id, u8 *data, u32 data_size, const u8 *NG_priv, u32 NG_id);
void make_blanksig_ec_cert(u8 *cert_out, const char *signer, const char *name, const u8 *private_key, u32 key_id);
void get_shared_secret(u8* shared_secret_out, u8* remote_public_key, const u8* NG_priv);
class EcWii
{
public:
EcWii();
~EcWii();
static EcWii& GetInstance();
u32 getNgId() {return Common::swap32(BootMiiKeysBin.ng_id);}
u32 getNgKeyId() {return Common::swap32(BootMiiKeysBin.ng_key_id);}
const u8* getNgPriv() {return BootMiiKeysBin.ng_priv;}
const u8* getNgSig() {return BootMiiKeysBin.ng_sig;};
private:
void InitDefaults();
#pragma pack(push,1)
typedef struct
{
u8 boot2version;
u8 unknown1;
u8 unknown2;
u8 pad;
u32 update_tag;
u16 checksum;
}
#ifndef _WIN32
__attribute__((packed))
#endif
eep_ctr_t;
struct
{
u8 creator [0x100]; // 0x000
u8 boot1_hash [ 0x14]; // 0x100
u8 common_key [ 0x10]; // 0x114
u32 ng_id; // 0x124
union {
struct {
u8 ng_priv [ 0x1e]; // 0x128
u8 pad1 [ 0x12];
};
struct {
u8 pad2 [ 0x1c];
u8 nand_hmac [ 0x14]; //0x144
};
};
u8 nand_key [ 0x10]; //0x158
u8 rng_key [ 0x10]; //0x168
u32 unk1; //0x178
u32 unk2; //0x17C
u8 eeprom_pad [ 0x80]; //0x180
u32 ms_id; //0x200
u32 ca_id; //0x204
u32 ng_key_id; //0x208
u8 ng_sig [ 0x3c]; //0x20c
eep_ctr_t counters [ 0x02]; //0x248
u8 fill [ 0x18]; //0x25c
u8 korean_key [ 0x10]; //0x274
u8 pad3 [ 0x74]; //0x284
u16 prng_seed [ 0x02]; //0x2F8
u8 pad4 [ 0x04]; //0x2FC
u8 crack_pad [0x100]; //0x300
}
#ifndef _WIN32
__attribute__((packed))
#endif
BootMiiKeysBin;
#pragma pack(pop)
};
#endif