diff --git a/rpcs3/Crypto/unedat.cpp b/rpcs3/Crypto/unedat.cpp index fe0f4a3dbc..0929319060 100644 --- a/rpcs3/Crypto/unedat.cpp +++ b/rpcs3/Crypto/unedat.cpp @@ -576,14 +576,32 @@ int validate_npd_hashes(const char* file_name, const u8* klicensee, NPD_HEADER * int dev_hash_result = 0; const s32 file_name_length = ::narrow(std::strlen(file_name), HERE); - std::unique_ptr buf(new u8[0x30 + file_name_length]); + const std::size_t buf_len = 0x30 + file_name_length; + + std::unique_ptr buf(new u8[buf_len]); + std::unique_ptr buf_lower(new u8[buf_len]); + std::unique_ptr buf_upper(new u8[buf_len]); // Build the title buffer (content_id + file_name). - memcpy(buf.get(), npd->content_id, 0x30); - memcpy(buf.get() + 0x30, file_name, file_name_length); + std::memcpy(buf.get(), npd->content_id, 0x30); + std::memcpy(buf.get() + 0x30, file_name, file_name_length); + + std::memcpy(buf_lower.get(), buf.get(), buf_len); + std::memcpy(buf_upper.get(), buf.get(), buf_len); + + for (std::size_t i = std::basic_string_view(buf.get() + 0x30, file_name_length).find_last_of('.'); i < buf_len; i++) + { + const u8 c = static_cast(buf[i]); + buf_upper[i] = std::toupper(c); + buf_lower[i] = std::tolower(c); + } // Hash with NPDRM_OMAC_KEY_3 and compare with title_hash. - title_hash_result = cmac_hash_compare(NP_OMAC_KEY_3, 0x10, buf.get(), 0x30 + file_name_length, npd->title_hash, 0x10); + // Try to ignore case sensivity with file extension + title_hash_result = + cmac_hash_compare(NP_OMAC_KEY_3, 0x10, buf.get(), buf_len, npd->title_hash, 0x10) || + cmac_hash_compare(NP_OMAC_KEY_3, 0x10, buf_lower.get(), buf_len, npd->title_hash, 0x10) || + cmac_hash_compare(NP_OMAC_KEY_3, 0x10, buf_upper.get(), buf_len, npd->title_hash, 0x10); if (verbose) {