mirror of
https://github.com/AlexAltea/orbital.git
synced 2024-06-16 03:07:58 -04:00
software: Fix decryption/decompression of blocked PUP segments
This commit is contained in:
parent
0b91ca52c8
commit
8b68b7f0fe
|
@ -21,6 +21,8 @@ find_package(SDL2 REQUIRED)
|
|||
find_package(imgui REQUIRED)
|
||||
find_package(RapidJSON CONFIG REQUIRED)
|
||||
find_package(Vulkan REQUIRED)
|
||||
find_package(zlib REQUIRED)
|
||||
find_library(BOTAN_LIBRARIES NAMES BOTAN2 botan2 BOTAN botan)
|
||||
|
||||
# Sources
|
||||
macro(ORBITAL_FILES_APPEND)
|
||||
|
@ -51,7 +53,7 @@ target_include_directories(orbital PUBLIC ${ORBITAL_DIR_EXTERNALS})
|
|||
target_include_directories(orbital PUBLIC ${ORBITAL_DIR_SOURCES})
|
||||
target_include_directories(orbital PUBLIC ${RAPIDJSON_INCLUDE_DIRS})
|
||||
target_include_directories(orbital PUBLIC ${Vulkan_INCLUDE_DIRS})
|
||||
target_link_libraries(orbital PRIVATE SDL2::SDL2 imgui::imgui ${Vulkan_LIBRARIES})
|
||||
target_link_libraries(orbital PRIVATE SDL2::SDL2 imgui::imgui ZLIB::ZLIB ${Vulkan_LIBRARIES} ${BOTAN_LIBRARIES})
|
||||
include(${ORBITAL_DIR_EXTERNALS}/core.cmake)
|
||||
|
||||
# Properties
|
||||
|
|
|
@ -10,8 +10,7 @@
|
|||
|
||||
#include "crypto.h"
|
||||
|
||||
// Global
|
||||
Crypto crypto;
|
||||
#include <stdexcept>
|
||||
|
||||
U64 CryptoStream::read(U64 size, void* buffer) {
|
||||
return 0;
|
||||
|
@ -35,7 +34,23 @@ void Crypto::decrypt(void* buf, size_t len, Key key) {
|
|||
|
||||
void Crypto::decrypt(const void* input_buf, size_t input_len,
|
||||
void* output_buf, size_t output_len, Key key) {
|
||||
// TODO
|
||||
const char* algo;
|
||||
switch (key.type) {
|
||||
case Key::AES_128_EBC:
|
||||
algo = "AES-128/EBC";
|
||||
break;
|
||||
case Key::AES_128_CBC:
|
||||
algo = "AES-128/CBC/CTS";
|
||||
break;
|
||||
default:
|
||||
throw std::invalid_argument("Unrecognized key type");
|
||||
}
|
||||
auto cipher = Botan::get_cipher(algo, key.key, key.iv, Botan::Cipher_Dir::DECRYPTION);
|
||||
Botan::Pipe pipe(cipher);
|
||||
pipe.start_msg();
|
||||
pipe.write((const uint8_t*)input_buf, input_len);
|
||||
pipe.end_msg();
|
||||
pipe.read((uint8_t*)output_buf, output_len);
|
||||
}
|
||||
|
||||
Buffer Crypto::decrypt(const Buffer& buffer, Key key) {
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
|
||||
#include <core.h>
|
||||
|
||||
#include <botan/botan.h>
|
||||
|
||||
#include <filesystem>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
@ -24,12 +26,16 @@ struct Key {
|
|||
AES_128_CBC,
|
||||
} type;
|
||||
|
||||
union {
|
||||
struct {
|
||||
U08 key[32];
|
||||
U08 iv[32];
|
||||
} aes;
|
||||
};
|
||||
Botan::SymmetricKey key;
|
||||
Botan::InitializationVector iv;
|
||||
|
||||
Key() : type(NONE) {}
|
||||
Key(Type type, const void* key_buf, size_t key_len, const void* iv_buf, size_t iv_len)
|
||||
: type(type), key((const U8*)key_buf, key_len), iv((const U8*)iv_buf, iv_len) {
|
||||
}
|
||||
Key(Type type, std::string_view key, std::string_view iv)
|
||||
: type(type), key(std::string(key)), iv(std::string(iv)) {
|
||||
}
|
||||
};
|
||||
|
||||
class CryptoStream : public Stream {
|
||||
|
|
|
@ -18,29 +18,10 @@
|
|||
|
||||
static Crypto g_ps4Crypto;
|
||||
|
||||
static uint8_t parseHex(char input) {
|
||||
if (input >= '0' && input <= '9')
|
||||
return input - '0';
|
||||
if (input >= 'A' && input <= 'F')
|
||||
return input - 'A' + 10;
|
||||
if (input >= 'a' && input <= 'f')
|
||||
return input - 'a' + 10;
|
||||
throw std::invalid_argument("Invalid input string");
|
||||
}
|
||||
|
||||
static void parseHexBytes(std::string_view hex, uint8_t* buf, size_t len) {
|
||||
for (size_t i = 0; i < hex.size() && i < 2*len; i += 2) {
|
||||
buf[i >> 1] = parseHex(hex[i]) * 16 + parseHex(hex[i + 1]);
|
||||
}
|
||||
}
|
||||
|
||||
static Key parseAesKey(Key::Type type, const rapidjson::Value& value) {
|
||||
Key k = { type };
|
||||
parseHexBytes(value["aes_key"].GetString(),
|
||||
k.aes.key, sizeof(k.aes.key));
|
||||
parseHexBytes(value["aes_iv"].GetString(),
|
||||
k.aes.iv, sizeof(k.aes.iv));
|
||||
return k;
|
||||
auto key = value["aes_key"].GetString();
|
||||
auto iv = value["aes_iv"].GetString();
|
||||
return Key(type, key, iv);
|
||||
}
|
||||
|
||||
const Crypto& ps4Crypto() {
|
||||
|
@ -57,6 +38,13 @@ const Crypto& ps4Crypto() {
|
|||
// Add individual keys
|
||||
g_ps4Crypto.add("pup.hdr",
|
||||
parseAesKey(Key::AES_128_CBC, document["pup"]["hdr"]));
|
||||
g_ps4Crypto.add("pup.root_key",
|
||||
parseAesKey(Key::AES_128_CBC, document["pup"]["root_key"]));
|
||||
|
||||
for (const auto& m : document["self"]["80010002"].GetObject()) {
|
||||
std::string name = "self.80010002.";
|
||||
g_ps4Crypto.add(name + m.name.GetString(), parseAesKey(Key::AES_128_CBC, m.value));
|
||||
}
|
||||
|
||||
return g_ps4Crypto;
|
||||
}
|
||||
|
|
|
@ -137,14 +137,14 @@ Buffer PupParser::get_blocked(U64 index) {
|
|||
// TODO: throw std::runtime_error("Unimplemented");
|
||||
}
|
||||
if (entry.is_encrypted()) {
|
||||
Key key(Key::AES_128_CBC, meta.data_key, 16, meta.data_iv, 16);
|
||||
crypto.decrypt(block.data(), block.size(), key);
|
||||
decrypt(block, meta);
|
||||
}
|
||||
segment.resize(segment.size() + cur_size);
|
||||
U08* dest = segment.data() + segment.size() - cur_size;
|
||||
if (entry.is_compressed()) {
|
||||
U08* dest = &segment[segment.size() - cur_size];
|
||||
if (entry.is_compressed() && cur_size != cur_zsize) {
|
||||
unsigned long cur_usize = cur_size;
|
||||
uncompress(dest, &cur_usize, block.data(), cur_zsize);
|
||||
int zerr = uncompress(dest, &cur_usize, block.data(), cur_zsize);
|
||||
assert(zerr == 0);
|
||||
} else {
|
||||
memcpy(dest, block.data(), block.size());
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue