diff --git a/Utilities/BEType.h b/Utilities/BEType.h index c516a62826..aaeadc21ae 100644 --- a/Utilities/BEType.h +++ b/Utilities/BEType.h @@ -15,7 +15,8 @@ // 128-bit vector type and also se_storage<> storage type union alignas(16) v128 { - char _bytes[16]; + uchar _bytes[16]; + char _chars[16]; template struct masked_array_t // array type accessed as (index ^ M) diff --git a/rpcs3/Crypto/unedat.cpp b/rpcs3/Crypto/unedat.cpp index ac3303fc47..8661adffdb 100644 --- a/rpcs3/Crypto/unedat.cpp +++ b/rpcs3/Crypto/unedat.cpp @@ -2,10 +2,15 @@ #include "key_vault.h" #include "unedat.h" +#include "Utilities/mutex.h" +#include "util/endian.hpp" #include LOG_CHANNEL(edat_log, "EDAT"); +// Static variables are being modified concurrently in ec.cpp, for now use a mutex +static shared_mutex ec_mtx; + void generate_key(int crypto_mode, int version, unsigned char *key_final, unsigned char *iv_final, unsigned char *key, unsigned char *iv) { int mode = crypto_mode & 0xF0000000; @@ -131,15 +136,15 @@ std::tuple dec_section(unsigned char* metadata) return std::make_tuple(offset, length, compression_end); } -std::array get_block_key(int block, NPD_HEADER *npd) +v128 get_block_key(int block, NPD_HEADER *npd) { unsigned char empty_key[0x10] = {}; unsigned char *src_key = (npd->version <= 1) ? empty_key : npd->dev_hash; - std::array dest_key{}; - memcpy(dest_key.data(), src_key, 0xC); + v128 dest_key{}; + memcpy(dest_key._bytes, src_key, 0xC); s32 swappedBlock = swap32(block); - memcpy(&dest_key[0xC], &swappedBlock, sizeof(swappedBlock)); + memcpy(&dest_key._bytes[0xC], &swappedBlock, sizeof(swappedBlock)); return dest_key; } @@ -241,10 +246,10 @@ s64 decrypt_block(const fs::file* in, u8* out, EDAT_HEADER *edat, NPD_HEADER *np in->read(enc_data.get(), length); // Generate a key for the current block. - std::array b_key = get_block_key(block_num, npd); + auto b_key = get_block_key(block_num, npd); // Encrypt the block key with the crypto key. - aesecb128_encrypt(crypt_key, b_key.data(), key_result); + aesecb128_encrypt(crypt_key, b_key._bytes, key_result); if ((edat->flags & EDAT_FLAG_0x10) != 0) aesecb128_encrypt(crypt_key, key_result, hash); // If FLAG 0x10 is set, encrypt again to get the final hash. else @@ -468,6 +473,8 @@ int check_data(unsigned char *key, EDAT_HEADER *edat, NPD_HEADER *npd, const fs: unsigned char signature_s[0x15] = { 0 }; unsigned char zero_buf[0x15] = { 0 }; + std::lock_guard lock(ec_mtx); + // Setup ECDSA curve and public key. ecdsa_set_curve(VSH_CURVE_P, VSH_CURVE_A, VSH_CURVE_B, VSH_CURVE_N, VSH_CURVE_GX, VSH_CURVE_GY); ecdsa_set_pub(VSH_PUB); @@ -518,10 +525,10 @@ int check_data(unsigned char *key, EDAT_HEADER *edat, NPD_HEADER *npd, const fs: { // Setup header signature hash. memset(signature_hash, 0, 20); - std::unique_ptr header_buf(new u8[0xD8]); + u8 header_buf[0xD8]; f->seek(file_offset); - f->read(header_buf.get(), 0xD8); - sha1(header_buf.get(), 0xD8, signature_hash ); + f->read(header_buf, 0xD8); + sha1(header_buf, 0xD8, signature_hash); if (!ecdsa_verify(signature_hash, signature_r, signature_s)) edat_log.warning("EDAT: Header signature is invalid!"); @@ -534,7 +541,6 @@ int check_data(unsigned char *key, EDAT_HEADER *edat, NPD_HEADER *npd, const fs: int validate_dev_klic(const u8* klicensee, NPD_HEADER *npd) { unsigned char dev[0x60] = { 0 }; - unsigned char key[0x10] = { 0 }; // Build the dev buffer (first 0x60 bytes of NPD header in big-endian). memcpy(dev, npd, 0x60); @@ -548,17 +554,9 @@ int validate_dev_klic(const u8* klicensee, NPD_HEADER *npd) memcpy(dev + 0xC, &type, 4); // Check for an empty dev_hash (can't validate if devklic is NULL); - bool isDevklicEmpty = true; - for (int i = 0; i < 0x10; i++) - { - if (klicensee[i] != 0) - { - isDevklicEmpty = false; - break; - } - } + auto klic = v128::loadu(klicensee); - if (isDevklicEmpty) + if (klic == v128{}) { // Allow empty dev hash. return 1; @@ -566,10 +564,10 @@ int validate_dev_klic(const u8* klicensee, NPD_HEADER *npd) else { // Generate klicensee xor key. - xor_key(key, klicensee, NP_OMAC_KEY_2); + auto key = klic ^ std::bit_cast(NP_OMAC_KEY_2); // Hash with generated key and compare with dev_hash. - return cmac_hash_compare(key, 0x10, dev, 0x60, npd->dev_hash, 0x10); + return cmac_hash_compare(key._bytes, 0x10, dev, 0x60, npd->dev_hash, 0x10); } } @@ -650,7 +648,7 @@ bool extract_all_data(const fs::file* input, const fs::file* output, const char* } // Set decryption key. - u8 key[0x10] = { 0 }; + v128 key{}; // Check EDAT/SDAT flag. if ((EDAT.flags & SDAT_FLAG) == SDAT_FLAG) @@ -664,7 +662,7 @@ bool extract_all_data(const fs::file* input, const fs::file* output, const char* } // Generate SDAT key. - xor_key(key, NPD.dev_hash, SDAT_KEY); + key = std::bit_cast(NPD.dev_hash) ^ std::bit_cast(SDAT_KEY); } else { @@ -691,23 +689,13 @@ bool extract_all_data(const fs::file* input, const fs::file* output, const char* // Select EDAT key. if ((NPD.license & 0x3) == 0x3) // Type 3: Use supplied devklic. - memcpy(key, devklic, 0x10); + memcpy(&key, devklic, 0x10); else if ((NPD.license & 0x2) == 0x2) // Type 2: Use key from RAP file (RIF key). { - memcpy(key, rifkey, 0x10); + memcpy(&key, rifkey, 0x10); // Make sure we don't have an empty RIF key. - int i, test = 0; - for (i = 0; i < 0x10; i++) - { - if (key[i] != 0) - { - test = 1; - break; - } - } - - if (!test) + if (key == v128{}) { edat_log.error("EDAT: A valid RAP file is needed for this EDAT file!"); return 1; @@ -721,34 +709,29 @@ bool extract_all_data(const fs::file* input, const fs::file* output, const char* if (verbose) { - int i; - edat_log.notice("DEVKLIC: "); - for (i = 0; i < 0x10; i++) - edat_log.notice("%02X", devklic[i]); + be_t data; - edat_log.notice("RIF KEY: "); - for (i = 0; i < 0x10; i++) - edat_log.notice("%02X", rifkey[i]); + std::memcpy(&data, devklic, sizeof(data)); + edat_log.notice("DEVKLIC: %s", data); + std::memcpy(&data, rifkey, sizeof(data)); + edat_log.notice("RIF KEY: %s", data); } } if (verbose) { - int i; - edat_log.notice("DECRYPTION KEY: "); - for (i = 0; i < 0x10; i++) - edat_log.notice("%02X", key[i]); + edat_log.notice("DECRYPTION KEY: %s", std::bit_cast>(key)); } input->seek(0); - if (check_data(key, &EDAT, &NPD, input, verbose)) + if (check_data(key._bytes, &EDAT, &NPD, input, verbose)) { edat_log.error("EDAT: Data parsing failed!"); return 1; } input->seek(0); - if (decrypt_data(input, output, &EDAT, &NPD, key, verbose)) + if (decrypt_data(input, output, &EDAT, &NPD, key._bytes, verbose)) { edat_log.error("EDAT: Data decryption failed!"); return 1; @@ -757,19 +740,19 @@ bool extract_all_data(const fs::file* input, const fs::file* output, const char* return 0; } -std::array GetEdatRifKeyFromRapFile(const fs::file& rap_file) +v128 GetEdatRifKeyFromRapFile(const fs::file& rap_file) { - std::array rapkey{ 0 }; - std::array rifkey{ 0 }; + v128 rapkey{}; + v128 rifkey{}; - rap_file.read>(rapkey); + rap_file.read(rapkey); - rap_to_rif(rapkey.data(), rifkey.data()); + rap_to_rif(rapkey._bytes, rifkey._bytes); return rifkey; } -bool VerifyEDATHeaderWithKLicense(const fs::file& input, const std::string& input_file_name, const std::array& custom_klic, std::string* contentID) +bool VerifyEDATHeaderWithKLicense(const fs::file& input, const std::string& input_file_name, const u8* custom_klic, std::string* contentID) { // Setup NPD and EDAT/SDAT structs. NPD_HEADER NPD; @@ -794,7 +777,7 @@ bool VerifyEDATHeaderWithKLicense(const fs::file& input, const std::string& inpu // Perform header validation (EDAT only). char real_file_name[MAX_PATH]; extract_file_name(input_file_name.c_str(), real_file_name); - if (!validate_npd_hashes(real_file_name, custom_klic.data(), &NPD, false)) + if (!validate_npd_hashes(real_file_name, custom_klic, &NPD, false)) { // Ignore header validation in DEBUG data. if ((EDAT.flags & EDAT_DEBUG_DATA_FLAG) != EDAT_DEBUG_DATA_FLAG) @@ -815,8 +798,8 @@ fs::file DecryptEDAT(const fs::file& input, const std::string& input_file_name, input.seek(0); // Set keys (RIF and DEVKLIC). - std::array rifKey{ 0 }; - unsigned char devklic[0x10] = { 0 }; + v128 rifKey{}; + v128 devklic{}; // Select the EDAT key mode. switch (mode) @@ -824,30 +807,30 @@ fs::file DecryptEDAT(const fs::file& input, const std::string& input_file_name, case 0: break; case 1: - memcpy(devklic, NP_KLIC_FREE, 0x10); + memcpy(&devklic, NP_KLIC_FREE, 0x10); break; case 2: - memcpy(devklic, NP_OMAC_KEY_2, 0x10); + memcpy(&devklic, NP_OMAC_KEY_2, 0x10); break; case 3: - memcpy(devklic, NP_OMAC_KEY_3, 0x10); + memcpy(&devklic, NP_OMAC_KEY_3, 0x10); break; case 4: - memcpy(devklic, NP_KLIC_KEY, 0x10); + memcpy(&devklic, NP_KLIC_KEY, 0x10); break; case 5: - memcpy(devklic, NP_PSX_KEY, 0x10); + memcpy(&devklic, NP_PSX_KEY, 0x10); break; case 6: - memcpy(devklic, NP_PSP_KEY_1, 0x10); + memcpy(&devklic, NP_PSP_KEY_1, 0x10); break; case 7: - memcpy(devklic, NP_PSP_KEY_2, 0x10); + memcpy(&devklic, NP_PSP_KEY_2, 0x10); break; case 8: { if (custom_klic != NULL) - memcpy(devklic, custom_klic, 0x10); + memcpy(&devklic, custom_klic, 0x10); else { edat_log.error("EDAT: Invalid custom klic!"); @@ -870,7 +853,7 @@ fs::file DecryptEDAT(const fs::file& input, const std::string& input_file_name, // Delete the bad output file if any errors arise. fs::file output = fs::make_stream>(); - if (extract_all_data(&input, &output, input_file_name.c_str(), devklic, rifKey.data(), verbose)) + if (extract_all_data(&input, &output, input_file_name.c_str(), devklic._bytes, rifKey._bytes, verbose)) { output.release(); return fs::file{}; @@ -896,12 +879,12 @@ bool EDATADecrypter::ReadHeader() if ((edatHeader.flags & SDAT_FLAG) == SDAT_FLAG) { // Generate SDAT key. - xor_key(dec_key.data(), npdHeader.dev_hash, SDAT_KEY); + dec_key = std::bit_cast(npdHeader.dev_hash) ^ std::bit_cast(SDAT_KEY); } else { // verify key - if (validate_dev_klic(dev_key.data(), &npdHeader) == 0) + if (validate_dev_klic(dev_key._bytes, &npdHeader) == 0) { edat_log.error("EDAT: Failed validating klic"); return false; @@ -914,7 +897,7 @@ bool EDATADecrypter::ReadHeader() { dec_key = std::move(rif_key); - if (dec_key == std::array{0}) + if (dec_key == v128{}) { edat_log.warning("EDAT: Empty Dec key!"); } @@ -931,13 +914,13 @@ bool EDATADecrypter::ReadHeader() // k the ecdsa_verify function in this check_data function takes a ridiculous amount of time // like it slows down load time by a factor of x20, at least, so its ignored for now - /*if (check_data(dec_key.data(), &edatHeader, &npdHeader, &sdata_file, false)) + /*if (check_data(dec_key._bytes, &edatHeader, &npdHeader, &sdata_file, false)) { return false; }*/ file_size = edatHeader.file_size; - total_blocks = static_cast((edatHeader.file_size + edatHeader.block_size - 1) / edatHeader.block_size); + total_blocks = ::aligned_div(edatHeader.file_size, edatHeader.block_size); return true; } @@ -950,7 +933,7 @@ u64 EDATADecrypter::ReadData(u64 pos, u8* data, u64 size) // now we need to offset things to account for the actual 'range' requested const u64 startOffset = pos % edatHeader.block_size; - const u32 num_blocks = static_cast(std::ceil((startOffset + size) / (0. + edatHeader.block_size))); + const u32 num_blocks = static_cast(::aligned_div(startOffset + size, edatHeader.block_size)); const u64 bufSize = num_blocks*edatHeader.block_size; if (data_buf_size < (bufSize)) { @@ -965,7 +948,7 @@ u64 EDATADecrypter::ReadData(u64 pos, u8* data, u64 size) for (u32 i = starting_block; i < ending_block; ++i) { edata_file.seek(0); - u64 res = decrypt_block(&edata_file, &data_buf[writeOffset], &edatHeader, &npdHeader, dec_key.data(), i, total_blocks, edatHeader.file_size); + u64 res = decrypt_block(&edata_file, &data_buf[writeOffset], &edatHeader, &npdHeader, dec_key._bytes, i, total_blocks, edatHeader.file_size); if (res == umax) { edat_log.error("Error Decrypting data"); diff --git a/rpcs3/Crypto/unedat.h b/rpcs3/Crypto/unedat.h index 94788e497f..cb98db0c69 100644 --- a/rpcs3/Crypto/unedat.h +++ b/rpcs3/Crypto/unedat.h @@ -4,6 +4,7 @@ #include "utils.h" +#include "Utilities/BEType.h" #include "Utilities/File.h" constexpr u32 SDAT_FLAG = 0x01000000; @@ -16,8 +17,8 @@ constexpr u32 EDAT_DEBUG_DATA_FLAG = 0x80000000; struct loaded_npdrm_keys { - std::array devKlic{}; - std::array rifKey{}; + atomic_t devKlic{}; + atomic_t rifKey{}; atomic_t npdrm_fds{0}; }; @@ -45,9 +46,9 @@ 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, std::string* contentID); +extern bool VerifyEDATHeaderWithKLicense(const fs::file& input, const std::string& input_file_name, const u8* custom_klic, std::string* contentID); -extern std::array GetEdatRifKeyFromRapFile(const fs::file& rap_file); +v128 GetEdatRifKeyFromRapFile(const fs::file& rap_file); struct EDATADecrypter final : fs::file_base { @@ -64,17 +65,17 @@ struct EDATADecrypter final : fs::file_base std::unique_ptr data_buf; u64 data_buf_size{0}; - std::array dec_key{}; + v128 dec_key{}; // edat usage - std::array rif_key{}; - std::array dev_key{}; + v128 rif_key{}; + v128 dev_key{}; public: // SdataByFd usage EDATADecrypter(fs::file&& input) : edata_file(std::move(input)) {} // Edat usage - EDATADecrypter(fs::file&& input, const std::array& dev_key, const std::array& rif_key) + EDATADecrypter(fs::file&& input, const v128& dev_key, const v128& rif_key) : edata_file(std::move(input)), rif_key(rif_key), dev_key(dev_key) {} ~EDATADecrypter() override {} diff --git a/rpcs3/Crypto/unself.cpp b/rpcs3/Crypto/unself.cpp index 7523e87c03..0c6ae80bad 100644 --- a/rpcs3/Crypto/unself.cpp +++ b/rpcs3/Crypto/unself.cpp @@ -3,6 +3,7 @@ #include "sha1.h" #include "utils.h" #include "unself.h" +#include "Utilities/BEType.h" #include "Emu/VFS.h" #include "Emu/System.h" @@ -1483,9 +1484,7 @@ bool verify_npdrm_self_headers(const fs::file& self, u8* klic_key) return true; } -std::array get_default_self_klic() +v128 get_default_self_klic() { - std::array key; - std::copy(std::begin(NP_KLIC_FREE), std::end(NP_KLIC_FREE), std::begin(key)); - return key; + return std::bit_cast(NP_KLIC_FREE); } diff --git a/rpcs3/Crypto/unself.h b/rpcs3/Crypto/unself.h index 5826cf21ca..d201a04820 100644 --- a/rpcs3/Crypto/unself.h +++ b/rpcs3/Crypto/unself.h @@ -508,4 +508,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); -std::array get_default_self_klic(); + +union v128; +v128 get_default_self_klic(); diff --git a/rpcs3/Crypto/utils.cpp b/rpcs3/Crypto/utils.cpp index 6d2db2792e..4694eb73c6 100644 --- a/rpcs3/Crypto/utils.cpp +++ b/rpcs3/Crypto/utils.cpp @@ -15,14 +15,6 @@ // Auxiliary functions (endian swap, xor). -void xor_key(unsigned char *dest, const u8* src1, const u8* src2) -{ - for(int i = 0; i < 0x10; i++) - { - dest[i] = src1[i] ^ src2[i]; - } -} - // Hex string conversion auxiliary functions. u64 hex_to_u64(const char* hex_str) { @@ -67,22 +59,6 @@ void hex_to_bytes(unsigned char* data, const char* hex_str, unsigned int str_len } } -bool is_hex(const char* hex_str, unsigned int str_length) -{ - static const char hex_chars[] = "0123456789abcdefABCDEF"; - - if (hex_str == NULL) - return false; - - unsigned int i; - for (i = 0; i < str_length; i++) - { - if (strchr(hex_chars, hex_str[i]) == 0) - return false; - } - - return true; -} // Crypto functions (AES128-CBC, AES128-ECB, SHA1-HMAC and AES-CMAC). void aescbc128_decrypt(unsigned char *key, unsigned char *iv, unsigned char *in, unsigned char *out, int len) diff --git a/rpcs3/Crypto/utils.h b/rpcs3/Crypto/utils.h index c86d1c8b48..80a0d69d63 100644 --- a/rpcs3/Crypto/utils.h +++ b/rpcs3/Crypto/utils.h @@ -42,19 +42,11 @@ inline u64 swap64(u64 i) #endif } -void xor_key(unsigned char *dest, const u8* src1, const u8* src2); -inline void xor_key_sse(u8* dest, const u8* src1, const u8* src2) -{ - _mm_storeu_si128(reinterpret_cast<__m128i*>(dest), - _mm_xor_si128(_mm_loadu_si128(reinterpret_cast(src1)), _mm_loadu_si128(reinterpret_cast(src2)))); -} - char* extract_file_name(const char* file_path, char real_file_name[MAX_PATH]); // Hex string conversion auxiliary functions. u64 hex_to_u64(const char* hex_str); void hex_to_bytes(unsigned char *data, const char *hex_str, unsigned int str_length); -bool is_hex(const char* hex_str, unsigned int str_length); // Crypto functions (AES128-CBC, AES128-ECB, SHA1-HMAC and AES-CMAC). void aescbc128_decrypt(unsigned char *key, unsigned char *iv, unsigned char *in, unsigned char *out, int len); diff --git a/rpcs3/Emu/Cell/Modules/sceNp.cpp b/rpcs3/Emu/Cell/Modules/sceNp.cpp index 56d504db2f..6d7298d54a 100644 --- a/rpcs3/Emu/Cell/Modules/sceNp.cpp +++ b/rpcs3/Emu/Cell/Modules/sceNp.cpp @@ -428,17 +428,17 @@ error_code sceNpTerm() error_code npDrmIsAvailable(vm::cptr k_licensee_addr, vm::cptr drm_path) { - std::array k_licensee{}; + v128 k_licensee{}; if (k_licensee_addr) { - std::copy_n(k_licensee_addr.get_ptr(), k_licensee.size(), k_licensee.begin()); - sceNp.notice("npDrmIsAvailable(): KLicense key %s", *reinterpret_cast*>(k_licensee.data())); + std::memcpy(&k_licensee, k_licensee_addr.get_ptr(), sizeof(k_licensee)); + sceNp.notice("npDrmIsAvailable(): KLicense key %s", std::bit_cast>(k_licensee)); } if (Emu.GetCat() == "PE") { - std::copy_n(NP_PSP_KEY_2, std::size(NP_PSP_KEY_2), k_licensee.begin()); + std::memcpy(&k_licensee, NP_PSP_KEY_2, sizeof(k_licensee)); sceNp.success("npDrmIsAvailable(): PSP remaster KLicense key applied."); } @@ -469,9 +469,9 @@ error_code npDrmIsAvailable(vm::cptr k_licensee_addr, vm::cptr drm_pat if (!k_licensee_addr) k_licensee = get_default_self_klic(); - if (verify_npdrm_self_headers(enc_file, k_licensee.data())) + if (verify_npdrm_self_headers(enc_file, k_licensee._bytes)) { - npdrmkeys->devKlic = std::move(k_licensee); + npdrmkeys->devKlic = k_licensee; } else { @@ -485,10 +485,10 @@ error_code npDrmIsAvailable(vm::cptr k_licensee_addr, vm::cptr drm_pat std::string contentID; - if (VerifyEDATHeaderWithKLicense(enc_file, enc_drm_path_local, k_licensee, &contentID)) + if (VerifyEDATHeaderWithKLicense(enc_file, enc_drm_path_local, k_licensee._bytes, &contentID)) { const std::string rap_file = rap_dir_path + contentID + ".rap"; - npdrmkeys->devKlic = std::move(k_licensee); + npdrmkeys->devKlic = k_licensee; if (fs::is_file(vfs::get(rap_file))) npdrmkeys->rifKey = GetEdatRifKeyFromRapFile(fs::file{vfs::get(rap_file)}); diff --git a/rpcs3/Emu/Cell/lv2/sys_fs.cpp b/rpcs3/Emu/Cell/lv2/sys_fs.cpp index 5dff954841..807505dafb 100644 --- a/rpcs3/Emu/Cell/lv2/sys_fs.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_fs.cpp @@ -437,7 +437,7 @@ lv2_file::open_result_t lv2_file::open(std::string_view vpath, s32 flags, s32 mo if (magic == "NPD\0"_u32) { auto edatkeys = g_fxo->get(); - auto sdata_file = std::make_unique(std::move(file), edatkeys->devKlic, edatkeys->rifKey); + auto sdata_file = std::make_unique(std::move(file), edatkeys->devKlic.load(), edatkeys->rifKey.load()); if (!sdata_file->ReadHeader()) { return {CELL_EFSSPECIFIC, path}; diff --git a/rpcs3/Emu/Cell/lv2/sys_overlay.cpp b/rpcs3/Emu/Cell/lv2/sys_overlay.cpp index b285d3a720..d3fb31b148 100644 --- a/rpcs3/Emu/Cell/lv2/sys_overlay.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_overlay.cpp @@ -31,7 +31,7 @@ static error_code overlay_load_module(vm::ptr ovlmid, const std::string& vp src = std::move(lv2_file); } - const ppu_exec_object obj = decrypt_self(std::move(src), g_fxo->get()->devKlic.data()); + const ppu_exec_object obj = decrypt_self(std::move(src), g_fxo->get()->devKlic.load()._bytes); if (obj != elf_error::ok) { diff --git a/rpcs3/Emu/Cell/lv2/sys_process.cpp b/rpcs3/Emu/Cell/lv2/sys_process.cpp index 19695a7d1f..964d5b0165 100644 --- a/rpcs3/Emu/Cell/lv2/sys_process.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_process.cpp @@ -341,7 +341,7 @@ void _sys_process_exit2(ppu_thread& ppu, s32 status, vm::ptr ar vm::temporary_unlock(ppu); - Emu.CallAfter([path = std::move(path), argv = std::move(argv), envp = std::move(envp), data = std::move(data), disc = std::move(disc), hdd1 = std::move(hdd1), klic = g_fxo->get()->devKlic]() mutable + Emu.CallAfter([path = std::move(path), argv = std::move(argv), envp = std::move(envp), data = std::move(data), disc = std::move(disc), hdd1 = std::move(hdd1), klic = g_fxo->get()->devKlic.load()]() mutable { sys_process.success("Process finished -> %s", argv[0]); Emu.SetForceBoot(true); @@ -352,9 +352,10 @@ void _sys_process_exit2(ppu_thread& ppu, s32 status, vm::ptr ar Emu.disc = std::move(disc); Emu.hdd1 = std::move(hdd1); - if (klic != std::array{}) + if (klic != v128{}) { - Emu.klic.assign(klic.begin(), klic.end()); + // TODO: Use std::optional + Emu.klic.assign(std::begin(klic._bytes), std::end(klic._bytes)); } Emu.SetForceBoot(true); diff --git a/rpcs3/Emu/Cell/lv2/sys_prx.cpp b/rpcs3/Emu/Cell/lv2/sys_prx.cpp index 6e92c3d0e6..1c5090db7a 100644 --- a/rpcs3/Emu/Cell/lv2/sys_prx.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_prx.cpp @@ -166,7 +166,7 @@ static error_code prx_load_module(const std::string& vpath, u64 flags, vm::ptrget()->devKlic.data()); + const ppu_prx_object obj = decrypt_self(std::move(src), g_fxo->get()->devKlic.load()._bytes); if (obj != elf_error::ok) { diff --git a/rpcs3/Emu/Cell/lv2/sys_spu.cpp b/rpcs3/Emu/Cell/lv2/sys_spu.cpp index a5cd6a6dcd..5f88a36b94 100644 --- a/rpcs3/Emu/Cell/lv2/sys_spu.cpp +++ b/rpcs3/Emu/Cell/lv2/sys_spu.cpp @@ -249,7 +249,7 @@ error_code sys_spu_image_open(ppu_thread& ppu, vm::ptr img, vm::c return {fs_error, path}; } - const fs::file elf_file = decrypt_self(std::move(file), g_fxo->get()->devKlic.data()); + const fs::file elf_file = decrypt_self(std::move(file), g_fxo->get()->devKlic.load()._bytes); if (!elf_file) {