1
0
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:
Eladash 2024-02-02 21:08:17 +02:00 committed by Elad.Ash
parent 5a64556fbf
commit f87e11d16a
3 changed files with 38 additions and 2 deletions

View File

@ -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;
}
};

View File

@ -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)

View File

@ -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)