summaryrefslogtreecommitdiff
path: root/src/core/crypto/key_manager.h
diff options
context:
space:
mode:
authorGravatar Zach Hilman2019-04-16 09:12:04 -0400
committerGravatar Zach Hilman2019-07-07 21:38:33 -0400
commitf8718ae779bbdc6a3f514b5ce141515baa97e14f (patch)
tree4a7712329982e2cb512412cbb4a17fa52a53f780 /src/core/crypto/key_manager.h
parentes: Implement ETicket GetPersonalizedTicketData (17) (diff)
downloadyuzu-f8718ae779bbdc6a3f514b5ce141515baa97e14f.tar.gz
yuzu-f8718ae779bbdc6a3f514b5ce141515baa97e14f.tar.xz
yuzu-f8718ae779bbdc6a3f514b5ce141515baa97e14f.zip
key_manager: Add structure for Ticket parsing
Diffstat (limited to 'src/core/crypto/key_manager.h')
-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 @@
11 11
12#include <boost/container/flat_map.hpp> 12#include <boost/container/flat_map.hpp>
13#include <fmt/format.h> 13#include <fmt/format.h>
14#include "common/common_funcs.h"
14#include "common/common_types.h" 15#include "common/common_types.h"
15#include "core/crypto/partition_data_manager.h" 16#include "core/crypto/partition_data_manager.h"
16#include "core/file_sys/vfs_types.h" 17#include "core/file_sys/vfs_types.h"
@@ -30,7 +31,76 @@ constexpr u64 TICKET_FILE_TITLEKEY_OFFSET = 0x180;
30using Key128 = std::array<u8, 0x10>; 31using Key128 = std::array<u8, 0x10>;
31using Key256 = std::array<u8, 0x20>; 32using Key256 = std::array<u8, 0x20>;
32using SHA256Hash = std::array<u8, 0x20>; 33using SHA256Hash = std::array<u8, 0x20>;
33using TicketRaw = std::array<u8, 0x400>; 34
35enum class SignatureType {
36 RSA_4096_SHA1 = 0x10000,
37 RSA_2048_SHA1 = 0x10001,
38 ECDSA_SHA1 = 0x10002,
39 RSA_4096_SHA256 = 0x10003,
40 RSA_2048_SHA256 = 0x10004,
41 ECDSA_SHA256 = 0x10005,
42};
43
44u64 GetSignatureTypeDataSize(SignatureType type);
45u64 GetSignatureTypePaddingSize(SignatureType type);
46
47enum class TitleKeyType : u8 {
48 Common = 0,
49 Personalized = 1,
50};
51
52struct TicketData {
53 std::array<u8, 0x40> issuer;
54 union {
55 std::array<u8, 0x100> title_key_block;
56
57 struct {
58 Key128 title_key_common;
59 std::array<u8, 0xF0> title_key_common_pad;
60 };
61 };
62
63 INSERT_PADDING_BYTES(0x1);
64 TitleKeyType type;
65 INSERT_PADDING_BYTES(0x3);
66 u8 revision;
67 INSERT_PADDING_BYTES(0xA);
68 u64 ticket_id;
69 u64 device_id;
70 std::array<u8, 0x10> rights_id;
71 u32 account_id;
72 INSERT_PADDING_BYTES(0x14C);
73};
74static_assert(sizeof(TicketData) == 0x2C0, "TicketData has incorrect size.");
75
76struct Ticket {
77 SignatureType sig_type;
78 union {
79 struct {
80 std::array<u8, 0x200> sig_data;
81 INSERT_PADDING_BYTES(0x3C);
82 TicketData data;
83 } rsa_4096;
84
85 struct {
86 std::array<u8, 0x100> sig_data;
87 INSERT_PADDING_BYTES(0x3C);
88 TicketData data;
89 } rsa_2048;
90
91 struct {
92 std::array<u8, 0x3C> sig_data;
93 INSERT_PADDING_BYTES(0x40);
94 TicketData data;
95 } ecdsa;
96 };
97
98 TicketData& GetData();
99 const TicketData& GetData() const;
100 u64 GetSize() const;
101
102 static Ticket SynthesizeCommon(Key128 title_key, std::array<u8, 0x10> rights_id);
103};
34 104
35static_assert(sizeof(Key128) == 16, "Key128 must be 128 bytes big."); 105static_assert(sizeof(Key128) == 16, "Key128 must be 128 bytes big.");
36static_assert(sizeof(Key256) == 32, "Key256 must be 256 bytes big."); 106static_assert(sizeof(Key256) == 32, "Key256 must be 256 bytes big.");
@@ -158,8 +228,8 @@ public:
158 228
159 static bool KeyFileExists(bool title); 229 static bool KeyFileExists(bool title);
160 230
161 // Call before using the sd seed to attempt to derive it if it dosen't exist. Needs system save 231 // Call before using the sd seed to attempt to derive it if it dosen't exist. Needs system
162 // 8*43 and the private file to exist. 232 // save 8*43 and the private file to exist.
163 void DeriveSDSeedLazy(); 233 void DeriveSDSeedLazy();
164 234
165 bool BaseDeriveNecessary() const; 235 bool BaseDeriveNecessary() const;
@@ -169,19 +239,19 @@ public:
169 239
170 void PopulateFromPartitionData(PartitionDataManager& data); 240 void PopulateFromPartitionData(PartitionDataManager& data);
171 241
172 const std::map<u128, TicketRaw>& GetCommonTickets() const; 242 const std::map<u128, Ticket>& GetCommonTickets() const;
173 const std::map<u128, TicketRaw>& GetPersonalizedTickets() const; 243 const std::map<u128, Ticket>& GetPersonalizedTickets() const;
174 244
175 bool AddTicketCommon(TicketRaw raw); 245 bool AddTicketCommon(Ticket raw);
176 bool AddTicketPersonalized(TicketRaw raw); 246 bool AddTicketPersonalized(Ticket raw);
177 247
178private: 248private:
179 std::map<KeyIndex<S128KeyType>, Key128> s128_keys; 249 std::map<KeyIndex<S128KeyType>, Key128> s128_keys;
180 std::map<KeyIndex<S256KeyType>, Key256> s256_keys; 250 std::map<KeyIndex<S256KeyType>, Key256> s256_keys;
181 251
182 // Map from rights ID to ticket 252 // Map from rights ID to ticket
183 std::map<u128, TicketRaw> common_tickets; 253 std::map<u128, Ticket> common_tickets;
184 std::map<u128, TicketRaw> personal_tickets; 254 std::map<u128, Ticket> personal_tickets;
185 255
186 std::array<std::array<u8, 0xB0>, 0x20> encrypted_keyblobs{}; 256 std::array<std::array<u8, 0xB0>, 0x20> encrypted_keyblobs{};
187 std::array<std::array<u8, 0x90>, 0x20> keyblobs{}; 257 std::array<std::array<u8, 0x90>, 0x20> keyblobs{};
@@ -216,11 +286,11 @@ std::array<u8, 0x90> DecryptKeyblob(const std::array<u8, 0xB0>& encrypted_keyblo
216std::optional<Key128> DeriveSDSeed(); 286std::optional<Key128> DeriveSDSeed();
217Loader::ResultStatus DeriveSDKeys(std::array<Key256, 2>& sd_keys, KeyManager& keys); 287Loader::ResultStatus DeriveSDKeys(std::array<Key256, 2>& sd_keys, KeyManager& keys);
218 288
219std::vector<TicketRaw> GetTicketblob(const FileUtil::IOFile& ticket_save); 289std::vector<Ticket> GetTicketblob(const FileUtil::IOFile& ticket_save);
220 290
221// Returns a pair of {rights_id, titlekey}. Fails if the ticket has no certificate authority (offset 291// Returns a pair of {rights_id, titlekey}. Fails if the ticket has no certificate authority
222// 0x140-0x144 is zero) 292// (offset 0x140-0x144 is zero)
223std::optional<std::pair<Key128, Key128>> ParseTicket(const TicketRaw& ticket, 293std::optional<std::pair<Key128, Key128>> ParseTicket(const Ticket& ticket,
224 const RSAKeyPair<2048>& eticket_extended_key); 294 const RSAKeyPair<2048>& eticket_extended_key);
225 295
226} // namespace Core::Crypto 296} // namespace Core::Crypto