From aaca7543f0a13d7a052d08d1e1a4dbf51a18c441 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Sat, 13 Oct 2018 08:33:45 -0400 Subject: partition_data_manager: Remove unused includes Gets unused includes out of the headers and moves them into the cpp file if they're used there instead. --- src/core/crypto/partition_data_manager.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/core/crypto/partition_data_manager.cpp') diff --git a/src/core/crypto/partition_data_manager.cpp b/src/core/crypto/partition_data_manager.cpp index d1c04e98d..4baf8ccc5 100644 --- a/src/core/crypto/partition_data_manager.cpp +++ b/src/core/crypto/partition_data_manager.cpp @@ -11,7 +11,6 @@ #include #include #include -#include #include #include "common/assert.h" #include "common/common_funcs.h" @@ -19,7 +18,7 @@ #include "common/hex_util.h" #include "common/logging/log.h" #include "common/string_util.h" -#include "core/crypto/ctr_encryption_layer.h" +#include "common/swap.h" #include "core/crypto/key_manager.h" #include "core/crypto/partition_data_manager.h" #include "core/crypto/xts_encryption_layer.h" -- cgit v1.2.3 From e96d69c328ff217de01e457250504d08dfe785ca Mon Sep 17 00:00:00 2001 From: Lioncash Date: Sat, 13 Oct 2018 08:36:23 -0400 Subject: partition_data_manager: Amend constructor initializer list order Orders the members in the exact order they would be initialized. This also prevents compiler warnings about this sort of thing. --- src/core/crypto/partition_data_manager.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/core/crypto/partition_data_manager.cpp') diff --git a/src/core/crypto/partition_data_manager.cpp b/src/core/crypto/partition_data_manager.cpp index 4baf8ccc5..7c3d9661d 100644 --- a/src/core/crypto/partition_data_manager.cpp +++ b/src/core/crypto/partition_data_manager.cpp @@ -313,13 +313,14 @@ PartitionDataManager::PartitionDataManager(FileSys::VirtualDir sysdata_dir) FindFileInDirWithNames(sysdata_dir, "BCPKG2-5-Repair-Main"), FindFileInDirWithNames(sysdata_dir, "BCPKG2-6-Repair-Sub"), }), + prodinfo(FindFileInDirWithNames(sysdata_dir, "PRODINFO")), secure_monitor(FindFileInDirWithNames(sysdata_dir, "secmon")), package1_decrypted(FindFileInDirWithNames(sysdata_dir, "pkg1_decr")), secure_monitor_bytes(secure_monitor == nullptr ? std::vector{} : secure_monitor->ReadAllBytes()), package1_decrypted_bytes(package1_decrypted == nullptr ? std::vector{} - : package1_decrypted->ReadAllBytes()), - prodinfo(FindFileInDirWithNames(sysdata_dir, "PRODINFO")) {} + : package1_decrypted->ReadAllBytes()) { +} PartitionDataManager::~PartitionDataManager() = default; -- cgit v1.2.3 From d257a3b56cac582fe296994b98f050e7b8f39056 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Sat, 13 Oct 2018 08:39:02 -0400 Subject: partition_data_manager: Take VirtualFile by const reference in constructor Given the VirtualFile instance isn't stored into the class as a data member, or written to, this can just be turned into a const reference, as the constructor doesn't need to make a copy of it. --- src/core/crypto/partition_data_manager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/core/crypto/partition_data_manager.cpp') diff --git a/src/core/crypto/partition_data_manager.cpp b/src/core/crypto/partition_data_manager.cpp index 7c3d9661d..ff46aad7c 100644 --- a/src/core/crypto/partition_data_manager.cpp +++ b/src/core/crypto/partition_data_manager.cpp @@ -301,7 +301,7 @@ FileSys::VirtualFile FindFileInDirWithNames(const FileSys::VirtualDir& dir, return nullptr; } -PartitionDataManager::PartitionDataManager(FileSys::VirtualDir sysdata_dir) +PartitionDataManager::PartitionDataManager(const FileSys::VirtualDir& sysdata_dir) : boot0(FindFileInDirWithNames(sysdata_dir, "BOOT0")), fuses(FindFileInDirWithNames(sysdata_dir, "fuse")), kfuses(FindFileInDirWithNames(sysdata_dir, "kfuse")), -- cgit v1.2.3 From f56a8da46a58c0a4a1ce2570038a7060de29a18c Mon Sep 17 00:00:00 2001 From: Lioncash Date: Sat, 13 Oct 2018 08:52:34 -0400 Subject: partition_data_manager: Dehardcode array bounds Instead, we can make it part of the type and make named variables for them, so they only require one definition (and if they ever change for whatever reason, they only need to be changed in one spot). --- src/core/crypto/partition_data_manager.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/core/crypto/partition_data_manager.cpp') diff --git a/src/core/crypto/partition_data_manager.cpp b/src/core/crypto/partition_data_manager.cpp index ff46aad7c..bef8cdaf0 100644 --- a/src/core/crypto/partition_data_manager.cpp +++ b/src/core/crypto/partition_data_manager.cpp @@ -332,18 +332,18 @@ FileSys::VirtualFile PartitionDataManager::GetBoot0Raw() const { return boot0; } -std::array PartitionDataManager::GetEncryptedKeyblob(u8 index) const { - if (HasBoot0() && index < 32) +PartitionDataManager::EncryptedKeyBlob PartitionDataManager::GetEncryptedKeyblob(u8 index) const { + if (HasBoot0() && index < NUM_ENCRYPTED_KEYBLOBS) return GetEncryptedKeyblobs()[index]; return {}; } -std::array, 32> PartitionDataManager::GetEncryptedKeyblobs() const { +PartitionDataManager::EncryptedKeyBlobs PartitionDataManager::GetEncryptedKeyblobs() const { if (!HasBoot0()) return {}; - std::array, 32> out{}; - for (size_t i = 0; i < 0x20; ++i) + EncryptedKeyBlobs out{}; + for (size_t i = 0; i < out.size(); ++i) boot0->Read(out[i].data(), out[i].size(), 0x180000 + i * 0x200); return out; } -- cgit v1.2.3 From 6da2ed4232d3b3ecde7a04621c554f66de558fab Mon Sep 17 00:00:00 2001 From: Lioncash Date: Sat, 13 Oct 2018 09:13:19 -0400 Subject: key_manager/partition_data_manager: Silence truncation compiler warnings --- src/core/crypto/partition_data_manager.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'src/core/crypto/partition_data_manager.cpp') diff --git a/src/core/crypto/partition_data_manager.cpp b/src/core/crypto/partition_data_manager.cpp index bef8cdaf0..51d89508b 100644 --- a/src/core/crypto/partition_data_manager.cpp +++ b/src/core/crypto/partition_data_manager.cpp @@ -332,7 +332,8 @@ FileSys::VirtualFile PartitionDataManager::GetBoot0Raw() const { return boot0; } -PartitionDataManager::EncryptedKeyBlob PartitionDataManager::GetEncryptedKeyblob(u8 index) const { +PartitionDataManager::EncryptedKeyBlob PartitionDataManager::GetEncryptedKeyblob( + std::size_t index) const { if (HasBoot0() && index < NUM_ENCRYPTED_KEYBLOBS) return GetEncryptedKeyblobs()[index]; return {}; @@ -389,7 +390,7 @@ std::array PartitionDataManager::GetKeyblobMACKeySource() const { return FindKeyFromHex(package1_decrypted_bytes, source_hashes[0]); } -std::array PartitionDataManager::GetKeyblobKeySource(u8 revision) const { +std::array PartitionDataManager::GetKeyblobKeySource(std::size_t revision) const { if (keyblob_source_hashes[revision] == SHA256Hash{}) { LOG_WARNING(Crypto, "No keyblob source hash for crypto revision {:02X}! Cannot derive keys...", @@ -456,11 +457,12 @@ void PartitionDataManager::DecryptPackage2(std::array, 0x20> if (file->ReadObject(&header) != sizeof(Package2Header)) return; - u8 revision = 0xFF; + std::size_t revision = 0xFF; if (header.magic != Common::MakeMagic('P', 'K', '2', '1')) { - for (size_t i = 0; i < package2_keys.size(); ++i) { - if (AttemptDecrypt(package2_keys[i], header)) + for (std::size_t i = 0; i < package2_keys.size(); ++i) { + if (AttemptDecrypt(package2_keys[i], header)) { revision = i; + } } } -- cgit v1.2.3 From bc2196bb090e14a71f47bb6a41a35529116dcf66 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Sat, 13 Oct 2018 09:16:27 -0400 Subject: partition_data_manager: Remove commented out code Commented out code shouldn't be left in without a reason indicating why in a comment. --- src/core/crypto/partition_data_manager.cpp | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/core/crypto/partition_data_manager.cpp') diff --git a/src/core/crypto/partition_data_manager.cpp b/src/core/crypto/partition_data_manager.cpp index 51d89508b..056119c04 100644 --- a/src/core/crypto/partition_data_manager.cpp +++ b/src/core/crypto/partition_data_manager.cpp @@ -480,8 +480,6 @@ void PartitionDataManager::DecryptPackage2(std::array, 0x20> cipher.SetIV(s1_iv); cipher.Transcode(c.data(), c.size(), c.data(), Op::Decrypt); - // package2_decrypted[static_cast(type)] = s1; - INIHeader ini; std::memcpy(&ini, c.data(), sizeof(INIHeader)); if (ini.magic != Common::MakeMagic('I', 'N', 'I', '1')) -- cgit v1.2.3 From 3d9df49619a44bacda8c02fea60e63d9a7aa22fc Mon Sep 17 00:00:00 2001 From: Lioncash Date: Sat, 13 Oct 2018 09:20:19 -0400 Subject: partition_data_manager: Move IV data to where it's needed in DecryptPackage2() Given it's only used in one spot and has a fairly generic name, we can just specify it directly in the function call. This also the benefit of automatically moving it. --- src/core/crypto/partition_data_manager.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'src/core/crypto/partition_data_manager.cpp') diff --git a/src/core/crypto/partition_data_manager.cpp b/src/core/crypto/partition_data_manager.cpp index 056119c04..e364affba 100644 --- a/src/core/crypto/partition_data_manager.cpp +++ b/src/core/crypto/partition_data_manager.cpp @@ -469,15 +469,13 @@ void PartitionDataManager::DecryptPackage2(std::array, 0x20> if (header.magic != Common::MakeMagic('P', 'K', '2', '1')) return; - const std::vector s1_iv(header.section_ctr[1].begin(), header.section_ctr[1].end()); - const auto a = std::make_shared( file, header.section_size[1], header.section_size[0] + sizeof(Package2Header)); auto c = a->ReadAllBytes(); AESCipher cipher(package2_keys[revision], Mode::CTR); - cipher.SetIV(s1_iv); + cipher.SetIV({header.section_ctr[1].begin(), header.section_ctr[1].end()}); cipher.Transcode(c.data(), c.size(), c.data(), Op::Decrypt); INIHeader ini; -- cgit v1.2.3 From e0c76226ad3a100637348d822d2c5d7047f78bda Mon Sep 17 00:00:00 2001 From: Lioncash Date: Sat, 13 Oct 2018 09:23:34 -0400 Subject: partition_data_manager: Take package2_keys by const reference These are only ever read from, so we don't need to make a copy of all the keys here. --- src/core/crypto/partition_data_manager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/core/crypto/partition_data_manager.cpp') diff --git a/src/core/crypto/partition_data_manager.cpp b/src/core/crypto/partition_data_manager.cpp index e364affba..6862a0884 100644 --- a/src/core/crypto/partition_data_manager.cpp +++ b/src/core/crypto/partition_data_manager.cpp @@ -447,7 +447,7 @@ bool AttemptDecrypt(const std::array& key, Package2Header& header) { return false; } -void PartitionDataManager::DecryptPackage2(std::array, 0x20> package2_keys, +void PartitionDataManager::DecryptPackage2(const std::array& package2_keys, Package2Type type) { FileSys::VirtualFile file = std::make_shared( package2[static_cast(type)], -- cgit v1.2.3 From 781fd7983cf543fc98685a38c82c5dd4576514dc Mon Sep 17 00:00:00 2001 From: Lioncash Date: Sat, 13 Oct 2018 09:27:07 -0400 Subject: partition_data_manager: Remove unused std::map instance within DecryptPackage2() Aside from emplacing elements into the map, the map itself is never actually queried for contained data. --- src/core/crypto/partition_data_manager.cpp | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/core/crypto/partition_data_manager.cpp') diff --git a/src/core/crypto/partition_data_manager.cpp b/src/core/crypto/partition_data_manager.cpp index 6862a0884..a311ad846 100644 --- a/src/core/crypto/partition_data_manager.cpp +++ b/src/core/crypto/partition_data_manager.cpp @@ -483,14 +483,12 @@ void PartitionDataManager::DecryptPackage2(const std::array& packa if (ini.magic != Common::MakeMagic('I', 'N', 'I', '1')) return; - std::map kips{}; u64 offset = sizeof(INIHeader); for (size_t i = 0; i < ini.process_count; ++i) { KIPHeader kip; std::memcpy(&kip, c.data() + offset, sizeof(KIPHeader)); if (kip.magic != Common::MakeMagic('K', 'I', 'P', '1')) return; - kips.emplace(offset, kip); const auto name = Common::StringFromFixedZeroTerminatedBuffer(kip.name.data(), kip.name.size()); -- cgit v1.2.3 From 6467b01de2debf86db8c409160ab50d24d32149e Mon Sep 17 00:00:00 2001 From: Lioncash Date: Sat, 13 Oct 2018 09:30:09 -0400 Subject: partition_data_manager: Reserve and insert data within output vector in DecryptPackage2() We can just reserve the memory then perform successive insertions instead of needing to use memcpy. This also avoids the need to zero out the output vector's memory before performing the insertions. We can also std::move the output std::vector into the destination so that we don't need to make a completely new copy of the vector, getting rid of an unnecessary allocation. Additionally, we can use iterators to determine the beginning and end ranges of the std::vector instances that comprise the output vector, as the end of one range just becomes the beginning for the next successive range, and since std::vector's iterator constructor copies data within the range [begin, end), this is more straightforward and gets rid of the need to have an offset variable that keeps getting incremented to determine where to do the next std::memcpy. --- src/core/crypto/partition_data_manager.cpp | 36 +++++++++++++----------------- 1 file changed, 16 insertions(+), 20 deletions(-) (limited to 'src/core/crypto/partition_data_manager.cpp') diff --git a/src/core/crypto/partition_data_manager.cpp b/src/core/crypto/partition_data_manager.cpp index a311ad846..ed5e2b145 100644 --- a/src/core/crypto/partition_data_manager.cpp +++ b/src/core/crypto/partition_data_manager.cpp @@ -499,33 +499,29 @@ void PartitionDataManager::DecryptPackage2(const std::array& packa continue; } - std::vector text(kip.sections[0].size_compressed); - std::vector rodata(kip.sections[1].size_compressed); - std::vector data(kip.sections[2].size_compressed); + const u64 initial_offset = sizeof(KIPHeader) + offset; + const auto text_begin = c.cbegin() + initial_offset; + const auto text_end = text_begin + kip.sections[0].size_compressed; + const std::vector text = DecompressBLZ({text_begin, text_end}); - u64 offset_sec = sizeof(KIPHeader) + offset; - std::memcpy(text.data(), c.data() + offset_sec, text.size()); - offset_sec += text.size(); - std::memcpy(rodata.data(), c.data() + offset_sec, rodata.size()); - offset_sec += rodata.size(); - std::memcpy(data.data(), c.data() + offset_sec, data.size()); + const auto rodata_end = text_end + kip.sections[1].size_compressed; + const std::vector rodata = DecompressBLZ({text_end, rodata_end}); - offset += sizeof(KIPHeader) + kip.sections[0].size_compressed + - kip.sections[1].size_compressed + kip.sections[2].size_compressed; + const auto data_end = rodata_end + kip.sections[2].size_compressed; + const std::vector data = DecompressBLZ({rodata_end, data_end}); - text = DecompressBLZ(text); - rodata = DecompressBLZ(rodata); - data = DecompressBLZ(data); + std::vector out; + out.reserve(text.size() + rodata.size() + data.size()); + out.insert(out.end(), text.begin(), text.end()); + out.insert(out.end(), rodata.begin(), rodata.end()); + out.insert(out.end(), data.begin(), data.end()); - std::vector out(text.size() + rodata.size() + data.size()); - std::memcpy(out.data(), text.data(), text.size()); - std::memcpy(out.data() + text.size(), rodata.data(), rodata.size()); - std::memcpy(out.data() + text.size() + rodata.size(), data.data(), data.size()); + offset += sizeof(KIPHeader) + out.size(); if (name == "FS") - package2_fs[static_cast(type)] = out; + package2_fs[static_cast(type)] = std::move(out); else if (name == "spl") - package2_spl[static_cast(type)] = out; + package2_spl[static_cast(type)] = std::move(out); } } -- cgit v1.2.3