summaryrefslogtreecommitdiffstats
path: root/src/core/crypto/key_manager.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/core/crypto/key_manager.h96
1 files changed, 83 insertions, 13 deletions
diff --git a/src/core/crypto/key_manager.h b/src/core/crypto/key_manager.h
index 8a67b172d..ff6bd08e1 100644
--- a/src/core/crypto/key_manager.h
+++ b/src/core/crypto/key_manager.h
@@ -11,6 +11,7 @@
#include <boost/container/flat_map.hpp>
#include <fmt/format.h>
+#include "common/common_funcs.h"
#include "common/common_types.h"
#include "core/crypto/partition_data_manager.h"
#include "core/file_sys/vfs_types.h"
@@ -30,7 +31,76 @@ constexpr u64 TICKET_FILE_TITLEKEY_OFFSET = 0x180;
using Key128 = std::array<u8, 0x10>;
using Key256 = std::array<u8, 0x20>;
using SHA256Hash = std::array<u8, 0x20>;
-using TicketRaw = std::array<u8, 0x400>;
+
+enum class SignatureType {
+ RSA_4096_SHA1 = 0x10000,
+ RSA_2048_SHA1 = 0x10001,
+ ECDSA_SHA1 = 0x10002,
+ RSA_4096_SHA256 = 0x10003,
+ RSA_2048_SHA256 = 0x10004,
+ ECDSA_SHA256 = 0x10005,
+};
+
+u64 GetSignatureTypeDataSize(SignatureType type);
+u64 GetSignatureTypePaddingSize(SignatureType type);
+
+enum class TitleKeyType : u8 {
+ Common = 0,
+ Personalized = 1,
+};
+
+struct TicketData {
+ std::array<u8, 0x40> issuer;
+ union {
+ std::array<u8, 0x100> title_key_block;
+
+ struct {
+ Key128 title_key_common;
+ std::array<u8, 0xF0> title_key_common_pad;
+ };
+ };
+
+ INSERT_PADDING_BYTES(0x1);
+ TitleKeyType type;
+ INSERT_PADDING_BYTES(0x3);
+ u8 revision;
+ INSERT_PADDING_BYTES(0xA);
+ u64 ticket_id;
+ u64 device_id;
+ std::array<u8, 0x10> rights_id;
+ u32 account_id;
+ INSERT_PADDING_BYTES(0x14C);
+};
+static_assert(sizeof(TicketData) == 0x2C0, "TicketData has incorrect size.");
+
+struct Ticket {
+ SignatureType sig_type;
+ union {
+ struct {
+ std::array<u8, 0x200> sig_data;
+ INSERT_PADDING_BYTES(0x3C);
+ TicketData data;
+ } rsa_4096;
+
+ struct {
+ std::array<u8, 0x100> sig_data;
+ INSERT_PADDING_BYTES(0x3C);
+ TicketData data;
+ } rsa_2048;
+
+ struct {
+ std::array<u8, 0x3C> sig_data;
+ INSERT_PADDING_BYTES(0x40);
+ TicketData data;
+ } ecdsa;
+ };
+
+ TicketData& GetData();
+ const TicketData& GetData() const;
+ u64 GetSize() const;
+
+ static Ticket SynthesizeCommon(Key128 title_key, std::array<u8, 0x10> rights_id);
+};
static_assert(sizeof(Key128) == 16, "Key128 must be 128 bytes big.");
static_assert(sizeof(Key256) == 32, "Key256 must be 256 bytes big.");
@@ -158,8 +228,8 @@ public:
static bool KeyFileExists(bool title);
- // Call before using the sd seed to attempt to derive it if it dosen't exist. Needs system save
- // 8*43 and the private file to exist.
+ // Call before using the sd seed to attempt to derive it if it dosen't exist. Needs system
+ // save 8*43 and the private file to exist.
void DeriveSDSeedLazy();
bool BaseDeriveNecessary() const;
@@ -169,19 +239,19 @@ public:
void PopulateFromPartitionData(PartitionDataManager& data);
- const std::map<u128, TicketRaw>& GetCommonTickets() const;
- const std::map<u128, TicketRaw>& GetPersonalizedTickets() const;
+ const std::map<u128, Ticket>& GetCommonTickets() const;
+ const std::map<u128, Ticket>& GetPersonalizedTickets() const;
- bool AddTicketCommon(TicketRaw raw);
- bool AddTicketPersonalized(TicketRaw raw);
+ bool AddTicketCommon(Ticket raw);
+ bool AddTicketPersonalized(Ticket raw);
private:
std::map<KeyIndex<S128KeyType>, Key128> s128_keys;
std::map<KeyIndex<S256KeyType>, Key256> s256_keys;
// Map from rights ID to ticket
- std::map<u128, TicketRaw> common_tickets;
- std::map<u128, TicketRaw> personal_tickets;
+ std::map<u128, Ticket> common_tickets;
+ std::map<u128, Ticket> personal_tickets;
std::array<std::array<u8, 0xB0>, 0x20> encrypted_keyblobs{};
std::array<std::array<u8, 0x90>, 0x20> keyblobs{};
@@ -216,11 +286,11 @@ std::array<u8, 0x90> DecryptKeyblob(const std::array<u8, 0xB0>& encrypted_keyblo
std::optional<Key128> DeriveSDSeed();
Loader::ResultStatus DeriveSDKeys(std::array<Key256, 2>& sd_keys, KeyManager& keys);
-std::vector<TicketRaw> GetTicketblob(const FileUtil::IOFile& ticket_save);
+std::vector<Ticket> GetTicketblob(const FileUtil::IOFile& ticket_save);
-// Returns a pair of {rights_id, titlekey}. Fails if the ticket has no certificate authority (offset
-// 0x140-0x144 is zero)
-std::optional<std::pair<Key128, Key128>> ParseTicket(const TicketRaw& ticket,
+// Returns a pair of {rights_id, titlekey}. Fails if the ticket has no certificate authority
+// (offset 0x140-0x144 is zero)
+std::optional<std::pair<Key128, Key128>> ParseTicket(const Ticket& ticket,
const RSAKeyPair<2048>& eticket_extended_key);
} // namespace Core::Crypto