key_manager.h 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318
  1. // Copyright 2018 yuzu emulator team
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #pragma once
  5. #include <array>
  6. #include <map>
  7. #include <optional>
  8. #include <string>
  9. #include <variant>
  10. #include <fmt/format.h>
  11. #include "common/common_funcs.h"
  12. #include "common/common_types.h"
  13. #include "core/crypto/partition_data_manager.h"
  14. #include "core/file_sys/vfs_types.h"
  15. namespace Common::FS {
  16. class IOFile;
  17. }
  18. namespace FileSys {
  19. class ContentProvider;
  20. }
  21. namespace Loader {
  22. enum class ResultStatus : u16;
  23. }
  24. namespace Core::Crypto {
  25. constexpr u64 TICKET_FILE_TITLEKEY_OFFSET = 0x180;
  26. using Key128 = std::array<u8, 0x10>;
  27. using Key256 = std::array<u8, 0x20>;
  28. using SHA256Hash = std::array<u8, 0x20>;
  29. enum class SignatureType {
  30. RSA_4096_SHA1 = 0x10000,
  31. RSA_2048_SHA1 = 0x10001,
  32. ECDSA_SHA1 = 0x10002,
  33. RSA_4096_SHA256 = 0x10003,
  34. RSA_2048_SHA256 = 0x10004,
  35. ECDSA_SHA256 = 0x10005,
  36. };
  37. u64 GetSignatureTypeDataSize(SignatureType type);
  38. u64 GetSignatureTypePaddingSize(SignatureType type);
  39. enum class TitleKeyType : u8 {
  40. Common = 0,
  41. Personalized = 1,
  42. };
  43. struct TicketData {
  44. std::array<u8, 0x40> issuer;
  45. union {
  46. std::array<u8, 0x100> title_key_block;
  47. struct {
  48. Key128 title_key_common;
  49. std::array<u8, 0xF0> title_key_common_pad;
  50. };
  51. };
  52. INSERT_PADDING_BYTES(0x1);
  53. TitleKeyType type;
  54. INSERT_PADDING_BYTES(0x3);
  55. u8 revision;
  56. INSERT_PADDING_BYTES(0xA);
  57. u64 ticket_id;
  58. u64 device_id;
  59. std::array<u8, 0x10> rights_id;
  60. u32 account_id;
  61. INSERT_PADDING_BYTES(0x14C);
  62. };
  63. static_assert(sizeof(TicketData) == 0x2C0, "TicketData has incorrect size.");
  64. struct RSA4096Ticket {
  65. SignatureType sig_type;
  66. std::array<u8, 0x200> sig_data;
  67. INSERT_PADDING_BYTES(0x3C);
  68. TicketData data;
  69. };
  70. struct RSA2048Ticket {
  71. SignatureType sig_type;
  72. std::array<u8, 0x100> sig_data;
  73. INSERT_PADDING_BYTES(0x3C);
  74. TicketData data;
  75. };
  76. struct ECDSATicket {
  77. SignatureType sig_type;
  78. std::array<u8, 0x3C> sig_data;
  79. INSERT_PADDING_BYTES(0x40);
  80. TicketData data;
  81. };
  82. struct Ticket {
  83. std::variant<RSA4096Ticket, RSA2048Ticket, ECDSATicket> data;
  84. SignatureType GetSignatureType() const;
  85. TicketData& GetData();
  86. const TicketData& GetData() const;
  87. u64 GetSize() const;
  88. static Ticket SynthesizeCommon(Key128 title_key, const std::array<u8, 0x10>& rights_id);
  89. };
  90. static_assert(sizeof(Key128) == 16, "Key128 must be 128 bytes big.");
  91. static_assert(sizeof(Key256) == 32, "Key256 must be 256 bytes big.");
  92. template <size_t bit_size, size_t byte_size = (bit_size >> 3)>
  93. struct RSAKeyPair {
  94. std::array<u8, byte_size> encryption_key;
  95. std::array<u8, byte_size> decryption_key;
  96. std::array<u8, byte_size> modulus;
  97. std::array<u8, 4> exponent;
  98. };
  99. template <size_t bit_size, size_t byte_size>
  100. bool operator==(const RSAKeyPair<bit_size, byte_size>& lhs,
  101. const RSAKeyPair<bit_size, byte_size>& rhs) {
  102. return std::tie(lhs.encryption_key, lhs.decryption_key, lhs.modulus, lhs.exponent) ==
  103. std::tie(rhs.encryption_key, rhs.decryption_key, rhs.modulus, rhs.exponent);
  104. }
  105. template <size_t bit_size, size_t byte_size>
  106. bool operator!=(const RSAKeyPair<bit_size, byte_size>& lhs,
  107. const RSAKeyPair<bit_size, byte_size>& rhs) {
  108. return !(lhs == rhs);
  109. }
  110. enum class KeyCategory : u8 {
  111. Standard,
  112. Title,
  113. Console,
  114. };
  115. enum class S256KeyType : u64 {
  116. SDKey, // f1=SDKeyType
  117. Header, //
  118. SDKeySource, // f1=SDKeyType
  119. HeaderSource, //
  120. };
  121. enum class S128KeyType : u64 {
  122. Master, // f1=crypto revision
  123. Package1, // f1=crypto revision
  124. Package2, // f1=crypto revision
  125. Titlekek, // f1=crypto revision
  126. ETicketRSAKek, //
  127. KeyArea, // f1=crypto revision f2=type {app, ocean, system}
  128. SDSeed, //
  129. Titlekey, // f1=rights id LSB f2=rights id MSB
  130. Source, // f1=source type, f2= sub id
  131. Keyblob, // f1=crypto revision
  132. KeyblobMAC, // f1=crypto revision
  133. TSEC, //
  134. SecureBoot, //
  135. BIS, // f1=partition (0-3), f2=type {crypt, tweak}
  136. HeaderKek, //
  137. SDKek, //
  138. RSAKek, //
  139. };
  140. enum class KeyAreaKeyType : u8 {
  141. Application,
  142. Ocean,
  143. System,
  144. };
  145. enum class SourceKeyType : u8 {
  146. SDKek, //
  147. AESKekGeneration, //
  148. AESKeyGeneration, //
  149. RSAOaepKekGeneration, //
  150. Master, //
  151. Keyblob, // f2=crypto revision
  152. KeyAreaKey, // f2=KeyAreaKeyType
  153. Titlekek, //
  154. Package2, //
  155. HeaderKek, //
  156. KeyblobMAC, //
  157. ETicketKek, //
  158. ETicketKekek, //
  159. };
  160. enum class SDKeyType : u8 {
  161. Save,
  162. NCA,
  163. };
  164. enum class BISKeyType : u8 {
  165. Crypto,
  166. Tweak,
  167. };
  168. enum class RSAKekType : u8 {
  169. Mask0,
  170. Seed3,
  171. };
  172. template <typename KeyType>
  173. struct KeyIndex {
  174. KeyType type;
  175. u64 field1;
  176. u64 field2;
  177. std::string DebugInfo() const {
  178. u8 key_size = 16;
  179. if constexpr (std::is_same_v<KeyType, S256KeyType>)
  180. key_size = 32;
  181. return fmt::format("key_size={:02X}, key={:02X}, field1={:016X}, field2={:016X}", key_size,
  182. static_cast<u8>(type), field1, field2);
  183. }
  184. };
  185. // boost flat_map requires operator< for O(log(n)) lookups.
  186. template <typename KeyType>
  187. bool operator<(const KeyIndex<KeyType>& lhs, const KeyIndex<KeyType>& rhs) {
  188. return std::tie(lhs.type, lhs.field1, lhs.field2) < std::tie(rhs.type, rhs.field1, rhs.field2);
  189. }
  190. class KeyManager {
  191. public:
  192. static KeyManager& Instance() {
  193. static KeyManager instance;
  194. return instance;
  195. }
  196. KeyManager(const KeyManager&) = delete;
  197. KeyManager& operator=(const KeyManager&) = delete;
  198. KeyManager(KeyManager&&) = delete;
  199. KeyManager& operator=(KeyManager&&) = delete;
  200. bool HasKey(S128KeyType id, u64 field1 = 0, u64 field2 = 0) const;
  201. bool HasKey(S256KeyType id, u64 field1 = 0, u64 field2 = 0) const;
  202. Key128 GetKey(S128KeyType id, u64 field1 = 0, u64 field2 = 0) const;
  203. Key256 GetKey(S256KeyType id, u64 field1 = 0, u64 field2 = 0) const;
  204. Key256 GetBISKey(u8 partition_id) const;
  205. void SetKey(S128KeyType id, Key128 key, u64 field1 = 0, u64 field2 = 0);
  206. void SetKey(S256KeyType id, Key256 key, u64 field1 = 0, u64 field2 = 0);
  207. static bool KeyFileExists(bool title);
  208. // Call before using the sd seed to attempt to derive it if it dosen't exist. Needs system
  209. // save 8*43 and the private file to exist.
  210. void DeriveSDSeedLazy();
  211. bool BaseDeriveNecessary() const;
  212. void DeriveBase();
  213. void DeriveETicket(PartitionDataManager& data, const FileSys::ContentProvider& provider);
  214. void PopulateTickets();
  215. void SynthesizeTickets();
  216. void PopulateFromPartitionData(PartitionDataManager& data);
  217. const std::map<u128, Ticket>& GetCommonTickets() const;
  218. const std::map<u128, Ticket>& GetPersonalizedTickets() const;
  219. bool AddTicketCommon(Ticket raw);
  220. bool AddTicketPersonalized(Ticket raw);
  221. private:
  222. KeyManager();
  223. std::map<KeyIndex<S128KeyType>, Key128> s128_keys;
  224. std::map<KeyIndex<S256KeyType>, Key256> s256_keys;
  225. // Map from rights ID to ticket
  226. std::map<u128, Ticket> common_tickets;
  227. std::map<u128, Ticket> personal_tickets;
  228. std::array<std::array<u8, 0xB0>, 0x20> encrypted_keyblobs{};
  229. std::array<std::array<u8, 0x90>, 0x20> keyblobs{};
  230. std::array<u8, 576> eticket_extended_kek{};
  231. bool dev_mode;
  232. void LoadFromFile(const std::string& filename, bool is_title_keys);
  233. void AttemptLoadKeyFile(const std::string& dir1, const std::string& dir2,
  234. const std::string& filename, bool title);
  235. template <size_t Size>
  236. void WriteKeyToFile(KeyCategory category, std::string_view keyname,
  237. const std::array<u8, Size>& key);
  238. void DeriveGeneralPurposeKeys(std::size_t crypto_revision);
  239. RSAKeyPair<2048> GetETicketRSAKey() const;
  240. void SetKeyWrapped(S128KeyType id, Key128 key, u64 field1 = 0, u64 field2 = 0);
  241. void SetKeyWrapped(S256KeyType id, Key256 key, u64 field1 = 0, u64 field2 = 0);
  242. };
  243. Key128 GenerateKeyEncryptionKey(Key128 source, Key128 master, Key128 kek_seed, Key128 key_seed);
  244. Key128 DeriveKeyblobKey(const Key128& sbk, const Key128& tsec, Key128 source);
  245. Key128 DeriveKeyblobMACKey(const Key128& keyblob_key, const Key128& mac_source);
  246. Key128 DeriveMasterKey(const std::array<u8, 0x90>& keyblob, const Key128& master_source);
  247. std::array<u8, 0x90> DecryptKeyblob(const std::array<u8, 0xB0>& encrypted_keyblob,
  248. const Key128& key);
  249. std::optional<Key128> DeriveSDSeed();
  250. Loader::ResultStatus DeriveSDKeys(std::array<Key256, 2>& sd_keys, KeyManager& keys);
  251. std::vector<Ticket> GetTicketblob(const Common::FS::IOFile& ticket_save);
  252. // Returns a pair of {rights_id, titlekey}. Fails if the ticket has no certificate authority
  253. // (offset 0x140-0x144 is zero)
  254. std::optional<std::pair<Key128, Key128>> ParseTicket(const Ticket& ticket,
  255. const RSAKeyPair<2048>& eticket_extended_key);
  256. } // namespace Core::Crypto