diff options
author | liamwhite <liamwhite@users.noreply.github.com> | 2023-09-02 20:42:20 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-09-02 20:42:20 +0200 |
commit | 02e2aea50d30333e3f793fdc3acf76d718b0fe59 (patch) | |
tree | 6fc5d83f8af5c867b04953308cb2e7acbafd7b71 | |
parent | general: make -fwrapv generic to all architectures (#11379) (diff) | |
parent | vfs: ensure key area keys are validated (diff) | |
download | yuzu-02e2aea50d30333e3f793fdc3acf76d718b0fe59.tar yuzu-02e2aea50d30333e3f793fdc3acf76d718b0fe59.tar.gz yuzu-02e2aea50d30333e3f793fdc3acf76d718b0fe59.tar.bz2 yuzu-02e2aea50d30333e3f793fdc3acf76d718b0fe59.tar.lz yuzu-02e2aea50d30333e3f793fdc3acf76d718b0fe59.tar.xz yuzu-02e2aea50d30333e3f793fdc3acf76d718b0fe59.tar.zst yuzu-02e2aea50d30333e3f793fdc3acf76d718b0fe59.zip |
-rw-r--r-- | src/core/file_sys/content_archive.cpp | 17 |
1 files changed, 13 insertions, 4 deletions
diff --git a/src/core/file_sys/content_archive.cpp b/src/core/file_sys/content_archive.cpp index 44e6852fe..7d2f0abb8 100644 --- a/src/core/file_sys/content_archive.cpp +++ b/src/core/file_sys/content_archive.cpp @@ -22,6 +22,10 @@ namespace FileSys { +static u8 MasterKeyIdForKeyGeneration(u8 key_generation) { + return std::max<u8>(key_generation, 1) - 1; +} + NCA::NCA(VirtualFile file_, const NCA* base_nca) : file(std::move(file_)), keys{Core::Crypto::KeyManager::Instance()} { if (file == nullptr) { @@ -41,12 +45,17 @@ NCA::NCA(VirtualFile file_, const NCA* base_nca) return; } + // Ensure we have the proper key area keys to continue. + const u8 master_key_id = MasterKeyIdForKeyGeneration(reader->GetKeyGeneration()); + if (!keys.HasKey(Core::Crypto::S128KeyType::KeyArea, master_key_id, reader->GetKeyIndex())) { + status = Loader::ResultStatus::ErrorMissingKeyAreaKey; + return; + } + RightsId rights_id{}; reader->GetRightsId(rights_id.data(), rights_id.size()); if (rights_id != RightsId{}) { // External decryption key required; provide it here. - const auto key_generation = std::max<s32>(reader->GetKeyGeneration(), 1) - 1; - u128 rights_id_u128; std::memcpy(rights_id_u128.data(), rights_id.data(), sizeof(rights_id)); @@ -57,12 +66,12 @@ NCA::NCA(VirtualFile file_, const NCA* base_nca) return; } - if (!keys.HasKey(Core::Crypto::S128KeyType::Titlekek, key_generation)) { + if (!keys.HasKey(Core::Crypto::S128KeyType::Titlekek, master_key_id)) { status = Loader::ResultStatus::ErrorMissingTitlekek; return; } - auto titlekek = keys.GetKey(Core::Crypto::S128KeyType::Titlekek, key_generation); + auto titlekek = keys.GetKey(Core::Crypto::S128KeyType::Titlekek, master_key_id); Core::Crypto::AESCipher<Core::Crypto::Key128> cipher(titlekek, Core::Crypto::Mode::ECB); cipher.Transcode(titlekey.data(), titlekey.size(), titlekey.data(), Core::Crypto::Op::Decrypt); |