diff options
| author | liamwhite <liamwhite@users.noreply.github.com> | 2023-09-02 14:42:20 -0400 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-09-02 14:42:20 -0400 | 
| commit | 02e2aea50d30333e3f793fdc3acf76d718b0fe59 (patch) | |
| tree | 6fc5d83f8af5c867b04953308cb2e7acbafd7b71 | |
| parent | 32b2436f80f09fae88deef20711d34c037239bc5 (diff) | |
| parent | 5a09ba7255dc4428137bd2f51fb1bb197ef36957 (diff) | |
Merge pull request #11412 from liamwhite/key-area-keys
vfs: ensure key area keys are validated
| -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); | 
