From 12e201246540deefffd001b30b4c1a3641eae6e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Lam?= Date: Wed, 16 May 2018 14:43:57 +0200 Subject: [PATCH] IOSC: Fix hardcoded MS and CA IDs The values that are used for the MS and CA IDs come from the SEEPROM. Also, the default CA and MS values are respectively 2 and 3, not 1 and 2. --- Source/Core/Core/IOS/IOSC.cpp | 21 ++++++++++++++------- Source/Core/Core/IOS/IOSC.h | 3 +++ Source/Core/Core/State.cpp | 2 +- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/Source/Core/Core/IOS/IOSC.cpp b/Source/Core/Core/IOS/IOSC.cpp index 5df9f49672..72f9c7a6ed 100644 --- a/Source/Core/Core/IOS/IOSC.cpp +++ b/Source/Core/Core/IOS/IOSC.cpp @@ -461,16 +461,16 @@ u32 IOSC::GetDeviceId() const // Copyright 2007,2008 Segher Boessenkool // Licensed under the terms of the GNU GPL, version 2 // http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt -static Certificate MakeBlankSigECCert(const char* signer, const char* name, const u8* private_key, - u32 key_id) +static Certificate MakeBlankSigECCert(const std::string& signer, const std::string& name, + const u8* private_key, u32 key_id) { Certificate cert_out{}; const u32 type = Common::swap32(static_cast(SignatureType::ECC)); std::memcpy(cert_out.data(), &type, sizeof(type)); - std::strncpy(reinterpret_cast(cert_out.data()) + 0x80, signer, 0x40); + std::strncpy(reinterpret_cast(cert_out.data()) + 0x80, signer.c_str(), 0x40); const u32 two = Common::swap32(2); std::memcpy(cert_out.data() + 0xc0, &two, sizeof(two)); - std::strncpy(reinterpret_cast(cert_out.data()) + 0xc4, name, 0x40); + std::strncpy(reinterpret_cast(cert_out.data()) + 0xc4, name.c_str(), 0x40); const u32 swapped_key_id = Common::swap32(key_id); std::memcpy(cert_out.data() + 0x104, &swapped_key_id, sizeof(swapped_key_id)); ec_priv_to_pub(private_key, cert_out.data() + 0x108); @@ -480,7 +480,7 @@ static Certificate MakeBlankSigECCert(const char* signer, const char* name, cons Certificate IOSC::GetDeviceCertificate() const { const std::string name = StringFromFormat("NG%08x", GetDeviceId()); - auto cert = MakeBlankSigECCert("Root-CA00000001-MS00000002", name.c_str(), + auto cert = MakeBlankSigECCert(StringFromFormat("Root-CA%08x-MS%08x", m_ca_id, m_ms_id), name, m_key_entries[HANDLE_CONSOLE_KEY].data.data(), m_console_key_id); std::copy(m_console_signature.begin(), m_console_signature.end(), cert.begin() + 4); return cert; @@ -496,9 +496,10 @@ void IOSC::Sign(u8* sig_out, u8* ap_cert_out, u64 title_id, const u8* data, u32 // get_rand_bytes(ap_priv, 0x1e); // ap_priv[0] &= 1; - const std::string signer = StringFromFormat("Root-CA00000001-MS00000002-NG%08x", GetDeviceId()); + const std::string signer = + StringFromFormat("Root-CA%08x-MS%08x-NG%08x", m_ca_id, m_ms_id, GetDeviceId()); const std::string name = StringFromFormat("AP%016" PRIx64, title_id); - const auto cert = MakeBlankSigECCert(signer.c_str(), name.c_str(), ap_priv.data(), 0); + const auto cert = MakeBlankSigECCert(signer, name, ap_priv.data(), 0); std::copy(cert.begin(), cert.end(), ap_cert_out); mbedtls_sha1(ap_cert_out + 0x80, 0x100, hash.data()); @@ -620,6 +621,8 @@ void IOSC::LoadEntries() m_key_entries[HANDLE_CONSOLE_KEY].data = {dump.ng_priv.begin(), dump.ng_priv.end()}; m_console_signature = dump.ng_sig; + m_ms_id = Common::swap32(dump.ms_id); + m_ca_id = Common::swap32(dump.ca_id); m_console_key_id = Common::swap32(dump.ng_key_id); m_key_entries[HANDLE_CONSOLE_ID].misc_data = Common::swap32(dump.ng_id); m_key_entries[HANDLE_FS_KEY].data = {dump.nand_key.begin(), dump.nand_key.end()}; @@ -683,6 +686,10 @@ void IOSC::DoState(PointerWrap& p) { for (auto& entry : m_key_entries) entry.DoState(p); + p.Do(m_console_signature); + p.Do(m_ms_id); + p.Do(m_ca_id); + p.Do(m_console_key_id); } void IOSC::KeyEntry::DoState(PointerWrap& p) diff --git a/Source/Core/Core/IOS/IOSC.h b/Source/Core/Core/IOS/IOSC.h index ce56921937..7ecf0c71f7 100644 --- a/Source/Core/Core/IOS/IOSC.h +++ b/Source/Core/Core/IOS/IOSC.h @@ -248,6 +248,9 @@ private: KeyEntries m_key_entries; KeyEntry m_root_key_entry; ECCSignature m_console_signature{}; + // Retail keyblob are issued by CA00000001. Default to 1 even though IOSC actually defaults to 2. + u32 m_ms_id = 2; + u32 m_ca_id = 1; u32 m_console_key_id = 0; }; } // namespace HLE diff --git a/Source/Core/Core/State.cpp b/Source/Core/Core/State.cpp index 6f1a8817fc..f67c91452d 100644 --- a/Source/Core/Core/State.cpp +++ b/Source/Core/Core/State.cpp @@ -74,7 +74,7 @@ static Common::Event g_compressAndDumpStateSyncEvent; static std::thread g_save_thread; // Don't forget to increase this after doing changes on the savestate system -static const u32 STATE_VERSION = 97; // Last changed in PR 6772 +static const u32 STATE_VERSION = 98; // Last changed in PR 6895 // Maps savestate versions to Dolphin versions. // Versions after 42 don't need to be added to this list,