fix for trophy decryption

This commit is contained in:
psucien 2025-01-01 17:18:25 +01:00
parent a76e8f0211
commit 0cc5808bf4
5 changed files with 24 additions and 23 deletions

View File

@ -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::vector<u8> trophyKey;
// Gui
std::vector<std::filesystem::path> settings_install_dirs = {};
@ -92,11 +92,11 @@ std::string emulator_language = "en";
// Language
u32 m_language = 1; // english
std::string getTrophyKey() {
std::vector<u8> getTrophyKey() {
return trophyKey;
}
void setTrophyKey(std::string key) {
void setTrophyKey(std::vector<u8> key) {
trophyKey = key;
}
@ -664,7 +664,7 @@ void load(const std::filesystem::path& path) {
if (data.contains("Keys")) {
const toml::value& keys = data.at("Keys");
trophyKey = toml::find_or<std::string>(keys, "TrophyKey", "");
trophyKey = toml::find<std::vector<u8>>(keys, "TrophyKey");
}
}

View File

@ -15,8 +15,8 @@ void load(const std::filesystem::path& path);
void save(const std::filesystem::path& path);
void saveMainWindow(const std::filesystem::path& path);
std::string getTrophyKey();
void setTrophyKey(std::string key);
std::vector<u8> getTrophyKey();
void setTrophyKey(std::vector<u8> key);
bool isNeoMode();
bool isFullscreenMode();

View File

@ -2,7 +2,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#include <array>
#include <common/config.h>
#include "crypto.h"
CryptoPP::RSA::PrivateKey Crypto::key_pkg_derived_key3_keyset_init() {
@ -138,29 +138,19 @@ void Crypto::aesCbcCfb128DecryptEntry(std::span<const CryptoPP::byte, 32> 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<CryptoPP::byte, 16> NPcommID,
void Crypto::decryptEFSM(std::span<CryptoPP::byte, 16> trophyKey,
std::span<CryptoPP::byte, 16> NPcommID,
std::span<CryptoPP::byte, 16> efsmIv, std::span<CryptoPP::byte> ciphertext,
std::span<CryptoPP::byte> decrypted) {
std::vector<CryptoPP::byte> TrophyIV = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
// step 1: Encrypt NPcommID
CryptoPP::CBC_Mode<CryptoPP::AES>::Encryption encrypt;
const char* TrophyKeyget = Config::getTrophyKey().c_str();
std::vector<CryptoPP::byte> TrophyKey;
hexToBytes(TrophyKeyget, TrophyKey.data());
std::vector<CryptoPP::byte> trophyIv(16, 0);
std::vector<CryptoPP::byte> 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<CryptoPP::AES>::Decryption decrypt;

View File

@ -32,7 +32,8 @@ public:
void aesCbcCfb128DecryptEntry(std::span<const CryptoPP::byte, 32> ivkey,
std::span<CryptoPP::byte> ciphertext,
std::span<CryptoPP::byte> decrypted);
void decryptEFSM(std::span<CryptoPP::byte, 16>, std::span<CryptoPP::byte, 16> efsmIv,
void decryptEFSM(std::span<CryptoPP::byte, 16> trophyKey,
std::span<CryptoPP::byte, 16> NPcommID, std::span<CryptoPP::byte, 16> efsmIv,
std::span<CryptoPP::byte> ciphertext, std::span<CryptoPP::byte> decrypted);
void PfsGenCryptoKey(std::span<const CryptoPP::byte, 32> ekpfs,
std::span<const CryptoPP::byte, 16> seed,

View File

@ -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"
@ -39,6 +40,15 @@ bool TRP::Extract(const std::filesystem::path& trophyPath, const std::string tit
LOG_CRITICAL(Common_Filesystem, "Game sce_sys directory doesn't exist");
return false;
}
const auto user_key = Config::getTrophyKey();
if (user_key.size() != 16) {
LOG_CRITICAL(Common_Filesystem, "Trophy decryption key is not specified");
return false;
}
const std::span<CryptoPP::byte, 16> key{(CryptoPP::byte*)user_key.data(), 16};
for (int index = 0; const auto& it : std::filesystem::directory_iterator(gameSysDir)) {
if (it.is_regular_file()) {
GetNPcommID(trophyPath, index);
@ -97,7 +107,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(key, np_comm_id, esfmIv, ESFM, XML); // decrypt
removePadding(XML);
std::string xml_name = entry.entry_name;
size_t pos = xml_name.find("ESFM");