summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZach Hilman <zachhilman@gmail.com>2018-09-24 03:05:01 +0200
committerZach Hilman <zachhilman@gmail.com>2018-10-07 19:15:11 +0200
commit4aad010f7adbcf7d524b245139cd35869c7799f2 (patch)
treeab2390e5a5aabe75998652f1981927a9a0c7b401
parentkey_manager: Add ETicket key derivation (diff)
downloadyuzu-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
-rw-r--r--src/core/crypto/key_manager.cpp86
-rw-r--r--src/core/crypto/key_manager.h2
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;