|
|
@ -1,4 +1,4 @@
|
|
|
|
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
|
|
|
|
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project & 2024 suyu Emulator Project
|
|
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
|
|
|
|
|
|
|
|
#include <algorithm>
|
|
|
|
#include <algorithm>
|
|
|
@ -372,7 +372,7 @@ Key128 DeriveKeyblobMACKey(const Key128& keyblob_key, const Key128& mac_source)
|
|
|
|
|
|
|
|
|
|
|
|
std::optional<Key128> DeriveSDSeed() {
|
|
|
|
std::optional<Key128> DeriveSDSeed() {
|
|
|
|
const auto system_save_43_path =
|
|
|
|
const auto system_save_43_path =
|
|
|
|
Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir) / "system/save/8000000000000043";
|
|
|
|
Common::FS::GetSuyuPath(Common::FS::SuyuPath::NANDDir) / "system/save/8000000000000043";
|
|
|
|
const Common::FS::IOFile save_43{system_save_43_path, Common::FS::FileAccessMode::Read,
|
|
|
|
const Common::FS::IOFile save_43{system_save_43_path, Common::FS::FileAccessMode::Read,
|
|
|
|
Common::FS::FileType::BinaryFile};
|
|
|
|
Common::FS::FileType::BinaryFile};
|
|
|
|
|
|
|
|
|
|
|
@ -381,7 +381,7 @@ std::optional<Key128> DeriveSDSeed() {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const auto sd_private_path =
|
|
|
|
const auto sd_private_path =
|
|
|
|
Common::FS::GetYuzuPath(Common::FS::YuzuPath::SDMCDir) / "Nintendo/Contents/private";
|
|
|
|
Common::FS::GetSuyuPath(Common::FS::SuyuPath::SDMCDir) / "Nintendo/Contents/private";
|
|
|
|
|
|
|
|
|
|
|
|
const Common::FS::IOFile sd_private{sd_private_path, Common::FS::FileAccessMode::Read,
|
|
|
|
const Common::FS::IOFile sd_private{sd_private_path, Common::FS::FileAccessMode::Read,
|
|
|
|
Common::FS::FileType::BinaryFile};
|
|
|
|
Common::FS::FileType::BinaryFile};
|
|
|
@ -640,7 +640,7 @@ KeyManager::KeyManager() {
|
|
|
|
|
|
|
|
|
|
|
|
void KeyManager::ReloadKeys() {
|
|
|
|
void KeyManager::ReloadKeys() {
|
|
|
|
// Initialize keys
|
|
|
|
// Initialize keys
|
|
|
|
const auto yuzu_keys_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::KeysDir);
|
|
|
|
const auto yuzu_keys_dir = Common::FS::GetSuyuPath(Common::FS::SuyuPath::KeysDir);
|
|
|
|
|
|
|
|
|
|
|
|
if (!Common::FS::CreateDir(yuzu_keys_dir)) {
|
|
|
|
if (!Common::FS::CreateDir(yuzu_keys_dir)) {
|
|
|
|
LOG_ERROR(Core, "Failed to create the keys directory.");
|
|
|
|
LOG_ERROR(Core, "Failed to create the keys directory.");
|
|
|
@ -648,13 +648,17 @@ void KeyManager::ReloadKeys() {
|
|
|
|
|
|
|
|
|
|
|
|
if (Settings::values.use_dev_keys) {
|
|
|
|
if (Settings::values.use_dev_keys) {
|
|
|
|
dev_mode = true;
|
|
|
|
dev_mode = true;
|
|
|
|
|
|
|
|
LoadFromFile(yuzu_keys_dir / "dev.keys_autogenerated", false);
|
|
|
|
LoadFromFile(yuzu_keys_dir / "dev.keys", false);
|
|
|
|
LoadFromFile(yuzu_keys_dir / "dev.keys", false);
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
dev_mode = false;
|
|
|
|
dev_mode = false;
|
|
|
|
|
|
|
|
LoadFromFile(yuzu_keys_dir / "prod.keys_autogenerated", false);
|
|
|
|
LoadFromFile(yuzu_keys_dir / "prod.keys", false);
|
|
|
|
LoadFromFile(yuzu_keys_dir / "prod.keys", false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
LoadFromFile(yuzu_keys_dir / "title.keys_autogenerated", true);
|
|
|
|
LoadFromFile(yuzu_keys_dir / "title.keys", true);
|
|
|
|
LoadFromFile(yuzu_keys_dir / "title.keys", true);
|
|
|
|
|
|
|
|
LoadFromFile(yuzu_keys_dir / "console.keys_autogenerated", false);
|
|
|
|
LoadFromFile(yuzu_keys_dir / "console.keys", false);
|
|
|
|
LoadFromFile(yuzu_keys_dir / "console.keys", false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -840,6 +844,8 @@ Key256 KeyManager::GetBISKey(u8 partition_id) const {
|
|
|
|
return out;
|
|
|
|
return out;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
template <size_t Size>
|
|
|
|
|
|
|
|
|
|
|
|
void KeyManager::SetKey(S128KeyType id, Key128 key, u64 field1, u64 field2) {
|
|
|
|
void KeyManager::SetKey(S128KeyType id, Key128 key, u64 field1, u64 field2) {
|
|
|
|
if (s128_keys.find({id, field1, field2}) != s128_keys.end() || key == Key128{}) {
|
|
|
|
if (s128_keys.find({id, field1, field2}) != s128_keys.end() || key == Key128{}) {
|
|
|
|
return;
|
|
|
|
return;
|
|
|
@ -850,6 +856,29 @@ void KeyManager::SetKey(S128KeyType id, Key128 key, u64 field1, u64 field2) {
|
|
|
|
std::memcpy(rights_id.data() + sizeof(u64), &field1, sizeof(u64));
|
|
|
|
std::memcpy(rights_id.data() + sizeof(u64), &field1, sizeof(u64));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
auto category = KeyCategory::Standard;
|
|
|
|
|
|
|
|
if (id == S128KeyType::Keyblob || id == S128KeyType::KeyblobMAC || id == S128KeyType::TSEC ||
|
|
|
|
|
|
|
|
id == S128KeyType::SecureBoot || id == S128KeyType::SDSeed || id == S128KeyType::BIS) {
|
|
|
|
|
|
|
|
category = KeyCategory::Console;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const auto iter2 = std::find_if(
|
|
|
|
|
|
|
|
s128_file_id.begin(), s128_file_id.end(), [&id, &field1, &field2](const auto& elem) {
|
|
|
|
|
|
|
|
return std::tie(elem.second.type, elem.second.field1, elem.second.field2) ==
|
|
|
|
|
|
|
|
std::tie(id, field1, field2);
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
if (iter2 != s128_file_id.end()) {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Variable cases
|
|
|
|
|
|
|
|
if (id == S128KeyType::KeyArea) {
|
|
|
|
|
|
|
|
static constexpr std::array<const char*, 3> kak_names = {
|
|
|
|
|
|
|
|
"key_area_key_application_{:02X}",
|
|
|
|
|
|
|
|
"key_area_key_ocean_{:02X}",
|
|
|
|
|
|
|
|
"key_area_key_system_{:02X}",
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
s128_keys[{id, field1, field2}] = key;
|
|
|
|
s128_keys[{id, field1, field2}] = key;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -857,11 +886,16 @@ void KeyManager::SetKey(S256KeyType id, Key256 key, u64 field1, u64 field2) {
|
|
|
|
if (s256_keys.find({id, field1, field2}) != s256_keys.end() || key == Key256{}) {
|
|
|
|
if (s256_keys.find({id, field1, field2}) != s256_keys.end() || key == Key256{}) {
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const auto iter = std::find_if(
|
|
|
|
|
|
|
|
s256_file_id.begin(), s256_file_id.end(), [&id, &field1, &field2](const auto& elem) {
|
|
|
|
|
|
|
|
return std::tie(elem.second.type, elem.second.field1, elem.second.field2) ==
|
|
|
|
|
|
|
|
std::tie(id, field1, field2);
|
|
|
|
|
|
|
|
});
|
|
|
|
s256_keys[{id, field1, field2}] = key;
|
|
|
|
s256_keys[{id, field1, field2}] = key;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool KeyManager::KeyFileExists(bool title) {
|
|
|
|
bool KeyManager::KeyFileExists(bool title) {
|
|
|
|
const auto yuzu_keys_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::KeysDir);
|
|
|
|
const auto yuzu_keys_dir = Common::FS::GetSuyuPath(Common::FS::SuyuPath::KeysDir);
|
|
|
|
|
|
|
|
|
|
|
|
if (title) {
|
|
|
|
if (title) {
|
|
|
|
return Common::FS::Exists(yuzu_keys_dir / "title.keys");
|
|
|
|
return Common::FS::Exists(yuzu_keys_dir / "title.keys");
|
|
|
@ -1108,7 +1142,7 @@ void KeyManager::PopulateTickets() {
|
|
|
|
std::vector<Ticket> tickets;
|
|
|
|
std::vector<Ticket> tickets;
|
|
|
|
|
|
|
|
|
|
|
|
const auto system_save_e1_path =
|
|
|
|
const auto system_save_e1_path =
|
|
|
|
Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir) / "system/save/80000000000000e1";
|
|
|
|
Common::FS::GetSuyuPath(Common::FS::SuyuPath::NANDDir) / "system/save/80000000000000e1";
|
|
|
|
if (Common::FS::Exists(system_save_e1_path)) {
|
|
|
|
if (Common::FS::Exists(system_save_e1_path)) {
|
|
|
|
const Common::FS::IOFile save_e1{system_save_e1_path, Common::FS::FileAccessMode::Read,
|
|
|
|
const Common::FS::IOFile save_e1{system_save_e1_path, Common::FS::FileAccessMode::Read,
|
|
|
|
Common::FS::FileType::BinaryFile};
|
|
|
|
Common::FS::FileType::BinaryFile};
|
|
|
@ -1117,7 +1151,7 @@ void KeyManager::PopulateTickets() {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const auto system_save_e2_path =
|
|
|
|
const auto system_save_e2_path =
|
|
|
|
Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir) / "system/save/80000000000000e2";
|
|
|
|
Common::FS::GetSuyuPath(Common::FS::SuyuPath::NANDDir) / "system/save/80000000000000e2";
|
|
|
|
if (Common::FS::Exists(system_save_e2_path)) {
|
|
|
|
if (Common::FS::Exists(system_save_e2_path)) {
|
|
|
|
const Common::FS::IOFile save_e2{system_save_e2_path, Common::FS::FileAccessMode::Read,
|
|
|
|
const Common::FS::IOFile save_e2{system_save_e2_path, Common::FS::FileAccessMode::Read,
|
|
|
|
Common::FS::FileType::BinaryFile};
|
|
|
|
Common::FS::FileType::BinaryFile};
|
|
|
|