key_manager.h 8.9 KB

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