summaryrefslogtreecommitdiff
path: root/src/core/crypto/key_manager.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/crypto/key_manager.h')
-rw-r--r--src/core/crypto/key_manager.h104
1 files changed, 93 insertions, 11 deletions
diff --git a/src/core/crypto/key_manager.h b/src/core/crypto/key_manager.h
index 978eec8dc..a41abbdfc 100644
--- a/src/core/crypto/key_manager.h
+++ b/src/core/crypto/key_manager.h
@@ -5,11 +5,18 @@
5#pragma once 5#pragma once
6 6
7#include <array> 7#include <array>
8#include <map>
8#include <string> 9#include <string>
9#include <boost/container/flat_map.hpp> 10#include <boost/container/flat_map.hpp>
10#include <boost/optional.hpp> 11#include <boost/optional.hpp>
11#include <fmt/format.h> 12#include <fmt/format.h>
12#include "common/common_types.h" 13#include "common/common_types.h"
14#include "core/crypto/partition_data_manager.h"
15#include "core/file_sys/vfs_types.h"
16
17namespace FileUtil {
18class IOFile;
19}
13 20
14namespace Loader { 21namespace Loader {
15enum class ResultStatus : u16; 22enum class ResultStatus : u16;
@@ -22,13 +29,30 @@ constexpr u64 TICKET_FILE_TITLEKEY_OFFSET = 0x180;
22using Key128 = std::array<u8, 0x10>; 29using Key128 = std::array<u8, 0x10>;
23using Key256 = std::array<u8, 0x20>; 30using Key256 = std::array<u8, 0x20>;
24using SHA256Hash = std::array<u8, 0x20>; 31using SHA256Hash = std::array<u8, 0x20>;
32using TicketRaw = std::array<u8, 0x400>;
25 33
26static_assert(sizeof(Key128) == 16, "Key128 must be 128 bytes big."); 34static_assert(sizeof(Key128) == 16, "Key128 must be 128 bytes big.");
27static_assert(sizeof(Key256) == 32, "Key128 must be 128 bytes big."); 35static_assert(sizeof(Key256) == 32, "Key256 must be 256 bytes big.");
36
37template <size_t bit_size, size_t byte_size = (bit_size >> 3)>
38struct RSAKeyPair {
39 std::array<u8, byte_size> encryption_key;
40 std::array<u8, byte_size> decryption_key;
41 std::array<u8, byte_size> modulus;
42 std::array<u8, 4> exponent;
43};
44
45enum class KeyCategory : u8 {
46 Standard,
47 Title,
48 Console,
49};
28 50
29enum class S256KeyType : u64 { 51enum class S256KeyType : u64 {
30 Header, // 52 SDKey, // f1=SDKeyType
31 SDKeySource, // f1=SDKeyType 53 Header, //
54 SDKeySource, // f1=SDKeyType
55 HeaderSource, //
32}; 56};
33 57
34enum class S128KeyType : u64 { 58enum class S128KeyType : u64 {
@@ -41,6 +65,14 @@ enum class S128KeyType : u64 {
41 SDSeed, // 65 SDSeed, //
42 Titlekey, // f1=rights id LSB f2=rights id MSB 66 Titlekey, // f1=rights id LSB f2=rights id MSB
43 Source, // f1=source type, f2= sub id 67 Source, // f1=source type, f2= sub id
68 Keyblob, // f1=crypto revision
69 KeyblobMAC, // f1=crypto revision
70 TSEC, //
71 SecureBoot, //
72 BIS, // f1=partition (0-3), f2=type {crypt, tweak}
73 HeaderKek, //
74 SDKek, //
75 RSAKek, //
44}; 76};
45 77
46enum class KeyAreaKeyType : u8 { 78enum class KeyAreaKeyType : u8 {
@@ -50,9 +82,19 @@ enum class KeyAreaKeyType : u8 {
50}; 82};
51 83
52enum class SourceKeyType : u8 { 84enum class SourceKeyType : u8 {
53 SDKEK, 85 SDKek, //
54 AESKEKGeneration, 86 AESKekGeneration, //
55 AESKeyGeneration, 87 AESKeyGeneration, //
88 RSAOaepKekGeneration, //
89 Master, //
90 Keyblob, // f2=crypto revision
91 KeyAreaKey, // f2=KeyAreaKeyType
92 Titlekek, //
93 Package2, //
94 HeaderKek, //
95 KeyblobMAC, //
96 ETicketKek, //
97 ETicketKekek, //
56}; 98};
57 99
58enum class SDKeyType : u8 { 100enum class SDKeyType : u8 {
@@ -60,6 +102,16 @@ enum class SDKeyType : u8 {
60 NCA, 102 NCA,
61}; 103};
62 104
105enum class BISKeyType : u8 {
106 Crypto,
107 Tweak,
108};
109
110enum class RSAKekType : u8 {
111 Mask0,
112 Seed3,
113};
114
63template <typename KeyType> 115template <typename KeyType>
64struct KeyIndex { 116struct KeyIndex {
65 KeyType type; 117 KeyType type;
@@ -91,6 +143,8 @@ public:
91 Key128 GetKey(S128KeyType id, u64 field1 = 0, u64 field2 = 0) const; 143 Key128 GetKey(S128KeyType id, u64 field1 = 0, u64 field2 = 0) const;
92 Key256 GetKey(S256KeyType id, u64 field1 = 0, u64 field2 = 0) const; 144 Key256 GetKey(S256KeyType id, u64 field1 = 0, u64 field2 = 0) const;
93 145
146 Key256 GetBISKey(u8 partition_id) const;
147
94 void SetKey(S128KeyType id, Key128 key, u64 field1 = 0, u64 field2 = 0); 148 void SetKey(S128KeyType id, Key128 key, u64 field1 = 0, u64 field2 = 0);
95 void SetKey(S256KeyType id, Key256 key, u64 field1 = 0, u64 field2 = 0); 149 void SetKey(S256KeyType id, Key256 key, u64 field1 = 0, u64 field2 = 0);
96 150
@@ -100,23 +154,51 @@ public:
100 // 8*43 and the private file to exist. 154 // 8*43 and the private file to exist.
101 void DeriveSDSeedLazy(); 155 void DeriveSDSeedLazy();
102 156
157 bool BaseDeriveNecessary() const;
158 void DeriveBase();
159 void DeriveETicket(PartitionDataManager& data);
160
161 void PopulateFromPartitionData(PartitionDataManager& data);
162
103private: 163private:
104 boost::container::flat_map<KeyIndex<S128KeyType>, Key128> s128_keys; 164 std::map<KeyIndex<S128KeyType>, Key128> s128_keys;
105 boost::container::flat_map<KeyIndex<S256KeyType>, Key256> s256_keys; 165 std::map<KeyIndex<S256KeyType>, Key256> s256_keys;
166
167 std::array<std::array<u8, 0xB0>, 0x20> encrypted_keyblobs{};
168 std::array<std::array<u8, 0x90>, 0x20> keyblobs{};
106 169
107 bool dev_mode; 170 bool dev_mode;
108 void LoadFromFile(const std::string& filename, bool is_title_keys); 171 void LoadFromFile(const std::string& filename, bool is_title_keys);
109 void AttemptLoadKeyFile(const std::string& dir1, const std::string& dir2, 172 void AttemptLoadKeyFile(const std::string& dir1, const std::string& dir2,
110 const std::string& filename, bool title); 173 const std::string& filename, bool title);
111 template <std::size_t Size> 174 template <size_t Size>
112 void WriteKeyToFile(bool title_key, std::string_view keyname, const std::array<u8, Size>& key); 175 void WriteKeyToFile(KeyCategory category, std::string_view keyname,
176 const std::array<u8, Size>& key);
177
178 void DeriveGeneralPurposeKeys(u8 crypto_revision);
179
180 void SetKeyWrapped(S128KeyType id, Key128 key, u64 field1 = 0, u64 field2 = 0);
181 void SetKeyWrapped(S256KeyType id, Key256 key, u64 field1 = 0, u64 field2 = 0);
113 182
114 static const boost::container::flat_map<std::string, KeyIndex<S128KeyType>> s128_file_id; 183 static const boost::container::flat_map<std::string, KeyIndex<S128KeyType>> s128_file_id;
115 static const boost::container::flat_map<std::string, KeyIndex<S256KeyType>> s256_file_id; 184 static const boost::container::flat_map<std::string, KeyIndex<S256KeyType>> s256_file_id;
116}; 185};
117 186
118Key128 GenerateKeyEncryptionKey(Key128 source, Key128 master, Key128 kek_seed, Key128 key_seed); 187Key128 GenerateKeyEncryptionKey(Key128 source, Key128 master, Key128 kek_seed, Key128 key_seed);
188Key128 DeriveKeyblobKey(const Key128& sbk, const Key128& tsec, Key128 source);
189Key128 DeriveKeyblobMACKey(const Key128& keyblob_key, const Key128& mac_source);
190Key128 DeriveMasterKey(const std::array<u8, 0x90>& keyblob, const Key128& master_source);
191std::array<u8, 0x90> DecryptKeyblob(const std::array<u8, 0xB0>& encrypted_keyblob,
192 const Key128& key);
193
119boost::optional<Key128> DeriveSDSeed(); 194boost::optional<Key128> DeriveSDSeed();
120Loader::ResultStatus DeriveSDKeys(std::array<Key256, 2>& sd_keys, const KeyManager& keys); 195Loader::ResultStatus DeriveSDKeys(std::array<Key256, 2>& sd_keys, KeyManager& keys);
196
197std::vector<TicketRaw> GetTicketblob(const FileUtil::IOFile& ticket_save);
198
199// Returns a pair of {rights_id, titlekey}. Fails if the ticket has no certificate authority (offset
200// 0x140-0x144 is zero)
201boost::optional<std::pair<Key128, Key128>> ParseTicket(
202 const TicketRaw& ticket, const RSAKeyPair<2048>& eticket_extended_key);
121 203
122} // namespace Core::Crypto 204} // namespace Core::Crypto