mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-25 20:22:30 +01:00
Savestates/sys_fs: Save NPDRM decryption key
This commit is contained in:
parent
5a64556fbf
commit
f87e11d16a
@ -18,6 +18,7 @@ struct loaded_npdrm_keys
|
||||
{
|
||||
atomic_t<u128> dec_keys[16]{};
|
||||
atomic_t<u64> dec_keys_pos = 0;
|
||||
u128 one_time_key{}; // For savestates
|
||||
atomic_t<u32> npdrm_fds{0};
|
||||
|
||||
void install_decryption_key(u128 key)
|
||||
@ -162,4 +163,9 @@ public:
|
||||
id.type.insert(0, "EDATADecrypter: "sv);
|
||||
return id;
|
||||
}
|
||||
|
||||
u128 get_key() const
|
||||
{
|
||||
return dec_key;
|
||||
}
|
||||
};
|
||||
|
@ -439,6 +439,8 @@ lv2_file::lv2_file(utils::serial& ar)
|
||||
, flags(ar)
|
||||
, type(ar)
|
||||
{
|
||||
[[maybe_unused]] const s32 version = GET_SERIALIZATION_VERSION(lv2_fs);
|
||||
|
||||
ar(lock);
|
||||
|
||||
be_t<u64> arg = 0;
|
||||
@ -451,13 +453,19 @@ lv2_file::lv2_file(utils::serial& ar)
|
||||
case lv2_file_type::edata: arg = 0x2, size = 8; break;
|
||||
}
|
||||
|
||||
const std::string retrieve_real = ar;
|
||||
const std::string retrieve_real = ar.pop<std::string>();
|
||||
|
||||
if (type == lv2_file_type::edata && version >= 2)
|
||||
{
|
||||
ar(g_fxo->get<loaded_npdrm_keys>().one_time_key);
|
||||
}
|
||||
|
||||
open_result_t res = lv2_file::open(retrieve_real, flags & CELL_FS_O_ACCMODE, mode, size ? &arg : nullptr, size);
|
||||
file = std::move(res.file);
|
||||
real_path = std::move(res.real_path);
|
||||
|
||||
g_fxo->get<loaded_npdrm_keys>().npdrm_fds.raw() += type != lv2_file_type::regular;
|
||||
g_fxo->get<loaded_npdrm_keys>().one_time_key = {};
|
||||
|
||||
if (ar.pop<bool>()) // see lv2_file::save in_mem
|
||||
{
|
||||
@ -489,6 +497,13 @@ void lv2_file::save(utils::serial& ar)
|
||||
USING_SERIALIZATION_VERSION(lv2_fs);
|
||||
ar(name, mode, flags, type, lock, ensure(vfs::retrieve(real_path), FN(!x.empty())));
|
||||
|
||||
if (type == lv2_file_type::edata)
|
||||
{
|
||||
auto file_ptr = file.release();
|
||||
ar(static_cast<EDATADecrypter*>(file_ptr.get())->get_key());
|
||||
file.reset(std::move(file_ptr));
|
||||
}
|
||||
|
||||
if (!mp.read_only && flags & CELL_FS_O_ACCMODE)
|
||||
{
|
||||
// Ensure accurate timestamps and content on disk
|
||||
@ -919,6 +934,21 @@ lv2_file::open_raw_result_t lv2_file::open_raw(const std::string& local_path, s3
|
||||
const auto& dec_keys = edatkeys.dec_keys;
|
||||
const u64 max_i = std::min<u64>(std::size(dec_keys), init_pos);
|
||||
|
||||
if (edatkeys.one_time_key)
|
||||
{
|
||||
auto edata_file = std::make_unique<EDATADecrypter>(std::move(file), edatkeys.one_time_key);
|
||||
edatkeys.one_time_key = {};
|
||||
|
||||
if (!edata_file->ReadHeader())
|
||||
{
|
||||
// Read failure
|
||||
return {CELL_EFSSPECIFIC};
|
||||
}
|
||||
|
||||
file.reset(std::move(edata_file));
|
||||
break;
|
||||
}
|
||||
|
||||
for (u64 i = 0;; i++)
|
||||
{
|
||||
if (i == max_i)
|
||||
|
@ -47,7 +47,7 @@ SERIALIZATION_VER(spu, 2, 1)
|
||||
SERIALIZATION_VER(lv2_sync, 3, 1)
|
||||
SERIALIZATION_VER(lv2_vm, 4, 1)
|
||||
SERIALIZATION_VER(lv2_net, 5, 1)
|
||||
SERIALIZATION_VER(lv2_fs, 6, 1)
|
||||
SERIALIZATION_VER(lv2_fs, 6, 1, 2/*NPDRM key saving*/)
|
||||
SERIALIZATION_VER(lv2_prx_overlay, 7, 1)
|
||||
SERIALIZATION_VER(lv2_memory, 8, 1)
|
||||
SERIALIZATION_VER(lv2_config, 9, 1)
|
||||
|
Loading…
Reference in New Issue
Block a user