summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Liam2023-08-28 22:22:00 -0400
committerGravatar Liam2023-08-28 22:22:00 -0400
commit5a09ba7255dc4428137bd2f51fb1bb197ef36957 (patch)
tree653a6fff417e36c1f20a1371a27c0cbf82d8b687
parentMerge pull request #11390 from FearlessTobi/hwopus-multi (diff)
downloadyuzu-5a09ba7255dc4428137bd2f51fb1bb197ef36957.tar.gz
yuzu-5a09ba7255dc4428137bd2f51fb1bb197ef36957.tar.xz
yuzu-5a09ba7255dc4428137bd2f51fb1bb197ef36957.zip
vfs: ensure key area keys are validated
-rw-r--r--src/core/file_sys/content_archive.cpp17
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 @@
22 22
23namespace FileSys { 23namespace FileSys {
24 24
25static u8 MasterKeyIdForKeyGeneration(u8 key_generation) {
26 return std::max<u8>(key_generation, 1) - 1;
27}
28
25NCA::NCA(VirtualFile file_, const NCA* base_nca) 29NCA::NCA(VirtualFile file_, const NCA* base_nca)
26 : file(std::move(file_)), keys{Core::Crypto::KeyManager::Instance()} { 30 : file(std::move(file_)), keys{Core::Crypto::KeyManager::Instance()} {
27 if (file == nullptr) { 31 if (file == nullptr) {
@@ -41,12 +45,17 @@ NCA::NCA(VirtualFile file_, const NCA* base_nca)
41 return; 45 return;
42 } 46 }
43 47
48 // Ensure we have the proper key area keys to continue.
49 const u8 master_key_id = MasterKeyIdForKeyGeneration(reader->GetKeyGeneration());
50 if (!keys.HasKey(Core::Crypto::S128KeyType::KeyArea, master_key_id, reader->GetKeyIndex())) {
51 status = Loader::ResultStatus::ErrorMissingKeyAreaKey;
52 return;
53 }
54
44 RightsId rights_id{}; 55 RightsId rights_id{};
45 reader->GetRightsId(rights_id.data(), rights_id.size()); 56 reader->GetRightsId(rights_id.data(), rights_id.size());
46 if (rights_id != RightsId{}) { 57 if (rights_id != RightsId{}) {
47 // External decryption key required; provide it here. 58 // External decryption key required; provide it here.
48 const auto key_generation = std::max<s32>(reader->GetKeyGeneration(), 1) - 1;
49
50 u128 rights_id_u128; 59 u128 rights_id_u128;
51 std::memcpy(rights_id_u128.data(), rights_id.data(), sizeof(rights_id)); 60 std::memcpy(rights_id_u128.data(), rights_id.data(), sizeof(rights_id));
52 61
@@ -57,12 +66,12 @@ NCA::NCA(VirtualFile file_, const NCA* base_nca)
57 return; 66 return;
58 } 67 }
59 68
60 if (!keys.HasKey(Core::Crypto::S128KeyType::Titlekek, key_generation)) { 69 if (!keys.HasKey(Core::Crypto::S128KeyType::Titlekek, master_key_id)) {
61 status = Loader::ResultStatus::ErrorMissingTitlekek; 70 status = Loader::ResultStatus::ErrorMissingTitlekek;
62 return; 71 return;
63 } 72 }
64 73
65 auto titlekek = keys.GetKey(Core::Crypto::S128KeyType::Titlekek, key_generation); 74 auto titlekek = keys.GetKey(Core::Crypto::S128KeyType::Titlekek, master_key_id);
66 Core::Crypto::AESCipher<Core::Crypto::Key128> cipher(titlekek, Core::Crypto::Mode::ECB); 75 Core::Crypto::AESCipher<Core::Crypto::Key128> cipher(titlekek, Core::Crypto::Mode::ECB);
67 cipher.Transcode(titlekey.data(), titlekey.size(), titlekey.data(), 76 cipher.Transcode(titlekey.data(), titlekey.size(), titlekey.data(),
68 Core::Crypto::Op::Decrypt); 77 Core::Crypto::Op::Decrypt);