diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/crypto/key_manager.cpp | 153 | ||||
| -rw-r--r-- | src/core/crypto/key_manager.h | 4 |
2 files changed, 82 insertions, 75 deletions
diff --git a/src/core/crypto/key_manager.cpp b/src/core/crypto/key_manager.cpp index 8783d1ac2..dc591c730 100644 --- a/src/core/crypto/key_manager.cpp +++ b/src/core/crypto/key_manager.cpp | |||
| @@ -36,6 +36,7 @@ | |||
| 36 | #include "core/settings.h" | 36 | #include "core/settings.h" |
| 37 | 37 | ||
| 38 | namespace Core::Crypto { | 38 | namespace Core::Crypto { |
| 39 | namespace { | ||
| 39 | 40 | ||
| 40 | constexpr u64 CURRENT_CRYPTO_REVISION = 0x5; | 41 | constexpr u64 CURRENT_CRYPTO_REVISION = 0x5; |
| 41 | constexpr u64 FULL_TICKET_SIZE = 0x400; | 42 | constexpr u64 FULL_TICKET_SIZE = 0x400; |
| @@ -49,7 +50,72 @@ constexpr std::array eticket_source_hashes{ | |||
| 49 | }; | 50 | }; |
| 50 | // clang-format on | 51 | // clang-format on |
| 51 | 52 | ||
| 52 | const std::map<std::pair<S128KeyType, u64>, std::string> KEYS_VARIABLE_LENGTH{ | 53 | constexpr std::array<std::pair<std::string_view, KeyIndex<S128KeyType>>, 30> s128_file_id{{ |
| 54 | {"eticket_rsa_kek", {S128KeyType::ETicketRSAKek, 0, 0}}, | ||
| 55 | {"eticket_rsa_kek_source", | ||
| 56 | {S128KeyType::Source, static_cast<u64>(SourceKeyType::ETicketKek), 0}}, | ||
| 57 | {"eticket_rsa_kekek_source", | ||
| 58 | {S128KeyType::Source, static_cast<u64>(SourceKeyType::ETicketKekek), 0}}, | ||
| 59 | {"rsa_kek_mask_0", {S128KeyType::RSAKek, static_cast<u64>(RSAKekType::Mask0), 0}}, | ||
| 60 | {"rsa_kek_seed_3", {S128KeyType::RSAKek, static_cast<u64>(RSAKekType::Seed3), 0}}, | ||
| 61 | {"rsa_oaep_kek_generation_source", | ||
| 62 | {S128KeyType::Source, static_cast<u64>(SourceKeyType::RSAOaepKekGeneration), 0}}, | ||
| 63 | {"sd_card_kek_source", {S128KeyType::Source, static_cast<u64>(SourceKeyType::SDKek), 0}}, | ||
| 64 | {"aes_kek_generation_source", | ||
| 65 | {S128KeyType::Source, static_cast<u64>(SourceKeyType::AESKekGeneration), 0}}, | ||
| 66 | {"aes_key_generation_source", | ||
| 67 | {S128KeyType::Source, static_cast<u64>(SourceKeyType::AESKeyGeneration), 0}}, | ||
| 68 | {"package2_key_source", {S128KeyType::Source, static_cast<u64>(SourceKeyType::Package2), 0}}, | ||
| 69 | {"master_key_source", {S128KeyType::Source, static_cast<u64>(SourceKeyType::Master), 0}}, | ||
| 70 | {"header_kek_source", {S128KeyType::Source, static_cast<u64>(SourceKeyType::HeaderKek), 0}}, | ||
| 71 | {"key_area_key_application_source", | ||
| 72 | {S128KeyType::Source, static_cast<u64>(SourceKeyType::KeyAreaKey), | ||
| 73 | static_cast<u64>(KeyAreaKeyType::Application)}}, | ||
| 74 | {"key_area_key_ocean_source", | ||
| 75 | {S128KeyType::Source, static_cast<u64>(SourceKeyType::KeyAreaKey), | ||
| 76 | static_cast<u64>(KeyAreaKeyType::Ocean)}}, | ||
| 77 | {"key_area_key_system_source", | ||
| 78 | {S128KeyType::Source, static_cast<u64>(SourceKeyType::KeyAreaKey), | ||
| 79 | static_cast<u64>(KeyAreaKeyType::System)}}, | ||
| 80 | {"titlekek_source", {S128KeyType::Source, static_cast<u64>(SourceKeyType::Titlekek), 0}}, | ||
| 81 | {"keyblob_mac_key_source", | ||
| 82 | {S128KeyType::Source, static_cast<u64>(SourceKeyType::KeyblobMAC), 0}}, | ||
| 83 | {"tsec_key", {S128KeyType::TSEC, 0, 0}}, | ||
| 84 | {"secure_boot_key", {S128KeyType::SecureBoot, 0, 0}}, | ||
| 85 | {"sd_seed", {S128KeyType::SDSeed, 0, 0}}, | ||
| 86 | {"bis_key_0_crypt", {S128KeyType::BIS, 0, static_cast<u64>(BISKeyType::Crypto)}}, | ||
| 87 | {"bis_key_0_tweak", {S128KeyType::BIS, 0, static_cast<u64>(BISKeyType::Tweak)}}, | ||
| 88 | {"bis_key_1_crypt", {S128KeyType::BIS, 1, static_cast<u64>(BISKeyType::Crypto)}}, | ||
| 89 | {"bis_key_1_tweak", {S128KeyType::BIS, 1, static_cast<u64>(BISKeyType::Tweak)}}, | ||
| 90 | {"bis_key_2_crypt", {S128KeyType::BIS, 2, static_cast<u64>(BISKeyType::Crypto)}}, | ||
| 91 | {"bis_key_2_tweak", {S128KeyType::BIS, 2, static_cast<u64>(BISKeyType::Tweak)}}, | ||
| 92 | {"bis_key_3_crypt", {S128KeyType::BIS, 3, static_cast<u64>(BISKeyType::Crypto)}}, | ||
| 93 | {"bis_key_3_tweak", {S128KeyType::BIS, 3, static_cast<u64>(BISKeyType::Tweak)}}, | ||
| 94 | {"header_kek", {S128KeyType::HeaderKek, 0, 0}}, | ||
| 95 | {"sd_card_kek", {S128KeyType::SDKek, 0, 0}}, | ||
| 96 | }}; | ||
| 97 | |||
| 98 | auto Find128ByName(std::string_view name) { | ||
| 99 | return std::find_if(s128_file_id.begin(), s128_file_id.end(), | ||
| 100 | [&name](const auto& pair) { return pair.first == name; }); | ||
| 101 | } | ||
| 102 | |||
| 103 | constexpr std::array<std::pair<std::string_view, KeyIndex<S256KeyType>>, 6> s256_file_id{{ | ||
| 104 | {"header_key", {S256KeyType::Header, 0, 0}}, | ||
| 105 | {"sd_card_save_key_source", {S256KeyType::SDKeySource, static_cast<u64>(SDKeyType::Save), 0}}, | ||
| 106 | {"sd_card_nca_key_source", {S256KeyType::SDKeySource, static_cast<u64>(SDKeyType::NCA), 0}}, | ||
| 107 | {"header_key_source", {S256KeyType::HeaderSource, 0, 0}}, | ||
| 108 | {"sd_card_save_key", {S256KeyType::SDKey, static_cast<u64>(SDKeyType::Save), 0}}, | ||
| 109 | {"sd_card_nca_key", {S256KeyType::SDKey, static_cast<u64>(SDKeyType::NCA), 0}}, | ||
| 110 | }}; | ||
| 111 | |||
| 112 | auto Find256ByName(std::string_view name) { | ||
| 113 | return std::find_if(s256_file_id.begin(), s256_file_id.end(), | ||
| 114 | [&name](const auto& pair) { return pair.first == name; }); | ||
| 115 | } | ||
| 116 | |||
| 117 | using KeyArray = std::array<std::pair<std::pair<S128KeyType, u64>, std::string_view>, 7>; | ||
| 118 | constexpr KeyArray KEYS_VARIABLE_LENGTH{{ | ||
| 53 | {{S128KeyType::Master, 0}, "master_key_"}, | 119 | {{S128KeyType::Master, 0}, "master_key_"}, |
| 54 | {{S128KeyType::Package1, 0}, "package1_key_"}, | 120 | {{S128KeyType::Package1, 0}, "package1_key_"}, |
| 55 | {{S128KeyType::Package2, 0}, "package2_key_"}, | 121 | {{S128KeyType::Package2, 0}, "package2_key_"}, |
| @@ -57,14 +123,13 @@ const std::map<std::pair<S128KeyType, u64>, std::string> KEYS_VARIABLE_LENGTH{ | |||
| 57 | {{S128KeyType::Source, static_cast<u64>(SourceKeyType::Keyblob)}, "keyblob_key_source_"}, | 123 | {{S128KeyType::Source, static_cast<u64>(SourceKeyType::Keyblob)}, "keyblob_key_source_"}, |
| 58 | {{S128KeyType::Keyblob, 0}, "keyblob_key_"}, | 124 | {{S128KeyType::Keyblob, 0}, "keyblob_key_"}, |
| 59 | {{S128KeyType::KeyblobMAC, 0}, "keyblob_mac_key_"}, | 125 | {{S128KeyType::KeyblobMAC, 0}, "keyblob_mac_key_"}, |
| 60 | }; | 126 | }}; |
| 61 | 127 | ||
| 62 | namespace { | ||
| 63 | template <std::size_t Size> | 128 | template <std::size_t Size> |
| 64 | bool IsAllZeroArray(const std::array<u8, Size>& array) { | 129 | bool IsAllZeroArray(const std::array<u8, Size>& array) { |
| 65 | return std::all_of(array.begin(), array.end(), [](const auto& elem) { return elem == 0; }); | 130 | return std::all_of(array.begin(), array.end(), [](const auto& elem) { return elem == 0; }); |
| 66 | } | 131 | } |
| 67 | } // namespace | 132 | } // Anonymous namespace |
| 68 | 133 | ||
| 69 | u64 GetSignatureTypeDataSize(SignatureType type) { | 134 | u64 GetSignatureTypeDataSize(SignatureType type) { |
| 70 | switch (type) { | 135 | switch (type) { |
| @@ -564,13 +629,13 @@ void KeyManager::LoadFromFile(const std::string& filename, bool is_title_keys) { | |||
| 564 | s128_keys[{S128KeyType::Titlekey, rights_id[1], rights_id[0]}] = key; | 629 | s128_keys[{S128KeyType::Titlekey, rights_id[1], rights_id[0]}] = key; |
| 565 | } else { | 630 | } else { |
| 566 | out[0] = Common::ToLower(out[0]); | 631 | out[0] = Common::ToLower(out[0]); |
| 567 | if (s128_file_id.find(out[0]) != s128_file_id.end()) { | 632 | if (const auto iter128 = Find128ByName(out[0]); iter128 != s128_file_id.end()) { |
| 568 | const auto index = s128_file_id.at(out[0]); | 633 | const auto& index = iter128->second; |
| 569 | Key128 key = Common::HexStringToArray<16>(out[1]); | 634 | const Key128 key = Common::HexStringToArray<16>(out[1]); |
| 570 | s128_keys[{index.type, index.field1, index.field2}] = key; | 635 | s128_keys[{index.type, index.field1, index.field2}] = key; |
| 571 | } else if (s256_file_id.find(out[0]) != s256_file_id.end()) { | 636 | } else if (const auto iter256 = Find256ByName(out[0]); iter256 != s256_file_id.end()) { |
| 572 | const auto index = s256_file_id.at(out[0]); | 637 | const auto& index = iter256->second; |
| 573 | Key256 key = Common::HexStringToArray<32>(out[1]); | 638 | const Key256 key = Common::HexStringToArray<32>(out[1]); |
| 574 | s256_keys[{index.type, index.field1, index.field2}] = key; | 639 | s256_keys[{index.type, index.field1, index.field2}] = key; |
| 575 | } else if (out[0].compare(0, 8, "keyblob_") == 0 && | 640 | } else if (out[0].compare(0, 8, "keyblob_") == 0 && |
| 576 | out[0].compare(0, 9, "keyblob_k") != 0) { | 641 | out[0].compare(0, 9, "keyblob_k") != 0) { |
| @@ -742,8 +807,7 @@ void KeyManager::SetKey(S128KeyType id, Key128 key, u64 field1, u64 field2) { | |||
| 742 | } | 807 | } |
| 743 | 808 | ||
| 744 | const auto iter2 = std::find_if( | 809 | const auto iter2 = std::find_if( |
| 745 | s128_file_id.begin(), s128_file_id.end(), | 810 | s128_file_id.begin(), s128_file_id.end(), [&id, &field1, &field2](const auto& elem) { |
| 746 | [&id, &field1, &field2](const std::pair<std::string, KeyIndex<S128KeyType>> elem) { | ||
| 747 | return std::tie(elem.second.type, elem.second.field1, elem.second.field2) == | 811 | return std::tie(elem.second.type, elem.second.field1, elem.second.field2) == |
| 748 | std::tie(id, field1, field2); | 812 | std::tie(id, field1, field2); |
| 749 | }); | 813 | }); |
| @@ -753,9 +817,11 @@ void KeyManager::SetKey(S128KeyType id, Key128 key, u64 field1, u64 field2) { | |||
| 753 | 817 | ||
| 754 | // Variable cases | 818 | // Variable cases |
| 755 | if (id == S128KeyType::KeyArea) { | 819 | if (id == S128KeyType::KeyArea) { |
| 756 | static constexpr std::array<const char*, 3> kak_names = {"key_area_key_application_{:02X}", | 820 | static constexpr std::array<const char*, 3> kak_names = { |
| 757 | "key_area_key_ocean_{:02X}", | 821 | "key_area_key_application_{:02X}", |
| 758 | "key_area_key_system_{:02X}"}; | 822 | "key_area_key_ocean_{:02X}", |
| 823 | "key_area_key_system_{:02X}", | ||
| 824 | }; | ||
| 759 | WriteKeyToFile(category, fmt::format(kak_names.at(field2), field1), key); | 825 | WriteKeyToFile(category, fmt::format(kak_names.at(field2), field1), key); |
| 760 | } else if (id == S128KeyType::Master) { | 826 | } else if (id == S128KeyType::Master) { |
| 761 | WriteKeyToFile(category, fmt::format("master_key_{:02X}", field1), key); | 827 | WriteKeyToFile(category, fmt::format("master_key_{:02X}", field1), key); |
| @@ -781,8 +847,7 @@ void KeyManager::SetKey(S256KeyType id, Key256 key, u64 field1, u64 field2) { | |||
| 781 | return; | 847 | return; |
| 782 | } | 848 | } |
| 783 | const auto iter = std::find_if( | 849 | const auto iter = std::find_if( |
| 784 | s256_file_id.begin(), s256_file_id.end(), | 850 | s256_file_id.begin(), s256_file_id.end(), [&id, &field1, &field2](const auto& elem) { |
| 785 | [&id, &field1, &field2](const std::pair<std::string, KeyIndex<S256KeyType>> elem) { | ||
| 786 | return std::tie(elem.second.type, elem.second.field1, elem.second.field2) == | 851 | return std::tie(elem.second.type, elem.second.field1, elem.second.field2) == |
| 787 | std::tie(id, field1, field2); | 852 | std::tie(id, field1, field2); |
| 788 | }); | 853 | }); |
| @@ -1245,58 +1310,4 @@ bool KeyManager::AddTicketPersonalized(Ticket raw) { | |||
| 1245 | SetKey(S128KeyType::Titlekey, key, rights_id[1], rights_id[0]); | 1310 | SetKey(S128KeyType::Titlekey, key, rights_id[1], rights_id[0]); |
| 1246 | return true; | 1311 | return true; |
| 1247 | } | 1312 | } |
| 1248 | |||
| 1249 | const boost::container::flat_map<std::string, KeyIndex<S128KeyType>> KeyManager::s128_file_id = { | ||
| 1250 | {"eticket_rsa_kek", {S128KeyType::ETicketRSAKek, 0, 0}}, | ||
| 1251 | {"eticket_rsa_kek_source", | ||
| 1252 | {S128KeyType::Source, static_cast<u64>(SourceKeyType::ETicketKek), 0}}, | ||
| 1253 | {"eticket_rsa_kekek_source", | ||
| 1254 | {S128KeyType::Source, static_cast<u64>(SourceKeyType::ETicketKekek), 0}}, | ||
| 1255 | {"rsa_kek_mask_0", {S128KeyType::RSAKek, static_cast<u64>(RSAKekType::Mask0), 0}}, | ||
| 1256 | {"rsa_kek_seed_3", {S128KeyType::RSAKek, static_cast<u64>(RSAKekType::Seed3), 0}}, | ||
| 1257 | {"rsa_oaep_kek_generation_source", | ||
| 1258 | {S128KeyType::Source, static_cast<u64>(SourceKeyType::RSAOaepKekGeneration), 0}}, | ||
| 1259 | {"sd_card_kek_source", {S128KeyType::Source, static_cast<u64>(SourceKeyType::SDKek), 0}}, | ||
| 1260 | {"aes_kek_generation_source", | ||
| 1261 | {S128KeyType::Source, static_cast<u64>(SourceKeyType::AESKekGeneration), 0}}, | ||
| 1262 | {"aes_key_generation_source", | ||
| 1263 | {S128KeyType::Source, static_cast<u64>(SourceKeyType::AESKeyGeneration), 0}}, | ||
| 1264 | {"package2_key_source", {S128KeyType::Source, static_cast<u64>(SourceKeyType::Package2), 0}}, | ||
| 1265 | {"master_key_source", {S128KeyType::Source, static_cast<u64>(SourceKeyType::Master), 0}}, | ||
| 1266 | {"header_kek_source", {S128KeyType::Source, static_cast<u64>(SourceKeyType::HeaderKek), 0}}, | ||
| 1267 | {"key_area_key_application_source", | ||
| 1268 | {S128KeyType::Source, static_cast<u64>(SourceKeyType::KeyAreaKey), | ||
| 1269 | static_cast<u64>(KeyAreaKeyType::Application)}}, | ||
| 1270 | {"key_area_key_ocean_source", | ||
| 1271 | {S128KeyType::Source, static_cast<u64>(SourceKeyType::KeyAreaKey), | ||
| 1272 | static_cast<u64>(KeyAreaKeyType::Ocean)}}, | ||
| 1273 | {"key_area_key_system_source", | ||
| 1274 | {S128KeyType::Source, static_cast<u64>(SourceKeyType::KeyAreaKey), | ||
| 1275 | static_cast<u64>(KeyAreaKeyType::System)}}, | ||
| 1276 | {"titlekek_source", {S128KeyType::Source, static_cast<u64>(SourceKeyType::Titlekek), 0}}, | ||
| 1277 | {"keyblob_mac_key_source", | ||
| 1278 | {S128KeyType::Source, static_cast<u64>(SourceKeyType::KeyblobMAC), 0}}, | ||
| 1279 | {"tsec_key", {S128KeyType::TSEC, 0, 0}}, | ||
| 1280 | {"secure_boot_key", {S128KeyType::SecureBoot, 0, 0}}, | ||
| 1281 | {"sd_seed", {S128KeyType::SDSeed, 0, 0}}, | ||
| 1282 | {"bis_key_0_crypt", {S128KeyType::BIS, 0, static_cast<u64>(BISKeyType::Crypto)}}, | ||
| 1283 | {"bis_key_0_tweak", {S128KeyType::BIS, 0, static_cast<u64>(BISKeyType::Tweak)}}, | ||
| 1284 | {"bis_key_1_crypt", {S128KeyType::BIS, 1, static_cast<u64>(BISKeyType::Crypto)}}, | ||
| 1285 | {"bis_key_1_tweak", {S128KeyType::BIS, 1, static_cast<u64>(BISKeyType::Tweak)}}, | ||
| 1286 | {"bis_key_2_crypt", {S128KeyType::BIS, 2, static_cast<u64>(BISKeyType::Crypto)}}, | ||
| 1287 | {"bis_key_2_tweak", {S128KeyType::BIS, 2, static_cast<u64>(BISKeyType::Tweak)}}, | ||
| 1288 | {"bis_key_3_crypt", {S128KeyType::BIS, 3, static_cast<u64>(BISKeyType::Crypto)}}, | ||
| 1289 | {"bis_key_3_tweak", {S128KeyType::BIS, 3, static_cast<u64>(BISKeyType::Tweak)}}, | ||
| 1290 | {"header_kek", {S128KeyType::HeaderKek, 0, 0}}, | ||
| 1291 | {"sd_card_kek", {S128KeyType::SDKek, 0, 0}}, | ||
| 1292 | }; | ||
| 1293 | |||
| 1294 | const boost::container::flat_map<std::string, KeyIndex<S256KeyType>> KeyManager::s256_file_id = { | ||
| 1295 | {"header_key", {S256KeyType::Header, 0, 0}}, | ||
| 1296 | {"sd_card_save_key_source", {S256KeyType::SDKeySource, static_cast<u64>(SDKeyType::Save), 0}}, | ||
| 1297 | {"sd_card_nca_key_source", {S256KeyType::SDKeySource, static_cast<u64>(SDKeyType::NCA), 0}}, | ||
| 1298 | {"header_key_source", {S256KeyType::HeaderSource, 0, 0}}, | ||
| 1299 | {"sd_card_save_key", {S256KeyType::SDKey, static_cast<u64>(SDKeyType::Save), 0}}, | ||
| 1300 | {"sd_card_nca_key", {S256KeyType::SDKey, static_cast<u64>(SDKeyType::NCA), 0}}, | ||
| 1301 | }; | ||
| 1302 | } // namespace Core::Crypto | 1313 | } // namespace Core::Crypto |
diff --git a/src/core/crypto/key_manager.h b/src/core/crypto/key_manager.h index bdca3770a..321b75323 100644 --- a/src/core/crypto/key_manager.h +++ b/src/core/crypto/key_manager.h | |||
| @@ -10,7 +10,6 @@ | |||
| 10 | #include <string> | 10 | #include <string> |
| 11 | 11 | ||
| 12 | #include <variant> | 12 | #include <variant> |
| 13 | #include <boost/container/flat_map.hpp> | ||
| 14 | #include <fmt/format.h> | 13 | #include <fmt/format.h> |
| 15 | #include "common/common_funcs.h" | 14 | #include "common/common_funcs.h" |
| 16 | #include "common/common_types.h" | 15 | #include "common/common_types.h" |
| @@ -293,9 +292,6 @@ private: | |||
| 293 | 292 | ||
| 294 | void SetKeyWrapped(S128KeyType id, Key128 key, u64 field1 = 0, u64 field2 = 0); | 293 | void SetKeyWrapped(S128KeyType id, Key128 key, u64 field1 = 0, u64 field2 = 0); |
| 295 | void SetKeyWrapped(S256KeyType id, Key256 key, u64 field1 = 0, u64 field2 = 0); | 294 | void SetKeyWrapped(S256KeyType id, Key256 key, u64 field1 = 0, u64 field2 = 0); |
| 296 | |||
| 297 | static const boost::container::flat_map<std::string, KeyIndex<S128KeyType>> s128_file_id; | ||
| 298 | static const boost::container::flat_map<std::string, KeyIndex<S256KeyType>> s256_file_id; | ||
| 299 | }; | 295 | }; |
| 300 | 296 | ||
| 301 | Key128 GenerateKeyEncryptionKey(Key128 source, Key128 master, Key128 kek_seed, Key128 key_seed); | 297 | Key128 GenerateKeyEncryptionKey(Key128 source, Key128 master, Key128 kek_seed, Key128 key_seed); |