key_manager.cpp 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011
  1. // Copyright 2018 yuzu emulator team
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #include <algorithm>
  5. #include <array>
  6. #include <bitset>
  7. #include <fstream>
  8. #include <locale>
  9. #include <map>
  10. #include <sstream>
  11. #include <string_view>
  12. #include <tuple>
  13. #include <vector>
  14. #include <mbedtls/bignum.h>
  15. #include <mbedtls/cipher.h>
  16. #include <mbedtls/cmac.h>
  17. #include <mbedtls/sha256.h>
  18. #include "common/common_funcs.h"
  19. #include "common/common_paths.h"
  20. #include "common/file_util.h"
  21. #include "common/hex_util.h"
  22. #include "common/logging/log.h"
  23. #include "core/crypto/aes_util.h"
  24. #include "core/crypto/key_manager.h"
  25. #include "core/file_sys/content_archive.h"
  26. #include "core/file_sys/nca_metadata.h"
  27. #include "core/file_sys/partition_filesystem.h"
  28. #include "core/file_sys/registered_cache.h"
  29. #include "core/hle/service/filesystem/filesystem.h"
  30. #include "core/loader/loader.h"
  31. #include "core/settings.h"
  32. namespace Core::Crypto {
  33. constexpr u64 CURRENT_CRYPTO_REVISION = 0x5;
  34. using namespace Common;
  35. const static std::array<SHA256Hash, 4> eticket_source_hashes{
  36. "B71DB271DC338DF380AA2C4335EF8873B1AFD408E80B3582D8719FC81C5E511C"_array32, // eticket_rsa_kek_source
  37. "E8965A187D30E57869F562D04383C996DE487BBA5761363D2D4D32391866A85C"_array32, // eticket_rsa_kekek_source
  38. };
  39. Key128 GenerateKeyEncryptionKey(Key128 source, Key128 master, Key128 kek_seed, Key128 key_seed) {
  40. Key128 out{};
  41. AESCipher<Key128> cipher1(master, Mode::ECB);
  42. cipher1.Transcode(kek_seed.data(), kek_seed.size(), out.data(), Op::Decrypt);
  43. AESCipher<Key128> cipher2(out, Mode::ECB);
  44. cipher2.Transcode(source.data(), source.size(), out.data(), Op::Decrypt);
  45. if (key_seed != Key128{}) {
  46. AESCipher<Key128> cipher3(out, Mode::ECB);
  47. cipher3.Transcode(key_seed.data(), key_seed.size(), out.data(), Op::Decrypt);
  48. }
  49. return out;
  50. }
  51. Key128 DeriveKeyblobKey(Key128 sbk, Key128 tsec, Key128 source) {
  52. AESCipher<Key128> sbk_cipher(sbk, Mode::ECB);
  53. AESCipher<Key128> tsec_cipher(tsec, Mode::ECB);
  54. tsec_cipher.Transcode(source.data(), source.size(), source.data(), Op::Decrypt);
  55. sbk_cipher.Transcode(source.data(), source.size(), source.data(), Op::Decrypt);
  56. return source;
  57. }
  58. boost::optional<Key128> DeriveSDSeed() {
  59. const FileUtil::IOFile save_43(FileUtil::GetUserPath(FileUtil::UserPath::NANDDir) +
  60. "/system/save/8000000000000043",
  61. "rb+");
  62. if (!save_43.IsOpen())
  63. return boost::none;
  64. const FileUtil::IOFile sd_private(
  65. FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir) + "/Nintendo/Contents/private", "rb+");
  66. if (!sd_private.IsOpen())
  67. return boost::none;
  68. sd_private.Seek(0, SEEK_SET);
  69. std::array<u8, 0x10> private_seed{};
  70. if (sd_private.ReadBytes(private_seed.data(), private_seed.size()) != 0x10)
  71. return boost::none;
  72. std::array<u8, 0x10> buffer{};
  73. std::size_t offset = 0;
  74. for (; offset + 0x10 < save_43.GetSize(); ++offset) {
  75. save_43.Seek(offset, SEEK_SET);
  76. save_43.ReadBytes(buffer.data(), buffer.size());
  77. if (buffer == private_seed)
  78. break;
  79. }
  80. if (offset + 0x10 >= save_43.GetSize())
  81. return boost::none;
  82. Key128 seed{};
  83. save_43.Seek(offset + 0x10, SEEK_SET);
  84. save_43.ReadBytes(seed.data(), seed.size());
  85. return seed;
  86. }
  87. Loader::ResultStatus DeriveSDKeys(std::array<Key256, 2>& sd_keys, KeyManager& keys) {
  88. if (!keys.HasKey(S128KeyType::Source, static_cast<u64>(SourceKeyType::SDKek)))
  89. return Loader::ResultStatus::ErrorMissingSDKEKSource;
  90. if (!keys.HasKey(S128KeyType::Source, static_cast<u64>(SourceKeyType::AESKekGeneration)))
  91. return Loader::ResultStatus::ErrorMissingAESKEKGenerationSource;
  92. if (!keys.HasKey(S128KeyType::Source, static_cast<u64>(SourceKeyType::AESKeyGeneration)))
  93. return Loader::ResultStatus::ErrorMissingAESKeyGenerationSource;
  94. const auto sd_kek_source =
  95. keys.GetKey(S128KeyType::Source, static_cast<u64>(SourceKeyType::SDKek));
  96. const auto aes_kek_gen =
  97. keys.GetKey(S128KeyType::Source, static_cast<u64>(SourceKeyType::AESKekGeneration));
  98. const auto aes_key_gen =
  99. keys.GetKey(S128KeyType::Source, static_cast<u64>(SourceKeyType::AESKeyGeneration));
  100. const auto master_00 = keys.GetKey(S128KeyType::Master);
  101. const auto sd_kek =
  102. GenerateKeyEncryptionKey(sd_kek_source, master_00, aes_kek_gen, aes_key_gen);
  103. keys.SetKey(S128KeyType::SDKek, sd_kek);
  104. if (!keys.HasKey(S128KeyType::SDSeed))
  105. return Loader::ResultStatus::ErrorMissingSDSeed;
  106. const auto sd_seed = keys.GetKey(S128KeyType::SDSeed);
  107. if (!keys.HasKey(S256KeyType::SDKeySource, static_cast<u64>(SDKeyType::Save)))
  108. return Loader::ResultStatus::ErrorMissingSDSaveKeySource;
  109. if (!keys.HasKey(S256KeyType::SDKeySource, static_cast<u64>(SDKeyType::NCA)))
  110. return Loader::ResultStatus::ErrorMissingSDNCAKeySource;
  111. std::array<Key256, 2> sd_key_sources{
  112. keys.GetKey(S256KeyType::SDKeySource, static_cast<u64>(SDKeyType::Save)),
  113. keys.GetKey(S256KeyType::SDKeySource, static_cast<u64>(SDKeyType::NCA)),
  114. };
  115. // Combine sources and seed
  116. for (auto& source : sd_key_sources) {
  117. for (std::size_t i = 0; i < source.size(); ++i)
  118. source[i] ^= sd_seed[i & 0xF];
  119. }
  120. AESCipher<Key128> cipher(sd_kek, Mode::ECB);
  121. // The transform manipulates sd_keys as part of the Transcode, so the return/output is
  122. // unnecessary. This does not alter sd_keys_sources.
  123. std::transform(sd_key_sources.begin(), sd_key_sources.end(), sd_keys.begin(),
  124. sd_key_sources.begin(), [&cipher](const Key256& source, Key256& out) {
  125. cipher.Transcode(source.data(), source.size(), out.data(), Op::Decrypt);
  126. return source; ///< Return unaltered source to satisfy output requirement.
  127. });
  128. keys.SetKey(S256KeyType::SDKey, sd_keys[0], static_cast<u64>(SDKeyType::Save));
  129. keys.SetKey(S256KeyType::SDKey, sd_keys[1], static_cast<u64>(SDKeyType::NCA));
  130. return Loader::ResultStatus::Success;
  131. }
  132. std::vector<TicketRaw> GetTicketblob(const FileUtil::IOFile& ticket_save) {
  133. if (!ticket_save.IsOpen())
  134. return {};
  135. std::vector<u8> buffer(ticket_save.GetSize());
  136. ticket_save.ReadBytes(buffer.data(), buffer.size());
  137. std::vector<TicketRaw> out;
  138. u32 magic{};
  139. for (std::size_t offset = 0; offset + 0x4 < buffer.size(); ++offset) {
  140. if (buffer[offset] == 0x4 && buffer[offset + 1] == 0x0 && buffer[offset + 2] == 0x1 &&
  141. buffer[offset + 3] == 0x0) {
  142. TicketRaw next{};
  143. std::memcpy(&next, buffer.data() + offset, sizeof(TicketRaw));
  144. offset += next.size();
  145. out.push_back(next);
  146. }
  147. }
  148. return out;
  149. }
  150. template <size_t size>
  151. static std::array<u8, size> operator^(const std::array<u8, size>& lhs,
  152. const std::array<u8, size>& rhs) {
  153. std::array<u8, size> out{};
  154. for (size_t i = 0; i < size; ++i)
  155. out[i] = lhs[i] ^ rhs[i];
  156. return out;
  157. }
  158. template <size_t target_size, size_t in_size>
  159. static std::array<u8, target_size> MGF1(const std::array<u8, in_size>& seed) {
  160. std::array<u8, in_size + 4> seed_exp{};
  161. std::memcpy(seed_exp.data(), seed.data(), in_size);
  162. std::vector<u8> out;
  163. size_t i = 0;
  164. while (out.size() < target_size) {
  165. out.resize(out.size() + 0x20, 0);
  166. seed_exp[in_size + 3] = i;
  167. mbedtls_sha256(seed_exp.data(), seed_exp.size(), out.data() + out.size() - 0x20, 0);
  168. ++i;
  169. }
  170. std::array<u8, target_size> target{};
  171. std::memcpy(target.data(), out.data(), target_size);
  172. return target;
  173. }
  174. boost::optional<std::pair<Key128, Key128>> ParseTicket(const TicketRaw& ticket,
  175. const RSAKeyPair<2048>& key) {
  176. u32 cert_authority;
  177. std::memcpy(&cert_authority, ticket.data() + 0x140, sizeof(cert_authority));
  178. if (cert_authority == 0)
  179. return boost::none;
  180. if (cert_authority != Common::MakeMagic('R', 'o', 'o', 't'))
  181. LOG_INFO(Crypto,
  182. "Attempting to parse ticket with non-standard certificate authority {:08X}.",
  183. cert_authority);
  184. Key128 rights_id{};
  185. std::memcpy(rights_id.data(), ticket.data() + 0x2A0, sizeof(Key128));
  186. Key128 key_temp{};
  187. if (!std::any_of(ticket.begin() + 0x190, ticket.begin() + 0x280, [](u8 b) { return b != 0; })) {
  188. std::memcpy(key_temp.data(), ticket.data() + 0x180, key_temp.size());
  189. return std::pair<Key128, Key128>{rights_id, key_temp};
  190. }
  191. mbedtls_mpi D; // RSA Private Exponent
  192. mbedtls_mpi N; // RSA Modulus
  193. mbedtls_mpi S; // Input
  194. mbedtls_mpi M; // Output
  195. mbedtls_mpi_init(&D);
  196. mbedtls_mpi_init(&N);
  197. mbedtls_mpi_init(&S);
  198. mbedtls_mpi_init(&M);
  199. mbedtls_mpi_read_binary(&D, key.decryption_key.data(), key.decryption_key.size());
  200. mbedtls_mpi_read_binary(&N, key.modulus.data(), key.modulus.size());
  201. mbedtls_mpi_read_binary(&S, ticket.data() + 0x180, 0x100);
  202. mbedtls_mpi_exp_mod(&M, &S, &D, &N, nullptr);
  203. std::array<u8, 0x100> rsa_step{};
  204. mbedtls_mpi_write_binary(&M, rsa_step.data(), rsa_step.size());
  205. u8 m_0 = rsa_step[0];
  206. std::array<u8, 0x20> m_1{};
  207. std::memcpy(m_1.data(), rsa_step.data() + 0x01, m_1.size());
  208. std::array<u8, 0xDF> m_2{};
  209. std::memcpy(m_2.data(), rsa_step.data() + 0x21, m_2.size());
  210. if (m_0 != 0)
  211. return boost::none;
  212. m_1 = m_1 ^ MGF1<0x20>(m_2);
  213. m_2 = m_2 ^ MGF1<0xDF>(m_1);
  214. u64 offset = 0;
  215. for (size_t i = 0x20; i < m_2.size() - 0x10; ++i) {
  216. if (m_2[i] == 0x1) {
  217. offset = i + 1;
  218. break;
  219. } else if (m_2[i] != 0x0) {
  220. return boost::none;
  221. }
  222. }
  223. ASSERT(offset > 0);
  224. std::memcpy(key_temp.data(), m_2.data() + offset, key_temp.size());
  225. return std::pair<Key128, Key128>{rights_id, key_temp};
  226. }
  227. KeyManager::KeyManager() {
  228. // Initialize keys
  229. const std::string hactool_keys_dir = FileUtil::GetHactoolConfigurationPath();
  230. const std::string yuzu_keys_dir = FileUtil::GetUserPath(FileUtil::UserPath::KeysDir);
  231. if (Settings::values.use_dev_keys) {
  232. dev_mode = true;
  233. AttemptLoadKeyFile(yuzu_keys_dir, hactool_keys_dir, "dev.keys", false);
  234. AttemptLoadKeyFile(yuzu_keys_dir, yuzu_keys_dir, "dev.keys_autogenerated", false);
  235. } else {
  236. dev_mode = false;
  237. AttemptLoadKeyFile(yuzu_keys_dir, hactool_keys_dir, "prod.keys", false);
  238. AttemptLoadKeyFile(yuzu_keys_dir, yuzu_keys_dir, "prod.keys_autogenerated", false);
  239. }
  240. AttemptLoadKeyFile(yuzu_keys_dir, hactool_keys_dir, "title.keys", true);
  241. AttemptLoadKeyFile(yuzu_keys_dir, yuzu_keys_dir, "title.keys_autogenerated", true);
  242. AttemptLoadKeyFile(yuzu_keys_dir, hactool_keys_dir, "console.keys", false);
  243. AttemptLoadKeyFile(yuzu_keys_dir, yuzu_keys_dir, "console.keys_autogenerated", false);
  244. }
  245. static bool ValidCryptoRevisionString(const std::string& base, size_t begin, size_t length) {
  246. if (base.size() < begin + length)
  247. return false;
  248. return std::all_of(base.begin() + begin, base.begin() + begin + length, ::isdigit);
  249. }
  250. void KeyManager::LoadFromFile(const std::string& filename, bool is_title_keys) {
  251. std::ifstream file(filename);
  252. if (!file.is_open())
  253. return;
  254. std::string line;
  255. while (std::getline(file, line)) {
  256. std::vector<std::string> out;
  257. std::stringstream stream(line);
  258. std::string item;
  259. while (std::getline(stream, item, '='))
  260. out.push_back(std::move(item));
  261. if (out.size() != 2)
  262. continue;
  263. out[0].erase(std::remove(out[0].begin(), out[0].end(), ' '), out[0].end());
  264. out[1].erase(std::remove(out[1].begin(), out[1].end(), ' '), out[1].end());
  265. if (out[0].compare(0, 1, "#") == 0)
  266. continue;
  267. if (is_title_keys) {
  268. auto rights_id_raw = Common::HexStringToArray<16>(out[0]);
  269. u128 rights_id{};
  270. std::memcpy(rights_id.data(), rights_id_raw.data(), rights_id_raw.size());
  271. Key128 key = Common::HexStringToArray<16>(out[1]);
  272. s128_keys[{S128KeyType::Titlekey, rights_id[1], rights_id[0]}] = key;
  273. } else {
  274. std::transform(out[0].begin(), out[0].end(), out[0].begin(), ::tolower);
  275. if (s128_file_id.find(out[0]) != s128_file_id.end()) {
  276. const auto index = s128_file_id.at(out[0]);
  277. Key128 key = Common::HexStringToArray<16>(out[1]);
  278. s128_keys[{index.type, index.field1, index.field2}] = key;
  279. } else if (s256_file_id.find(out[0]) != s256_file_id.end()) {
  280. const auto index = s256_file_id.at(out[0]);
  281. Key256 key = Common::HexStringToArray<32>(out[1]);
  282. s256_keys[{index.type, index.field1, index.field2}] = key;
  283. } else if (out[0].compare(0, 8, "keyblob_") == 0 &&
  284. out[0].compare(0, 9, "keyblob_k") != 0) {
  285. if (!ValidCryptoRevisionString(out[0], 8, 2))
  286. continue;
  287. const auto index = std::stoul(out[0].substr(8, 2), nullptr, 16);
  288. keyblobs[index] = Common::HexStringToArray<0x90>(out[1]);
  289. } else if (out[0].compare(0, 18, "encrypted_keyblob_") == 0) {
  290. if (!ValidCryptoRevisionString(out[0], 18, 2))
  291. continue;
  292. const auto index = std::stoul(out[0].substr(18, 2), nullptr, 16);
  293. encrypted_keyblobs[index] = Common::HexStringToArray<0xB0>(out[1]);
  294. } else {
  295. for (const auto& kv : std::map<std::pair<S128KeyType, u64>, std::string>{
  296. {{S128KeyType::Master, 0}, "master_key_"},
  297. {{S128KeyType::Package1, 0}, "package1_key_"},
  298. {{S128KeyType::Package2, 0}, "package2_key_"},
  299. {{S128KeyType::Titlekek, 0}, "titlekek_"},
  300. {{S128KeyType::Source, static_cast<u64>(SourceKeyType::Keyblob)},
  301. "keyblob_key_source_"},
  302. {{S128KeyType::Keyblob, 0}, "keyblob_key_"},
  303. {{S128KeyType::KeyblobMAC, 0}, "keyblob_mac_key_"},
  304. }) {
  305. if (!ValidCryptoRevisionString(out[0], kv.second.size(), 2))
  306. continue;
  307. if (out[0].compare(0, kv.second.size(), kv.second) == 0) {
  308. const auto index =
  309. std::stoul(out[0].substr(kv.second.size(), 2), nullptr, 16);
  310. const auto sub = kv.first.second;
  311. if (sub == 0) {
  312. s128_keys[{kv.first.first, index, 0}] =
  313. Common::HexStringToArray<16>(out[1]);
  314. } else {
  315. s128_keys[{kv.first.first, kv.first.second, index}] =
  316. Common::HexStringToArray<16>(out[1]);
  317. }
  318. break;
  319. }
  320. }
  321. const static std::array<const char*, 3> kak_names = {
  322. "key_area_key_application_", "key_area_key_ocean_", "key_area_key_system_"};
  323. for (size_t j = 0; j < 3; ++j) {
  324. const auto& match = kak_names[j];
  325. if (out[0].compare(0, std::strlen(match), match) == 0) {
  326. const auto index =
  327. std::stoul(out[0].substr(std::strlen(match), 2), nullptr, 16);
  328. s128_keys[{S128KeyType::KeyArea, index, j}] =
  329. Common::HexStringToArray<16>(out[1]);
  330. }
  331. }
  332. }
  333. }
  334. }
  335. }
  336. void KeyManager::AttemptLoadKeyFile(const std::string& dir1, const std::string& dir2,
  337. const std::string& filename, bool title) {
  338. if (FileUtil::Exists(dir1 + DIR_SEP + filename))
  339. LoadFromFile(dir1 + DIR_SEP + filename, title);
  340. else if (FileUtil::Exists(dir2 + DIR_SEP + filename))
  341. LoadFromFile(dir2 + DIR_SEP + filename, title);
  342. }
  343. bool KeyManager::BaseDeriveNecessary() {
  344. const auto check_key_existence = [this](auto key_type, u64 index1 = 0, u64 index2 = 0) {
  345. return !HasKey(key_type, index1, index2);
  346. };
  347. if (check_key_existence(S256KeyType::Header))
  348. return true;
  349. for (size_t i = 0; i < CURRENT_CRYPTO_REVISION; ++i) {
  350. if (check_key_existence(S128KeyType::Master, i) ||
  351. check_key_existence(S128KeyType::KeyArea, i,
  352. static_cast<u64>(KeyAreaKeyType::Application)) ||
  353. check_key_existence(S128KeyType::KeyArea, i, static_cast<u64>(KeyAreaKeyType::Ocean)) ||
  354. check_key_existence(S128KeyType::KeyArea, i,
  355. static_cast<u64>(KeyAreaKeyType::System)) ||
  356. check_key_existence(S128KeyType::Titlekek, i))
  357. return true;
  358. }
  359. return false;
  360. }
  361. bool KeyManager::HasKey(S128KeyType id, u64 field1, u64 field2) const {
  362. return s128_keys.find({id, field1, field2}) != s128_keys.end();
  363. }
  364. bool KeyManager::HasKey(S256KeyType id, u64 field1, u64 field2) const {
  365. return s256_keys.find({id, field1, field2}) != s256_keys.end();
  366. }
  367. Key128 KeyManager::GetKey(S128KeyType id, u64 field1, u64 field2) const {
  368. if (!HasKey(id, field1, field2))
  369. return {};
  370. return s128_keys.at({id, field1, field2});
  371. }
  372. Key256 KeyManager::GetKey(S256KeyType id, u64 field1, u64 field2) const {
  373. if (!HasKey(id, field1, field2))
  374. return {};
  375. return s256_keys.at({id, field1, field2});
  376. }
  377. Key256 KeyManager::GetBISKey(u8 partition_id) const {
  378. Key256 out{};
  379. for (const auto& bis_type : {BISKeyType::Crypto, BISKeyType::Tweak}) {
  380. if (HasKey(S128KeyType::BIS, partition_id, static_cast<u64>(bis_type))) {
  381. std::memcpy(
  382. out.data() + sizeof(Key128) * static_cast<u64>(bis_type),
  383. s128_keys.at({S128KeyType::BIS, partition_id, static_cast<u64>(bis_type)}).data(),
  384. sizeof(Key128));
  385. }
  386. }
  387. return out;
  388. }
  389. template <size_t Size>
  390. void KeyManager::WriteKeyToFile(KeyCategory category, std::string_view keyname,
  391. const std::array<u8, Size>& key) {
  392. const std::string yuzu_keys_dir = FileUtil::GetUserPath(FileUtil::UserPath::KeysDir);
  393. std::string filename = "title.keys_autogenerated";
  394. if (category == KeyCategory::Standard)
  395. filename = dev_mode ? "dev.keys_autogenerated" : "prod.keys_autogenerated";
  396. else if (category == KeyCategory::Console)
  397. filename = "console.keys_autogenerated";
  398. const auto add_info_text = !FileUtil::Exists(yuzu_keys_dir + DIR_SEP + filename);
  399. FileUtil::CreateFullPath(yuzu_keys_dir + DIR_SEP + filename);
  400. std::ofstream file(yuzu_keys_dir + DIR_SEP + filename, std::ios::app);
  401. if (!file.is_open())
  402. return;
  403. if (add_info_text) {
  404. file
  405. << "# This file is autogenerated by Yuzu\n"
  406. << "# It serves to store keys that were automatically generated from the normal keys\n"
  407. << "# If you are experiencing issues involving keys, it may help to delete this file\n";
  408. }
  409. file << fmt::format("\n{} = {}", keyname, Common::HexArrayToString(key));
  410. AttemptLoadKeyFile(yuzu_keys_dir, yuzu_keys_dir, filename, category == KeyCategory::Title);
  411. }
  412. void KeyManager::SetKey(S128KeyType id, Key128 key, u64 field1, u64 field2) {
  413. if (s128_keys.find({id, field1, field2}) != s128_keys.end())
  414. return;
  415. if (id == S128KeyType::Titlekey) {
  416. Key128 rights_id;
  417. std::memcpy(rights_id.data(), &field2, sizeof(u64));
  418. std::memcpy(rights_id.data() + sizeof(u64), &field1, sizeof(u64));
  419. WriteKeyToFile(KeyCategory::Title, Common::HexArrayToString(rights_id), key);
  420. }
  421. auto category = KeyCategory::Standard;
  422. if (id == S128KeyType::Keyblob || id == S128KeyType::KeyblobMAC || id == S128KeyType::TSEC ||
  423. id == S128KeyType::SecureBoot || id == S128KeyType::SDSeed || id == S128KeyType::BIS) {
  424. category = KeyCategory::Console;
  425. }
  426. const auto iter2 = std::find_if(
  427. s128_file_id.begin(), s128_file_id.end(),
  428. [&id, &field1, &field2](const std::pair<std::string, KeyIndex<S128KeyType>> elem) {
  429. return std::tie(elem.second.type, elem.second.field1, elem.second.field2) ==
  430. std::tie(id, field1, field2);
  431. });
  432. if (iter2 != s128_file_id.end())
  433. WriteKeyToFile(category, iter2->first, key);
  434. // Variable cases
  435. if (id == S128KeyType::KeyArea) {
  436. const static std::array<const char*, 3> kak_names = {"key_area_key_application_{:02X}",
  437. "key_area_key_ocean_{:02X}",
  438. "key_area_key_system_{:02X}"};
  439. WriteKeyToFile(category, fmt::format(kak_names.at(field2), field1), key);
  440. } else if (id == S128KeyType::Master) {
  441. WriteKeyToFile(category, fmt::format("master_key_{:02X}", field1), key);
  442. } else if (id == S128KeyType::Package1) {
  443. WriteKeyToFile(category, fmt::format("package1_key_{:02X}", field1), key);
  444. } else if (id == S128KeyType::Package2) {
  445. WriteKeyToFile(category, fmt::format("package2_key_{:02X}", field1), key);
  446. } else if (id == S128KeyType::Titlekek) {
  447. WriteKeyToFile(category, fmt::format("titlekek_{:02X}", field1), key);
  448. } else if (id == S128KeyType::Keyblob) {
  449. WriteKeyToFile(category, fmt::format("keyblob_key_{:02X}", field1), key);
  450. } else if (id == S128KeyType::KeyblobMAC) {
  451. WriteKeyToFile(category, fmt::format("keyblob_mac_key_{:02X}", field1), key);
  452. } else if (id == S128KeyType::Source && field1 == static_cast<u64>(SourceKeyType::Keyblob)) {
  453. WriteKeyToFile(category, fmt::format("keyblob_key_source_{:02X}", field2), key);
  454. }
  455. s128_keys[{id, field1, field2}] = key;
  456. }
  457. void KeyManager::SetKey(S256KeyType id, Key256 key, u64 field1, u64 field2) {
  458. if (s256_keys.find({id, field1, field2}) != s256_keys.end())
  459. return;
  460. const auto iter = std::find_if(
  461. s256_file_id.begin(), s256_file_id.end(),
  462. [&id, &field1, &field2](const std::pair<std::string, KeyIndex<S256KeyType>> elem) {
  463. return std::tie(elem.second.type, elem.second.field1, elem.second.field2) ==
  464. std::tie(id, field1, field2);
  465. });
  466. if (iter != s256_file_id.end())
  467. WriteKeyToFile(KeyCategory::Standard, iter->first, key);
  468. s256_keys[{id, field1, field2}] = key;
  469. }
  470. bool KeyManager::KeyFileExists(bool title) {
  471. const std::string hactool_keys_dir = FileUtil::GetHactoolConfigurationPath();
  472. const std::string yuzu_keys_dir = FileUtil::GetUserPath(FileUtil::UserPath::KeysDir);
  473. if (title) {
  474. return FileUtil::Exists(hactool_keys_dir + DIR_SEP + "title.keys") ||
  475. FileUtil::Exists(yuzu_keys_dir + DIR_SEP + "title.keys");
  476. }
  477. if (Settings::values.use_dev_keys) {
  478. return FileUtil::Exists(hactool_keys_dir + DIR_SEP + "dev.keys") ||
  479. FileUtil::Exists(yuzu_keys_dir + DIR_SEP + "dev.keys");
  480. }
  481. return FileUtil::Exists(hactool_keys_dir + DIR_SEP + "prod.keys") ||
  482. FileUtil::Exists(yuzu_keys_dir + DIR_SEP + "prod.keys");
  483. }
  484. void KeyManager::DeriveSDSeedLazy() {
  485. if (HasKey(S128KeyType::SDSeed))
  486. return;
  487. const auto res = DeriveSDSeed();
  488. if (res != boost::none)
  489. SetKey(S128KeyType::SDSeed, res.get());
  490. }
  491. static Key128 CalculateCMAC(const u8* source, size_t size, Key128 key) {
  492. Key128 out{};
  493. mbedtls_cipher_cmac(mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_128_ECB), key.data(), 0x80,
  494. source, size, out.data());
  495. return out;
  496. }
  497. void KeyManager::DeriveBase() {
  498. if (!BaseDeriveNecessary())
  499. return;
  500. if (!HasKey(S128KeyType::SecureBoot) || !HasKey(S128KeyType::TSEC))
  501. return;
  502. const auto has_bis = [this](u64 id) {
  503. return HasKey(S128KeyType::BIS, id, static_cast<u64>(BISKeyType::Crypto)) &&
  504. HasKey(S128KeyType::BIS, id, static_cast<u64>(BISKeyType::Tweak));
  505. };
  506. const auto copy_bis = [this](u64 id_from, u64 id_to) {
  507. SetKey(S128KeyType::BIS,
  508. GetKey(S128KeyType::BIS, id_from, static_cast<u64>(BISKeyType::Crypto)), id_to,
  509. static_cast<u64>(BISKeyType::Crypto));
  510. SetKey(S128KeyType::BIS,
  511. GetKey(S128KeyType::BIS, id_from, static_cast<u64>(BISKeyType::Tweak)), id_to,
  512. static_cast<u64>(BISKeyType::Tweak));
  513. };
  514. if (has_bis(2) && !has_bis(3))
  515. copy_bis(2, 3);
  516. else if (has_bis(3) && !has_bis(2))
  517. copy_bis(3, 2);
  518. std::bitset<32> revisions{};
  519. revisions.set();
  520. for (size_t i = 0; i < 32; ++i) {
  521. if (!HasKey(S128KeyType::Source, static_cast<u64>(SourceKeyType::Keyblob), i) ||
  522. encrypted_keyblobs[i] == std::array<u8, 0xB0>{})
  523. revisions.reset(i);
  524. }
  525. if (!revisions.any())
  526. return;
  527. const auto sbk = GetKey(S128KeyType::SecureBoot);
  528. const auto tsec = GetKey(S128KeyType::TSEC);
  529. const auto master_source = GetKey(S128KeyType::Source, static_cast<u64>(SourceKeyType::Master));
  530. const auto kek_generation_source =
  531. GetKey(S128KeyType::Source, static_cast<u64>(SourceKeyType::AESKekGeneration));
  532. const auto key_generation_source =
  533. GetKey(S128KeyType::Source, static_cast<u64>(SourceKeyType::AESKeyGeneration));
  534. for (size_t i = 0; i < 32; ++i) {
  535. if (!revisions[i])
  536. continue;
  537. // Derive keyblob key
  538. const auto key = DeriveKeyblobKey(
  539. sbk, tsec, GetKey(S128KeyType::Source, static_cast<u64>(SourceKeyType::Keyblob), i));
  540. SetKey(S128KeyType::Keyblob, key, i);
  541. // Derive keyblob MAC key
  542. if (!HasKey(S128KeyType::Source, static_cast<u64>(SourceKeyType::KeyblobMAC)))
  543. continue;
  544. const auto mac_source =
  545. GetKey(S128KeyType::Source, static_cast<u64>(SourceKeyType::KeyblobMAC));
  546. AESCipher<Key128> mac_cipher(key, Mode::ECB);
  547. Key128 mac_key{};
  548. mac_cipher.Transcode(mac_source.data(), mac_key.size(), mac_key.data(), Op::Decrypt);
  549. SetKey(S128KeyType::KeyblobMAC, mac_key, i);
  550. Key128 cmac = CalculateCMAC(encrypted_keyblobs[i].data() + 0x10, 0xA0, mac_key);
  551. if (std::memcmp(cmac.data(), encrypted_keyblobs[i].data(), cmac.size()) != 0)
  552. continue;
  553. // Decrypt keyblob
  554. bool has_keyblob = keyblobs[i] != std::array<u8, 0x90>{};
  555. AESCipher<Key128> cipher(key, Mode::CTR);
  556. cipher.SetIV(std::vector<u8>(encrypted_keyblobs[i].data() + 0x10,
  557. encrypted_keyblobs[i].data() + 0x20));
  558. cipher.Transcode(encrypted_keyblobs[i].data() + 0x20, keyblobs[i].size(),
  559. keyblobs[i].data(), Op::Decrypt);
  560. if (!has_keyblob) {
  561. WriteKeyToFile<0x90>(KeyCategory::Console, fmt::format("keyblob_{:02X}", i),
  562. keyblobs[i]);
  563. }
  564. Key128 package1{};
  565. std::memcpy(package1.data(), keyblobs[i].data() + 0x80, sizeof(Key128));
  566. SetKey(S128KeyType::Package1, package1, i);
  567. // Derive master key
  568. if (HasKey(S128KeyType::Source, static_cast<u64>(SourceKeyType::Master))) {
  569. Key128 master_root{};
  570. std::memcpy(master_root.data(), keyblobs[i].data(), sizeof(Key128));
  571. AESCipher<Key128> master_cipher(master_root, Mode::ECB);
  572. Key128 master{};
  573. master_cipher.Transcode(master_source.data(), master_source.size(), master.data(),
  574. Op::Decrypt);
  575. SetKey(S128KeyType::Master, master, i);
  576. }
  577. }
  578. revisions.set();
  579. for (size_t i = 0; i < 32; ++i) {
  580. if (!HasKey(S128KeyType::Master, i))
  581. revisions.reset(i);
  582. }
  583. if (!revisions.any())
  584. return;
  585. for (size_t i = 0; i < 32; ++i) {
  586. if (!revisions[i])
  587. continue;
  588. // Derive general purpose keys
  589. if (HasKey(S128KeyType::Master, i)) {
  590. for (auto kak_type :
  591. {KeyAreaKeyType::Application, KeyAreaKeyType::Ocean, KeyAreaKeyType::System}) {
  592. if (HasKey(S128KeyType::Source, static_cast<u64>(SourceKeyType::KeyAreaKey),
  593. static_cast<u64>(kak_type))) {
  594. const auto source =
  595. GetKey(S128KeyType::Source, static_cast<u64>(SourceKeyType::KeyAreaKey),
  596. static_cast<u64>(kak_type));
  597. const auto kek =
  598. GenerateKeyEncryptionKey(source, GetKey(S128KeyType::Master, i),
  599. kek_generation_source, key_generation_source);
  600. SetKey(S128KeyType::KeyArea, kek, i, static_cast<u64>(kak_type));
  601. }
  602. }
  603. AESCipher<Key128> master_cipher(GetKey(S128KeyType::Master, i), Mode::ECB);
  604. for (auto key_type : {SourceKeyType::Titlekek, SourceKeyType::Package2}) {
  605. if (HasKey(S128KeyType::Source, static_cast<u64>(key_type))) {
  606. Key128 key{};
  607. master_cipher.Transcode(
  608. GetKey(S128KeyType::Source, static_cast<u64>(key_type)).data(), key.size(),
  609. key.data(), Op::Decrypt);
  610. SetKey(key_type == SourceKeyType::Titlekek ? S128KeyType::Titlekek
  611. : S128KeyType::Package2,
  612. key, i);
  613. }
  614. }
  615. }
  616. }
  617. if (HasKey(S128KeyType::Master, 0) &&
  618. HasKey(S128KeyType::Source, static_cast<u64>(SourceKeyType::AESKeyGeneration)) &&
  619. HasKey(S128KeyType::Source, static_cast<u64>(SourceKeyType::AESKekGeneration)) &&
  620. HasKey(S128KeyType::Source, static_cast<u64>(SourceKeyType::HeaderKek)) &&
  621. HasKey(S256KeyType::HeaderSource)) {
  622. const auto header_kek = GenerateKeyEncryptionKey(
  623. GetKey(S128KeyType::Source, static_cast<u64>(SourceKeyType::HeaderKek)),
  624. GetKey(S128KeyType::Master, 0),
  625. GetKey(S128KeyType::Source, static_cast<u64>(SourceKeyType::AESKekGeneration)),
  626. GetKey(S128KeyType::Source, static_cast<u64>(SourceKeyType::AESKeyGeneration)));
  627. SetKey(S128KeyType::HeaderKek, header_kek);
  628. AESCipher<Key128> header_cipher(header_kek, Mode::ECB);
  629. Key256 out = GetKey(S256KeyType::HeaderSource);
  630. header_cipher.Transcode(out.data(), out.size(), out.data(), Op::Decrypt);
  631. SetKey(S256KeyType::Header, out);
  632. }
  633. }
  634. void KeyManager::DeriveETicket(PartitionDataManager data) {
  635. // ETicket keys
  636. const auto es = Service::FileSystem::GetUnionContents()->GetEntry(
  637. 0x0100000000000033, FileSys::ContentRecordType::Program);
  638. if (es == nullptr)
  639. return;
  640. const auto exefs = es->GetExeFS();
  641. if (exefs == nullptr)
  642. return;
  643. const auto main = exefs->GetFile("main");
  644. if (main == nullptr)
  645. return;
  646. const auto bytes = main->ReadAllBytes();
  647. using namespace Common;
  648. const auto eticket_kek = FindKeyFromHex(bytes, eticket_source_hashes[0]);
  649. const auto eticket_kekek = FindKeyFromHex(bytes, eticket_source_hashes[1]);
  650. const auto seed3 = data.GetRSAKekSeed3();
  651. const auto mask0 = data.GetRSAKekMask0();
  652. if (eticket_kek != Key128{})
  653. SetKey(S128KeyType::Source, eticket_kek, static_cast<size_t>(SourceKeyType::ETicketKek));
  654. if (eticket_kekek != Key128{})
  655. SetKey(S128KeyType::Source, eticket_kekek,
  656. static_cast<size_t>(SourceKeyType::ETicketKekek));
  657. if (seed3 != Key128{})
  658. SetKey(S128KeyType::RSAKek, seed3, static_cast<size_t>(RSAKekType::Seed3));
  659. if (mask0 != Key128{})
  660. SetKey(S128KeyType::RSAKek, mask0, static_cast<size_t>(RSAKekType::Mask0));
  661. if (eticket_kek == Key128{} || eticket_kekek == Key128{} || seed3 == Key128{} ||
  662. mask0 == Key128{})
  663. return;
  664. Key128 rsa_oaep_kek{};
  665. for (size_t i = 0; i < rsa_oaep_kek.size(); ++i)
  666. rsa_oaep_kek[i] = seed3[i] ^ mask0[i];
  667. if (rsa_oaep_kek == Key128{})
  668. return;
  669. SetKey(S128KeyType::Source, rsa_oaep_kek,
  670. static_cast<u64>(SourceKeyType::RSAOaepKekGeneration));
  671. Key128 temp_kek{};
  672. Key128 temp_kekek{};
  673. Key128 eticket_final{};
  674. // Derive ETicket RSA Kek
  675. AESCipher<Key128> es_master(GetKey(S128KeyType::Master), Mode::ECB);
  676. es_master.Transcode(rsa_oaep_kek.data(), rsa_oaep_kek.size(), temp_kek.data(), Op::Decrypt);
  677. AESCipher<Key128> es_kekek(temp_kek, Mode::ECB);
  678. es_kekek.Transcode(eticket_kekek.data(), eticket_kekek.size(), temp_kekek.data(), Op::Decrypt);
  679. AESCipher<Key128> es_kek(temp_kekek, Mode::ECB);
  680. es_kek.Transcode(eticket_kek.data(), eticket_kek.size(), eticket_final.data(), Op::Decrypt);
  681. if (eticket_final == Key128{})
  682. return;
  683. SetKey(S128KeyType::ETicketRSAKek, eticket_final);
  684. // Titlekeys
  685. data.DecryptProdInfo(GetKey(S128KeyType::BIS),
  686. GetKey(S128KeyType::BIS, 0, static_cast<u64>(BISKeyType::Tweak)));
  687. const auto eticket_extended_kek = data.GetETicketExtendedKek();
  688. std::vector<u8> extended_iv(0x10);
  689. std::memcpy(extended_iv.data(), eticket_extended_kek.data(), extended_iv.size());
  690. std::array<u8, 0x230> extended_dec{};
  691. AESCipher<Key128> rsa_1(eticket_final, Mode::CTR);
  692. rsa_1.SetIV(extended_iv);
  693. rsa_1.Transcode(eticket_extended_kek.data() + 0x10, eticket_extended_kek.size() - 0x10,
  694. extended_dec.data(), Op::Decrypt);
  695. RSAKeyPair<2048> rsa_key{};
  696. std::memcpy(rsa_key.decryption_key.data(), extended_dec.data(), rsa_key.decryption_key.size());
  697. std::memcpy(rsa_key.modulus.data(), extended_dec.data() + 0x100, rsa_key.modulus.size());
  698. std::memcpy(rsa_key.exponent.data(), extended_dec.data() + 0x200, rsa_key.exponent.size());
  699. const FileUtil::IOFile save1(FileUtil::GetUserPath(FileUtil::UserPath::NANDDir) +
  700. "/system/save/80000000000000e1",
  701. "rb+");
  702. const FileUtil::IOFile save2(FileUtil::GetUserPath(FileUtil::UserPath::NANDDir) +
  703. "/system/save/80000000000000e2",
  704. "rb+");
  705. auto res = GetTicketblob(save1);
  706. const auto res2 = GetTicketblob(save2);
  707. std::copy(res2.begin(), res2.end(), std::back_inserter(res));
  708. for (const auto& raw : res) {
  709. const auto pair = ParseTicket(raw, rsa_key);
  710. if (pair == boost::none)
  711. continue;
  712. auto [rid, key] = pair.value();
  713. u128 rights_id{};
  714. std::memcpy(rights_id.data(), rid.data(), rid.size());
  715. SetKey(S128KeyType::Titlekey, key, rights_id[1], rights_id[0]);
  716. }
  717. }
  718. void KeyManager::SetKeyWrapped(S128KeyType id, Key128 key, u64 field1, u64 field2) {
  719. if (key == Key128{})
  720. return;
  721. SetKey(id, key, field1, field2);
  722. }
  723. void KeyManager::SetKeyWrapped(S256KeyType id, Key256 key, u64 field1, u64 field2) {
  724. if (key == Key256{})
  725. return;
  726. SetKey(id, key, field1, field2);
  727. }
  728. void KeyManager::PopulateFromPartitionData(PartitionDataManager data) {
  729. if (!BaseDeriveNecessary())
  730. return;
  731. if (!data.HasBoot0())
  732. return;
  733. for (size_t i = 0; i < 0x20; ++i) {
  734. if (encrypted_keyblobs[i] != std::array<u8, 0xB0>{})
  735. continue;
  736. encrypted_keyblobs[i] = data.GetEncryptedKeyblob(i);
  737. WriteKeyToFile<0xB0>(KeyCategory::Console, fmt::format("encrypted_keyblob_{:02X}", i),
  738. encrypted_keyblobs[i]);
  739. }
  740. SetKeyWrapped(S128KeyType::Source, data.GetPackage2KeySource(),
  741. static_cast<u64>(SourceKeyType::Package2));
  742. SetKeyWrapped(S128KeyType::Source, data.GetAESKekGenerationSource(),
  743. static_cast<u64>(SourceKeyType::AESKekGeneration));
  744. SetKeyWrapped(S128KeyType::Source, data.GetTitlekekSource(),
  745. static_cast<u64>(SourceKeyType::Titlekek));
  746. SetKeyWrapped(S128KeyType::Source, data.GetMasterKeySource(),
  747. static_cast<u64>(SourceKeyType::Master));
  748. SetKeyWrapped(S128KeyType::Source, data.GetKeyblobMACKeySource(),
  749. static_cast<u64>(SourceKeyType::KeyblobMAC));
  750. for (size_t i = 0; i < PartitionDataManager::MAX_KEYBLOB_SOURCE_HASH; ++i) {
  751. SetKeyWrapped(S128KeyType::Source, data.GetKeyblobKeySource(i),
  752. static_cast<u64>(SourceKeyType::Keyblob), i);
  753. }
  754. if (data.HasFuses())
  755. SetKeyWrapped(S128KeyType::SecureBoot, data.GetSecureBootKey());
  756. DeriveBase();
  757. Key128 latest_master{};
  758. for (s8 i = 0x1F; i > 0; --i) {
  759. if (GetKey(S128KeyType::Master, i) != Key128{}) {
  760. latest_master = GetKey(S128KeyType::Master, i);
  761. break;
  762. }
  763. }
  764. const auto masters = data.GetTZMasterKeys(latest_master);
  765. for (size_t i = 0; i < 0x20; ++i) {
  766. if (masters[i] != Key128{} && !HasKey(S128KeyType::Master, i))
  767. SetKey(S128KeyType::Master, masters[i], i);
  768. }
  769. DeriveBase();
  770. if (!data.HasPackage2())
  771. return;
  772. std::array<Key128, 0x20> package2_keys{};
  773. for (size_t i = 0; i < 0x20; ++i) {
  774. if (HasKey(S128KeyType::Package2, i))
  775. package2_keys[i] = GetKey(S128KeyType::Package2, i);
  776. }
  777. data.DecryptPackage2(package2_keys, Package2Type::NormalMain);
  778. SetKeyWrapped(S128KeyType::Source, data.GetKeyAreaKeyApplicationSource(),
  779. static_cast<u64>(SourceKeyType::KeyAreaKey),
  780. static_cast<u64>(KeyAreaKeyType::Application));
  781. SetKeyWrapped(S128KeyType::Source, data.GetKeyAreaKeyOceanSource(),
  782. static_cast<u64>(SourceKeyType::KeyAreaKey),
  783. static_cast<u64>(KeyAreaKeyType::Ocean));
  784. SetKeyWrapped(S128KeyType::Source, data.GetKeyAreaKeySystemSource(),
  785. static_cast<u64>(SourceKeyType::KeyAreaKey),
  786. static_cast<u64>(KeyAreaKeyType::System));
  787. SetKeyWrapped(S128KeyType::Source, data.GetSDKekSource(),
  788. static_cast<u64>(SourceKeyType::SDKek));
  789. SetKeyWrapped(S256KeyType::SDKeySource, data.GetSDSaveKeySource(),
  790. static_cast<u64>(SDKeyType::Save));
  791. SetKeyWrapped(S256KeyType::SDKeySource, data.GetSDNCAKeySource(),
  792. static_cast<u64>(SDKeyType::NCA));
  793. SetKeyWrapped(S128KeyType::Source, data.GetHeaderKekSource(),
  794. static_cast<u64>(SourceKeyType::HeaderKek));
  795. SetKeyWrapped(S256KeyType::HeaderSource, data.GetHeaderKeySource());
  796. SetKeyWrapped(S128KeyType::Source, data.GetAESKeyGenerationSource(),
  797. static_cast<u64>(SourceKeyType::AESKeyGeneration));
  798. DeriveBase();
  799. }
  800. const boost::container::flat_map<std::string, KeyIndex<S128KeyType>> KeyManager::s128_file_id = {
  801. {"eticket_rsa_kek", {S128KeyType::ETicketRSAKek, 0, 0}},
  802. {"eticket_rsa_kek_source",
  803. {S128KeyType::Source, static_cast<u64>(SourceKeyType::ETicketKek), 0}},
  804. {"eticket_rsa_kekek_source",
  805. {S128KeyType::Source, static_cast<u64>(SourceKeyType::ETicketKekek), 0}},
  806. {"rsa_kek_mask_0", {S128KeyType::RSAKek, static_cast<u64>(RSAKekType::Mask0), 0}},
  807. {"rsa_kek_seed_3", {S128KeyType::RSAKek, static_cast<u64>(RSAKekType::Seed3), 0}},
  808. {"rsa_oaep_kek_generation_source",
  809. {S128KeyType::Source, static_cast<u64>(SourceKeyType::RSAOaepKekGeneration), 0}},
  810. {"sd_card_kek_source", {S128KeyType::Source, static_cast<u64>(SourceKeyType::SDKek), 0}},
  811. {"aes_kek_generation_source",
  812. {S128KeyType::Source, static_cast<u64>(SourceKeyType::AESKekGeneration), 0}},
  813. {"aes_key_generation_source",
  814. {S128KeyType::Source, static_cast<u64>(SourceKeyType::AESKeyGeneration), 0}},
  815. {"package2_key_source", {S128KeyType::Source, static_cast<u64>(SourceKeyType::Package2), 0}},
  816. {"master_key_source", {S128KeyType::Source, static_cast<u64>(SourceKeyType::Master), 0}},
  817. {"header_kek_source", {S128KeyType::Source, static_cast<u64>(SourceKeyType::HeaderKek), 0}},
  818. {"key_area_key_application_source",
  819. {S128KeyType::Source, static_cast<u64>(SourceKeyType::KeyAreaKey),
  820. static_cast<u64>(KeyAreaKeyType::Application)}},
  821. {"key_area_key_ocean_source",
  822. {S128KeyType::Source, static_cast<u64>(SourceKeyType::KeyAreaKey),
  823. static_cast<u64>(KeyAreaKeyType::Ocean)}},
  824. {"key_area_key_system_source",
  825. {S128KeyType::Source, static_cast<u64>(SourceKeyType::KeyAreaKey),
  826. static_cast<u64>(KeyAreaKeyType::System)}},
  827. {"titlekek_source", {S128KeyType::Source, static_cast<u64>(SourceKeyType::Titlekek), 0}},
  828. {"keyblob_mac_key_source", {S128KeyType::Source, static_cast<u64>(SourceKeyType::KeyblobMAC)}},
  829. {"tsec_key", {S128KeyType::TSEC, 0, 0}},
  830. {"secure_boot_key", {S128KeyType::SecureBoot, 0, 0}},
  831. {"sd_seed", {S128KeyType::SDSeed, 0, 0}},
  832. {"bis_key_0_crypt", {S128KeyType::BIS, 0, static_cast<u64>(BISKeyType::Crypto)}},
  833. {"bis_key_0_tweak", {S128KeyType::BIS, 0, static_cast<u64>(BISKeyType::Tweak)}},
  834. {"bis_key_1_crypt", {S128KeyType::BIS, 1, static_cast<u64>(BISKeyType::Crypto)}},
  835. {"bis_key_1_tweak", {S128KeyType::BIS, 1, static_cast<u64>(BISKeyType::Tweak)}},
  836. {"bis_key_2_crypt", {S128KeyType::BIS, 2, static_cast<u64>(BISKeyType::Crypto)}},
  837. {"bis_key_2_tweak", {S128KeyType::BIS, 2, static_cast<u64>(BISKeyType::Tweak)}},
  838. {"bis_key_3_crypt", {S128KeyType::BIS, 3, static_cast<u64>(BISKeyType::Crypto)}},
  839. {"bis_key_3_tweak", {S128KeyType::BIS, 3, static_cast<u64>(BISKeyType::Tweak)}},
  840. {"header_kek", {S128KeyType::HeaderKek, 0, 0}},
  841. {"sd_card_kek", {S128KeyType::SDKek, 0, 0}},
  842. };
  843. const boost::container::flat_map<std::string, KeyIndex<S256KeyType>> KeyManager::s256_file_id = {
  844. {"header_key", {S256KeyType::Header, 0, 0}},
  845. {"sd_card_save_key_source", {S256KeyType::SDKeySource, static_cast<u64>(SDKeyType::Save), 0}},
  846. {"sd_card_nca_key_source", {S256KeyType::SDKeySource, static_cast<u64>(SDKeyType::NCA), 0}},
  847. {"header_key_source", {S256KeyType::HeaderSource, 0, 0}},
  848. {"sd_card_save_key", {S256KeyType::SDKey, static_cast<u64>(SDKeyType::Save), 0}},
  849. {"sd_card_nca_key", {S256KeyType::SDKey, static_cast<u64>(SDKeyType::NCA), 0}},
  850. };
  851. } // namespace Core::Crypto