diff --git a/Source/Core/Core/IOS/IOSC.cpp b/Source/Core/Core/IOS/IOSC.cpp index 8c21906f3b..2e473f136a 100644 --- a/Source/Core/Core/IOS/IOSC.cpp +++ b/Source/Core/Core/IOS/IOSC.cpp @@ -23,6 +23,7 @@ #include "Common/File.h" #include "Common/FileUtil.h" #include "Common/ScopeGuard.h" +#include "Common/StringUtil.h" #include "Common/Swap.h" #include "Core/IOS/Device.h" #include "Core/ec_wii.h" @@ -442,6 +443,40 @@ ReturnCode IOSC::SetOwnership(Handle handle, u32 new_owner, u32 pid) return IPC_SUCCESS; } +u32 IOSC::GetDeviceId() const +{ + return m_key_entries[HANDLE_CONSOLE_ID].misc_data; +} + +// Based off of twintig http://git.infradead.org/?p=users/segher/wii.git +// 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) +{ + 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); + 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); + 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); + return cert_out; +} + +Certificate IOSC::GetDeviceCertificate() const +{ + const std::string name = StringFromFormat("NG%08x", GetDeviceId()); + auto cert = MakeBlankSigECCert("Root-CA00000001-MS00000002", name.c_str(), + 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; +} + constexpr std::array ROOT_PUBLIC_KEY = { {0xF8, 0x24, 0x6C, 0x58, 0xBA, 0xE7, 0x50, 0x03, 0x01, 0xFB, 0xB7, 0xC2, 0xEB, 0xE0, 0x01, 0x05, 0x71, 0xDA, 0x92, 0x23, 0x78, 0xF0, 0x51, 0x4E, 0xC0, 0x03, 0x1D, 0xD0, 0xD2, 0x1E, diff --git a/Source/Core/Core/IOS/IOSC.h b/Source/Core/Core/IOS/IOSC.h index 2eeb33aed2..c640e401b0 100644 --- a/Source/Core/Core/IOS/IOSC.h +++ b/Source/Core/Core/IOS/IOSC.h @@ -21,7 +21,7 @@ enum class SignatureType : u32 { RSA4096 = 0x00010000, RSA2048 = 0x00010001, - // XXX: Add support for ECC (0x00010002). + ECC = 0x00010002, }; enum class PublicKeyType : u32 @@ -97,6 +97,7 @@ union Cert #pragma pack(pop) using ECCSignature = std::array; +using Certificate = std::array; namespace HLE { @@ -198,6 +199,9 @@ public: ReturnCode GetOwnership(Handle handle, u32* owner) const; ReturnCode SetOwnership(Handle handle, u32 owner, u32 pid); + u32 GetDeviceId() const; + Certificate GetDeviceCertificate() const; + void DoState(PointerWrap& p); private: