mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-01-26 15:55:31 +01:00
Use CertECC struct instead of hardcoded offsets
This commit is contained in:
parent
5de2f960a1
commit
44827ba369
@ -454,9 +454,10 @@ void WiiSave::do_sig()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Sign the data.
|
// Sign the data.
|
||||||
IOS::Certificate ap_cert;
|
IOS::CertECC ap_cert;
|
||||||
IOS::ECCSignature ap_sig;
|
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<u8*>(&ap_cert), Titles::SYSTEM_MENU,
|
||||||
|
data.get(), data_size);
|
||||||
|
|
||||||
// Write signatures.
|
// Write signatures.
|
||||||
data_file.Open(m_encrypted_save_path, "ab");
|
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());
|
data_file.WriteArray(ap_sig.data(), ap_sig.size());
|
||||||
const u32 SIGNATURE_END_MAGIC = Common::swap32(0x2f536969);
|
const u32 SIGNATURE_END_MAGIC = Common::swap32(0x2f536969);
|
||||||
data_file.WriteArray(&SIGNATURE_END_MAGIC, 1);
|
data_file.WriteArray(&SIGNATURE_END_MAGIC, 1);
|
||||||
const IOS::Certificate device_certificate = m_ios.GetIOSC().GetDeviceCertificate();
|
const IOS::CertECC device_certificate = m_ios.GetIOSC().GetDeviceCertificate();
|
||||||
data_file.WriteArray(device_certificate.data(), device_certificate.size());
|
data_file.WriteArray(&device_certificate, 1);
|
||||||
data_file.WriteArray(ap_cert.data(), ap_cert.size());
|
data_file.WriteArray(&ap_cert, 1);
|
||||||
|
|
||||||
m_valid = data_file.IsGood();
|
m_valid = data_file.IsGood();
|
||||||
}
|
}
|
||||||
|
@ -96,8 +96,8 @@ IPCCommandResult ES::GetDeviceCertificate(const IOCtlVRequest& request)
|
|||||||
|
|
||||||
INFO_LOG(IOS_ES, "IOCTL_ES_GETDEVICECERT");
|
INFO_LOG(IOS_ES, "IOCTL_ES_GETDEVICECERT");
|
||||||
|
|
||||||
const auto cert = m_ios.GetIOSC().GetDeviceCertificate();
|
const IOS::CertECC cert = m_ios.GetIOSC().GetDeviceCertificate();
|
||||||
Memory::CopyToEmu(request.io_vectors[0].address, cert.data(), cert.size());
|
Memory::CopyToEmu(request.io_vectors[0].address, &cert, sizeof(cert));
|
||||||
return GetDefaultReply(IPC_SUCCESS);
|
return GetDefaultReply(IPC_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -417,29 +417,25 @@ u32 IOSC::GetDeviceId() const
|
|||||||
// Copyright 2007,2008 Segher Boessenkool <segher@kernel.crashing.org>
|
// Copyright 2007,2008 Segher Boessenkool <segher@kernel.crashing.org>
|
||||||
// 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
|
||||||
static Certificate MakeBlankSigECCert(const std::string& signer, const std::string& name,
|
static CertECC MakeBlankEccCert(const std::string& issuer, const std::string& name,
|
||||||
const u8* private_key, u32 key_id)
|
const u8* private_key, u32 key_id)
|
||||||
{
|
{
|
||||||
Certificate cert_out{};
|
CertECC cert{};
|
||||||
const u32 type = Common::swap32(static_cast<u32>(SignatureType::ECC));
|
cert.signature.type = SignatureType(Common::swap32(u32(SignatureType::ECC)));
|
||||||
std::memcpy(cert_out.data(), &type, sizeof(type));
|
std::strncpy(cert.signature.issuer, issuer.c_str(), 0x40);
|
||||||
std::strncpy(reinterpret_cast<char*>(cert_out.data()) + 0x80, signer.c_str(), 0x40);
|
cert.header.public_key_type = PublicKeyType(Common::swap32(u32(PublicKeyType::ECC)));
|
||||||
const u32 two = Common::swap32(2);
|
std::strncpy(cert.header.name, name.c_str(), 0x40);
|
||||||
std::memcpy(cert_out.data() + 0xc0, &two, sizeof(two));
|
cert.header.id = Common::swap32(key_id);
|
||||||
std::strncpy(reinterpret_cast<char*>(cert_out.data()) + 0xc4, name.c_str(), 0x40);
|
cert.public_key = Common::ec::PrivToPub(private_key);
|
||||||
const u32 swapped_key_id = Common::swap32(key_id);
|
return cert;
|
||||||
std::memcpy(cert_out.data() + 0x104, &swapped_key_id, sizeof(swapped_key_id));
|
|
||||||
const std::array<u8, 60> public_key = Common::ec::PrivToPub(private_key);
|
|
||||||
std::copy(public_key.cbegin(), public_key.cend(), cert_out.begin() + 0x108);
|
|
||||||
return cert_out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Certificate IOSC::GetDeviceCertificate() const
|
CertECC IOSC::GetDeviceCertificate() const
|
||||||
{
|
{
|
||||||
const std::string name = StringFromFormat("NG%08x", GetDeviceId());
|
const std::string name = StringFromFormat("NG%08x", GetDeviceId());
|
||||||
auto cert = MakeBlankSigECCert(StringFromFormat("Root-CA%08x-MS%08x", m_ca_id, m_ms_id), name,
|
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);
|
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);
|
cert.signature.sig = m_console_signature;
|
||||||
return cert;
|
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 =
|
const std::string signer =
|
||||||
StringFromFormat("Root-CA%08x-MS%08x-NG%08x", m_ca_id, m_ms_id, GetDeviceId());
|
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 std::string name = StringFromFormat("AP%016" PRIx64, title_id);
|
||||||
const auto cert = MakeBlankSigECCert(signer, name, ap_priv.data(), 0);
|
CertECC cert = MakeBlankEccCert(signer, name, ap_priv.data(), 0);
|
||||||
std::copy(cert.begin(), cert.end(), ap_cert_out);
|
// Sign the AP cert.
|
||||||
|
const size_t skip = offsetof(CertECC, signature.issuer);
|
||||||
mbedtls_sha1(ap_cert_out + 0x80, 0x100, hash.data());
|
mbedtls_sha1(reinterpret_cast<const u8*>(&cert) + skip, sizeof(cert) - skip, hash.data());
|
||||||
auto signature = Common::ec::Sign(m_key_entries[HANDLE_CONSOLE_KEY].data.data(), hash.data());
|
cert.signature.sig = Common::ec::Sign(m_key_entries[HANDLE_CONSOLE_KEY].data.data(), hash.data());
|
||||||
std::copy(signature.cbegin(), signature.cend(), ap_cert_out + 4);
|
std::memcpy(ap_cert_out, &cert, sizeof(cert));
|
||||||
|
|
||||||
|
// Sign the data.
|
||||||
mbedtls_sha1(data, data_size, hash.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);
|
std::copy(signature.cbegin(), signature.cend(), sig_out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,6 +37,8 @@ enum class PublicKeyType : u32
|
|||||||
ECC = 2,
|
ECC = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
using ECCSignature = std::array<u8, 60>;
|
||||||
|
|
||||||
#pragma pack(push, 4)
|
#pragma pack(push, 4)
|
||||||
struct SignatureRSA4096
|
struct SignatureRSA4096
|
||||||
{
|
{
|
||||||
@ -59,7 +61,7 @@ static_assert(sizeof(SignatureRSA2048) == 0x180, "Wrong size for SignatureRSA204
|
|||||||
struct SignatureECC
|
struct SignatureECC
|
||||||
{
|
{
|
||||||
SignatureType type;
|
SignatureType type;
|
||||||
u8 sig[0x3c];
|
ECCSignature sig;
|
||||||
u8 fill[0x40];
|
u8 fill[0x40];
|
||||||
char issuer[0x40];
|
char issuer[0x40];
|
||||||
};
|
};
|
||||||
@ -117,9 +119,6 @@ struct CertECC
|
|||||||
static_assert(sizeof(CertECC) == 0x180, "Wrong size for CertECC");
|
static_assert(sizeof(CertECC) == 0x180, "Wrong size for CertECC");
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
using ECCSignature = std::array<u8, 60>;
|
|
||||||
using Certificate = std::array<u8, 0x180>;
|
|
||||||
|
|
||||||
namespace HLE
|
namespace HLE
|
||||||
{
|
{
|
||||||
enum ReturnCode : s32;
|
enum ReturnCode : s32;
|
||||||
@ -223,7 +222,7 @@ public:
|
|||||||
|
|
||||||
bool IsUsingDefaultId() const;
|
bool IsUsingDefaultId() const;
|
||||||
u32 GetDeviceId() 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 Sign(u8* sig_out, u8* ap_cert_out, u64 title_id, const u8* data, u32 data_size) const;
|
||||||
|
|
||||||
void DoState(PointerWrap& p);
|
void DoState(PointerWrap& p);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user