From df5b75694f5abde94ccf05fa6c7a557b1ba9079b Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Fri, 27 Jul 2018 23:55:23 -0400 Subject: Remove files that are not used --- src/common/file_util.cpp | 12 ++++++++++++ src/common/file_util.h | 2 ++ src/common/logging/backend.cpp | 1 + src/common/logging/log.h | 1 + 4 files changed, 16 insertions(+) (limited to 'src/common') diff --git a/src/common/file_util.cpp b/src/common/file_util.cpp index b8dd92b65..89004c3c0 100644 --- a/src/common/file_util.cpp +++ b/src/common/file_util.cpp @@ -736,6 +736,18 @@ const std::string& GetUserPath(UserPath path, const std::string& new_path) { return paths[path]; } +std::string GetHactoolConfigurationPath() { +#ifdef _WIN32 + char path[MAX_PATH]; + if (SHGetFolderPathA(NULL, CSIDL_PROFILE, NULL, 0, path) != S_OK) + return ""; + std::string local_path = Common::StringFromFixedZeroTerminatedBuffer(path, MAX_PATH); + return local_path + "\\.switch"; +#else + return GetHomeDirectory() + "/.switch"; +#endif +} + size_t WriteStringToFile(bool text_file, const std::string& str, const char* filename) { return FileUtil::IOFile(filename, text_file ? "w" : "wb").WriteBytes(str.data(), str.size()); } diff --git a/src/common/file_util.h b/src/common/file_util.h index bc9272d89..d530d86c9 100644 --- a/src/common/file_util.h +++ b/src/common/file_util.h @@ -125,6 +125,8 @@ bool SetCurrentDir(const std::string& directory); // directory. To be used in "multi-user" mode (that is, installed). const std::string& GetUserPath(UserPath path, const std::string& new_path = ""); +std::string GetHactoolConfigurationPath(); + // Returns the path to where the sys file are std::string GetSysDirectory(); diff --git a/src/common/logging/backend.cpp b/src/common/logging/backend.cpp index d86c40d26..d7d2f9a20 100644 --- a/src/common/logging/backend.cpp +++ b/src/common/logging/backend.cpp @@ -212,6 +212,7 @@ void FileBackend::Write(const Entry& entry) { CLS(Input) \ CLS(Network) \ CLS(Loader) \ + CLS(Crypto) \ CLS(WebService) // GetClassName is a macro defined by Windows.h, grrr... diff --git a/src/common/logging/log.h b/src/common/logging/log.h index 140cd8e47..5a580b004 100644 --- a/src/common/logging/log.h +++ b/src/common/logging/log.h @@ -97,6 +97,7 @@ enum class Class : ClassType { Audio_DSP, ///< The HLE implementation of the DSP Audio_Sink, ///< Emulator audio output backend Loader, ///< ROM loader + Crypto, ///< Cryptographic engine/functions Input, ///< Input emulation Network, ///< Network emulation WebService, ///< Interface to yuzu Web Services -- cgit v1.2.3 From 22342487e8fb851a9837db22408db56240aa6931 Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Sat, 28 Jul 2018 16:23:00 -0400 Subject: Extract mbedtls to cpp file --- src/common/file_util.cpp | 2 +- src/core/CMakeLists.txt | 1 + src/core/crypto/aes_util.cpp | 102 +++++++++++++++++++++++++++++++++- src/core/crypto/aes_util.h | 106 ++++++++---------------------------- src/core/file_sys/content_archive.h | 3 +- 5 files changed, 127 insertions(+), 87 deletions(-) (limited to 'src/common') diff --git a/src/common/file_util.cpp b/src/common/file_util.cpp index 89004c3c0..a26702f54 100644 --- a/src/common/file_util.cpp +++ b/src/common/file_util.cpp @@ -739,7 +739,7 @@ const std::string& GetUserPath(UserPath path, const std::string& new_path) { std::string GetHactoolConfigurationPath() { #ifdef _WIN32 char path[MAX_PATH]; - if (SHGetFolderPathA(NULL, CSIDL_PROFILE, NULL, 0, path) != S_OK) + if (SHGetFolderPathA(nullptr, CSIDL_PROFILE, nullptr, 0, path) != S_OK) return ""; std::string local_path = Common::StringFromFixedZeroTerminatedBuffer(path, MAX_PATH); return local_path + "\\.switch"; diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index a69ee9146..528d96a58 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -12,6 +12,7 @@ add_library(core STATIC core_timing.h core_timing_util.cpp core_timing_util.h + crypto/aes_util.cpp crypto/aes_util.h crypto/encryption_layer.cpp crypto/encryption_layer.h diff --git a/src/core/crypto/aes_util.cpp b/src/core/crypto/aes_util.cpp index 46326cdec..a9646e52f 100644 --- a/src/core/crypto/aes_util.cpp +++ b/src/core/crypto/aes_util.cpp @@ -2,5 +2,103 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -namespace Crypto { -} // namespace Crypto +#include "core/crypto/aes_util.h" +#include "mbedtls/cipher.h" + +namespace Core::Crypto { +static_assert(static_cast(Mode::CTR) == static_cast(MBEDTLS_CIPHER_AES_128_CTR), "CTR mode is incorrect."); +static_assert(static_cast(Mode::ECB) == static_cast(MBEDTLS_CIPHER_AES_128_ECB), "ECB mode is incorrect."); +static_assert(static_cast(Mode::XTS) == static_cast(MBEDTLS_CIPHER_AES_128_XTS), "XTS mode is incorrect."); + +template +Crypto::AESCipher::AESCipher(Key key, Mode mode) { + mbedtls_cipher_init(encryption_context.get()); + mbedtls_cipher_init(decryption_context.get()); + + ASSERT_MSG((mbedtls_cipher_setup( + encryption_context.get(), + mbedtls_cipher_info_from_type(static_cast(mode))) || + mbedtls_cipher_setup(decryption_context.get(), + mbedtls_cipher_info_from_type( + static_cast(mode)))) == 0, + "Failed to initialize mbedtls ciphers."); + + ASSERT( + !mbedtls_cipher_setkey(encryption_context.get(), key.data(), KeySize * 8, MBEDTLS_ENCRYPT)); + ASSERT( + !mbedtls_cipher_setkey(decryption_context.get(), key.data(), KeySize * 8, MBEDTLS_DECRYPT)); + //"Failed to set key on mbedtls ciphers."); +} + +template +AESCipher::~AESCipher() { + mbedtls_cipher_free(encryption_context.get()); + mbedtls_cipher_free(decryption_context.get()); +} + +template +void AESCipher::SetIV(std::vector iv) { + ASSERT_MSG((mbedtls_cipher_set_iv(encryption_context.get(), iv.data(), iv.size()) || + mbedtls_cipher_set_iv(decryption_context.get(), iv.data(), iv.size())) == 0, + "Failed to set IV on mbedtls ciphers."); +} + +template +void AESCipher::Transcode(const u8* src, size_t size, u8* dest, Op op) { + size_t written = 0; + + const auto context = op == Op::Encrypt ? encryption_context.get() : decryption_context.get(); + + mbedtls_cipher_reset(context); + + if (mbedtls_cipher_get_cipher_mode(context) == MBEDTLS_MODE_XTS) { + mbedtls_cipher_update(context, src, size, + dest, &written); + if (written != size) + LOG_WARNING(Crypto, "Not all data was decrypted requested={:016X}, actual={:016X}.", + size, written); + } else { + const auto block_size = mbedtls_cipher_get_block_size(context); + + for (size_t offset = 0; offset < size; offset += block_size) { + auto length = std::min(block_size, size - offset); + mbedtls_cipher_update(context, src + offset, length, + dest + offset, &written); + if (written != length) + LOG_WARNING(Crypto, + "Not all data was decrypted requested={:016X}, actual={:016X}.", + length, written); + } + } + + mbedtls_cipher_finish(context, nullptr, nullptr); +} + +template +void AESCipher::XTSTranscode(const u8* src, size_t size, u8* dest, size_t sector_id, size_t sector_size, + Op op) { + if (size % sector_size > 0) { + LOG_CRITICAL(Crypto, "Data size must be a multiple of sector size."); + return; + } + + for (size_t i = 0; i < size; i += sector_size) { + SetIV(CalculateNintendoTweak(sector_id++)); + Transcode(src + i, sector_size, + dest + i, op); + } +} + +template +std::vector AESCipher::CalculateNintendoTweak(size_t sector_id) { + std::vector out(0x10); + for (size_t i = 0xF; i <= 0xF; --i) { + out[i] = sector_id & 0xFF; + sector_id >>= 8; + } + return out; +} + +template class AESCipher; +template class AESCipher; +} \ No newline at end of file diff --git a/src/core/crypto/aes_util.h b/src/core/crypto/aes_util.h index 9807b9234..5c09718b2 100644 --- a/src/core/crypto/aes_util.h +++ b/src/core/crypto/aes_util.h @@ -6,113 +6,53 @@ #include "common/assert.h" #include "core/file_sys/vfs.h" -#include "mbedtls/cipher.h" -namespace Crypto { +namespace Core::Crypto { enum class Mode { - CTR = MBEDTLS_CIPHER_AES_128_CTR, - ECB = MBEDTLS_CIPHER_AES_128_ECB, - XTS = MBEDTLS_CIPHER_AES_128_XTS, + CTR = 11, + ECB = 2, + XTS = 70, }; enum class Op { - ENCRYPT, - DECRYPT, + Encrypt, + Decrypt, }; +struct mbedtls_cipher_context_t; + template -struct AESCipher { +class AESCipher { static_assert(std::is_same_v>, "Key must be std::array of u8."); static_assert(KeySize == 0x10 || KeySize == 0x20, "KeySize must be 128 or 256."); - AESCipher(Key key, Mode mode) { - mbedtls_cipher_init(&encryption_context); - mbedtls_cipher_init(&decryption_context); - - ASSERT_MSG((mbedtls_cipher_setup( - &encryption_context, - mbedtls_cipher_info_from_type(static_cast(mode))) || - mbedtls_cipher_setup(&decryption_context, - mbedtls_cipher_info_from_type( - static_cast(mode)))) == 0, - "Failed to initialize mbedtls ciphers."); - - ASSERT( - !mbedtls_cipher_setkey(&encryption_context, key.data(), KeySize * 8, MBEDTLS_ENCRYPT)); - ASSERT( - !mbedtls_cipher_setkey(&decryption_context, key.data(), KeySize * 8, MBEDTLS_DECRYPT)); - //"Failed to set key on mbedtls ciphers."); - } +public: + AESCipher(Key key, Mode mode); - ~AESCipher() { - mbedtls_cipher_free(&encryption_context); - mbedtls_cipher_free(&decryption_context); - } + ~AESCipher(); - void SetIV(std::vector iv) { - ASSERT_MSG((mbedtls_cipher_set_iv(&encryption_context, iv.data(), iv.size()) || - mbedtls_cipher_set_iv(&decryption_context, iv.data(), iv.size())) == 0, - "Failed to set IV on mbedtls ciphers."); - } + void SetIV(std::vector iv); template void Transcode(const Source* src, size_t size, Dest* dest, Op op) { - size_t written = 0; - - const auto context = op == Op::ENCRYPT ? &encryption_context : &decryption_context; - - mbedtls_cipher_reset(context); - - if (mbedtls_cipher_get_cipher_mode(context) == MBEDTLS_MODE_XTS) { - mbedtls_cipher_update(context, reinterpret_cast(src), size, - reinterpret_cast(dest), &written); - if (written != size) - LOG_WARNING(Crypto, "Not all data was decrypted requested={:016X}, actual={:016X}.", - size, written); - } else { - const auto block_size = mbedtls_cipher_get_block_size(context); - - for (size_t offset = 0; offset < size; offset += block_size) { - auto length = std::min(block_size, size - offset); - mbedtls_cipher_update(context, reinterpret_cast(src) + offset, length, - reinterpret_cast(dest) + offset, &written); - if (written != length) - LOG_WARNING(Crypto, - "Not all data was decrypted requested={:016X}, actual={:016X}.", - length, written); - } - } - - mbedtls_cipher_finish(context, nullptr, nullptr); + Transcode(reinterpret_cast(src), size, reinterpret_cast(dest), op); } + void Transcode(const u8* src, size_t size, u8* dest, Op op); + template void XTSTranscode(const Source* src, size_t size, Dest* dest, size_t sector_id, size_t sector_size, Op op) { - if (size % sector_size > 0) { - LOG_CRITICAL(Crypto, "Data size must be a multiple of sector size."); - return; - } - - for (size_t i = 0; i < size; i += sector_size) { - SetIV(CalculateNintendoTweak(sector_id++)); - Transcode(reinterpret_cast(src) + i, sector_size, - reinterpret_cast(dest) + i, op); - } + XTSTranscode(reinterpret_cast(src), size, reinterpret_cast(dest), sector_id, sector_size, op); } + void XTSTranscode(const u8* src, size_t size, u8* dest, size_t sector_id, size_t sector_size, Op op); + private: - mbedtls_cipher_context_t encryption_context; - mbedtls_cipher_context_t decryption_context; - - static std::vector CalculateNintendoTweak(size_t sector_id) { - std::vector out(0x10); - for (size_t i = 0xF; i <= 0xF; --i) { - out[i] = sector_id & 0xFF; - sector_id >>= 8; - } - return out; - } + std::unique_ptr encryption_context; + std::unique_ptr decryption_context; + + static std::vector CalculateNintendoTweak(size_t sector_id); }; } // namespace Crypto diff --git a/src/core/file_sys/content_archive.h b/src/core/file_sys/content_archive.h index 1e8d9c8ae..d9ad3bf7e 100644 --- a/src/core/file_sys/content_archive.h +++ b/src/core/file_sys/content_archive.h @@ -9,6 +9,7 @@ #include #include +#include "core/loader/loader.h" #include "common/common_funcs.h" #include "common/common_types.h" #include "common/swap.h" @@ -108,7 +109,7 @@ private: Crypto::Key128 GetKeyAreaKey(NCASectionCryptoType type); - VirtualFile Decrypt(NCASectionHeader header, VirtualFile in, size_t starting_offset); + VirtualFile Decrypt(NCASectionHeader header, VirtualFile in, u64 starting_offset); }; } // namespace FileSys -- cgit v1.2.3 From cc8234fa89f1a7dcc2709e6d3be03f8458c841d4 Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Sun, 29 Jul 2018 17:45:12 -0400 Subject: Use SHGetKnownFolderPath instead of SHGetFolderPathA --- src/common/file_util.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src/common') diff --git a/src/common/file_util.cpp b/src/common/file_util.cpp index a26702f54..ed38c3ced 100644 --- a/src/common/file_util.cpp +++ b/src/common/file_util.cpp @@ -738,10 +738,11 @@ const std::string& GetUserPath(UserPath path, const std::string& new_path) { std::string GetHactoolConfigurationPath() { #ifdef _WIN32 - char path[MAX_PATH]; - if (SHGetFolderPathA(nullptr, CSIDL_PROFILE, nullptr, 0, path) != S_OK) + PWSTR pw_local_path = nullptr; + if (SHGetKnownFolderPath(FOLDERID_Profile, 0, nullptr, &pw_local_path) != S_OK) return ""; - std::string local_path = Common::StringFromFixedZeroTerminatedBuffer(path, MAX_PATH); + std::string local_path = Common::UTF16ToUTF8(pw_local_path); + CoTaskMemFree(pw_local_path); return local_path + "\\.switch"; #else return GetHomeDirectory() + "/.switch"; -- cgit v1.2.3 From 150527ec194107f0ba5ea9bdef487782e64090ef Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Sun, 29 Jul 2018 18:42:04 -0400 Subject: Allow key loading from %YUZU_DIR%/keys in addition to ~/.switch --- src/common/common_paths.h | 1 + src/common/file_util.cpp | 1 + src/common/file_util.h | 1 + src/core/crypto/key_manager.cpp | 25 ++++++++++++++++++------- src/core/crypto/key_manager.h | 2 ++ 5 files changed, 23 insertions(+), 7 deletions(-) (limited to 'src/common') diff --git a/src/common/common_paths.h b/src/common/common_paths.h index 6799a357a..df2ce80b1 100644 --- a/src/common/common_paths.h +++ b/src/common/common_paths.h @@ -32,6 +32,7 @@ #define SDMC_DIR "sdmc" #define NAND_DIR "nand" #define SYSDATA_DIR "sysdata" +#define KEYS_DIR "keys" #define LOG_DIR "log" // Filenames diff --git a/src/common/file_util.cpp b/src/common/file_util.cpp index ed38c3ced..7aeda737f 100644 --- a/src/common/file_util.cpp +++ b/src/common/file_util.cpp @@ -706,6 +706,7 @@ const std::string& GetUserPath(UserPath path, const std::string& new_path) { paths.emplace(UserPath::SDMCDir, user_path + SDMC_DIR DIR_SEP); paths.emplace(UserPath::NANDDir, user_path + NAND_DIR DIR_SEP); paths.emplace(UserPath::SysDataDir, user_path + SYSDATA_DIR DIR_SEP); + paths.emplace(UserPath::KeysDir, user_path + KEYS_DIR DIR_SEP); // TODO: Put the logs in a better location for each OS paths.emplace(UserPath::LogDir, user_path + LOG_DIR DIR_SEP); } diff --git a/src/common/file_util.h b/src/common/file_util.h index d530d86c9..28697d527 100644 --- a/src/common/file_util.h +++ b/src/common/file_util.h @@ -23,6 +23,7 @@ namespace FileUtil { enum class UserPath { CacheDir, ConfigDir, + KeysDir, LogDir, NANDDir, RootDir, diff --git a/src/core/crypto/key_manager.cpp b/src/core/crypto/key_manager.cpp index ea20bc31b..dea092b5e 100644 --- a/src/core/crypto/key_manager.cpp +++ b/src/core/crypto/key_manager.cpp @@ -12,6 +12,7 @@ #include "common/logging/log.h" #include "core/crypto/key_manager.h" #include "core/settings.h" +#include "key_manager.h" namespace Core::Crypto { @@ -50,18 +51,17 @@ std::array operator""_array32(const char* str, size_t len) { KeyManager::KeyManager() { // Initialize keys - std::string keys_dir = FileUtil::GetHactoolConfigurationPath(); + std::string hactool_keys_dir = FileUtil::GetHactoolConfigurationPath(); + std::string yuzu_keys_dir = FileUtil::GetUserPath(FileUtil::UserPath::KeysDir); if (Settings::values.use_dev_keys) { dev_mode = true; - if (FileUtil::Exists(keys_dir + DIR_SEP + "dev.keys")) - LoadFromFile(keys_dir + DIR_SEP + "dev.keys", false); + AttemptLoadKeyFile(yuzu_keys_dir, hactool_keys_dir, "dev.keys", false); } else { dev_mode = false; - if (FileUtil::Exists(keys_dir + DIR_SEP + "prod.keys")) - LoadFromFile(keys_dir + DIR_SEP + "prod.keys", false); + AttemptLoadKeyFile(yuzu_keys_dir, hactool_keys_dir, "prod.keys", false); } - if (FileUtil::Exists(keys_dir + DIR_SEP + "title.keys")) - LoadFromFile(keys_dir + DIR_SEP + "title.keys", true); + + AttemptLoadKeyFile(yuzu_keys_dir, hactool_keys_dir, "title.keys", true); } void KeyManager::LoadFromFile(std::string_view filename_, bool is_title_keys) { @@ -104,6 +104,17 @@ void KeyManager::LoadFromFile(std::string_view filename_, bool is_title_keys) { } } +void KeyManager::AttemptLoadKeyFile(std::string_view dir1_, std::string_view dir2_, + std::string_view filename_, bool title) { + std::string dir1(dir1_); + std::string dir2(dir2_); + std::string filename(filename_); + if (FileUtil::Exists(dir1 + DIR_SEP + filename)) + LoadFromFile(dir1 + DIR_SEP + filename, title); + else if (FileUtil::Exists(dir2 + DIR_SEP + filename)) + LoadFromFile(dir2 + DIR_SEP + filename, title); +} + bool KeyManager::HasKey(S128KeyType id, u64 field1, u64 field2) const { return s128_keys.find({id, field1, field2}) != s128_keys.end(); } diff --git a/src/core/crypto/key_manager.h b/src/core/crypto/key_manager.h index e04f1d49f..a52ea4cb9 100644 --- a/src/core/crypto/key_manager.h +++ b/src/core/crypto/key_manager.h @@ -107,6 +107,8 @@ private: bool dev_mode; void LoadFromFile(std::string_view filename, bool is_title_keys); + void AttemptLoadKeyFile(std::string_view dir1, std::string_view dir2, std::string_view filename, + bool title); static std::unordered_map> s128_file_id; static std::unordered_map> s256_file_id; -- cgit v1.2.3