diff options
| -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 | |||
| 870 | SetKey(id, key, field1, field2); | 870 | SetKey(id, key, field1, field2); |
| 871 | } | 871 | } |
| 872 | 872 | ||
| 873 | void KeyManager::PopulateFromPartitionData(PartitionDataManager data) { | ||
| 874 | if (!BaseDeriveNecessary()) | ||
| 875 | return; | ||
| 876 | |||
| 877 | if (!data.HasBoot0()) | ||
| 878 | return; | ||
| 879 | |||
| 880 | for (size_t i = 0; i < 0x20; ++i) { | ||
| 881 | if (encrypted_keyblobs[i] != std::array<u8, 0xB0>{}) | ||
| 882 | continue; | ||
| 883 | encrypted_keyblobs[i] = data.GetEncryptedKeyblob(i); | ||
| 884 | WriteKeyToFile<0xB0>(KeyCategory::Console, fmt::format("encrypted_keyblob_{:02X}", i), | ||
| 885 | encrypted_keyblobs[i]); | ||
| 886 | } | ||
| 887 | |||
| 888 | SetKeyWrapped(S128KeyType::Source, data.GetPackage2KeySource(), | ||
| 889 | static_cast<u64>(SourceKeyType::Package2)); | ||
| 890 | SetKeyWrapped(S128KeyType::Source, data.GetAESKekGenerationSource(), | ||
| 891 | static_cast<u64>(SourceKeyType::AESKekGeneration)); | ||
| 892 | SetKeyWrapped(S128KeyType::Source, data.GetTitlekekSource(), | ||
| 893 | static_cast<u64>(SourceKeyType::Titlekek)); | ||
| 894 | SetKeyWrapped(S128KeyType::Source, data.GetMasterKeySource(), | ||
| 895 | static_cast<u64>(SourceKeyType::Master)); | ||
| 896 | SetKeyWrapped(S128KeyType::Source, data.GetKeyblobMACKeySource(), | ||
| 897 | static_cast<u64>(SourceKeyType::KeyblobMAC)); | ||
| 898 | |||
| 899 | for (size_t i = 0; i < PartitionDataManager::MAX_KEYBLOB_SOURCE_HASH; ++i) { | ||
| 900 | SetKeyWrapped(S128KeyType::Source, data.GetKeyblobKeySource(i), | ||
| 901 | static_cast<u64>(SourceKeyType::Keyblob), i); | ||
| 902 | } | ||
| 903 | |||
| 904 | if (data.HasFuses()) | ||
| 905 | SetKeyWrapped(S128KeyType::SecureBoot, data.GetSecureBootKey()); | ||
| 906 | |||
| 907 | DeriveBase(); | ||
| 908 | |||
| 909 | Key128 latest_master{}; | ||
| 910 | for (s8 i = 0x1F; i > 0; --i) { | ||
| 911 | if (GetKey(S128KeyType::Master, i) != Key128{}) { | ||
| 912 | latest_master = GetKey(S128KeyType::Master, i); | ||
| 913 | break; | ||
| 914 | } | ||
| 915 | } | ||
| 916 | |||
| 917 | const auto masters = data.GetTZMasterKeys(latest_master); | ||
| 918 | for (size_t i = 0; i < 0x20; ++i) { | ||
| 919 | if (masters[i] != Key128{} && !HasKey(S128KeyType::Master, i)) | ||
| 920 | SetKey(S128KeyType::Master, masters[i], i); | ||
| 921 | } | ||
| 922 | |||
| 923 | DeriveBase(); | ||
| 924 | |||
| 925 | if (!data.HasPackage2()) | ||
| 926 | return; | ||
| 927 | |||
| 928 | std::array<Key128, 0x20> package2_keys{}; | ||
| 929 | for (size_t i = 0; i < 0x20; ++i) { | ||
| 930 | if (HasKey(S128KeyType::Package2, i)) | ||
| 931 | package2_keys[i] = GetKey(S128KeyType::Package2, i); | ||
| 932 | } | ||
| 933 | data.DecryptPackage2(package2_keys, Package2Type::NormalMain); | ||
| 934 | |||
| 935 | SetKeyWrapped(S128KeyType::Source, data.GetKeyAreaKeyApplicationSource(), | ||
| 936 | static_cast<u64>(SourceKeyType::KeyAreaKey), | ||
| 937 | static_cast<u64>(KeyAreaKeyType::Application)); | ||
| 938 | SetKeyWrapped(S128KeyType::Source, data.GetKeyAreaKeyOceanSource(), | ||
| 939 | static_cast<u64>(SourceKeyType::KeyAreaKey), | ||
| 940 | static_cast<u64>(KeyAreaKeyType::Ocean)); | ||
| 941 | SetKeyWrapped(S128KeyType::Source, data.GetKeyAreaKeySystemSource(), | ||
| 942 | static_cast<u64>(SourceKeyType::KeyAreaKey), | ||
| 943 | static_cast<u64>(KeyAreaKeyType::System)); | ||
| 944 | SetKeyWrapped(S128KeyType::Source, data.GetSDKekSource(), | ||
| 945 | static_cast<u64>(SourceKeyType::SDKek)); | ||
| 946 | SetKeyWrapped(S256KeyType::SDKeySource, data.GetSDSaveKeySource(), | ||
| 947 | static_cast<u64>(SDKeyType::Save)); | ||
| 948 | SetKeyWrapped(S256KeyType::SDKeySource, data.GetSDNCAKeySource(), | ||
| 949 | static_cast<u64>(SDKeyType::NCA)); | ||
| 950 | SetKeyWrapped(S128KeyType::Source, data.GetHeaderKekSource(), | ||
| 951 | static_cast<u64>(SourceKeyType::HeaderKek)); | ||
| 952 | SetKeyWrapped(S256KeyType::HeaderSource, data.GetHeaderKeySource()); | ||
| 953 | SetKeyWrapped(S128KeyType::Source, data.GetAESKeyGenerationSource(), | ||
| 954 | static_cast<u64>(SourceKeyType::AESKeyGeneration)); | ||
| 955 | |||
| 956 | DeriveBase(); | ||
| 957 | } | ||
| 958 | |||
| 873 | const boost::container::flat_map<std::string, KeyIndex<S128KeyType>> KeyManager::s128_file_id = { | 959 | const boost::container::flat_map<std::string, KeyIndex<S128KeyType>> KeyManager::s128_file_id = { |
| 874 | {"eticket_rsa_kek", {S128KeyType::ETicketRSAKek, 0, 0}}, | 960 | {"eticket_rsa_kek", {S128KeyType::ETicketRSAKek, 0, 0}}, |
| 875 | {"eticket_rsa_kek_source", | 961 | {"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: | |||
| 158 | void DeriveBase(); | 158 | void DeriveBase(); |
| 159 | void DeriveETicket(PartitionDataManager data); | 159 | void DeriveETicket(PartitionDataManager data); |
| 160 | 160 | ||
| 161 | void PopulateFromPartitionData(PartitionDataManager data); | ||
| 162 | |||
| 161 | private: | 163 | private: |
| 162 | std::map<KeyIndex<S128KeyType>, Key128> s128_keys; | 164 | std::map<KeyIndex<S128KeyType>, Key128> s128_keys; |
| 163 | std::map<KeyIndex<S256KeyType>, Key256> s256_keys; | 165 | std::map<KeyIndex<S256KeyType>, Key256> s256_keys; |