From 9f82a9a2444a232e746992fa89084b928255cb63 Mon Sep 17 00:00:00 2001 From: FearlessTobi Date: Wed, 20 May 2020 21:28:16 +0200 Subject: [PATCH] crypto: Make KeyManager a singleton class Previously, we were reading the keys everytime a KeyManager object was created, causing yuzu to reread the keys file multiple hundreds of times when loading the game list. With this change, it is only loaded once. On my system, this decreased game list loading times by a factor of 20. --- src/core/crypto/key_manager.h | 10 +++++++++- src/core/file_sys/bis_factory.cpp | 2 +- src/core/file_sys/card_image.cpp | 4 ++-- src/core/file_sys/card_image.h | 2 +- src/core/file_sys/content_archive.cpp | 5 ++--- src/core/file_sys/content_archive.h | 5 ++--- src/core/file_sys/registered_cache.cpp | 6 +++--- src/core/file_sys/registered_cache.h | 2 +- src/core/file_sys/submission_package.cpp | 4 ++-- src/core/file_sys/submission_package.h | 2 +- src/core/file_sys/xts_archive.h | 2 +- src/core/hle/service/es/es.cpp | 2 +- src/yuzu/main.cpp | 2 +- 13 files changed, 27 insertions(+), 21 deletions(-) diff --git a/src/core/crypto/key_manager.h b/src/core/crypto/key_manager.h index 7265c41714..bf3434e1cd 100644 --- a/src/core/crypto/key_manager.h +++ b/src/core/crypto/key_manager.h @@ -223,7 +223,13 @@ bool operator<(const KeyIndex& lhs, const KeyIndex& rhs) { class KeyManager { public: - KeyManager(); + static KeyManager& instance() { + static KeyManager instance; + return instance; + } + + KeyManager(KeyManager const&) = delete; + void operator=(KeyManager const&) = delete; bool HasKey(S128KeyType id, u64 field1 = 0, u64 field2 = 0) const; bool HasKey(S256KeyType id, u64 field1 = 0, u64 field2 = 0) const; @@ -257,6 +263,8 @@ public: bool AddTicketPersonalized(Ticket raw); private: + KeyManager(); + std::map, Key128> s128_keys; std::map, Key256> s256_keys; diff --git a/src/core/file_sys/bis_factory.cpp b/src/core/file_sys/bis_factory.cpp index 0af44f3409..464ca65033 100644 --- a/src/core/file_sys/bis_factory.cpp +++ b/src/core/file_sys/bis_factory.cpp @@ -79,7 +79,7 @@ VirtualDir BISFactory::OpenPartition(BisPartitionId id) const { } VirtualFile BISFactory::OpenPartitionStorage(BisPartitionId id) const { - Core::Crypto::KeyManager keys; + Core::Crypto::KeyManager& keys = Core::Crypto::KeyManager::instance(); Core::Crypto::PartitionDataManager pdm{ Core::System::GetInstance().GetFilesystem()->OpenDirectory( FileUtil::GetUserPath(FileUtil::UserPath::SysDataDir), Mode::Read)}; diff --git a/src/core/file_sys/card_image.cpp b/src/core/file_sys/card_image.cpp index 07d0c8d5d6..664a47e7f1 100644 --- a/src/core/file_sys/card_image.cpp +++ b/src/core/file_sys/card_image.cpp @@ -178,7 +178,7 @@ u32 XCI::GetSystemUpdateVersion() { return 0; for (const auto& file : update->GetFiles()) { - NCA nca{file, nullptr, 0, keys}; + NCA nca{file, nullptr, 0}; if (nca.GetStatus() != Loader::ResultStatus::Success) continue; @@ -286,7 +286,7 @@ Loader::ResultStatus XCI::AddNCAFromPartition(XCIPartition part) { continue; } - auto nca = std::make_shared(file, nullptr, 0, keys); + auto nca = std::make_shared(file, nullptr, 0); if (nca->IsUpdate()) { continue; } diff --git a/src/core/file_sys/card_image.h b/src/core/file_sys/card_image.h index c2ee0ea996..a09d504ae1 100644 --- a/src/core/file_sys/card_image.h +++ b/src/core/file_sys/card_image.h @@ -140,6 +140,6 @@ private: u64 update_normal_partition_end; - Core::Crypto::KeyManager keys; + Core::Crypto::KeyManager& keys = Core::Crypto::KeyManager::instance(); }; } // namespace FileSys diff --git a/src/core/file_sys/content_archive.cpp b/src/core/file_sys/content_archive.cpp index b8bbdd1ef3..473245d5a1 100644 --- a/src/core/file_sys/content_archive.cpp +++ b/src/core/file_sys/content_archive.cpp @@ -118,9 +118,8 @@ static bool IsValidNCA(const NCAHeader& header) { return header.magic == Common::MakeMagic('N', 'C', 'A', '3'); } -NCA::NCA(VirtualFile file_, VirtualFile bktr_base_romfs_, u64 bktr_base_ivfc_offset, - Core::Crypto::KeyManager keys_) - : file(std::move(file_)), bktr_base_romfs(std::move(bktr_base_romfs_)), keys(std::move(keys_)) { +NCA::NCA(VirtualFile file_, VirtualFile bktr_base_romfs_, u64 bktr_base_ivfc_offset) + : file(std::move(file_)), bktr_base_romfs(std::move(bktr_base_romfs_)) { if (file == nullptr) { status = Loader::ResultStatus::ErrorNullFile; return; diff --git a/src/core/file_sys/content_archive.h b/src/core/file_sys/content_archive.h index e249079b5b..e6c887b32a 100644 --- a/src/core/file_sys/content_archive.h +++ b/src/core/file_sys/content_archive.h @@ -99,8 +99,7 @@ inline bool IsDirectoryLogoPartition(const VirtualDir& pfs) { class NCA : public ReadOnlyVfsDirectory { public: explicit NCA(VirtualFile file, VirtualFile bktr_base_romfs = nullptr, - u64 bktr_base_ivfc_offset = 0, - Core::Crypto::KeyManager keys = Core::Crypto::KeyManager()); + u64 bktr_base_ivfc_offset = 0); ~NCA() override; Loader::ResultStatus GetStatus() const; @@ -159,7 +158,7 @@ private: bool encrypted = false; bool is_update = false; - Core::Crypto::KeyManager keys; + Core::Crypto::KeyManager& keys = Core::Crypto::KeyManager::instance(); }; } // namespace FileSys diff --git a/src/core/file_sys/registered_cache.cpp b/src/core/file_sys/registered_cache.cpp index ba5f762888..27c1b02330 100644 --- a/src/core/file_sys/registered_cache.cpp +++ b/src/core/file_sys/registered_cache.cpp @@ -408,7 +408,7 @@ void RegisteredCache::ProcessFiles(const std::vector& ids) { if (file == nullptr) continue; - const auto nca = std::make_shared(parser(file, id), nullptr, 0, keys); + const auto nca = std::make_shared(parser(file, id), nullptr, 0); if (nca->GetStatus() != Loader::ResultStatus::Success || nca->GetType() != NCAContentType::Meta) { continue; @@ -486,7 +486,7 @@ std::unique_ptr RegisteredCache::GetEntry(u64 title_id, ContentRecordType t const auto raw = GetEntryRaw(title_id, type); if (raw == nullptr) return nullptr; - return std::make_unique(raw, nullptr, 0, keys); + return std::make_unique(raw, nullptr, 0); } template @@ -865,7 +865,7 @@ std::unique_ptr ManualContentProvider::GetEntry(u64 title_id, ContentRecord const auto res = GetEntryRaw(title_id, type); if (res == nullptr) return nullptr; - return std::make_unique(res, nullptr, 0, keys); + return std::make_unique(res, nullptr, 0); } std::vector ManualContentProvider::ListEntriesFilter( diff --git a/src/core/file_sys/registered_cache.h b/src/core/file_sys/registered_cache.h index d1eec240e7..4b2fb08cb5 100644 --- a/src/core/file_sys/registered_cache.h +++ b/src/core/file_sys/registered_cache.h @@ -88,7 +88,7 @@ public: protected: // A single instance of KeyManager to be used by GetEntry() - Core::Crypto::KeyManager keys; + Core::Crypto::KeyManager& keys = Core::Crypto::KeyManager::instance(); }; class PlaceholderCache { diff --git a/src/core/file_sys/submission_package.cpp b/src/core/file_sys/submission_package.cpp index ef30846810..c35a0d10b4 100644 --- a/src/core/file_sys/submission_package.cpp +++ b/src/core/file_sys/submission_package.cpp @@ -21,7 +21,7 @@ namespace FileSys { namespace { void SetTicketKeys(const std::vector& files) { - Core::Crypto::KeyManager keys; + Core::Crypto::KeyManager& keys = Core::Crypto::KeyManager::instance(); for (const auto& ticket_file : files) { if (ticket_file == nullptr) { @@ -285,7 +285,7 @@ void NSP::ReadNCAs(const std::vector& files) { continue; } - auto next_nca = std::make_shared(std::move(next_file), nullptr, 0, keys); + auto next_nca = std::make_shared(std::move(next_file), nullptr, 0); if (next_nca->GetType() == NCAContentType::Program) { program_status[cnmt.GetTitleID()] = next_nca->GetStatus(); } diff --git a/src/core/file_sys/submission_package.h b/src/core/file_sys/submission_package.h index ee9b6ce173..bd577f6e55 100644 --- a/src/core/file_sys/submission_package.h +++ b/src/core/file_sys/submission_package.h @@ -73,7 +73,7 @@ private: std::map, std::shared_ptr>> ncas; std::vector ticket_files; - Core::Crypto::KeyManager keys; + Core::Crypto::KeyManager& keys = Core::Crypto::KeyManager::instance(); VirtualFile romfs; VirtualDir exefs; diff --git a/src/core/file_sys/xts_archive.h b/src/core/file_sys/xts_archive.h index 7704dee904..95da907bc7 100644 --- a/src/core/file_sys/xts_archive.h +++ b/src/core/file_sys/xts_archive.h @@ -62,6 +62,6 @@ private: VirtualFile dec_file; - Core::Crypto::KeyManager keys; + Core::Crypto::KeyManager& keys = Core::Crypto::KeyManager::instance(); }; } // namespace FileSys diff --git a/src/core/hle/service/es/es.cpp b/src/core/hle/service/es/es.cpp index f8e9df4b12..ad6841a646 100644 --- a/src/core/hle/service/es/es.cpp +++ b/src/core/hle/service/es/es.cpp @@ -263,7 +263,7 @@ private: rb.Push(write_size); } - Core::Crypto::KeyManager keys; + Core::Crypto::KeyManager& keys = Core::Crypto::KeyManager::instance(); }; void InstallInterfaces(SM::ServiceManager& service_manager) { diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 0a6839b2d1..62f9d2ab24 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -2116,7 +2116,7 @@ void GMainWindow::OnReinitializeKeys(ReinitializeKeyBehavior behavior) { "title.keys_autogenerated"); } - Core::Crypto::KeyManager keys{}; + Core::Crypto::KeyManager& keys = Core::Crypto::KeyManager::instance(); if (keys.BaseDeriveNecessary()) { Core::Crypto::PartitionDataManager pdm{vfs->OpenDirectory( FileUtil::GetUserPath(FileUtil::UserPath::SysDataDir), FileSys::Mode::Read)};