From 44827ba3696ef33f27f79e5874023da6c5e7c81e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Lam?= Date: Thu, 17 May 2018 21:55:02 +0200 Subject: [PATCH] Use CertECC struct instead of hardcoded offsets --- Source/Core/Core/HW/WiiSave.cpp | 11 ++++--- Source/Core/Core/IOS/ES/Identity.cpp | 4 +-- Source/Core/Core/IOS/IOSC.cpp | 47 +++++++++++++--------------- Source/Core/Core/IOS/IOSC.h | 9 +++--- 4 files changed, 34 insertions(+), 37 deletions(-) diff --git a/Source/Core/Core/HW/WiiSave.cpp b/Source/Core/Core/HW/WiiSave.cpp index 88f4a8aa0c..21fd3150a1 100644 --- a/Source/Core/Core/HW/WiiSave.cpp +++ b/Source/Core/Core/HW/WiiSave.cpp @@ -454,9 +454,10 @@ void WiiSave::do_sig() } // Sign the data. - IOS::Certificate ap_cert; + IOS::CertECC ap_cert; IOS::ECCSignature ap_sig; - m_ios.GetIOSC().Sign(ap_sig.data(), ap_cert.data(), Titles::SYSTEM_MENU, data.get(), data_size); + m_ios.GetIOSC().Sign(ap_sig.data(), reinterpret_cast(&ap_cert), Titles::SYSTEM_MENU, + data.get(), data_size); // Write signatures. data_file.Open(m_encrypted_save_path, "ab"); @@ -469,9 +470,9 @@ void WiiSave::do_sig() data_file.WriteArray(ap_sig.data(), ap_sig.size()); const u32 SIGNATURE_END_MAGIC = Common::swap32(0x2f536969); data_file.WriteArray(&SIGNATURE_END_MAGIC, 1); - const IOS::Certificate device_certificate = m_ios.GetIOSC().GetDeviceCertificate(); - data_file.WriteArray(device_certificate.data(), device_certificate.size()); - data_file.WriteArray(ap_cert.data(), ap_cert.size()); + const IOS::CertECC device_certificate = m_ios.GetIOSC().GetDeviceCertificate(); + data_file.WriteArray(&device_certificate, 1); + data_file.WriteArray(&ap_cert, 1); m_valid = data_file.IsGood(); } diff --git a/Source/Core/Core/IOS/ES/Identity.cpp b/Source/Core/Core/IOS/ES/Identity.cpp index 87ff012cb6..f33cd4bccd 100644 --- a/Source/Core/Core/IOS/ES/Identity.cpp +++ b/Source/Core/Core/IOS/ES/Identity.cpp @@ -96,8 +96,8 @@ IPCCommandResult ES::GetDeviceCertificate(const IOCtlVRequest& request) INFO_LOG(IOS_ES, "IOCTL_ES_GETDEVICECERT"); - const auto cert = m_ios.GetIOSC().GetDeviceCertificate(); - Memory::CopyToEmu(request.io_vectors[0].address, cert.data(), cert.size()); + const IOS::CertECC cert = m_ios.GetIOSC().GetDeviceCertificate(); + Memory::CopyToEmu(request.io_vectors[0].address, &cert, sizeof(cert)); return GetDefaultReply(IPC_SUCCESS); } diff --git a/Source/Core/Core/IOS/IOSC.cpp b/Source/Core/Core/IOS/IOSC.cpp index bba688dd4d..734d8e391e 100644 --- a/Source/Core/Core/IOS/IOSC.cpp +++ b/Source/Core/Core/IOS/IOSC.cpp @@ -417,29 +417,25 @@ 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 std::string& signer, const std::string& name, - const u8* private_key, u32 key_id) +static CertECC MakeBlankEccCert(const std::string& issuer, 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.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.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)); - const std::array public_key = Common::ec::PrivToPub(private_key); - std::copy(public_key.cbegin(), public_key.cend(), cert_out.begin() + 0x108); - return cert_out; + CertECC cert{}; + cert.signature.type = SignatureType(Common::swap32(u32(SignatureType::ECC))); + std::strncpy(cert.signature.issuer, issuer.c_str(), 0x40); + cert.header.public_key_type = PublicKeyType(Common::swap32(u32(PublicKeyType::ECC))); + std::strncpy(cert.header.name, name.c_str(), 0x40); + cert.header.id = Common::swap32(key_id); + cert.public_key = Common::ec::PrivToPub(private_key); + return cert; } -Certificate IOSC::GetDeviceCertificate() const +CertECC IOSC::GetDeviceCertificate() const { const std::string name = StringFromFormat("NG%08x", GetDeviceId()); - 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); + auto cert = MakeBlankEccCert(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); + cert.signature.sig = m_console_signature; return cert; } @@ -456,15 +452,16 @@ void IOSC::Sign(u8* sig_out, u8* ap_cert_out, u64 title_id, const u8* data, u32 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, name, ap_priv.data(), 0); - std::copy(cert.begin(), cert.end(), ap_cert_out); - - mbedtls_sha1(ap_cert_out + 0x80, 0x100, hash.data()); - auto signature = Common::ec::Sign(m_key_entries[HANDLE_CONSOLE_KEY].data.data(), hash.data()); - std::copy(signature.cbegin(), signature.cend(), ap_cert_out + 4); + CertECC cert = MakeBlankEccCert(signer, name, ap_priv.data(), 0); + // Sign the AP cert. + const size_t skip = offsetof(CertECC, signature.issuer); + mbedtls_sha1(reinterpret_cast(&cert) + skip, sizeof(cert) - skip, hash.data()); + cert.signature.sig = Common::ec::Sign(m_key_entries[HANDLE_CONSOLE_KEY].data.data(), hash.data()); + std::memcpy(ap_cert_out, &cert, sizeof(cert)); + // Sign the data. mbedtls_sha1(data, data_size, hash.data()); - signature = Common::ec::Sign(ap_priv.data(), hash.data()); + const auto signature = Common::ec::Sign(ap_priv.data(), hash.data()); std::copy(signature.cbegin(), signature.cend(), sig_out); } diff --git a/Source/Core/Core/IOS/IOSC.h b/Source/Core/Core/IOS/IOSC.h index 735e2ed6cc..394de9fdad 100644 --- a/Source/Core/Core/IOS/IOSC.h +++ b/Source/Core/Core/IOS/IOSC.h @@ -37,6 +37,8 @@ enum class PublicKeyType : u32 ECC = 2, }; +using ECCSignature = std::array; + #pragma pack(push, 4) struct SignatureRSA4096 { @@ -59,7 +61,7 @@ static_assert(sizeof(SignatureRSA2048) == 0x180, "Wrong size for SignatureRSA204 struct SignatureECC { SignatureType type; - u8 sig[0x3c]; + ECCSignature sig; u8 fill[0x40]; char issuer[0x40]; }; @@ -117,9 +119,6 @@ struct CertECC static_assert(sizeof(CertECC) == 0x180, "Wrong size for CertECC"); #pragma pack(pop) -using ECCSignature = std::array; -using Certificate = std::array; - namespace HLE { enum ReturnCode : s32; @@ -223,7 +222,7 @@ public: bool IsUsingDefaultId() const; u32 GetDeviceId() const; - Certificate GetDeviceCertificate() const; + CertECC GetDeviceCertificate() const; void Sign(u8* sig_out, u8* ap_cert_out, u64 title_id, const u8* data, u32 data_size) const; void DoState(PointerWrap& p);