diff options
| author | 2018-10-14 14:46:47 -0400 | |
|---|---|---|
| committer | 2018-10-14 14:46:47 -0400 | |
| commit | b3cca34f50dee6e50c4be3355a2344cdb90aca19 (patch) | |
| tree | f5605cf80458f9d7b3547a8773d376e9e24da312 /src | |
| parent | Merge pull request #1490 from lioncash/boot (diff) | |
| parent | partition_data_manager: Reserve and insert data within output vector in Decry... (diff) | |
| download | yuzu-b3cca34f50dee6e50c4be3355a2344cdb90aca19.tar.gz yuzu-b3cca34f50dee6e50c4be3355a2344cdb90aca19.tar.xz yuzu-b3cca34f50dee6e50c4be3355a2344cdb90aca19.zip | |
Merge pull request #1486 from lioncash/file
key_manager/partition_data_manager: Minor changes
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/crypto/key_manager.cpp | 39 | ||||
| -rw-r--r-- | src/core/crypto/key_manager.h | 2 | ||||
| -rw-r--r-- | src/core/crypto/partition_data_manager.cpp | 76 | ||||
| -rw-r--r-- | src/core/crypto/partition_data_manager.h | 18 |
4 files changed, 72 insertions, 63 deletions
diff --git a/src/core/crypto/key_manager.cpp b/src/core/crypto/key_manager.cpp index a59a7e1f5..fd0786068 100644 --- a/src/core/crypto/key_manager.cpp +++ b/src/core/crypto/key_manager.cpp | |||
| @@ -98,7 +98,7 @@ std::array<u8, 144> DecryptKeyblob(const std::array<u8, 176>& encrypted_keyblob, | |||
| 98 | return keyblob; | 98 | return keyblob; |
| 99 | } | 99 | } |
| 100 | 100 | ||
| 101 | void KeyManager::DeriveGeneralPurposeKeys(u8 crypto_revision) { | 101 | void KeyManager::DeriveGeneralPurposeKeys(std::size_t crypto_revision) { |
| 102 | const auto kek_generation_source = | 102 | const auto kek_generation_source = |
| 103 | GetKey(S128KeyType::Source, static_cast<u64>(SourceKeyType::AESKekGeneration)); | 103 | GetKey(S128KeyType::Source, static_cast<u64>(SourceKeyType::AESKekGeneration)); |
| 104 | const auto key_generation_source = | 104 | const auto key_generation_source = |
| @@ -147,31 +147,38 @@ boost::optional<Key128> DeriveSDSeed() { | |||
| 147 | "rb+"); | 147 | "rb+"); |
| 148 | if (!save_43.IsOpen()) | 148 | if (!save_43.IsOpen()) |
| 149 | return boost::none; | 149 | return boost::none; |
| 150 | |||
| 150 | const FileUtil::IOFile sd_private( | 151 | const FileUtil::IOFile sd_private( |
| 151 | FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir) + "/Nintendo/Contents/private", "rb+"); | 152 | FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir) + "/Nintendo/Contents/private", "rb+"); |
| 152 | if (!sd_private.IsOpen()) | 153 | if (!sd_private.IsOpen()) |
| 153 | return boost::none; | 154 | return boost::none; |
| 154 | 155 | ||
| 155 | sd_private.Seek(0, SEEK_SET); | ||
| 156 | std::array<u8, 0x10> private_seed{}; | 156 | std::array<u8, 0x10> private_seed{}; |
| 157 | if (sd_private.ReadBytes(private_seed.data(), private_seed.size()) != 0x10) | 157 | if (sd_private.ReadBytes(private_seed.data(), private_seed.size()) != private_seed.size()) { |
| 158 | return boost::none; | 158 | return boost::none; |
| 159 | } | ||
| 159 | 160 | ||
| 160 | std::array<u8, 0x10> buffer{}; | 161 | std::array<u8, 0x10> buffer{}; |
| 161 | std::size_t offset = 0; | 162 | std::size_t offset = 0; |
| 162 | for (; offset + 0x10 < save_43.GetSize(); ++offset) { | 163 | for (; offset + 0x10 < save_43.GetSize(); ++offset) { |
| 163 | save_43.Seek(offset, SEEK_SET); | 164 | if (!save_43.Seek(offset, SEEK_SET)) { |
| 165 | return boost::none; | ||
| 166 | } | ||
| 167 | |||
| 164 | save_43.ReadBytes(buffer.data(), buffer.size()); | 168 | save_43.ReadBytes(buffer.data(), buffer.size()); |
| 165 | if (buffer == private_seed) | 169 | if (buffer == private_seed) { |
| 166 | break; | 170 | break; |
| 171 | } | ||
| 167 | } | 172 | } |
| 168 | 173 | ||
| 169 | if (offset + 0x10 >= save_43.GetSize()) | 174 | if (!save_43.Seek(offset + 0x10, SEEK_SET)) { |
| 170 | return boost::none; | 175 | return boost::none; |
| 176 | } | ||
| 171 | 177 | ||
| 172 | Key128 seed{}; | 178 | Key128 seed{}; |
| 173 | save_43.Seek(offset + 0x10, SEEK_SET); | 179 | if (save_43.ReadBytes(seed.data(), seed.size()) != seed.size()) { |
| 174 | save_43.ReadBytes(seed.data(), seed.size()); | 180 | return boost::none; |
| 181 | } | ||
| 175 | return seed; | 182 | return seed; |
| 176 | } | 183 | } |
| 177 | 184 | ||
| @@ -234,7 +241,9 @@ std::vector<TicketRaw> GetTicketblob(const FileUtil::IOFile& ticket_save) { | |||
| 234 | return {}; | 241 | return {}; |
| 235 | 242 | ||
| 236 | std::vector<u8> buffer(ticket_save.GetSize()); | 243 | std::vector<u8> buffer(ticket_save.GetSize()); |
| 237 | ticket_save.ReadBytes(buffer.data(), buffer.size()); | 244 | if (ticket_save.ReadBytes(buffer.data(), buffer.size()) != buffer.size()) { |
| 245 | return {}; | ||
| 246 | } | ||
| 238 | 247 | ||
| 239 | std::vector<TicketRaw> out; | 248 | std::vector<TicketRaw> out; |
| 240 | u32 magic{}; | 249 | u32 magic{}; |
| @@ -261,6 +270,9 @@ static std::array<u8, size> operator^(const std::array<u8, size>& lhs, | |||
| 261 | 270 | ||
| 262 | template <size_t target_size, size_t in_size> | 271 | template <size_t target_size, size_t in_size> |
| 263 | static std::array<u8, target_size> MGF1(const std::array<u8, in_size>& seed) { | 272 | static std::array<u8, target_size> MGF1(const std::array<u8, in_size>& seed) { |
| 273 | // Avoids truncation overflow within the loop below. | ||
| 274 | static_assert(target_size <= 0xFF); | ||
| 275 | |||
| 264 | std::array<u8, in_size + 4> seed_exp{}; | 276 | std::array<u8, in_size + 4> seed_exp{}; |
| 265 | std::memcpy(seed_exp.data(), seed.data(), in_size); | 277 | std::memcpy(seed_exp.data(), seed.data(), in_size); |
| 266 | 278 | ||
| @@ -268,7 +280,7 @@ static std::array<u8, target_size> MGF1(const std::array<u8, in_size>& seed) { | |||
| 268 | size_t i = 0; | 280 | size_t i = 0; |
| 269 | while (out.size() < target_size) { | 281 | while (out.size() < target_size) { |
| 270 | out.resize(out.size() + 0x20); | 282 | out.resize(out.size() + 0x20); |
| 271 | seed_exp[in_size + 3] = i; | 283 | seed_exp[in_size + 3] = static_cast<u8>(i); |
| 272 | mbedtls_sha256(seed_exp.data(), seed_exp.size(), out.data() + out.size() - 0x20, 0); | 284 | mbedtls_sha256(seed_exp.data(), seed_exp.size(), out.data() + out.size() - 0x20, 0); |
| 273 | ++i; | 285 | ++i; |
| 274 | } | 286 | } |
| @@ -299,10 +311,11 @@ boost::optional<std::pair<Key128, Key128>> ParseTicket(const TicketRaw& ticket, | |||
| 299 | std::memcpy(&cert_authority, ticket.data() + 0x140, sizeof(cert_authority)); | 311 | std::memcpy(&cert_authority, ticket.data() + 0x140, sizeof(cert_authority)); |
| 300 | if (cert_authority == 0) | 312 | if (cert_authority == 0) |
| 301 | return boost::none; | 313 | return boost::none; |
| 302 | if (cert_authority != Common::MakeMagic('R', 'o', 'o', 't')) | 314 | if (cert_authority != Common::MakeMagic('R', 'o', 'o', 't')) { |
| 303 | LOG_INFO(Crypto, | 315 | LOG_INFO(Crypto, |
| 304 | "Attempting to parse ticket with non-standard certificate authority {:08X}.", | 316 | "Attempting to parse ticket with non-standard certificate authority {:08X}.", |
| 305 | cert_authority); | 317 | cert_authority); |
| 318 | } | ||
| 306 | 319 | ||
| 307 | Key128 rights_id; | 320 | Key128 rights_id; |
| 308 | std::memcpy(rights_id.data(), ticket.data() + 0x2A0, sizeof(Key128)); | 321 | std::memcpy(rights_id.data(), ticket.data() + 0x2A0, sizeof(Key128)); |
| @@ -871,9 +884,9 @@ void KeyManager::DeriveETicket(PartitionDataManager& data) { | |||
| 871 | "/system/save/80000000000000e2", | 884 | "/system/save/80000000000000e2", |
| 872 | "rb+"); | 885 | "rb+"); |
| 873 | 886 | ||
| 887 | const auto blob2 = GetTicketblob(save2); | ||
| 874 | auto res = GetTicketblob(save1); | 888 | auto res = GetTicketblob(save1); |
| 875 | const auto res2 = GetTicketblob(save2); | 889 | res.insert(res.end(), blob2.begin(), blob2.end()); |
| 876 | std::copy(res2.begin(), res2.end(), std::back_inserter(res)); | ||
| 877 | 890 | ||
| 878 | for (const auto& raw : res) { | 891 | for (const auto& raw : res) { |
| 879 | const auto pair = ParseTicket(raw, rsa_key); | 892 | const auto pair = ParseTicket(raw, rsa_key); |
diff --git a/src/core/crypto/key_manager.h b/src/core/crypto/key_manager.h index a41abbdfc..cccb3c0ae 100644 --- a/src/core/crypto/key_manager.h +++ b/src/core/crypto/key_manager.h | |||
| @@ -175,7 +175,7 @@ private: | |||
| 175 | void WriteKeyToFile(KeyCategory category, std::string_view keyname, | 175 | void WriteKeyToFile(KeyCategory category, std::string_view keyname, |
| 176 | const std::array<u8, Size>& key); | 176 | const std::array<u8, Size>& key); |
| 177 | 177 | ||
| 178 | void DeriveGeneralPurposeKeys(u8 crypto_revision); | 178 | void DeriveGeneralPurposeKeys(std::size_t crypto_revision); |
| 179 | 179 | ||
| 180 | void SetKeyWrapped(S128KeyType id, Key128 key, u64 field1 = 0, u64 field2 = 0); | 180 | void SetKeyWrapped(S128KeyType id, Key128 key, u64 field1 = 0, u64 field2 = 0); |
| 181 | void SetKeyWrapped(S256KeyType id, Key256 key, u64 field1 = 0, u64 field2 = 0); | 181 | void SetKeyWrapped(S256KeyType id, Key256 key, u64 field1 = 0, u64 field2 = 0); |
diff --git a/src/core/crypto/partition_data_manager.cpp b/src/core/crypto/partition_data_manager.cpp index d1c04e98d..ed5e2b145 100644 --- a/src/core/crypto/partition_data_manager.cpp +++ b/src/core/crypto/partition_data_manager.cpp | |||
| @@ -11,7 +11,6 @@ | |||
| 11 | #include <array> | 11 | #include <array> |
| 12 | #include <cctype> | 12 | #include <cctype> |
| 13 | #include <cstring> | 13 | #include <cstring> |
| 14 | #include <boost/optional/optional.hpp> | ||
| 15 | #include <mbedtls/sha256.h> | 14 | #include <mbedtls/sha256.h> |
| 16 | #include "common/assert.h" | 15 | #include "common/assert.h" |
| 17 | #include "common/common_funcs.h" | 16 | #include "common/common_funcs.h" |
| @@ -19,7 +18,7 @@ | |||
| 19 | #include "common/hex_util.h" | 18 | #include "common/hex_util.h" |
| 20 | #include "common/logging/log.h" | 19 | #include "common/logging/log.h" |
| 21 | #include "common/string_util.h" | 20 | #include "common/string_util.h" |
| 22 | #include "core/crypto/ctr_encryption_layer.h" | 21 | #include "common/swap.h" |
| 23 | #include "core/crypto/key_manager.h" | 22 | #include "core/crypto/key_manager.h" |
| 24 | #include "core/crypto/partition_data_manager.h" | 23 | #include "core/crypto/partition_data_manager.h" |
| 25 | #include "core/crypto/xts_encryption_layer.h" | 24 | #include "core/crypto/xts_encryption_layer.h" |
| @@ -302,7 +301,7 @@ FileSys::VirtualFile FindFileInDirWithNames(const FileSys::VirtualDir& dir, | |||
| 302 | return nullptr; | 301 | return nullptr; |
| 303 | } | 302 | } |
| 304 | 303 | ||
| 305 | PartitionDataManager::PartitionDataManager(FileSys::VirtualDir sysdata_dir) | 304 | PartitionDataManager::PartitionDataManager(const FileSys::VirtualDir& sysdata_dir) |
| 306 | : boot0(FindFileInDirWithNames(sysdata_dir, "BOOT0")), | 305 | : boot0(FindFileInDirWithNames(sysdata_dir, "BOOT0")), |
| 307 | fuses(FindFileInDirWithNames(sysdata_dir, "fuse")), | 306 | fuses(FindFileInDirWithNames(sysdata_dir, "fuse")), |
| 308 | kfuses(FindFileInDirWithNames(sysdata_dir, "kfuse")), | 307 | kfuses(FindFileInDirWithNames(sysdata_dir, "kfuse")), |
| @@ -314,13 +313,14 @@ PartitionDataManager::PartitionDataManager(FileSys::VirtualDir sysdata_dir) | |||
| 314 | FindFileInDirWithNames(sysdata_dir, "BCPKG2-5-Repair-Main"), | 313 | FindFileInDirWithNames(sysdata_dir, "BCPKG2-5-Repair-Main"), |
| 315 | FindFileInDirWithNames(sysdata_dir, "BCPKG2-6-Repair-Sub"), | 314 | FindFileInDirWithNames(sysdata_dir, "BCPKG2-6-Repair-Sub"), |
| 316 | }), | 315 | }), |
| 316 | prodinfo(FindFileInDirWithNames(sysdata_dir, "PRODINFO")), | ||
| 317 | secure_monitor(FindFileInDirWithNames(sysdata_dir, "secmon")), | 317 | secure_monitor(FindFileInDirWithNames(sysdata_dir, "secmon")), |
| 318 | package1_decrypted(FindFileInDirWithNames(sysdata_dir, "pkg1_decr")), | 318 | package1_decrypted(FindFileInDirWithNames(sysdata_dir, "pkg1_decr")), |
| 319 | secure_monitor_bytes(secure_monitor == nullptr ? std::vector<u8>{} | 319 | secure_monitor_bytes(secure_monitor == nullptr ? std::vector<u8>{} |
| 320 | : secure_monitor->ReadAllBytes()), | 320 | : secure_monitor->ReadAllBytes()), |
| 321 | package1_decrypted_bytes(package1_decrypted == nullptr ? std::vector<u8>{} | 321 | package1_decrypted_bytes(package1_decrypted == nullptr ? std::vector<u8>{} |
| 322 | : package1_decrypted->ReadAllBytes()), | 322 | : package1_decrypted->ReadAllBytes()) { |
| 323 | prodinfo(FindFileInDirWithNames(sysdata_dir, "PRODINFO")) {} | 323 | } |
| 324 | 324 | ||
| 325 | PartitionDataManager::~PartitionDataManager() = default; | 325 | PartitionDataManager::~PartitionDataManager() = default; |
| 326 | 326 | ||
| @@ -332,18 +332,19 @@ FileSys::VirtualFile PartitionDataManager::GetBoot0Raw() const { | |||
| 332 | return boot0; | 332 | return boot0; |
| 333 | } | 333 | } |
| 334 | 334 | ||
| 335 | std::array<u8, 176> PartitionDataManager::GetEncryptedKeyblob(u8 index) const { | 335 | PartitionDataManager::EncryptedKeyBlob PartitionDataManager::GetEncryptedKeyblob( |
| 336 | if (HasBoot0() && index < 32) | 336 | std::size_t index) const { |
| 337 | if (HasBoot0() && index < NUM_ENCRYPTED_KEYBLOBS) | ||
| 337 | return GetEncryptedKeyblobs()[index]; | 338 | return GetEncryptedKeyblobs()[index]; |
| 338 | return {}; | 339 | return {}; |
| 339 | } | 340 | } |
| 340 | 341 | ||
| 341 | std::array<std::array<u8, 176>, 32> PartitionDataManager::GetEncryptedKeyblobs() const { | 342 | PartitionDataManager::EncryptedKeyBlobs PartitionDataManager::GetEncryptedKeyblobs() const { |
| 342 | if (!HasBoot0()) | 343 | if (!HasBoot0()) |
| 343 | return {}; | 344 | return {}; |
| 344 | 345 | ||
| 345 | std::array<std::array<u8, 176>, 32> out{}; | 346 | EncryptedKeyBlobs out{}; |
| 346 | for (size_t i = 0; i < 0x20; ++i) | 347 | for (size_t i = 0; i < out.size(); ++i) |
| 347 | boot0->Read(out[i].data(), out[i].size(), 0x180000 + i * 0x200); | 348 | boot0->Read(out[i].data(), out[i].size(), 0x180000 + i * 0x200); |
| 348 | return out; | 349 | return out; |
| 349 | } | 350 | } |
| @@ -389,7 +390,7 @@ std::array<u8, 16> PartitionDataManager::GetKeyblobMACKeySource() const { | |||
| 389 | return FindKeyFromHex(package1_decrypted_bytes, source_hashes[0]); | 390 | return FindKeyFromHex(package1_decrypted_bytes, source_hashes[0]); |
| 390 | } | 391 | } |
| 391 | 392 | ||
| 392 | std::array<u8, 16> PartitionDataManager::GetKeyblobKeySource(u8 revision) const { | 393 | std::array<u8, 16> PartitionDataManager::GetKeyblobKeySource(std::size_t revision) const { |
| 393 | if (keyblob_source_hashes[revision] == SHA256Hash{}) { | 394 | if (keyblob_source_hashes[revision] == SHA256Hash{}) { |
| 394 | LOG_WARNING(Crypto, | 395 | LOG_WARNING(Crypto, |
| 395 | "No keyblob source hash for crypto revision {:02X}! Cannot derive keys...", | 396 | "No keyblob source hash for crypto revision {:02X}! Cannot derive keys...", |
| @@ -446,7 +447,7 @@ bool AttemptDecrypt(const std::array<u8, 16>& key, Package2Header& header) { | |||
| 446 | return false; | 447 | return false; |
| 447 | } | 448 | } |
| 448 | 449 | ||
| 449 | void PartitionDataManager::DecryptPackage2(std::array<std::array<u8, 16>, 0x20> package2_keys, | 450 | void PartitionDataManager::DecryptPackage2(const std::array<Key128, 0x20>& package2_keys, |
| 450 | Package2Type type) { | 451 | Package2Type type) { |
| 451 | FileSys::VirtualFile file = std::make_shared<FileSys::OffsetVfsFile>( | 452 | FileSys::VirtualFile file = std::make_shared<FileSys::OffsetVfsFile>( |
| 452 | package2[static_cast<size_t>(type)], | 453 | package2[static_cast<size_t>(type)], |
| @@ -456,43 +457,38 @@ void PartitionDataManager::DecryptPackage2(std::array<std::array<u8, 16>, 0x20> | |||
| 456 | if (file->ReadObject(&header) != sizeof(Package2Header)) | 457 | if (file->ReadObject(&header) != sizeof(Package2Header)) |
| 457 | return; | 458 | return; |
| 458 | 459 | ||
| 459 | u8 revision = 0xFF; | 460 | std::size_t revision = 0xFF; |
| 460 | if (header.magic != Common::MakeMagic('P', 'K', '2', '1')) { | 461 | if (header.magic != Common::MakeMagic('P', 'K', '2', '1')) { |
| 461 | for (size_t i = 0; i < package2_keys.size(); ++i) { | 462 | for (std::size_t i = 0; i < package2_keys.size(); ++i) { |
| 462 | if (AttemptDecrypt(package2_keys[i], header)) | 463 | if (AttemptDecrypt(package2_keys[i], header)) { |
| 463 | revision = i; | 464 | revision = i; |
| 465 | } | ||
| 464 | } | 466 | } |
| 465 | } | 467 | } |
| 466 | 468 | ||
| 467 | if (header.magic != Common::MakeMagic('P', 'K', '2', '1')) | 469 | if (header.magic != Common::MakeMagic('P', 'K', '2', '1')) |
| 468 | return; | 470 | return; |
| 469 | 471 | ||
| 470 | const std::vector<u8> s1_iv(header.section_ctr[1].begin(), header.section_ctr[1].end()); | ||
| 471 | |||
| 472 | const auto a = std::make_shared<FileSys::OffsetVfsFile>( | 472 | const auto a = std::make_shared<FileSys::OffsetVfsFile>( |
| 473 | file, header.section_size[1], header.section_size[0] + sizeof(Package2Header)); | 473 | file, header.section_size[1], header.section_size[0] + sizeof(Package2Header)); |
| 474 | 474 | ||
| 475 | auto c = a->ReadAllBytes(); | 475 | auto c = a->ReadAllBytes(); |
| 476 | 476 | ||
| 477 | AESCipher<Key128> cipher(package2_keys[revision], Mode::CTR); | 477 | AESCipher<Key128> cipher(package2_keys[revision], Mode::CTR); |
| 478 | cipher.SetIV(s1_iv); | 478 | cipher.SetIV({header.section_ctr[1].begin(), header.section_ctr[1].end()}); |
| 479 | cipher.Transcode(c.data(), c.size(), c.data(), Op::Decrypt); | 479 | cipher.Transcode(c.data(), c.size(), c.data(), Op::Decrypt); |
| 480 | 480 | ||
| 481 | // package2_decrypted[static_cast<size_t>(type)] = s1; | ||
| 482 | |||
| 483 | INIHeader ini; | 481 | INIHeader ini; |
| 484 | std::memcpy(&ini, c.data(), sizeof(INIHeader)); | 482 | std::memcpy(&ini, c.data(), sizeof(INIHeader)); |
| 485 | if (ini.magic != Common::MakeMagic('I', 'N', 'I', '1')) | 483 | if (ini.magic != Common::MakeMagic('I', 'N', 'I', '1')) |
| 486 | return; | 484 | return; |
| 487 | 485 | ||
| 488 | std::map<u64, KIPHeader> kips{}; | ||
| 489 | u64 offset = sizeof(INIHeader); | 486 | u64 offset = sizeof(INIHeader); |
| 490 | for (size_t i = 0; i < ini.process_count; ++i) { | 487 | for (size_t i = 0; i < ini.process_count; ++i) { |
| 491 | KIPHeader kip; | 488 | KIPHeader kip; |
| 492 | std::memcpy(&kip, c.data() + offset, sizeof(KIPHeader)); | 489 | std::memcpy(&kip, c.data() + offset, sizeof(KIPHeader)); |
| 493 | if (kip.magic != Common::MakeMagic('K', 'I', 'P', '1')) | 490 | if (kip.magic != Common::MakeMagic('K', 'I', 'P', '1')) |
| 494 | return; | 491 | return; |
| 495 | kips.emplace(offset, kip); | ||
| 496 | 492 | ||
| 497 | const auto name = | 493 | const auto name = |
| 498 | Common::StringFromFixedZeroTerminatedBuffer(kip.name.data(), kip.name.size()); | 494 | Common::StringFromFixedZeroTerminatedBuffer(kip.name.data(), kip.name.size()); |
| @@ -503,33 +499,29 @@ void PartitionDataManager::DecryptPackage2(std::array<std::array<u8, 16>, 0x20> | |||
| 503 | continue; | 499 | continue; |
| 504 | } | 500 | } |
| 505 | 501 | ||
| 506 | std::vector<u8> text(kip.sections[0].size_compressed); | 502 | const u64 initial_offset = sizeof(KIPHeader) + offset; |
| 507 | std::vector<u8> rodata(kip.sections[1].size_compressed); | 503 | const auto text_begin = c.cbegin() + initial_offset; |
| 508 | std::vector<u8> data(kip.sections[2].size_compressed); | 504 | const auto text_end = text_begin + kip.sections[0].size_compressed; |
| 505 | const std::vector<u8> text = DecompressBLZ({text_begin, text_end}); | ||
| 509 | 506 | ||
| 510 | u64 offset_sec = sizeof(KIPHeader) + offset; | 507 | const auto rodata_end = text_end + kip.sections[1].size_compressed; |
| 511 | std::memcpy(text.data(), c.data() + offset_sec, text.size()); | 508 | const std::vector<u8> rodata = DecompressBLZ({text_end, rodata_end}); |
| 512 | offset_sec += text.size(); | ||
| 513 | std::memcpy(rodata.data(), c.data() + offset_sec, rodata.size()); | ||
| 514 | offset_sec += rodata.size(); | ||
| 515 | std::memcpy(data.data(), c.data() + offset_sec, data.size()); | ||
| 516 | 509 | ||
| 517 | offset += sizeof(KIPHeader) + kip.sections[0].size_compressed + | 510 | const auto data_end = rodata_end + kip.sections[2].size_compressed; |
| 518 | kip.sections[1].size_compressed + kip.sections[2].size_compressed; | 511 | const std::vector<u8> data = DecompressBLZ({rodata_end, data_end}); |
| 519 | 512 | ||
| 520 | text = DecompressBLZ(text); | 513 | std::vector<u8> out; |
| 521 | rodata = DecompressBLZ(rodata); | 514 | out.reserve(text.size() + rodata.size() + data.size()); |
| 522 | data = DecompressBLZ(data); | 515 | out.insert(out.end(), text.begin(), text.end()); |
| 516 | out.insert(out.end(), rodata.begin(), rodata.end()); | ||
| 517 | out.insert(out.end(), data.begin(), data.end()); | ||
| 523 | 518 | ||
| 524 | std::vector<u8> out(text.size() + rodata.size() + data.size()); | 519 | offset += sizeof(KIPHeader) + out.size(); |
| 525 | std::memcpy(out.data(), text.data(), text.size()); | ||
| 526 | std::memcpy(out.data() + text.size(), rodata.data(), rodata.size()); | ||
| 527 | std::memcpy(out.data() + text.size() + rodata.size(), data.data(), data.size()); | ||
| 528 | 520 | ||
| 529 | if (name == "FS") | 521 | if (name == "FS") |
| 530 | package2_fs[static_cast<size_t>(type)] = out; | 522 | package2_fs[static_cast<size_t>(type)] = std::move(out); |
| 531 | else if (name == "spl") | 523 | else if (name == "spl") |
| 532 | package2_spl[static_cast<size_t>(type)] = out; | 524 | package2_spl[static_cast<size_t>(type)] = std::move(out); |
| 533 | } | 525 | } |
| 534 | } | 526 | } |
| 535 | 527 | ||
diff --git a/src/core/crypto/partition_data_manager.h b/src/core/crypto/partition_data_manager.h index 45c7fecfa..0ad007c72 100644 --- a/src/core/crypto/partition_data_manager.h +++ b/src/core/crypto/partition_data_manager.h | |||
| @@ -5,9 +5,7 @@ | |||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <vector> | 7 | #include <vector> |
| 8 | #include "common/common_funcs.h" | ||
| 9 | #include "common/common_types.h" | 8 | #include "common/common_types.h" |
| 10 | #include "common/swap.h" | ||
| 11 | #include "core/file_sys/vfs_types.h" | 9 | #include "core/file_sys/vfs_types.h" |
| 12 | 10 | ||
| 13 | namespace Core::Crypto { | 11 | namespace Core::Crypto { |
| @@ -24,15 +22,20 @@ enum class Package2Type { | |||
| 24 | class PartitionDataManager { | 22 | class PartitionDataManager { |
| 25 | public: | 23 | public: |
| 26 | static const u8 MAX_KEYBLOB_SOURCE_HASH; | 24 | static const u8 MAX_KEYBLOB_SOURCE_HASH; |
| 25 | static constexpr std::size_t NUM_ENCRYPTED_KEYBLOBS = 32; | ||
| 26 | static constexpr std::size_t ENCRYPTED_KEYBLOB_SIZE = 0xB0; | ||
| 27 | 27 | ||
| 28 | explicit PartitionDataManager(FileSys::VirtualDir sysdata_dir); | 28 | using EncryptedKeyBlob = std::array<u8, ENCRYPTED_KEYBLOB_SIZE>; |
| 29 | using EncryptedKeyBlobs = std::array<EncryptedKeyBlob, NUM_ENCRYPTED_KEYBLOBS>; | ||
| 30 | |||
| 31 | explicit PartitionDataManager(const FileSys::VirtualDir& sysdata_dir); | ||
| 29 | ~PartitionDataManager(); | 32 | ~PartitionDataManager(); |
| 30 | 33 | ||
| 31 | // BOOT0 | 34 | // BOOT0 |
| 32 | bool HasBoot0() const; | 35 | bool HasBoot0() const; |
| 33 | FileSys::VirtualFile GetBoot0Raw() const; | 36 | FileSys::VirtualFile GetBoot0Raw() const; |
| 34 | std::array<u8, 0xB0> GetEncryptedKeyblob(u8 index) const; | 37 | EncryptedKeyBlob GetEncryptedKeyblob(std::size_t index) const; |
| 35 | std::array<std::array<u8, 0xB0>, 0x20> GetEncryptedKeyblobs() const; | 38 | EncryptedKeyBlobs GetEncryptedKeyblobs() const; |
| 36 | std::vector<u8> GetSecureMonitor() const; | 39 | std::vector<u8> GetSecureMonitor() const; |
| 37 | std::array<u8, 0x10> GetPackage2KeySource() const; | 40 | std::array<u8, 0x10> GetPackage2KeySource() const; |
| 38 | std::array<u8, 0x10> GetAESKekGenerationSource() const; | 41 | std::array<u8, 0x10> GetAESKekGenerationSource() const; |
| @@ -43,7 +46,7 @@ public: | |||
| 43 | std::vector<u8> GetPackage1Decrypted() const; | 46 | std::vector<u8> GetPackage1Decrypted() const; |
| 44 | std::array<u8, 0x10> GetMasterKeySource() const; | 47 | std::array<u8, 0x10> GetMasterKeySource() const; |
| 45 | std::array<u8, 0x10> GetKeyblobMACKeySource() const; | 48 | std::array<u8, 0x10> GetKeyblobMACKeySource() const; |
| 46 | std::array<u8, 0x10> GetKeyblobKeySource(u8 revision) const; | 49 | std::array<u8, 0x10> GetKeyblobKeySource(std::size_t revision) const; |
| 47 | 50 | ||
| 48 | // Fuses | 51 | // Fuses |
| 49 | bool HasFuses() const; | 52 | bool HasFuses() const; |
| @@ -57,7 +60,8 @@ public: | |||
| 57 | // Package2 | 60 | // Package2 |
| 58 | bool HasPackage2(Package2Type type = Package2Type::NormalMain) const; | 61 | bool HasPackage2(Package2Type type = Package2Type::NormalMain) const; |
| 59 | FileSys::VirtualFile GetPackage2Raw(Package2Type type = Package2Type::NormalMain) const; | 62 | FileSys::VirtualFile GetPackage2Raw(Package2Type type = Package2Type::NormalMain) const; |
| 60 | void DecryptPackage2(std::array<std::array<u8, 16>, 0x20> package2, Package2Type type); | 63 | void DecryptPackage2(const std::array<std::array<u8, 16>, 0x20>& package2_keys, |
| 64 | Package2Type type); | ||
| 61 | const std::vector<u8>& GetPackage2FSDecompressed( | 65 | const std::vector<u8>& GetPackage2FSDecompressed( |
| 62 | Package2Type type = Package2Type::NormalMain) const; | 66 | Package2Type type = Package2Type::NormalMain) const; |
| 63 | std::array<u8, 0x10> GetKeyAreaKeyApplicationSource( | 67 | std::array<u8, 0x10> GetKeyAreaKeyApplicationSource( |