Make XCI comply to review and style guidelines
This commit is contained in:
parent
22342487e8
commit
239a3113e4
16 changed files with 223 additions and 482 deletions
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue