From 16d7eb4f5592f96ad150f3137d6d4820406626f3 Mon Sep 17 00:00:00 2001 From: Jake Date: Sat, 22 Apr 2017 02:09:35 -0500 Subject: [PATCH] [Crypto] Edat cleanup --- rpcs3/Crypto/unedat.cpp | 4 +++- rpcs3/Crypto/unedat.h | 2 +- rpcs3/Crypto/unself.cpp | 14 ++++++------- rpcs3/Emu/Cell/Modules/sceNp.cpp | 36 ++++++++++---------------------- 4 files changed, 21 insertions(+), 35 deletions(-) diff --git a/rpcs3/Crypto/unedat.cpp b/rpcs3/Crypto/unedat.cpp index b400895ee6..08e2773dc7 100644 --- a/rpcs3/Crypto/unedat.cpp +++ b/rpcs3/Crypto/unedat.cpp @@ -767,7 +767,7 @@ std::array GetEdatRifKeyFromRapFile(const fs::file& rap_file) return rifkey; } -bool VerifyEDATHeaderWithKLicense(const fs::file& input, const std::string& input_file_name, const std::array& custom_klic) +bool VerifyEDATHeaderWithKLicense(const fs::file& input, const std::string& input_file_name, const std::array& custom_klic, std::string* contentID) { // Setup NPD and EDAT/SDAT structs. NPD_HEADER NPD; @@ -801,6 +801,8 @@ bool VerifyEDATHeaderWithKLicense(const fs::file& input, const std::string& inpu return false; } } + + *contentID = std::string(reinterpret_cast(NPD.content_id)); return true; } diff --git a/rpcs3/Crypto/unedat.h b/rpcs3/Crypto/unedat.h index a5356c1e4f..41107a155f 100644 --- a/rpcs3/Crypto/unedat.h +++ b/rpcs3/Crypto/unedat.h @@ -44,7 +44,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, const std::string& rap_file_name, u8 *custom_klic, bool verbose); -extern bool VerifyEDATHeaderWithKLicense(const fs::file& input, const std::string& input_file_name, const std::array& custom_klic); +extern bool VerifyEDATHeaderWithKLicense(const fs::file& input, const std::string& input_file_name, const std::array& custom_klic, std::string* contentID); extern std::array GetEdatRifKeyFromRapFile(const fs::file& rap_file); diff --git a/rpcs3/Crypto/unself.cpp b/rpcs3/Crypto/unself.cpp index 1114812d4a..dc28f3e4ba 100644 --- a/rpcs3/Crypto/unself.cpp +++ b/rpcs3/Crypto/unself.cpp @@ -1088,12 +1088,7 @@ bool SELFDecrypter::DecryptNPDRM(u8 *metadata, u32 metadata_size) u8 klicensee_key[0x10]; memcpy(klicensee_key, key_v.GetKlicenseeKey(), 0x10); - // Use klicensee if available. - if (memcmp(klicensee_key, std::array{0}.data(), 0x10)) - { - memcpy(npdrm_key, klicensee_key, 0x10); - } - else if (ctrl->npdrm.license == 1) // Network license. + if (ctrl->npdrm.license == 1) // Network license. { LOG_ERROR(LOADER, "SELF: Can't decrypt network NPDRM!"); return false; @@ -1109,8 +1104,11 @@ bool SELFDecrypter::DecryptNPDRM(u8 *metadata, u32 metadata_size) } else if (ctrl->npdrm.license == 3) // Free license. { - // Use the NP_KLIC_FREE. - memcpy(npdrm_key, NP_KLIC_FREE, 0x10); + // Use klicensee if available. + if (memcmp(klicensee_key, std::array{0}.data(), 0x10)) + memcpy(npdrm_key, klicensee_key, 0x10); + else + memcpy(npdrm_key, NP_KLIC_FREE, 0x10); } else { diff --git a/rpcs3/Emu/Cell/Modules/sceNp.cpp b/rpcs3/Emu/Cell/Modules/sceNp.cpp index 3305505e79..aa90bc2446 100644 --- a/rpcs3/Emu/Cell/Modules/sceNp.cpp +++ b/rpcs3/Emu/Cell/Modules/sceNp.cpp @@ -62,35 +62,13 @@ s32 npDrmIsAvailable(vm::cptr k_licensee_addr, vm::cptr drm_path) sceNp.notice("npDrmIsAvailable(): KLicense key %s", k_licensee_str); } - sceNp.warning("npDrmIsAvailable(): Found DRM license file at %s", enc_drm_path); - - // TODO: Make more explicit what this actually does (currently it copies "XXXXXXXX" from drm_path (== "/dev_hdd0/game/XXXXXXXXX/*" assumed) - const std::string& drm_file_dir = enc_drm_path.substr(15); - const std::string& title_id = drm_file_dir.substr(0, drm_file_dir.find_first_of('/')); - - std::string rap_lpath = vfs::get("/dev_hdd0/home/00000001/exdata/"); // TODO: Allow multiple profiles. Use default for now. - - // Search for a compatible RAP file. - for (const auto& entry : fs::dir(rap_lpath)) - { - if (entry.name.find(title_id) != -1) - { - rap_lpath += entry.name; - break; - } - } - auto npdrmkeys = fxm::get_always(); npdrmkeys->devKlic.fill(0); npdrmkeys->rifKey.fill(0); - if (rap_lpath.back() == '/') - { - sceNp.warning("npDrmIsAvailable(): Can't find RAP file for %s", enc_drm_path); - } - else - npdrmkeys->rifKey = GetEdatRifKeyFromRapFile(fs::file{ rap_lpath }); + // todo: profile for rap_dir_path + std::string rap_dir_path = "/dev_hdd0/home/00000001/exdata/"; const std::string& enc_drm_path_local = vfs::get(enc_drm_path); const fs::file enc_file(enc_drm_path_local); @@ -117,9 +95,17 @@ s32 npDrmIsAvailable(vm::cptr k_licensee_addr, vm::cptr drm_path) { // edata / sdata files - if (VerifyEDATHeaderWithKLicense(enc_file, enc_drm_path_local, k_licensee)) + std::string contentID; + + if (VerifyEDATHeaderWithKLicense(enc_file, enc_drm_path_local, k_licensee, &contentID)) { + const std::string rap_file = rap_dir_path + contentID + ".rap"; npdrmkeys->devKlic = std::move(k_licensee); + + if (fs::is_file(vfs::get(rap_file))) + npdrmkeys->rifKey = GetEdatRifKeyFromRapFile(fs::file{ vfs::get(rap_file) }); + else + sceNp.warning("npDrmIsAvailable(): Rap file not found: %s", rap_file.c_str()); } else {