Просмотр исходного кода

key_manager: Add support for more keys
TSEC, SBK, BIS, and other Sources for proper derivation

Zach Hilman 7 лет назад
Родитель
Сommit
d6a0d5d432
2 измененных файлов с 99 добавлено и 3 удалено
  1. 67 1
      src/core/crypto/key_manager.cpp
  2. 32 2
      src/core/crypto/key_manager.h

+ 67 - 1
src/core/crypto/key_manager.cpp

@@ -152,6 +152,12 @@ KeyManager::KeyManager() {
     AttemptLoadKeyFile(yuzu_keys_dir, yuzu_keys_dir, "console.keys_autogenerated", false);
 }
 
+static bool ValidCryptoRevisionString(const std::string& base, size_t begin, size_t length) {
+    if (base.size() < begin + length)
+        return false;
+    return std::all_of(base.begin() + begin, base.begin() + begin + length, ::isdigit);
+}
+
 void KeyManager::LoadFromFile(const std::string& filename, bool is_title_keys) {
     std::ifstream file(filename);
     if (!file.is_open())
@@ -190,6 +196,59 @@ void KeyManager::LoadFromFile(const std::string& filename, bool is_title_keys) {
                 const auto index = s256_file_id.at(out[0]);
                 Key256 key = Common::HexStringToArray<32>(out[1]);
                 s256_keys[{index.type, index.field1, index.field2}] = key;
+            } else if (out[0].compare(0, 8, "keyblob_") == 0 &&
+                       out[0].compare(0, 9, "keyblob_k") != 0) {
+                if (!ValidCryptoRevisionString(out[0], 8, 2))
+                    continue;
+
+                const auto index = std::stoul(out[0].substr(8, 2), nullptr, 16);
+                keyblobs[index] = Common::HexStringToArray<0x90>(out[1]);
+            } else if (out[0].compare(0, 18, "encrypted_keyblob_") == 0) {
+                if (!ValidCryptoRevisionString(out[0], 18, 2))
+                    continue;
+
+                const auto index = std::stoul(out[0].substr(18, 2), nullptr, 16);
+                encrypted_keyblobs[index] = Common::HexStringToArray<0xB0>(out[1]);
+            } else {
+                for (const auto& kv : std::map<std::pair<S128KeyType, u64>, std::string>{
+                         {{S128KeyType::Master, 0}, "master_key_"},
+                         {{S128KeyType::Package1, 0}, "package1_key_"},
+                         {{S128KeyType::Package2, 0}, "package2_key_"},
+                         {{S128KeyType::Titlekek, 0}, "titlekek_"},
+                         {{S128KeyType::Source, static_cast<u64>(SourceKeyType::Keyblob)},
+                          "keyblob_key_source_"},
+                         {{S128KeyType::Keyblob, 0}, "keyblob_key_"},
+                         {{S128KeyType::KeyblobMAC, 0}, "keyblob_mac_key_"},
+                     }) {
+                    if (!ValidCryptoRevisionString(out[0], kv.second.size(), 2))
+                        continue;
+                    if (out[0].compare(0, kv.second.size(), kv.second) == 0) {
+                        const auto index =
+                            std::stoul(out[0].substr(kv.second.size(), 2), nullptr, 16);
+                        const auto sub = kv.first.second;
+                        if (sub == 0) {
+                            s128_keys[{kv.first.first, index, 0}] =
+                                Common::HexStringToArray<16>(out[1]);
+                        } else {
+                            s128_keys[{kv.first.first, kv.first.second, index}] =
+                                Common::HexStringToArray<16>(out[1]);
+                        }
+
+                        break;
+                    }
+                }
+
+                const static std::array<const char*, 3> kak_names = {
+                    "key_area_key_application_", "key_area_key_ocean_", "key_area_key_system_"};
+                for (size_t j = 0; j < 3; ++j) {
+                    const auto& match = kak_names[j];
+                    if (out[0].compare(0, std::strlen(match), match) == 0) {
+                        const auto index =
+                            std::stoul(out[0].substr(std::strlen(match), 2), nullptr, 16);
+                        s128_keys[{S128KeyType::KeyArea, index, j}] =
+                            Common::HexStringToArray<16>(out[1]);
+                    }
+                }
             }
         }
     }
@@ -255,8 +314,15 @@ void KeyManager::SetKey(S128KeyType id, Key128 key, u64 field1, u64 field2) {
         Key128 rights_id;
         std::memcpy(rights_id.data(), &field2, sizeof(u64));
         std::memcpy(rights_id.data() + sizeof(u64), &field1, sizeof(u64));
-        WriteKeyToFile(true, Common::HexArrayToString(rights_id), key);
+        WriteKeyToFile(KeyCategory::Title, Common::HexArrayToString(rights_id), key);
     }
+
+    auto category = KeyCategory::Standard;
+    if (id == S128KeyType::Keyblob || id == S128KeyType::KeyblobMAC || id == S128KeyType::TSEC ||
+        id == S128KeyType::SecureBoot || id == S128KeyType::SDSeed || id == S128KeyType::BIS) {
+        category = KeyCategory::Console;
+    }
+
     const auto iter2 = std::find_if(
         s128_file_id.begin(), s128_file_id.end(),
         [&id, &field1, &field2](const std::pair<std::string, KeyIndex<S128KeyType>> elem) {

+ 32 - 2
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 <typename KeyType>
 struct KeyIndex {
     KeyType type;