diff options
Diffstat (limited to 'src/core/file_sys')
-rw-r--r-- | src/core/file_sys/card_image.cpp | 15 | ||||
-rw-r--r-- | src/core/file_sys/content_archive.cpp | 48 | ||||
-rw-r--r-- | src/core/file_sys/content_archive.h | 5 | ||||
-rw-r--r-- | src/core/file_sys/vfs.cpp | 7 |
4 files changed, 30 insertions, 45 deletions
diff --git a/src/core/file_sys/card_image.cpp b/src/core/file_sys/card_image.cpp index 5ff09a362..3c1dbf46c 100644 --- a/src/core/file_sys/card_image.cpp +++ b/src/core/file_sys/card_image.cpp @@ -30,8 +30,8 @@ XCI::XCI(VirtualFile file_) : file(std::move(file_)), partitions(0x4) { return; } - const static std::array<std::string, 0x4> partition_names = {"update", "normal", "secure", - "logo"}; + static constexpr std::array<const char*, 0x4> partition_names = {"update", "normal", "secure", + "logo"}; for (XCIPartition partition : {XCIPartition::Update, XCIPartition::Normal, XCIPartition::Secure, XCIPartition::Logo}) { @@ -93,12 +93,9 @@ VirtualDir XCI::GetLogoPartition() const { } std::shared_ptr<NCA> XCI::GetNCAByType(NCAContentType type) const { - for (const auto& nca : ncas) { - if (nca->GetType() == type) - return nca; - } - - return nullptr; + auto iter = std::find_if(ncas.begin(), ncas.end(), + [type](std::shared_ptr<NCA> nca) { return nca->GetType() == type; }); + return iter == ncas.end() ? nullptr : *iter; } VirtualFile XCI::GetNCAFileByType(NCAContentType type) const { @@ -133,7 +130,7 @@ Loader::ResultStatus XCI::AddNCAFromPartition(XCIPartition part) { return Loader::ResultStatus::ErrorInvalidFormat; } - for (VirtualFile file : partitions[static_cast<size_t>(part)]->GetFiles()) { + for (const VirtualFile& file : partitions[static_cast<size_t>(part)]->GetFiles()) { if (file->GetExtension() != "nca") continue; auto nca = std::make_shared<NCA>(file); diff --git a/src/core/file_sys/content_archive.cpp b/src/core/file_sys/content_archive.cpp index add01974e..952dc7068 100644 --- a/src/core/file_sys/content_archive.cpp +++ b/src/core/file_sys/content_archive.cpp @@ -9,10 +9,9 @@ #include "core/crypto/aes_util.h" #include "core/crypto/ctr_encryption_layer.h" #include "core/file_sys/content_archive.h" +#include "core/file_sys/romfs.h" #include "core/file_sys/vfs_offset.h" #include "core/loader/loader.h" -#include "mbedtls/cipher.h" -#include "romfs.h" namespace FileSys { @@ -77,7 +76,7 @@ bool IsValidNCA(const NCAHeader& header) { return header.magic == Common::MakeMagic('N', 'C', 'A', '3'); } -Crypto::Key128 NCA::GetKeyAreaKey(NCASectionCryptoType type) { +Core::Crypto::Key128 NCA::GetKeyAreaKey(NCASectionCryptoType type) { u8 master_key_id = header.crypto_type; if (header.crypto_type_2 > master_key_id) master_key_id = header.crypto_type_2; @@ -85,16 +84,12 @@ Crypto::Key128 NCA::GetKeyAreaKey(NCASectionCryptoType type) { --master_key_id; std::vector<u8> key_area(header.key_area.begin(), header.key_area.end()); - if (!Crypto::keys.ValidateKey(Crypto::S128KeyType::KEY_AREA, master_key_id, header.key_index)) { - status = Loader::ResultStatus::ErrorEncrypted; - return {}; - } - Crypto::AESCipher<Crypto::Key128> cipher( - Crypto::keys.GetKey(Crypto::S128KeyType::KEY_AREA, master_key_id, header.key_index), - Crypto::Mode::ECB); - cipher.Transcode(key_area.data(), key_area.size(), key_area.data(), Crypto::Op::DECRYPT); + Core::Crypto::AESCipher<Core::Crypto::Key128> cipher( + keys.GetKey(Core::Crypto::S128KeyType::KeyArea, master_key_id, header.key_index), + Core::Crypto::Mode::ECB); + cipher.Transcode(key_area.data(), key_area.size(), key_area.data(), Core::Crypto::Op::Decrypt); - Crypto::Key128 out; + Core::Crypto::Key128 out; if (type == NCASectionCryptoType::XTS) std::copy(key_area.begin(), key_area.begin() + 0x10, out.begin()); else if (type == NCASectionCryptoType::CTR) @@ -102,8 +97,8 @@ Crypto::Key128 NCA::GetKeyAreaKey(NCASectionCryptoType type) { else LOG_CRITICAL(Crypto, "Called GetKeyAreaKey on invalid NCASectionCryptoType type={:02X}", static_cast<u8>(type)); - - u128 out_128 = *reinterpret_cast<u128*>(&out); + u128 out_128{}; + memcpy(out_128.data(), out.data(), 16); LOG_DEBUG(Crypto, "called with crypto_rev={:02X}, kak_index={:02X}, key={:016X}{:016X}", master_key_id, header.key_index, out_128[1], out_128[0]); @@ -121,9 +116,9 @@ VirtualFile NCA::Decrypt(NCASectionHeader header, VirtualFile in, u64 starting_o case NCASectionCryptoType::CTR: LOG_DEBUG(Crypto, "called with mode=CTR, starting_offset={:016X}", starting_offset); { - auto out = std::make_shared<Crypto::CTREncryptionLayer>( + auto out = std::make_shared<Core::Crypto::CTREncryptionLayer>( std::move(in), GetKeyAreaKey(NCASectionCryptoType::CTR), starting_offset); - std::vector<u8> iv(16, 0); + std::vector<u8> iv(16); for (u8 i = 0; i < 8; ++i) iv[i] = header.raw.section_ctr[0x8 - i - 1]; out->SetIV(iv); @@ -146,13 +141,10 @@ NCA::NCA(VirtualFile file_) : file(std::move(file_)) { if (!IsValidNCA(header)) { NCAHeader dec_header{}; - if (!Crypto::keys.ValidateKey(Crypto::S256KeyType::HEADER)) { - status = Loader::ResultStatus::ErrorEncrypted; - return; - } - Crypto::AESCipher<Crypto::Key256> cipher(Crypto::keys.GetKey(Crypto::S256KeyType::HEADER), - Crypto::Mode::XTS); - cipher.XTSTranscode(&header, sizeof(NCAHeader), &dec_header, 0, 0x200, Crypto::Op::DECRYPT); + Core::Crypto::AESCipher<Core::Crypto::Key256> cipher( + keys.GetKey(Core::Crypto::S256KeyType::Header), Core::Crypto::Mode::XTS); + cipher.XTSTranscode(&header, sizeof(NCAHeader), &dec_header, 0, 0x200, + Core::Crypto::Op::Decrypt); if (IsValidNCA(dec_header)) { header = dec_header; encrypted = true; @@ -171,14 +163,10 @@ NCA::NCA(VirtualFile file_) : file(std::move(file_)) { if (encrypted) { auto raw = file->ReadBytes(length_sections, SECTION_HEADER_OFFSET); - if (!Crypto::keys.ValidateKey(Crypto::S256KeyType::HEADER)) { - status = Loader::ResultStatus::ErrorEncrypted; - return; - } - Crypto::AESCipher<Crypto::Key256> cipher(Crypto::keys.GetKey(Crypto::S256KeyType::HEADER), - Crypto::Mode::XTS); + Core::Crypto::AESCipher<Core::Crypto::Key256> cipher( + keys.GetKey(Core::Crypto::S256KeyType::Header), Core::Crypto::Mode::XTS); cipher.XTSTranscode(raw.data(), length_sections, sections.data(), 2, SECTION_HEADER_SIZE, - Crypto::Op::DECRYPT); + Core::Crypto::Op::Decrypt); } else { file->ReadBytes(sections.data(), length_sections, SECTION_HEADER_OFFSET); } diff --git a/src/core/file_sys/content_archive.h b/src/core/file_sys/content_archive.h index d9ad3bf7e..153142b06 100644 --- a/src/core/file_sys/content_archive.h +++ b/src/core/file_sys/content_archive.h @@ -9,12 +9,12 @@ #include <string> #include <vector> -#include "core/loader/loader.h" #include "common/common_funcs.h" #include "common/common_types.h" #include "common/swap.h" #include "core/crypto/key_manager.h" #include "core/file_sys/partition_filesystem.h" +#include "core/loader/loader.h" namespace FileSys { enum class NCAContentType : u8 { @@ -107,7 +107,8 @@ private: bool encrypted; - Crypto::Key128 GetKeyAreaKey(NCASectionCryptoType type); + Core::Crypto::KeyManager keys; + Core::Crypto::Key128 GetKeyAreaKey(NCASectionCryptoType type); VirtualFile Decrypt(NCASectionHeader header, VirtualFile in, u64 starting_offset); }; diff --git a/src/core/file_sys/vfs.cpp b/src/core/file_sys/vfs.cpp index 57d0aeb85..dae1c16ef 100644 --- a/src/core/file_sys/vfs.cpp +++ b/src/core/file_sys/vfs.cpp @@ -297,10 +297,9 @@ bool DeepEquals(const VirtualFile& file1, const VirtualFile& file2, size_t block if (f1_vs != f2_vs) return false; - for (size_t j = 0; j < f1_vs; ++j) { - if (f1_v[j] != f2_v[j]) - return false; - } + auto iters = std::mismatch(f1_v.begin(), f1_v.end(), f2_v.begin(), f2_v.end()); + if (iters.first != f1_v.end() && iters.second != f2_v.end()) + return false; } return true; |