From 721632fe6602c18cc7e143b62020cbf436ced606 Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Sun, 23 Sep 2018 20:31:00 -0400 Subject: key_manager: Rename KEK to Kek --- src/core/crypto/key_manager.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/core/crypto/key_manager.h') diff --git a/src/core/crypto/key_manager.h b/src/core/crypto/key_manager.h index 978eec8dc..8bd33840d 100644 --- a/src/core/crypto/key_manager.h +++ b/src/core/crypto/key_manager.h @@ -50,9 +50,9 @@ enum class KeyAreaKeyType : u8 { }; enum class SourceKeyType : u8 { - SDKEK, - AESKEKGeneration, - AESKeyGeneration, + SDKek, // + AESKekGeneration, // + AESKeyGeneration, // }; enum class SDKeyType : u8 { -- cgit v1.2.3 From ce05df0a6dea513cf3f32a582535ccff61f6bcee Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Sun, 23 Sep 2018 20:37:27 -0400 Subject: key_manager: Add support for console-specific keyfile --- src/core/crypto/key_manager.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/core/crypto/key_manager.h') diff --git a/src/core/crypto/key_manager.h b/src/core/crypto/key_manager.h index 8bd33840d..ffc13fa8f 100644 --- a/src/core/crypto/key_manager.h +++ b/src/core/crypto/key_manager.h @@ -26,6 +26,12 @@ using SHA256Hash = std::array; static_assert(sizeof(Key128) == 16, "Key128 must be 128 bytes big."); static_assert(sizeof(Key256) == 32, "Key128 must be 128 bytes big."); +enum class KeyCategory : u8 { + Standard, + Title, + Console, +}; + enum class S256KeyType : u64 { Header, // SDKeySource, // f1=SDKeyType -- cgit v1.2.3 From c79d2ca6cf076bb5704ad221ff2a500cb8a94b84 Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Sun, 23 Sep 2018 20:51:44 -0400 Subject: key_manager: Add keyblob support --- src/core/crypto/key_manager.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/core/crypto/key_manager.h') diff --git a/src/core/crypto/key_manager.h b/src/core/crypto/key_manager.h index ffc13fa8f..b2c386bfb 100644 --- a/src/core/crypto/key_manager.h +++ b/src/core/crypto/key_manager.h @@ -109,6 +109,8 @@ public: private: boost::container::flat_map, Key128> s128_keys; boost::container::flat_map, Key256> s256_keys; + std::array, 0x20> encrypted_keyblobs{}; + std::array, 0x20> keyblobs{}; bool dev_mode; void LoadFromFile(const std::string& filename, bool is_title_keys); @@ -122,6 +124,8 @@ private: }; Key128 GenerateKeyEncryptionKey(Key128 source, Key128 master, Key128 kek_seed, Key128 key_seed); +Key128 DeriveKeyblobKey(Key128 sbk, Key128 tsec, Key128 source); + boost::optional DeriveSDSeed(); Loader::ResultStatus DeriveSDKeys(std::array& sd_keys, const KeyManager& keys); -- cgit v1.2.3 From d6a0d5d43263be84959ab74e8e6570c1b9a28693 Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Sun, 23 Sep 2018 20:56:02 -0400 Subject: key_manager: Add support for more keys TSEC, SBK, BIS, and other Sources for proper derivation --- src/core/crypto/key_manager.h | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) (limited to 'src/core/crypto/key_manager.h') diff --git a/src/core/crypto/key_manager.h b/src/core/crypto/key_manager.h index b2c386bfb..1cb62c2dc 100644 --- a/src/core/crypto/key_manager.h +++ b/src/core/crypto/key_manager.h @@ -33,8 +33,10 @@ enum class KeyCategory : u8 { }; enum class S256KeyType : u64 { - Header, // - SDKeySource, // f1=SDKeyType + SDKey, // f1=SDKeyType + Header, // + SDKeySource, // f1=SDKeyType + HeaderSource, // }; enum class S128KeyType : u64 { @@ -47,6 +49,14 @@ enum class S128KeyType : u64 { SDSeed, // Titlekey, // f1=rights id LSB f2=rights id MSB Source, // f1=source type, f2= sub id + Keyblob, // f1=crypto revision + KeyblobMAC, // f1=crypto revision + TSEC, // + SecureBoot, // + BIS, // f1=partition (0-3), f2=type {crypt, tweak} + HeaderKek, // + SDKek, // + RSAKek, // }; enum class KeyAreaKeyType : u8 { @@ -59,6 +69,16 @@ enum class SourceKeyType : u8 { SDKek, // AESKekGeneration, // AESKeyGeneration, // + RSAOaepKekGeneration, // + Master, // + Keyblob, // f2=crypto revision + KeyAreaKey, // f2=KeyAreaKeyType + Titlekek, // + Package2, // + HeaderKek, // + KeyblobMAC, // + ETicketKek, // + ETicketKekek, // }; enum class SDKeyType : u8 { @@ -66,6 +86,16 @@ enum class SDKeyType : u8 { NCA, }; +enum class BISKeyType : u8 { + Crypto, + Tweak, +}; + +enum class RSAKekType : u8 { + Mask0, + Seed3, +}; + template struct KeyIndex { KeyType type; -- cgit v1.2.3 From d7398283e3cab47bac3571c0a56903415ffa44e6 Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Sun, 23 Sep 2018 20:57:20 -0400 Subject: key_manager: Add BIS key getter --- src/core/crypto/key_manager.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/core/crypto/key_manager.h') diff --git a/src/core/crypto/key_manager.h b/src/core/crypto/key_manager.h index 1cb62c2dc..a729fa7a0 100644 --- a/src/core/crypto/key_manager.h +++ b/src/core/crypto/key_manager.h @@ -127,6 +127,8 @@ public: Key128 GetKey(S128KeyType id, u64 field1 = 0, u64 field2 = 0) const; Key256 GetKey(S256KeyType id, u64 field1 = 0, u64 field2 = 0) const; + Key256 GetBISKey(u8 partition_id) const; + void SetKey(S128KeyType id, Key128 key, u64 field1 = 0, u64 field2 = 0); void SetKey(S256KeyType id, Key256 key, u64 field1 = 0, u64 field2 = 0); -- cgit v1.2.3 From a57aac5772bc4cfde06faa68c75e7d8ef546dbee Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Sun, 23 Sep 2018 21:03:00 -0400 Subject: key_manager: Add base key derivation Derives master keys, game encryption keys, and package1/2 keys --- src/core/crypto/key_manager.h | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'src/core/crypto/key_manager.h') diff --git a/src/core/crypto/key_manager.h b/src/core/crypto/key_manager.h index a729fa7a0..8de65ec4e 100644 --- a/src/core/crypto/key_manager.h +++ b/src/core/crypto/key_manager.h @@ -138,9 +138,12 @@ public: // 8*43 and the private file to exist. void DeriveSDSeedLazy(); + bool BaseDeriveNecessary(); + void DeriveBase(); private: - boost::container::flat_map, Key128> s128_keys; - boost::container::flat_map, Key256> s256_keys; + std::map, Key128> s128_keys; + std::map, Key256> s256_keys; + std::array, 0x20> encrypted_keyblobs{}; std::array, 0x20> keyblobs{}; @@ -148,8 +151,12 @@ private: void LoadFromFile(const std::string& filename, bool is_title_keys); void AttemptLoadKeyFile(const std::string& dir1, const std::string& dir2, const std::string& filename, bool title); - template - void WriteKeyToFile(bool title_key, std::string_view keyname, const std::array& key); + template + void WriteKeyToFile(KeyCategory category, std::string_view keyname, + const std::array& key); + + void SetKeyWrapped(S128KeyType id, Key128 key, u64 field1 = 0, u64 field2 = 0); + void SetKeyWrapped(S256KeyType id, Key256 key, u64 field1 = 0, u64 field2 = 0); static const boost::container::flat_map> s128_file_id; static const boost::container::flat_map> s256_file_id; -- cgit v1.2.3 From d041d6231c97ea0c8af788da251ae019ee560e6a Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Sun, 23 Sep 2018 21:04:13 -0400 Subject: key_manager: Add ETicket key derivation Derives titlekeys --- src/core/crypto/key_manager.h | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) (limited to 'src/core/crypto/key_manager.h') diff --git a/src/core/crypto/key_manager.h b/src/core/crypto/key_manager.h index 8de65ec4e..58afcdcac 100644 --- a/src/core/crypto/key_manager.h +++ b/src/core/crypto/key_manager.h @@ -5,11 +5,18 @@ #pragma once #include +#include #include #include #include #include #include "common/common_types.h" +#include "core/file_sys/vfs_types.h" +#include "partition_data_manager.h" + +namespace FileUtil { +class IOFile; +} namespace Loader { enum class ResultStatus : u16; @@ -22,9 +29,18 @@ constexpr u64 TICKET_FILE_TITLEKEY_OFFSET = 0x180; using Key128 = std::array; using Key256 = std::array; using SHA256Hash = std::array; +using TicketRaw = std::array; static_assert(sizeof(Key128) == 16, "Key128 must be 128 bytes big."); -static_assert(sizeof(Key256) == 32, "Key128 must be 128 bytes big."); +static_assert(sizeof(Key256) == 32, "Key256 must be 256 bytes big."); + +template > 3)> +struct RSAKeyPair { + std::array encryption_key; + std::array decryption_key; + std::array modulus; + std::array exponent; +}; enum class KeyCategory : u8 { Standard, @@ -140,6 +156,8 @@ public: bool BaseDeriveNecessary(); void DeriveBase(); + void DeriveETicket(PartitionDataManager data); + private: std::map, Key128> s128_keys; std::map, Key256> s256_keys; @@ -166,6 +184,13 @@ Key128 GenerateKeyEncryptionKey(Key128 source, Key128 master, Key128 kek_seed, K Key128 DeriveKeyblobKey(Key128 sbk, Key128 tsec, Key128 source); boost::optional DeriveSDSeed(); -Loader::ResultStatus DeriveSDKeys(std::array& sd_keys, const KeyManager& keys); +Loader::ResultStatus DeriveSDKeys(std::array& sd_keys, KeyManager& keys); + +std::vector GetTicketblob(const FileUtil::IOFile& ticket_save); + +// Returns a pair of {rights_id, titlekey}. Fails if the ticket has no certificate authority (offset +// 0x140-0x144 is zero) +boost::optional> ParseTicket( + const TicketRaw& ticket, const RSAKeyPair<2048>& eticket_extended_key); } // namespace Core::Crypto -- cgit v1.2.3 From 4aad010f7adbcf7d524b245139cd35869c7799f2 Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Sun, 23 Sep 2018 21:05:01 -0400 Subject: key_manager: Add support for loading keys from partition data --- src/core/crypto/key_manager.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/core/crypto/key_manager.h') 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, Key128> s128_keys; std::map, Key256> s256_keys; -- cgit v1.2.3 From 3ec054643e50f2845fb6a1a924b83bd71a0e2234 Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Sat, 29 Sep 2018 11:48:51 -0400 Subject: partition_data_manager: Rename system files for hekate x --- src/core/crypto/key_manager.h | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'src/core/crypto/key_manager.h') diff --git a/src/core/crypto/key_manager.h b/src/core/crypto/key_manager.h index d26aa59b6..a41abbdfc 100644 --- a/src/core/crypto/key_manager.h +++ b/src/core/crypto/key_manager.h @@ -11,8 +11,8 @@ #include #include #include "common/common_types.h" +#include "core/crypto/partition_data_manager.h" #include "core/file_sys/vfs_types.h" -#include "partition_data_manager.h" namespace FileUtil { class IOFile; @@ -154,11 +154,11 @@ public: // 8*43 and the private file to exist. void DeriveSDSeedLazy(); - bool BaseDeriveNecessary(); + bool BaseDeriveNecessary() const; void DeriveBase(); - void DeriveETicket(PartitionDataManager data); + void DeriveETicket(PartitionDataManager& data); - void PopulateFromPartitionData(PartitionDataManager data); + void PopulateFromPartitionData(PartitionDataManager& data); private: std::map, Key128> s128_keys; @@ -175,6 +175,8 @@ private: void WriteKeyToFile(KeyCategory category, std::string_view keyname, const std::array& key); + void DeriveGeneralPurposeKeys(u8 crypto_revision); + void SetKeyWrapped(S128KeyType id, Key128 key, u64 field1 = 0, u64 field2 = 0); void SetKeyWrapped(S256KeyType id, Key256 key, u64 field1 = 0, u64 field2 = 0); @@ -183,7 +185,11 @@ private: }; Key128 GenerateKeyEncryptionKey(Key128 source, Key128 master, Key128 kek_seed, Key128 key_seed); -Key128 DeriveKeyblobKey(Key128 sbk, Key128 tsec, Key128 source); +Key128 DeriveKeyblobKey(const Key128& sbk, const Key128& tsec, Key128 source); +Key128 DeriveKeyblobMACKey(const Key128& keyblob_key, const Key128& mac_source); +Key128 DeriveMasterKey(const std::array& keyblob, const Key128& master_source); +std::array DecryptKeyblob(const std::array& encrypted_keyblob, + const Key128& key); boost::optional DeriveSDSeed(); Loader::ResultStatus DeriveSDKeys(std::array& sd_keys, KeyManager& keys); -- cgit v1.2.3