diff --git a/Source/Core/Core/IOS/ES/Formats.cpp b/Source/Core/Core/IOS/ES/Formats.cpp index 66ebb0dff4..e0cc70dea3 100644 --- a/Source/Core/Core/IOS/ES/Formats.cpp +++ b/Source/Core/Core/IOS/ES/Formats.cpp @@ -307,8 +307,8 @@ std::vector TicketReader::GetRawTicketView(u32 ticket_num) const std::string TicketReader::GetIssuer() const { const char* bytes = - reinterpret_cast(m_bytes.data() + offsetof(Ticket, signature_issuer)); - return std::string(bytes, strnlen(bytes, sizeof(Ticket::signature_issuer))); + reinterpret_cast(m_bytes.data() + offsetof(Ticket, signature.issuer)); + return std::string(bytes, strnlen(bytes, sizeof(Ticket::signature.issuer))); } u32 TicketReader::GetDeviceId() const diff --git a/Source/Core/Core/IOS/ES/Formats.h b/Source/Core/Core/IOS/ES/Formats.h index 77db4ec3b3..178fc643fa 100644 --- a/Source/Core/Core/IOS/ES/Formats.h +++ b/Source/Core/Core/IOS/ES/Formats.h @@ -16,6 +16,7 @@ #include "Common/CommonTypes.h" #include "Common/NandPaths.h" +#include "Core/IOS/IOSC.h" #include "DiscIO/Enums.h" class PointerWrap; @@ -56,10 +57,7 @@ enum TitleFlags : u32 #pragma pack(push, 4) struct TMDHeader { - u32 signature_type; - u8 rsa_2048_signature[256]; - u8 fill[60]; - u8 issuer[64]; + SignatureRSA2048 signature; u8 tmd_version; u8 ca_crl_version; u8 signer_crl_version; @@ -120,10 +118,7 @@ static_assert(sizeof(TicketView) == 0xd8, "TicketView has the wrong size"); // the only ticket type that is supported by the Wii's IOS. struct Ticket { - u32 signature_type; - u8 signature[256]; - u8 unused[60]; - u8 signature_issuer[0x40]; + SignatureRSA2048 signature; u8 server_public_key[0x3c]; u8 version; u8 ca_crl_version; diff --git a/Source/Core/Core/IOS/IOSC.h b/Source/Core/Core/IOS/IOSC.h index 773fba36c4..2c4c806c92 100644 --- a/Source/Core/Core/IOS/IOSC.h +++ b/Source/Core/Core/IOS/IOSC.h @@ -17,6 +17,85 @@ class PointerWrap; namespace IOS { +enum class SignatureType : u32 +{ + RSA4096 = 0x00010000, + RSA2048 = 0x00010001, + // XXX: Add support for ECC (0x00010002). +}; + +enum class PublicKeyType : u32 +{ + RSA4096 = 0, + RSA2048 = 1, +}; + +#pragma pack(push, 4) +struct SignatureRSA4096 +{ + SignatureType type; + u8 sig[0x200]; + u8 fill[0x3c]; + char issuer[0x40]; +}; +static_assert(sizeof(SignatureRSA4096) == 0x280, "Wrong size for SignatureRSA4096"); + +struct SignatureRSA2048 +{ + SignatureType type; + u8 sig[0x100]; + u8 fill[0x3c]; + char issuer[0x40]; +}; +static_assert(sizeof(SignatureRSA2048) == 0x180, "Wrong size for SignatureRSA2048"); + +struct SignatureECC +{ + SignatureType type; + u8 sig[0x3c]; + u8 fill[0x40]; + char issuer[0x40]; +}; +static_assert(sizeof(SignatureECC) == 0xc0, "Wrong size for SignatureECC"); + +// Source: https://wiibrew.org/wiki/Certificate_chain +struct CertHeader +{ + PublicKeyType public_key_type; + char name[0x40]; + u32 id; +}; + +struct CertRSA4096 +{ + SignatureRSA4096 signature; + CertHeader header; + // The signature is RSA4096, but the key is a RSA2048 public key, + // so its size is 0x100, not 0x200, as one would expect from the name. + u8 public_key[0x100]; + u8 exponent[0x4]; + u8 pad[0x34]; +}; +static_assert(sizeof(CertRSA4096) == 0x400, "Wrong size for CertRSA4096"); + +struct CertRSA2048 +{ + SignatureRSA2048 signature; + CertHeader header; + u8 public_key[0x100]; + u8 exponent[0x4]; + u8 pad[0x34]; +}; +static_assert(sizeof(CertRSA2048) == 0x300, "Wrong size for CertRSA2048"); + +union Cert +{ + SignatureType type; + CertRSA4096 rsa4096; + CertRSA2048 rsa2048; +}; +#pragma pack(pop) + namespace HLE { enum ReturnCode : s32;