diff --git a/src/common/config.cpp b/src/common/config.cpp index 4fce7d97..246644e2 100644 --- a/src/common/config.cpp +++ b/src/common/config.cpp @@ -67,7 +67,7 @@ static int cursorHideTimeout = 5; // 5 seconds (default) static bool separateupdatefolder = false; static bool compatibilityData = false; static bool checkCompatibilityOnStartup = false; -static std::string trophyKey = ""; +static std::string trophyKey; // Gui std::vector settings_install_dirs = {}; diff --git a/src/core/crypto/crypto.cpp b/src/core/crypto/crypto.cpp index 472d284f..4020edfd 100644 --- a/src/core/crypto/crypto.cpp +++ b/src/core/crypto/crypto.cpp @@ -2,7 +2,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include -#include + #include "crypto.h" CryptoPP::RSA::PrivateKey Crypto::key_pkg_derived_key3_keyset_init() { @@ -138,29 +138,19 @@ void Crypto::aesCbcCfb128DecryptEntry(std::span ivkey, } } -static void hexToBytes(const char* hex, unsigned char* dst) { - for (size_t i = 0; hex[i] != 0; i++) { - const unsigned char value = (hex[i] < 0x3A) ? (hex[i] - 0x30) : (hex[i] - 0x37); - dst[i / 2] |= ((i % 2) == 0) ? (value << 4) : (value); - } -} - -void Crypto::decryptEFSM(std::span NPcommID, +void Crypto::decryptEFSM(std::span trophyKey, + std::span NPcommID, std::span efsmIv, std::span ciphertext, std::span decrypted) { - std::vector TrophyIV = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // step 1: Encrypt NPcommID CryptoPP::CBC_Mode::Encryption encrypt; - const char* TrophyKeyget = Config::getTrophyKey().c_str(); - std::vector TrophyKey; - hexToBytes(TrophyKeyget, TrophyKey.data()); - + std::vector trophyIv(16, 0); std::vector trpKey(16); + encrypt.SetKeyWithIV(trophyKey.data(), trophyKey.size(), trophyIv.data()); encrypt.ProcessData(trpKey.data(), NPcommID.data(), 16); - encrypt.SetKeyWithIV(TrophyKey.data(), TrophyKey.size(), TrophyIV.data()); // step 2: decrypt efsm. CryptoPP::CBC_Mode::Decryption decrypt; diff --git a/src/core/crypto/crypto.h b/src/core/crypto/crypto.h index 83249bd7..b5d8104b 100644 --- a/src/core/crypto/crypto.h +++ b/src/core/crypto/crypto.h @@ -32,7 +32,8 @@ public: void aesCbcCfb128DecryptEntry(std::span ivkey, std::span ciphertext, std::span decrypted); - void decryptEFSM(std::span, std::span efsmIv, + void decryptEFSM(std::span trophyKey, + std::span NPcommID, std::span efsmIv, std::span ciphertext, std::span decrypted); void PfsGenCryptoKey(std::span ekpfs, std::span seed, diff --git a/src/core/file_format/trp.cpp b/src/core/file_format/trp.cpp index 2ca88c77..d25c93c3 100644 --- a/src/core/file_format/trp.cpp +++ b/src/core/file_format/trp.cpp @@ -1,6 +1,7 @@ // SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later +#include "common/config.h" #include "common/logging/log.h" #include "common/path_util.h" #include "trp.h" @@ -33,12 +34,29 @@ static void removePadding(std::vector& vec) { } } +static void hexToBytes(const char* hex, unsigned char* dst) { + for (size_t i = 0; hex[i] != 0; i++) { + const unsigned char value = (hex[i] < 0x3A) ? (hex[i] - 0x30) : (hex[i] - 0x37); + dst[i / 2] |= ((i % 2) == 0) ? (value << 4) : (value); + } +} + bool TRP::Extract(const std::filesystem::path& trophyPath, const std::string titleId) { std::filesystem::path gameSysDir = trophyPath / "sce_sys/trophy/"; if (!std::filesystem::exists(gameSysDir)) { LOG_CRITICAL(Common_Filesystem, "Game sce_sys directory doesn't exist"); return false; } + + const auto user_key_str = Config::getTrophyKey(); + if (user_key_str.size() != 32) { + LOG_CRITICAL(Common_Filesystem, "Trophy decryption key is not specified"); + return false; + } + + std::array user_key{}; + hexToBytes(user_key_str.c_str(), user_key.data()); + for (int index = 0; const auto& it : std::filesystem::directory_iterator(gameSysDir)) { if (it.is_regular_file()) { GetNPcommID(trophyPath, index); @@ -97,7 +115,7 @@ bool TRP::Extract(const std::filesystem::path& trophyPath, const std::string tit return false; } file.Read(ESFM); - crypto.decryptEFSM(np_comm_id, esfmIv, ESFM, XML); // decrypt + crypto.decryptEFSM(user_key, np_comm_id, esfmIv, ESFM, XML); // decrypt removePadding(XML); std::string xml_name = entry.entry_name; size_t pos = xml_name.find("ESFM");