diff --git a/rpcs3/Crypto/key_vault.cpp b/rpcs3/Crypto/key_vault.cpp index 8c1a2e8732..f84ad88b8a 100644 --- a/rpcs3/Crypto/key_vault.cpp +++ b/rpcs3/Crypto/key_vault.cpp @@ -748,12 +748,13 @@ SELF_KEY KeyVault::FindSelfKey(u32 type, u16 revision, u64 version) void KeyVault::SetKlicenseeKey(u8 *key) { - memcpy(klicensee_key, key, 0x10); + klicensee_key = std::make_unique(0x10); + memcpy(klicensee_key.get(), key, 0x10); } u8 *KeyVault::GetKlicenseeKey() { - return klicensee_key; + return klicensee_key.get(); } void rap_to_rif(unsigned char* rap, unsigned char* rif) diff --git a/rpcs3/Crypto/key_vault.h b/rpcs3/Crypto/key_vault.h index 634fd97c2a..f4da403da1 100644 --- a/rpcs3/Crypto/key_vault.h +++ b/rpcs3/Crypto/key_vault.h @@ -2,6 +2,7 @@ #include #include +#include enum SELF_KEY_TYPE { KEY_LV0 = 1, @@ -11,7 +12,7 @@ enum SELF_KEY_TYPE { KEY_ISO, KEY_LDR, KEY_UNK7, - KEY_NPDRM + KEY_NPDRM }; struct SELF_KEY { @@ -159,7 +160,7 @@ class KeyVault std::vector sk_LDR_arr; std::vector sk_UNK7_arr; std::vector sk_NPDRM_arr; - u8 klicensee_key[0x10] = {}; + std::unique_ptr klicensee_key; public: KeyVault(); diff --git a/rpcs3/Crypto/unself.cpp b/rpcs3/Crypto/unself.cpp index dc28f3e4ba..d95b3884c7 100644 --- a/rpcs3/Crypto/unself.cpp +++ b/rpcs3/Crypto/unself.cpp @@ -5,6 +5,7 @@ #include "unself.h" #include "Emu/VFS.h" +#include // TODO: Still reliant on wxWidgets for zlib functions. Alternative solutions? #include @@ -1085,9 +1086,6 @@ bool SELFDecrypter::DecryptNPDRM(u8 *metadata, u32 metadata_size) return true; } - u8 klicensee_key[0x10]; - memcpy(klicensee_key, key_v.GetKlicenseeKey(), 0x10); - if (ctrl->npdrm.license == 1) // Network license. { LOG_ERROR(LOADER, "SELF: Can't decrypt network NPDRM!"); @@ -1105,8 +1103,8 @@ bool SELFDecrypter::DecryptNPDRM(u8 *metadata, u32 metadata_size) else if (ctrl->npdrm.license == 3) // Free license. { // Use klicensee if available. - if (memcmp(klicensee_key, std::array{0}.data(), 0x10)) - memcpy(npdrm_key, klicensee_key, 0x10); + if (key_v.GetKlicenseeKey() != nullptr) + memcpy(npdrm_key, key_v.GetKlicenseeKey(), 0x10); else memcpy(npdrm_key, NP_KLIC_FREE, 0x10); } @@ -1559,4 +1557,11 @@ extern bool verify_npdrm_self_headers(const fs::file& self, u8* klic_key) } } return true; +} + +std::array get_default_self_klic() +{ + std::array key; + std::copy(std::begin(NP_KLIC_FREE), std::end(NP_KLIC_FREE), std::begin(key)); + return key; } \ No newline at end of file diff --git a/rpcs3/Crypto/unself.h b/rpcs3/Crypto/unself.h index 3336b41435..257a21dbef 100644 --- a/rpcs3/Crypto/unself.h +++ b/rpcs3/Crypto/unself.h @@ -418,3 +418,4 @@ public: extern fs::file decrypt_self(fs::file elf_or_self, u8* klic_key = nullptr); extern bool verify_npdrm_self_headers(const fs::file& self, u8* klic_key = nullptr); +extern std::array get_default_self_klic(); diff --git a/rpcs3/Emu/Cell/Modules/sceNp.cpp b/rpcs3/Emu/Cell/Modules/sceNp.cpp index aca7c3484c..981b957932 100644 --- a/rpcs3/Emu/Cell/Modules/sceNp.cpp +++ b/rpcs3/Emu/Cell/Modules/sceNp.cpp @@ -83,6 +83,9 @@ s32 npDrmIsAvailable(vm::cptr k_licensee_addr, vm::cptr drm_path) if (magic == "SCE\0"_u32) { + if (k_licensee_addr == vm::null) + k_licensee = get_default_self_klic(); + if (verify_npdrm_self_headers(enc_file, k_licensee.data())) { npdrmkeys->devKlic = std::move(k_licensee);