key_manager: Add support for more keys
TSEC, SBK, BIS, and other Sources for proper derivation
This commit is contained in:
		
							parent
							
								
									c79d2ca6cf
								
							
						
					
					
						commit
						d6a0d5d432
					
				@ -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) {
 | 
			
		||||
 | 
			
		||||
@ -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;
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user