summaryrefslogtreecommitdiffstats
path: root/src/core/crypto/key_manager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/crypto/key_manager.cpp')
-rw-r--r--src/core/crypto/key_manager.cpp139
1 files changed, 76 insertions, 63 deletions
diff --git a/src/core/crypto/key_manager.cpp b/src/core/crypto/key_manager.cpp
index a4b739c63..fb451a423 100644
--- a/src/core/crypto/key_manager.cpp
+++ b/src/core/crypto/key_manager.cpp
@@ -18,8 +18,9 @@
#include <mbedtls/cmac.h>
#include <mbedtls/sha256.h>
#include "common/common_funcs.h"
-#include "common/common_paths.h"
-#include "common/file_util.h"
+#include "common/fs/file.h"
+#include "common/fs/fs.h"
+#include "common/fs/path_util.h"
#include "common/hex_util.h"
#include "common/logging/log.h"
#include "common/settings.h"
@@ -325,46 +326,55 @@ Key128 DeriveKeyblobMACKey(const Key128& keyblob_key, const Key128& mac_source)
}
std::optional<Key128> DeriveSDSeed() {
- const Common::FS::IOFile save_43(Common::FS::GetUserPath(Common::FS::UserPath::NANDDir) +
- "/system/save/8000000000000043",
- "rb+");
+ const auto system_save_43_path =
+ Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir) / "system/save/8000000000000043";
+ const Common::FS::IOFile save_43{system_save_43_path, Common::FS::FileAccessMode::Read,
+ Common::FS::FileType::BinaryFile};
+
if (!save_43.IsOpen()) {
return std::nullopt;
}
- const Common::FS::IOFile sd_private(Common::FS::GetUserPath(Common::FS::UserPath::SDMCDir) +
- "/Nintendo/Contents/private",
- "rb+");
+ const auto sd_private_path =
+ Common::FS::GetYuzuPath(Common::FS::YuzuPath::SDMCDir) / "Nintendo/Contents/private";
+
+ const Common::FS::IOFile sd_private{sd_private_path, Common::FS::FileAccessMode::Read,
+ Common::FS::FileType::BinaryFile};
+
if (!sd_private.IsOpen()) {
return std::nullopt;
}
std::array<u8, 0x10> private_seed{};
- if (sd_private.ReadBytes(private_seed.data(), private_seed.size()) != private_seed.size()) {
+ if (sd_private.Read(private_seed) != private_seed.size()) {
return std::nullopt;
}
std::array<u8, 0x10> buffer{};
- std::size_t offset = 0;
- for (; offset + 0x10 < save_43.GetSize(); ++offset) {
- if (!save_43.Seek(offset, SEEK_SET)) {
+ s64 offset = 0;
+ for (; offset + 0x10 < static_cast<s64>(save_43.GetSize()); ++offset) {
+ if (!save_43.Seek(offset)) {
+ return std::nullopt;
+ }
+
+ if (save_43.Read(buffer) != buffer.size()) {
return std::nullopt;
}
- save_43.ReadBytes(buffer.data(), buffer.size());
if (buffer == private_seed) {
break;
}
}
- if (!save_43.Seek(offset + 0x10, SEEK_SET)) {
+ if (!save_43.Seek(offset + 0x10)) {
return std::nullopt;
}
Key128 seed{};
- if (save_43.ReadBytes(seed.data(), seed.size()) != seed.size()) {
+ if (save_43.Read(seed) != seed.size()) {
return std::nullopt;
}
+
return seed;
}
@@ -435,7 +445,7 @@ std::vector<Ticket> GetTicketblob(const Common::FS::IOFile& ticket_save) {
}
std::vector<u8> buffer(ticket_save.GetSize());
- if (ticket_save.ReadBytes(buffer.data(), buffer.size()) != buffer.size()) {
+ if (ticket_save.Read(buffer) != buffer.size()) {
return {};
}
@@ -566,27 +576,26 @@ std::optional<std::pair<Key128, Key128>> ParseTicket(const Ticket& ticket,
KeyManager::KeyManager() {
// Initialize keys
- const std::string hactool_keys_dir = Common::FS::GetHactoolConfigurationPath();
- const std::string yuzu_keys_dir = Common::FS::GetUserPath(Common::FS::UserPath::KeysDir);
+ const auto yuzu_keys_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::KeysDir);
- if (!Common::FS::Exists(yuzu_keys_dir)) {
- Common::FS::CreateDir(yuzu_keys_dir);
+ if (!Common::FS::CreateDir(yuzu_keys_dir)) {
+ LOG_ERROR(Core, "Failed to create the keys directory.");
}
if (Settings::values.use_dev_keys) {
dev_mode = true;
- AttemptLoadKeyFile(yuzu_keys_dir, hactool_keys_dir, "dev.keys", false);
- AttemptLoadKeyFile(yuzu_keys_dir, yuzu_keys_dir, "dev.keys_autogenerated", false);
+ LoadFromFile(yuzu_keys_dir / "dev.keys", false);
+ LoadFromFile(yuzu_keys_dir / "dev.keys_autogenerated", false);
} else {
dev_mode = false;
- AttemptLoadKeyFile(yuzu_keys_dir, hactool_keys_dir, "prod.keys", false);
- AttemptLoadKeyFile(yuzu_keys_dir, yuzu_keys_dir, "prod.keys_autogenerated", false);
+ LoadFromFile(yuzu_keys_dir / "prod.keys", false);
+ LoadFromFile(yuzu_keys_dir / "prod.keys_autogenerated", false);
}
- AttemptLoadKeyFile(yuzu_keys_dir, hactool_keys_dir, "title.keys", true);
- AttemptLoadKeyFile(yuzu_keys_dir, yuzu_keys_dir, "title.keys_autogenerated", true);
- AttemptLoadKeyFile(yuzu_keys_dir, hactool_keys_dir, "console.keys", false);
- AttemptLoadKeyFile(yuzu_keys_dir, yuzu_keys_dir, "console.keys_autogenerated", false);
+ LoadFromFile(yuzu_keys_dir / "title.keys", true);
+ LoadFromFile(yuzu_keys_dir / "title.keys_autogenerated", true);
+ LoadFromFile(yuzu_keys_dir / "console.keys", false);
+ LoadFromFile(yuzu_keys_dir / "console.keys_autogenerated", false);
}
static bool ValidCryptoRevisionString(std::string_view base, size_t begin, size_t length) {
@@ -597,9 +606,14 @@ static bool ValidCryptoRevisionString(std::string_view base, size_t begin, size_
[](u8 c) { return std::isxdigit(c); });
}
-void KeyManager::LoadFromFile(const std::string& filename, bool is_title_keys) {
+void KeyManager::LoadFromFile(const std::filesystem::path& file_path, bool is_title_keys) {
+ if (!Common::FS::Exists(file_path)) {
+ return;
+ }
+
std::ifstream file;
- Common::FS::OpenFStream(file, filename, std::ios_base::in);
+ Common::FS::OpenFileStream(file, file_path, std::ios_base::in);
+
if (!file.is_open()) {
return;
}
@@ -694,15 +708,6 @@ void KeyManager::LoadFromFile(const std::string& filename, bool is_title_keys) {
}
}
-void KeyManager::AttemptLoadKeyFile(const std::string& dir1, const std::string& dir2,
- const std::string& filename, bool title) {
- if (Common::FS::Exists(dir1 + DIR_SEP + filename)) {
- LoadFromFile(dir1 + DIR_SEP + filename, title);
- } else if (Common::FS::Exists(dir2 + DIR_SEP + filename)) {
- LoadFromFile(dir2 + DIR_SEP + filename, title);
- }
-}
-
bool KeyManager::BaseDeriveNecessary() const {
const auto check_key_existence = [this](auto key_type, u64 index1 = 0, u64 index2 = 0) {
return !HasKey(key_type, index1, index2);
@@ -766,30 +771,35 @@ Key256 KeyManager::GetBISKey(u8 partition_id) const {
template <size_t Size>
void KeyManager::WriteKeyToFile(KeyCategory category, std::string_view keyname,
const std::array<u8, Size>& key) {
- const std::string yuzu_keys_dir = Common::FS::GetUserPath(Common::FS::UserPath::KeysDir);
+ const auto yuzu_keys_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::KeysDir);
+
std::string filename = "title.keys_autogenerated";
+
if (category == KeyCategory::Standard) {
filename = dev_mode ? "dev.keys_autogenerated" : "prod.keys_autogenerated";
} else if (category == KeyCategory::Console) {
filename = "console.keys_autogenerated";
}
- const auto path = yuzu_keys_dir + DIR_SEP + filename;
+ const auto path = yuzu_keys_dir / filename;
const auto add_info_text = !Common::FS::Exists(path);
- Common::FS::CreateFullPath(path);
- Common::FS::IOFile file{path, "a"};
+
+ Common::FS::IOFile file{path, Common::FS::FileAccessMode::Append,
+ Common::FS::FileType::TextFile};
+
if (!file.IsOpen()) {
return;
}
+
if (add_info_text) {
- file.WriteString(
+ void(file.WriteString(
"# This file is autogenerated by Yuzu\n"
"# It serves to store keys that were automatically generated from the normal keys\n"
- "# If you are experiencing issues involving keys, it may help to delete this file\n");
+ "# If you are experiencing issues involving keys, it may help to delete this file\n"));
}
- file.WriteString(fmt::format("\n{} = {}", keyname, Common::HexToString(key)));
- AttemptLoadKeyFile(yuzu_keys_dir, yuzu_keys_dir, filename, category == KeyCategory::Title);
+ void(file.WriteString(fmt::format("\n{} = {}", keyname, Common::HexToString(key))));
+ LoadFromFile(path, category == KeyCategory::Title);
}
void KeyManager::SetKey(S128KeyType id, Key128 key, u64 field1, u64 field2) {
@@ -861,20 +871,17 @@ void KeyManager::SetKey(S256KeyType id, Key256 key, u64 field1, u64 field2) {
}
bool KeyManager::KeyFileExists(bool title) {
- const std::string hactool_keys_dir = Common::FS::GetHactoolConfigurationPath();
- const std::string yuzu_keys_dir = Common::FS::GetUserPath(Common::FS::UserPath::KeysDir);
+ const auto yuzu_keys_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::KeysDir);
+
if (title) {
- return Common::FS::Exists(hactool_keys_dir + DIR_SEP + "title.keys") ||
- Common::FS::Exists(yuzu_keys_dir + DIR_SEP + "title.keys");
+ return Common::FS::Exists(yuzu_keys_dir / "title.keys");
}
if (Settings::values.use_dev_keys) {
- return Common::FS::Exists(hactool_keys_dir + DIR_SEP + "dev.keys") ||
- Common::FS::Exists(yuzu_keys_dir + DIR_SEP + "dev.keys");
+ return Common::FS::Exists(yuzu_keys_dir / "dev.keys");
}
- return Common::FS::Exists(hactool_keys_dir + DIR_SEP + "prod.keys") ||
- Common::FS::Exists(yuzu_keys_dir + DIR_SEP + "prod.keys");
+ return Common::FS::Exists(yuzu_keys_dir / "prod.keys");
}
void KeyManager::DeriveSDSeedLazy() {
@@ -1115,15 +1122,21 @@ void KeyManager::PopulateTickets() {
return;
}
- const Common::FS::IOFile save1(Common::FS::GetUserPath(Common::FS::UserPath::NANDDir) +
- "/system/save/80000000000000e1",
- "rb+");
- const Common::FS::IOFile save2(Common::FS::GetUserPath(Common::FS::UserPath::NANDDir) +
- "/system/save/80000000000000e2",
- "rb+");
+ const auto system_save_e1_path =
+ Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir) / "system/save/80000000000000e1";
+
+ const Common::FS::IOFile save_e1{system_save_e1_path, Common::FS::FileAccessMode::Read,
+ Common::FS::FileType::BinaryFile};
+
+ const auto system_save_e2_path =
+ Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir) / "system/save/80000000000000e2";
+
+ const Common::FS::IOFile save_e2{system_save_e2_path, Common::FS::FileAccessMode::Read,
+ Common::FS::FileType::BinaryFile};
+
+ const auto blob2 = GetTicketblob(save_e2);
+ auto res = GetTicketblob(save_e1);
- const auto blob2 = GetTicketblob(save2);
- auto res = GetTicketblob(save1);
const auto idx = res.size();
res.insert(res.end(), blob2.begin(), blob2.end());