summaryrefslogtreecommitdiff
path: root/src/core/crypto/key_manager.cpp
diff options
context:
space:
mode:
authorGravatar Zach Hilman2018-09-23 20:56:02 -0400
committerGravatar Zach Hilman2018-10-07 13:15:11 -0400
commitd6a0d5d43263be84959ab74e8e6570c1b9a28693 (patch)
tree0a34564611279f9a55f91d6ee8a3d7a8a0d8a0e9 /src/core/crypto/key_manager.cpp
parentkey_manager: Add keyblob support (diff)
downloadyuzu-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.cpp68
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
155static 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
155void KeyManager::LoadFromFile(const std::string& filename, bool is_title_keys) { 161void 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) {