diff --git a/rpcs3/Crypto/unedat.cpp b/rpcs3/Crypto/unedat.cpp index b8fe283863..3635df77fd 100644 --- a/rpcs3/Crypto/unedat.cpp +++ b/rpcs3/Crypto/unedat.cpp @@ -785,7 +785,7 @@ u128 GetEdatRifKeyFromRapFile(const fs::file& rap_file) return rifkey; } -bool VerifyEDATHeaderWithKLicense(const fs::file& input, const std::string& input_file_name, const u8* custom_klic, std::string* contentID, u32* license) +bool VerifyEDATHeaderWithKLicense(const fs::file& input, const std::string& input_file_name, const u8* custom_klic, NPD_HEADER* npd_out) { // Setup NPD and EDAT/SDAT structs. NPD_HEADER NPD; @@ -818,8 +818,11 @@ bool VerifyEDATHeaderWithKLicense(const fs::file& input, const std::string& inpu std::string_view sv{NPD.content_id, std::size(NPD.content_id)}; sv = sv.substr(0, sv.find_first_of('\0')); - if (contentID) *contentID = std::string(sv); - if (license) *license = (NPD.license & 3); + if (npd_out) + { + memcpy(npd_out, &NPD, sizeof(NPD_HEADER)); + } + return true; } diff --git a/rpcs3/Crypto/unedat.h b/rpcs3/Crypto/unedat.h index 092dc4dc56..b438806233 100644 --- a/rpcs3/Crypto/unedat.h +++ b/rpcs3/Crypto/unedat.h @@ -57,7 +57,7 @@ struct EDAT_HEADER // Decrypts full file, or null/empty file extern fs::file DecryptEDAT(const fs::file& input, const std::string& input_file_name, int mode, u8 *custom_klic, bool verbose); -extern bool VerifyEDATHeaderWithKLicense(const fs::file& input, const std::string& input_file_name, const u8* custom_klic, std::string* contentID = nullptr, u32* license = nullptr); +extern bool VerifyEDATHeaderWithKLicense(const fs::file& input, const std::string& input_file_name, const u8* custom_klic, NPD_HEADER *npd_out = nullptr); u128 GetEdatRifKeyFromRapFile(const fs::file& rap_file); diff --git a/rpcs3/Crypto/unself.cpp b/rpcs3/Crypto/unself.cpp index e7b4ef4ad1..e71685f7fc 100644 --- a/rpcs3/Crypto/unself.cpp +++ b/rpcs3/Crypto/unself.cpp @@ -1460,7 +1460,7 @@ fs::file decrypt_self(fs::file elf_or_self, u8* klic_key, SelfAdditionalInfo* ou return elf_or_self; } -bool verify_npdrm_self_headers(const fs::file& self, u8* klic_key) +bool verify_npdrm_self_headers(const fs::file& self, u8* klic_key, NPD_HEADER* npd_out) { if (!self) return false; @@ -1488,6 +1488,14 @@ bool verify_npdrm_self_headers(const fs::file& self, u8* klic_key) self_log.error("SELF: Failed to load SELF file metadata!"); return false; } + + if (npd_out) + { + if (const NPD_HEADER* npd = self_dec.GetNPDHeader()) + { + memcpy(npd_out, npd, sizeof(NPD_HEADER)); + } + } } return true; } diff --git a/rpcs3/Crypto/unself.h b/rpcs3/Crypto/unself.h index ac89094da0..b6ed6445a2 100644 --- a/rpcs3/Crypto/unself.h +++ b/rpcs3/Crypto/unself.h @@ -497,6 +497,6 @@ private: }; fs::file decrypt_self(fs::file elf_or_self, u8* klic_key = nullptr, SelfAdditionalInfo* additional_info = nullptr); -bool verify_npdrm_self_headers(const fs::file& self, u8* klic_key = nullptr); +bool verify_npdrm_self_headers(const fs::file& self, u8* klic_key = nullptr, NPD_HEADER* npd_out = nullptr); u128 get_default_self_klic(); diff --git a/rpcs3/Emu/Cell/Modules/sceNp.cpp b/rpcs3/Emu/Cell/Modules/sceNp.cpp index 8056c49225..a555135a5e 100644 --- a/rpcs3/Emu/Cell/Modules/sceNp.cpp +++ b/rpcs3/Emu/Cell/Modules/sceNp.cpp @@ -510,19 +510,18 @@ error_code npDrmIsAvailable(vm::cptr k_licensee_addr, vm::cptr drm_pat { // edata / sdata files - std::string contentID; - u32 license_type = 0; + NPD_HEADER npd; - if (VerifyEDATHeaderWithKLicense(enc_file, enc_drm_path, reinterpret_cast(&k_licensee), &contentID, &license_type)) + if (VerifyEDATHeaderWithKLicense(enc_file, enc_drm_path, reinterpret_cast(&k_licensee), &npd)) { // Check if RAP-free - if (license_type == 3) + if (npd.license == 3) { npdrmkeys.install_decryption_key(k_licensee); } else { - const std::string rap_file = rpcs3::utils::get_rap_file_path(contentID); + const std::string rap_file = rpcs3::utils::get_rap_file_path(npd.content_id); if (fs::file rap_fd{rap_file}; rap_fd && rap_fd.size() >= sizeof(u128)) { @@ -572,7 +571,7 @@ error_code npDrmVerifyUpgradeLicense(vm::cptr content_id) } const std::string content_str(content_id.get_ptr(), std::find(content_id.get_ptr(), content_id.get_ptr() + 0x2f, '\0')); - sceNp.warning("npDrmVerifyUpgradeLicense(): content_id='%s'", content_id); + sceNp.warning("npDrmVerifyUpgradeLicense(): content_id=%s", content_id); if (!rpcs3::utils::verify_c00_unlock_edat(content_str)) return SCE_NP_DRM_ERROR_LICENSE_NOT_FOUND; diff --git a/rpcs3/Emu/system_utils.cpp b/rpcs3/Emu/system_utils.cpp index 9038e53684..24236ef2b4 100644 --- a/rpcs3/Emu/system_utils.cpp +++ b/rpcs3/Emu/system_utils.cpp @@ -244,14 +244,16 @@ namespace rpcs3::utils return true; u128 k_licensee = get_default_self_klic(); - std::string edat_content_id; + NPD_HEADER npd; - if (!VerifyEDATHeaderWithKLicense(enc_file, edat_path, reinterpret_cast(&k_licensee), &edat_content_id)) + if (!VerifyEDATHeaderWithKLicense(enc_file, edat_path, reinterpret_cast(&k_licensee), &npd)) { sys_log.error("verify_c00_unlock_edat(): Failed to verify npd file '%s'", edat_path); return false; } + std::string edat_content_id = npd.content_id; + if (edat_content_id != content_id) { sys_log.error("verify_c00_unlock_edat(): Content ID mismatch in npd header of '%s'", edat_path);