diff options
author | Zach Hilman <zachhilman@gmail.com> | 2018-09-24 03:05:01 +0200 |
---|---|---|
committer | Zach Hilman <zachhilman@gmail.com> | 2018-10-07 19:15:11 +0200 |
commit | 4aad010f7adbcf7d524b245139cd35869c7799f2 (patch) | |
tree | ab2390e5a5aabe75998652f1981927a9a0c7b401 /src | |
parent | key_manager: Add ETicket key derivation (diff) | |
download | yuzu-4aad010f7adbcf7d524b245139cd35869c7799f2.tar yuzu-4aad010f7adbcf7d524b245139cd35869c7799f2.tar.gz yuzu-4aad010f7adbcf7d524b245139cd35869c7799f2.tar.bz2 yuzu-4aad010f7adbcf7d524b245139cd35869c7799f2.tar.lz yuzu-4aad010f7adbcf7d524b245139cd35869c7799f2.tar.xz yuzu-4aad010f7adbcf7d524b245139cd35869c7799f2.tar.zst yuzu-4aad010f7adbcf7d524b245139cd35869c7799f2.zip |
Diffstat (limited to 'src')
-rw-r--r-- | src/core/crypto/key_manager.cpp | 86 | ||||
-rw-r--r-- | src/core/crypto/key_manager.h | 2 |
2 files changed, 88 insertions, 0 deletions
diff --git a/src/core/crypto/key_manager.cpp b/src/core/crypto/key_manager.cpp index 1328cdd47..027643654 100644 --- a/src/core/crypto/key_manager.cpp +++ b/src/core/crypto/key_manager.cpp @@ -870,6 +870,92 @@ void KeyManager::SetKeyWrapped(S256KeyType id, Key256 key, u64 field1, u64 field SetKey(id, key, field1, field2); } +void KeyManager::PopulateFromPartitionData(PartitionDataManager data) { + if (!BaseDeriveNecessary()) + return; + + if (!data.HasBoot0()) + return; + + for (size_t i = 0; i < 0x20; ++i) { + if (encrypted_keyblobs[i] != std::array<u8, 0xB0>{}) + continue; + encrypted_keyblobs[i] = data.GetEncryptedKeyblob(i); + WriteKeyToFile<0xB0>(KeyCategory::Console, fmt::format("encrypted_keyblob_{:02X}", i), + encrypted_keyblobs[i]); + } + + SetKeyWrapped(S128KeyType::Source, data.GetPackage2KeySource(), + static_cast<u64>(SourceKeyType::Package2)); + SetKeyWrapped(S128KeyType::Source, data.GetAESKekGenerationSource(), + static_cast<u64>(SourceKeyType::AESKekGeneration)); + SetKeyWrapped(S128KeyType::Source, data.GetTitlekekSource(), + static_cast<u64>(SourceKeyType::Titlekek)); + SetKeyWrapped(S128KeyType::Source, data.GetMasterKeySource(), + static_cast<u64>(SourceKeyType::Master)); + SetKeyWrapped(S128KeyType::Source, data.GetKeyblobMACKeySource(), + static_cast<u64>(SourceKeyType::KeyblobMAC)); + + for (size_t i = 0; i < PartitionDataManager::MAX_KEYBLOB_SOURCE_HASH; ++i) { + SetKeyWrapped(S128KeyType::Source, data.GetKeyblobKeySource(i), + static_cast<u64>(SourceKeyType::Keyblob), i); + } + + if (data.HasFuses()) + SetKeyWrapped(S128KeyType::SecureBoot, data.GetSecureBootKey()); + + DeriveBase(); + + Key128 latest_master{}; + for (s8 i = 0x1F; i > 0; --i) { + if (GetKey(S128KeyType::Master, i) != Key128{}) { + latest_master = GetKey(S128KeyType::Master, i); + break; + } + } + + const auto masters = data.GetTZMasterKeys(latest_master); + for (size_t i = 0; i < 0x20; ++i) { + if (masters[i] != Key128{} && !HasKey(S128KeyType::Master, i)) + SetKey(S128KeyType::Master, masters[i], i); + } + + DeriveBase(); + + if (!data.HasPackage2()) + return; + + std::array<Key128, 0x20> package2_keys{}; + for (size_t i = 0; i < 0x20; ++i) { + if (HasKey(S128KeyType::Package2, i)) + package2_keys[i] = GetKey(S128KeyType::Package2, i); + } + data.DecryptPackage2(package2_keys, Package2Type::NormalMain); + + SetKeyWrapped(S128KeyType::Source, data.GetKeyAreaKeyApplicationSource(), + static_cast<u64>(SourceKeyType::KeyAreaKey), + static_cast<u64>(KeyAreaKeyType::Application)); + SetKeyWrapped(S128KeyType::Source, data.GetKeyAreaKeyOceanSource(), + static_cast<u64>(SourceKeyType::KeyAreaKey), + static_cast<u64>(KeyAreaKeyType::Ocean)); + SetKeyWrapped(S128KeyType::Source, data.GetKeyAreaKeySystemSource(), + static_cast<u64>(SourceKeyType::KeyAreaKey), + static_cast<u64>(KeyAreaKeyType::System)); + SetKeyWrapped(S128KeyType::Source, data.GetSDKekSource(), + static_cast<u64>(SourceKeyType::SDKek)); + SetKeyWrapped(S256KeyType::SDKeySource, data.GetSDSaveKeySource(), + static_cast<u64>(SDKeyType::Save)); + SetKeyWrapped(S256KeyType::SDKeySource, data.GetSDNCAKeySource(), + static_cast<u64>(SDKeyType::NCA)); + SetKeyWrapped(S128KeyType::Source, data.GetHeaderKekSource(), + static_cast<u64>(SourceKeyType::HeaderKek)); + SetKeyWrapped(S256KeyType::HeaderSource, data.GetHeaderKeySource()); + SetKeyWrapped(S128KeyType::Source, data.GetAESKeyGenerationSource(), + static_cast<u64>(SourceKeyType::AESKeyGeneration)); + + DeriveBase(); +} + const boost::container::flat_map<std::string, KeyIndex<S128KeyType>> KeyManager::s128_file_id = { {"eticket_rsa_kek", {S128KeyType::ETicketRSAKek, 0, 0}}, {"eticket_rsa_kek_source", diff --git a/src/core/crypto/key_manager.h b/src/core/crypto/key_manager.h index 58afcdcac..d26aa59b6 100644 --- a/src/core/crypto/key_manager.h +++ b/src/core/crypto/key_manager.h @@ -158,6 +158,8 @@ public: void DeriveBase(); void DeriveETicket(PartitionDataManager data); + void PopulateFromPartitionData(PartitionDataManager data); + private: std::map<KeyIndex<S128KeyType>, Key128> s128_keys; std::map<KeyIndex<S256KeyType>, Key256> s256_keys; |