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.
This commit is contained in:
parent
41682e0888
commit
9f82a9a244
|
@ -223,7 +223,13 @@ bool operator<(const KeyIndex<KeyType>& lhs, const KeyIndex<KeyType>& rhs) {
|
||||||
|
|
||||||
class KeyManager {
|
class KeyManager {
|
||||||
public:
|
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(S128KeyType id, u64 field1 = 0, u64 field2 = 0) const;
|
||||||
bool HasKey(S256KeyType 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);
|
bool AddTicketPersonalized(Ticket raw);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
KeyManager();
|
||||||
|
|
||||||
std::map<KeyIndex<S128KeyType>, Key128> s128_keys;
|
std::map<KeyIndex<S128KeyType>, Key128> s128_keys;
|
||||||
std::map<KeyIndex<S256KeyType>, Key256> s256_keys;
|
std::map<KeyIndex<S256KeyType>, Key256> s256_keys;
|
||||||
|
|
||||||
|
|
|
@ -79,7 +79,7 @@ VirtualDir BISFactory::OpenPartition(BisPartitionId id) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
VirtualFile BISFactory::OpenPartitionStorage(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::Crypto::PartitionDataManager pdm{
|
||||||
Core::System::GetInstance().GetFilesystem()->OpenDirectory(
|
Core::System::GetInstance().GetFilesystem()->OpenDirectory(
|
||||||
FileUtil::GetUserPath(FileUtil::UserPath::SysDataDir), Mode::Read)};
|
FileUtil::GetUserPath(FileUtil::UserPath::SysDataDir), Mode::Read)};
|
||||||
|
|
|
@ -178,7 +178,7 @@ u32 XCI::GetSystemUpdateVersion() {
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
for (const auto& file : update->GetFiles()) {
|
for (const auto& file : update->GetFiles()) {
|
||||||
NCA nca{file, nullptr, 0, keys};
|
NCA nca{file, nullptr, 0};
|
||||||
|
|
||||||
if (nca.GetStatus() != Loader::ResultStatus::Success)
|
if (nca.GetStatus() != Loader::ResultStatus::Success)
|
||||||
continue;
|
continue;
|
||||||
|
@ -286,7 +286,7 @@ Loader::ResultStatus XCI::AddNCAFromPartition(XCIPartition part) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto nca = std::make_shared<NCA>(file, nullptr, 0, keys);
|
auto nca = std::make_shared<NCA>(file, nullptr, 0);
|
||||||
if (nca->IsUpdate()) {
|
if (nca->IsUpdate()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -140,6 +140,6 @@ private:
|
||||||
|
|
||||||
u64 update_normal_partition_end;
|
u64 update_normal_partition_end;
|
||||||
|
|
||||||
Core::Crypto::KeyManager keys;
|
Core::Crypto::KeyManager& keys = Core::Crypto::KeyManager::instance();
|
||||||
};
|
};
|
||||||
} // namespace FileSys
|
} // namespace FileSys
|
||||||
|
|
|
@ -118,9 +118,8 @@ static bool IsValidNCA(const NCAHeader& header) {
|
||||||
return header.magic == Common::MakeMagic('N', 'C', 'A', '3');
|
return header.magic == Common::MakeMagic('N', 'C', 'A', '3');
|
||||||
}
|
}
|
||||||
|
|
||||||
NCA::NCA(VirtualFile file_, VirtualFile bktr_base_romfs_, u64 bktr_base_ivfc_offset,
|
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_)) {
|
||||||
: file(std::move(file_)), bktr_base_romfs(std::move(bktr_base_romfs_)), keys(std::move(keys_)) {
|
|
||||||
if (file == nullptr) {
|
if (file == nullptr) {
|
||||||
status = Loader::ResultStatus::ErrorNullFile;
|
status = Loader::ResultStatus::ErrorNullFile;
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -99,8 +99,7 @@ inline bool IsDirectoryLogoPartition(const VirtualDir& pfs) {
|
||||||
class NCA : public ReadOnlyVfsDirectory {
|
class NCA : public ReadOnlyVfsDirectory {
|
||||||
public:
|
public:
|
||||||
explicit NCA(VirtualFile file, VirtualFile bktr_base_romfs = nullptr,
|
explicit NCA(VirtualFile file, VirtualFile bktr_base_romfs = nullptr,
|
||||||
u64 bktr_base_ivfc_offset = 0,
|
u64 bktr_base_ivfc_offset = 0);
|
||||||
Core::Crypto::KeyManager keys = Core::Crypto::KeyManager());
|
|
||||||
~NCA() override;
|
~NCA() override;
|
||||||
|
|
||||||
Loader::ResultStatus GetStatus() const;
|
Loader::ResultStatus GetStatus() const;
|
||||||
|
@ -159,7 +158,7 @@ private:
|
||||||
bool encrypted = false;
|
bool encrypted = false;
|
||||||
bool is_update = false;
|
bool is_update = false;
|
||||||
|
|
||||||
Core::Crypto::KeyManager keys;
|
Core::Crypto::KeyManager& keys = Core::Crypto::KeyManager::instance();
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace FileSys
|
} // namespace FileSys
|
||||||
|
|
|
@ -408,7 +408,7 @@ void RegisteredCache::ProcessFiles(const std::vector<NcaID>& ids) {
|
||||||
|
|
||||||
if (file == nullptr)
|
if (file == nullptr)
|
||||||
continue;
|
continue;
|
||||||
const auto nca = std::make_shared<NCA>(parser(file, id), nullptr, 0, keys);
|
const auto nca = std::make_shared<NCA>(parser(file, id), nullptr, 0);
|
||||||
if (nca->GetStatus() != Loader::ResultStatus::Success ||
|
if (nca->GetStatus() != Loader::ResultStatus::Success ||
|
||||||
nca->GetType() != NCAContentType::Meta) {
|
nca->GetType() != NCAContentType::Meta) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -486,7 +486,7 @@ std::unique_ptr<NCA> RegisteredCache::GetEntry(u64 title_id, ContentRecordType t
|
||||||
const auto raw = GetEntryRaw(title_id, type);
|
const auto raw = GetEntryRaw(title_id, type);
|
||||||
if (raw == nullptr)
|
if (raw == nullptr)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
return std::make_unique<NCA>(raw, nullptr, 0, keys);
|
return std::make_unique<NCA>(raw, nullptr, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
@ -865,7 +865,7 @@ std::unique_ptr<NCA> ManualContentProvider::GetEntry(u64 title_id, ContentRecord
|
||||||
const auto res = GetEntryRaw(title_id, type);
|
const auto res = GetEntryRaw(title_id, type);
|
||||||
if (res == nullptr)
|
if (res == nullptr)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
return std::make_unique<NCA>(res, nullptr, 0, keys);
|
return std::make_unique<NCA>(res, nullptr, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<ContentProviderEntry> ManualContentProvider::ListEntriesFilter(
|
std::vector<ContentProviderEntry> ManualContentProvider::ListEntriesFilter(
|
||||||
|
|
|
@ -88,7 +88,7 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// A single instance of KeyManager to be used by GetEntry()
|
// A single instance of KeyManager to be used by GetEntry()
|
||||||
Core::Crypto::KeyManager keys;
|
Core::Crypto::KeyManager& keys = Core::Crypto::KeyManager::instance();
|
||||||
};
|
};
|
||||||
|
|
||||||
class PlaceholderCache {
|
class PlaceholderCache {
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
namespace FileSys {
|
namespace FileSys {
|
||||||
namespace {
|
namespace {
|
||||||
void SetTicketKeys(const std::vector<VirtualFile>& files) {
|
void SetTicketKeys(const std::vector<VirtualFile>& files) {
|
||||||
Core::Crypto::KeyManager keys;
|
Core::Crypto::KeyManager& keys = Core::Crypto::KeyManager::instance();
|
||||||
|
|
||||||
for (const auto& ticket_file : files) {
|
for (const auto& ticket_file : files) {
|
||||||
if (ticket_file == nullptr) {
|
if (ticket_file == nullptr) {
|
||||||
|
@ -285,7 +285,7 @@ void NSP::ReadNCAs(const std::vector<VirtualFile>& files) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto next_nca = std::make_shared<NCA>(std::move(next_file), nullptr, 0, keys);
|
auto next_nca = std::make_shared<NCA>(std::move(next_file), nullptr, 0);
|
||||||
if (next_nca->GetType() == NCAContentType::Program) {
|
if (next_nca->GetType() == NCAContentType::Program) {
|
||||||
program_status[cnmt.GetTitleID()] = next_nca->GetStatus();
|
program_status[cnmt.GetTitleID()] = next_nca->GetStatus();
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,7 +73,7 @@ private:
|
||||||
std::map<u64, std::map<std::pair<TitleType, ContentRecordType>, std::shared_ptr<NCA>>> ncas;
|
std::map<u64, std::map<std::pair<TitleType, ContentRecordType>, std::shared_ptr<NCA>>> ncas;
|
||||||
std::vector<VirtualFile> ticket_files;
|
std::vector<VirtualFile> ticket_files;
|
||||||
|
|
||||||
Core::Crypto::KeyManager keys;
|
Core::Crypto::KeyManager& keys = Core::Crypto::KeyManager::instance();
|
||||||
|
|
||||||
VirtualFile romfs;
|
VirtualFile romfs;
|
||||||
VirtualDir exefs;
|
VirtualDir exefs;
|
||||||
|
|
|
@ -62,6 +62,6 @@ private:
|
||||||
|
|
||||||
VirtualFile dec_file;
|
VirtualFile dec_file;
|
||||||
|
|
||||||
Core::Crypto::KeyManager keys;
|
Core::Crypto::KeyManager& keys = Core::Crypto::KeyManager::instance();
|
||||||
};
|
};
|
||||||
} // namespace FileSys
|
} // namespace FileSys
|
||||||
|
|
|
@ -263,7 +263,7 @@ private:
|
||||||
rb.Push<u64>(write_size);
|
rb.Push<u64>(write_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
Core::Crypto::KeyManager keys;
|
Core::Crypto::KeyManager& keys = Core::Crypto::KeyManager::instance();
|
||||||
};
|
};
|
||||||
|
|
||||||
void InstallInterfaces(SM::ServiceManager& service_manager) {
|
void InstallInterfaces(SM::ServiceManager& service_manager) {
|
||||||
|
|
|
@ -2116,7 +2116,7 @@ void GMainWindow::OnReinitializeKeys(ReinitializeKeyBehavior behavior) {
|
||||||
"title.keys_autogenerated");
|
"title.keys_autogenerated");
|
||||||
}
|
}
|
||||||
|
|
||||||
Core::Crypto::KeyManager keys{};
|
Core::Crypto::KeyManager& keys = Core::Crypto::KeyManager::instance();
|
||||||
if (keys.BaseDeriveNecessary()) {
|
if (keys.BaseDeriveNecessary()) {
|
||||||
Core::Crypto::PartitionDataManager pdm{vfs->OpenDirectory(
|
Core::Crypto::PartitionDataManager pdm{vfs->OpenDirectory(
|
||||||
FileUtil::GetUserPath(FileUtil::UserPath::SysDataDir), FileSys::Mode::Read)};
|
FileUtil::GetUserPath(FileUtil::UserPath::SysDataDir), FileSys::Mode::Read)};
|
||||||
|
|
Reference in New Issue