diff options
| author | 2018-09-23 20:56:02 -0400 | |
|---|---|---|
| committer | 2018-10-07 13:15:11 -0400 | |
| commit | d6a0d5d43263be84959ab74e8e6570c1b9a28693 (patch) | |
| tree | 0a34564611279f9a55f91d6ee8a3d7a8a0d8a0e9 /src/core/crypto/key_manager.cpp | |
| parent | key_manager: Add keyblob support (diff) | |
| download | yuzu-d6a0d5d43263be84959ab74e8e6570c1b9a28693.tar.gz yuzu-d6a0d5d43263be84959ab74e8e6570c1b9a28693.tar.xz yuzu-d6a0d5d43263be84959ab74e8e6570c1b9a28693.zip | |
key_manager: Add support for more keys
TSEC, SBK, BIS, and other Sources for proper derivation
Diffstat (limited to 'src/core/crypto/key_manager.cpp')
| -rw-r--r-- | src/core/crypto/key_manager.cpp | 68 |
1 files changed, 67 insertions, 1 deletions
diff --git a/src/core/crypto/key_manager.cpp b/src/core/crypto/key_manager.cpp index 0f1a86d1e..2a0b0b574 100644 --- a/src/core/crypto/key_manager.cpp +++ b/src/core/crypto/key_manager.cpp | |||
| @@ -152,6 +152,12 @@ KeyManager::KeyManager() { | |||
| 152 | AttemptLoadKeyFile(yuzu_keys_dir, yuzu_keys_dir, "console.keys_autogenerated", false); | 152 | AttemptLoadKeyFile(yuzu_keys_dir, yuzu_keys_dir, "console.keys_autogenerated", false); |
| 153 | } | 153 | } |
| 154 | 154 | ||
| 155 | static bool ValidCryptoRevisionString(const std::string& base, size_t begin, size_t length) { | ||
| 156 | if (base.size() < begin + length) | ||
| 157 | return false; | ||
| 158 | return std::all_of(base.begin() + begin, base.begin() + begin + length, ::isdigit); | ||
| 159 | } | ||
| 160 | |||
| 155 | void KeyManager::LoadFromFile(const std::string& filename, bool is_title_keys) { | 161 | void KeyManager::LoadFromFile(const std::string& filename, bool is_title_keys) { |
| 156 | std::ifstream file(filename); | 162 | std::ifstream file(filename); |
| 157 | if (!file.is_open()) | 163 | if (!file.is_open()) |
| @@ -190,6 +196,59 @@ void KeyManager::LoadFromFile(const std::string& filename, bool is_title_keys) { | |||
| 190 | const auto index = s256_file_id.at(out[0]); | 196 | const auto index = s256_file_id.at(out[0]); |
| 191 | Key256 key = Common::HexStringToArray<32>(out[1]); | 197 | Key256 key = Common::HexStringToArray<32>(out[1]); |
| 192 | s256_keys[{index.type, index.field1, index.field2}] = key; | 198 | s256_keys[{index.type, index.field1, index.field2}] = key; |
| 199 | } else if (out[0].compare(0, 8, "keyblob_") == 0 && | ||
| 200 | out[0].compare(0, 9, "keyblob_k") != 0) { | ||
| 201 | if (!ValidCryptoRevisionString(out[0], 8, 2)) | ||
| 202 | continue; | ||
| 203 | |||
| 204 | const auto index = std::stoul(out[0].substr(8, 2), nullptr, 16); | ||
| 205 | keyblobs[index] = Common::HexStringToArray<0x90>(out[1]); | ||
| 206 | } else if (out[0].compare(0, 18, "encrypted_keyblob_") == 0) { | ||
| 207 | if (!ValidCryptoRevisionString(out[0], 18, 2)) | ||
| 208 | continue; | ||
| 209 | |||
| 210 | const auto index = std::stoul(out[0].substr(18, 2), nullptr, 16); | ||
| 211 | encrypted_keyblobs[index] = Common::HexStringToArray<0xB0>(out[1]); | ||
| 212 | } else { | ||
| 213 | for (const auto& kv : std::map<std::pair<S128KeyType, u64>, std::string>{ | ||
| 214 | {{S128KeyType::Master, 0}, "master_key_"}, | ||
| 215 | {{S128KeyType::Package1, 0}, "package1_key_"}, | ||
| 216 | {{S128KeyType::Package2, 0}, "package2_key_"}, | ||
| 217 | {{S128KeyType::Titlekek, 0}, "titlekek_"}, | ||
| 218 | {{S128KeyType::Source, static_cast<u64>(SourceKeyType::Keyblob)}, | ||
| 219 | "keyblob_key_source_"}, | ||
| 220 | {{S128KeyType::Keyblob, 0}, "keyblob_key_"}, | ||
| 221 | {{S128KeyType::KeyblobMAC, 0}, "keyblob_mac_key_"}, | ||
| 222 | }) { | ||
| 223 | if (!ValidCryptoRevisionString(out[0], kv.second.size(), 2)) | ||
| 224 | continue; | ||
| 225 | if (out[0].compare(0, kv.second.size(), kv.second) == 0) { | ||
| 226 | const auto index = | ||
| 227 | std::stoul(out[0].substr(kv.second.size(), 2), nullptr, 16); | ||
| 228 | const auto sub = kv.first.second; | ||
| 229 | if (sub == 0) { | ||
| 230 | s128_keys[{kv.first.first, index, 0}] = | ||
| 231 | Common::HexStringToArray<16>(out[1]); | ||
| 232 | } else { | ||
| 233 | s128_keys[{kv.first.first, kv.first.second, index}] = | ||
| 234 | Common::HexStringToArray<16>(out[1]); | ||
| 235 | } | ||
| 236 | |||
| 237 | break; | ||
| 238 | } | ||
| 239 | } | ||
| 240 | |||
| 241 | const static std::array<const char*, 3> kak_names = { | ||
| 242 | "key_area_key_application_", "key_area_key_ocean_", "key_area_key_system_"}; | ||
| 243 | for (size_t j = 0; j < 3; ++j) { | ||
| 244 | const auto& match = kak_names[j]; | ||
| 245 | if (out[0].compare(0, std::strlen(match), match) == 0) { | ||
| 246 | const auto index = | ||
| 247 | std::stoul(out[0].substr(std::strlen(match), 2), nullptr, 16); | ||
| 248 | s128_keys[{S128KeyType::KeyArea, index, j}] = | ||
| 249 | Common::HexStringToArray<16>(out[1]); | ||
| 250 | } | ||
| 251 | } | ||
| 193 | } | 252 | } |
| 194 | } | 253 | } |
| 195 | } | 254 | } |
| @@ -255,8 +314,15 @@ void KeyManager::SetKey(S128KeyType id, Key128 key, u64 field1, u64 field2) { | |||
| 255 | Key128 rights_id; | 314 | Key128 rights_id; |
| 256 | std::memcpy(rights_id.data(), &field2, sizeof(u64)); | 315 | std::memcpy(rights_id.data(), &field2, sizeof(u64)); |
| 257 | std::memcpy(rights_id.data() + sizeof(u64), &field1, sizeof(u64)); | 316 | std::memcpy(rights_id.data() + sizeof(u64), &field1, sizeof(u64)); |
| 258 | WriteKeyToFile(true, Common::HexArrayToString(rights_id), key); | 317 | WriteKeyToFile(KeyCategory::Title, Common::HexArrayToString(rights_id), key); |
| 259 | } | 318 | } |
| 319 | |||
| 320 | auto category = KeyCategory::Standard; | ||
| 321 | if (id == S128KeyType::Keyblob || id == S128KeyType::KeyblobMAC || id == S128KeyType::TSEC || | ||
| 322 | id == S128KeyType::SecureBoot || id == S128KeyType::SDSeed || id == S128KeyType::BIS) { | ||
| 323 | category = KeyCategory::Console; | ||
| 324 | } | ||
| 325 | |||
| 260 | const auto iter2 = std::find_if( | 326 | const auto iter2 = std::find_if( |
| 261 | s128_file_id.begin(), s128_file_id.end(), | 327 | s128_file_id.begin(), s128_file_id.end(), |
| 262 | [&id, &field1, &field2](const std::pair<std::string, KeyIndex<S128KeyType>> elem) { | 328 | [&id, &field1, &field2](const std::pair<std::string, KeyIndex<S128KeyType>> elem) { |