Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added .DS_Store
Binary file not shown.
4 changes: 4 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
v1.93
1. (#125) Added support for 3.74 with existing h-encore^2
2. (#108) Project builds on Apple M1 now

v1.92
1. Added support for 3.73 with existing h-encore^2

Expand Down
14 changes: 9 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Final h-encore

Push the h-encore exploit for PS VITA andPS TV through a Windows, macOS or Linux GUI.
Push the h-encore exploit for PS VITA and PS TV through a Windows, macOS or Linux GUI.

## Credits

Expand Down Expand Up @@ -29,15 +29,19 @@ Download a pre-built executable binary below and follow instructions. Supported
- `sudo zypper install finalhe`
3. Run "FinalHE"
- in your terminal type `FinalHE`
- For Arch Linux
1. Install the [`finalhe-git`](https://aur.archlinux.org/packages/finalhe-git/) package from AUR:
- `yay -S finalhe-git`
2. Run `finalhe` in your terminal

## Build from source

### Prerequisites

1. macOS: install [brew](https://brew.sh), install libusb, pkg-config & qt through brew (`brew install libusb pkg-config qt`)
2. Linux:
1. macOS: install [brew](https://brew.sh), build tools (`xcode-select --install`) then install dyld, libusb, pkg-config & qt5 through brew (`brew install dyld-headers libusb pkg-config qt5`)
1. Linux:
- Debian/Ubuntu: install build-essential, libxml2-dev, libusb-dev, libusb-1.0-0-dev, zlib-dev or zlib1g-dev, qtbase5-dev, qttools5, cmake(if use cmake to build)
- Fedora/CentOS: group install "Development Tools", install libxml2-devel, libusb-devel, zlib-devel, qt5-qtbase-devel, qt5-qtbase, cmake3(if use cmake to build)
- Fedora/CentOS: group install "Development Tools", install libxml2-devel, libusb-devel, zlib-devel, qt5-qtbase-devel, qt5-qtbase, qt5-linguist, cmake3(if use cmake to build)
- openSUSE: install cmake >= 11.0, gcc-c++, zlib-devel, libxml2-devel, libQt5Widgets-devel, libQt5Network-devel, libqt5-linguist-devel, libusb-compat-devel
- Arch: install base-devel, libxml2, libusb, zlib, qt5, cmake (if using cmake to build)

Expand All @@ -46,7 +50,7 @@ Download a pre-built executable binary below and follow instructions. Supported
You can choose either `qmake` or `cmake` to build

- cmake: run `cmake` to generate Makefile for compiling
- macOS: it cannot produce app bundle, and you need to specify `CMAKE_PREFIX_PATH` if Qt is not installed in default location: `cmake -DCMAKE_PREFIX_PATH=<Path of Qt Root> <Path of Project Root>`
- macOS: it cannot produce app bundle, and you need to specify `CMAKE_PREFIX_PATH` if Qt is not installed in default location: `cmake -DCMAKE_PREFIX_PATH=<Path of Qt Root> <Path of Project Root>`. If you have installed qt5 with brew, and are on project root directory, you can run with `cmake -DCMAKE_PREFIX_PATH=/usr/local/opt/qt@5 .`. Then run `make` and you can open it by double clicking at `src/FinalHE`.
- qmake: run `qmake` to generate Makefile for compiling, run `make lcopy` in `src` folder to compile translations and copy them to binary folder

## Contribute translations
Expand Down
Binary file added deps/.DS_Store
Binary file not shown.
1 change: 1 addition & 0 deletions deps/psvlib/img/backup.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <time.h>
Expand Down
1 change: 1 addition & 0 deletions deps/psvlib/pkg/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
if (MSVC)
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
endif ()
add_definitions(-Wno-implicit-function-declaration)
add_library(vitapkg
pkg.c pkg.h
pkg_out.c pkg_out.h
Expand Down
Binary file added deps/scrypto/.DS_Store
Binary file not shown.
21 changes: 21 additions & 0 deletions deps/scrypto/aes_x86.c
Original file line number Diff line number Diff line change
@@ -1,8 +1,29 @@
#include "aes.h"

#include <string.h>

#ifdef __arm64__
#include "sse2neon.h"

__m128i _mm_aesdec_si128 (__m128i a, __m128i RoundKey)
{
return vaesimcq_u8(vaesdq_u8(a, (__m128i){})) ^ RoundKey;
}

__m128i _mm_aesdeclast_si128 (__m128i a, __m128i RoundKey)
{
return vaesdq_u8(a, (__m128i){}) ^ RoundKey;
}

__m128i _mm_aesimc_si128 (__m128i a)
{
return vaesimcq_u8(a);
}

#else
#include <wmmintrin.h> // AESNI
#include <tmmintrin.h> // SSSE3
#endif

#define AES_INIT_128(rkeys, i, rcon) \
{ \
Expand Down
237 changes: 237 additions & 0 deletions deps/scrypto/aesni.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,237 @@
#include "aes.h"

#include <string.h>

#ifdef __arm64__
#include "sse2neon.h"

__m128i _mm_aesdec_si128 (__m128i a, __m128i RoundKey)
{
return vaesimcq_u8(vaesdq_u8(a, (__m128i){})) ^ RoundKey;
}

__m128i _mm_aesdeclast_si128 (__m128i a, __m128i RoundKey)
{
return vaesdq_u8(a, (__m128i){}) ^ RoundKey;
}

__m128i _mm_aesimc_si128 (__m128i a)
{
return vaesimcq_u8(a);
}

#else
#include <wmmintrin.h> // AESNI
#include <tmmintrin.h> // SSSE3
#endif

#define AES_INIT_128(rkeys, i, rcon) \
{ \
__m128i _s = rkeys[i]; \
__m128i _t = rkeys[i]; \
_s = _mm_xor_si128(_s, _mm_slli_si128(_s, 4)); \
_s = _mm_xor_si128(_s, _mm_slli_si128(_s, 8)); \
_t = _mm_aeskeygenassist_si128(_t, rcon); \
_t = _mm_shuffle_epi32(_t, 0xff); \
rkeys[i + 1] = _mm_xor_si128(_s, _t); \
}

#define AES_INIT_256(rkeys, i, shuffle, rcon) \
{ \
__m128i _s = rkeys[i]; \
__m128i _t = rkeys[i + 1]; \
_s = _mm_xor_si128(_s, _mm_slli_si128(_s, 4)); \
_s = _mm_xor_si128(_s, _mm_slli_si128(_s, 8)); \
_t = _mm_aeskeygenassist_si128(_t, rcon); \
_t = _mm_shuffle_epi32(_t, shuffle); \
rkeys[i + 2] = _mm_xor_si128(_s, _t); \
}

void aes_init_x86(aes_context* ctx, const uint8_t* key)
{
__m128i* ekey = (__m128i*)ctx->key;

if (ctx->nr == 10) {
ekey[0] = _mm_loadu_si128((const __m128i*)key);
AES_INIT_128(ekey, 0, 0x01);
AES_INIT_128(ekey, 1, 0x02);
AES_INIT_128(ekey, 2, 0x04);
AES_INIT_128(ekey, 3, 0x08);
AES_INIT_128(ekey, 4, 0x10);
AES_INIT_128(ekey, 5, 0x20);
AES_INIT_128(ekey, 6, 0x40);
AES_INIT_128(ekey, 7, 0x80);
AES_INIT_128(ekey, 8, 0x1b);
AES_INIT_128(ekey, 9, 0x36);
} else {
ekey[0] = _mm_loadu_si128((const __m128i*)key);
ekey[1] = _mm_loadu_si128((const __m128i*)(key+16));
AES_INIT_256(ekey, 0, 0xFF, 0x01);
AES_INIT_256(ekey, 1, 0xAA, 0x00);
AES_INIT_256(ekey, 2, 0xFF, 0x02);
AES_INIT_256(ekey, 3, 0xAA, 0x00);
AES_INIT_256(ekey, 4, 0xFF, 0x04);
AES_INIT_256(ekey, 5, 0xAA, 0x00);
AES_INIT_256(ekey, 6, 0xFF, 0x08);
AES_INIT_256(ekey, 7, 0xAA, 0x00);
AES_INIT_256(ekey, 8, 0xFF, 0x10);
AES_INIT_256(ekey, 9, 0xAA, 0x00);
AES_INIT_256(ekey, 10, 0xFF, 0x20);
AES_INIT_256(ekey, 11, 0xAA, 0x00);
AES_INIT_256(ekey, 12, 0xFF, 0x40);
}
}

void aes_init_dec_x86(aes_context* ctx, const uint8_t* key)
{
aes_context enc;
enc.nr = ctx->nr;
aes_init_x86(&enc, key);

const __m128i* ekey = (__m128i*)&enc.key;
__m128i* dkey = (__m128i*)&ctx->key;

_mm_store_si128(dkey + ctx->nr, _mm_load_si128(ekey + 0));
for (size_t i = 1; i < ctx->nr; i++)
{
_mm_store_si128(dkey + ctx->nr - i, _mm_aesimc_si128(_mm_load_si128(ekey + i)));
}
_mm_store_si128(dkey + 0, _mm_load_si128(ekey + ctx->nr));
}

static __m128i aes_encrypt_x86(__m128i input, const __m128i* key, int nr)
{
__m128i tmp;
tmp = _mm_xor_si128(input, _mm_load_si128(key + 0));
tmp = _mm_aesenc_si128(tmp, _mm_load_si128(key + 1));
tmp = _mm_aesenc_si128(tmp, _mm_load_si128(key + 2));
tmp = _mm_aesenc_si128(tmp, _mm_load_si128(key + 3));
tmp = _mm_aesenc_si128(tmp, _mm_load_si128(key + 4));
tmp = _mm_aesenc_si128(tmp, _mm_load_si128(key + 5));
tmp = _mm_aesenc_si128(tmp, _mm_load_si128(key + 6));
tmp = _mm_aesenc_si128(tmp, _mm_load_si128(key + 7));
tmp = _mm_aesenc_si128(tmp, _mm_load_si128(key + 8));
tmp = _mm_aesenc_si128(tmp, _mm_load_si128(key + 9));
if (nr > 10)
{
tmp = _mm_aesenc_si128(tmp, _mm_load_si128(key + 10));
tmp = _mm_aesenc_si128(tmp, _mm_load_si128(key + 11));
tmp = _mm_aesenc_si128(tmp, _mm_load_si128(key + 12));
tmp = _mm_aesenc_si128(tmp, _mm_load_si128(key + 13));
}
return _mm_aesenclast_si128(tmp, _mm_load_si128(key + nr));
}

static __m128i aes_decrypt_x86(__m128i input, const __m128i* key, int nr)
{
__m128i tmp;
tmp = _mm_xor_si128(input, _mm_load_si128(key + 0));
tmp = _mm_aesdec_si128(tmp, _mm_load_si128(key + 1));
tmp = _mm_aesdec_si128(tmp, _mm_load_si128(key + 2));
tmp = _mm_aesdec_si128(tmp, _mm_load_si128(key + 3));
tmp = _mm_aesdec_si128(tmp, _mm_load_si128(key + 4));
tmp = _mm_aesdec_si128(tmp, _mm_load_si128(key + 5));
tmp = _mm_aesdec_si128(tmp, _mm_load_si128(key + 6));
tmp = _mm_aesdec_si128(tmp, _mm_load_si128(key + 7));
tmp = _mm_aesdec_si128(tmp, _mm_load_si128(key + 8));
tmp = _mm_aesdec_si128(tmp, _mm_load_si128(key + 9));
if (nr > 10)
{
tmp = _mm_aesdec_si128(tmp, _mm_load_si128(key + 10));
tmp = _mm_aesdec_si128(tmp, _mm_load_si128(key + 11));
tmp = _mm_aesdec_si128(tmp, _mm_load_si128(key + 12));
tmp = _mm_aesdec_si128(tmp, _mm_load_si128(key + 13));
}
return _mm_aesdeclast_si128(tmp, _mm_load_si128(key + nr));
}

void aes_ecb_encrypt_x86(const aes_context* ctx, const uint8_t* input, uint8_t* output)
{
const __m128i* key = (__m128i*)ctx->key;
__m128i tmp = aes_encrypt_x86(_mm_loadu_si128((const __m128i*)input), key, ctx->nr);
_mm_storeu_si128((__m128i*)output, tmp);
}

void aes_ecb_decrypt_x86(const aes_context* ctx, const uint8_t* input, uint8_t* output)
{
const __m128i* key = (__m128i*)ctx->key;
__m128i tmp = aes_decrypt_x86(_mm_loadu_si128((const __m128i*)input), key, ctx->nr);
_mm_storeu_si128((__m128i*)output, tmp);
}

static __m128i ctr_increment(__m128i counter)
{
__m128i swap = _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
__m128i tmp = _mm_shuffle_epi8(counter, swap);
tmp = _mm_add_epi64(tmp, _mm_set_epi32(0, 0, 0, 1));
return _mm_shuffle_epi8(tmp, swap);
}

void aes_ctr_xor_x86(const aes_context* ctx, const uint8_t* iv, uint8_t* buffer, size_t size)
{
const __m128i* key = (__m128i*)ctx->key;
__m128i counter = _mm_loadu_si128((const __m128i*)iv);

while (size >= 16)
{
__m128i block = aes_encrypt_x86(counter, key, ctx->nr);
__m128i tmp = _mm_xor_si128(_mm_loadu_si128((const __m128i*)buffer), block);
_mm_storeu_si128((__m128i*)buffer, tmp);

counter = ctr_increment(counter);

buffer += 16;
size -= 16;
}

if (size != 0)
{
uint8_t full[16];
memcpy(full, buffer, size);
memset(full + size, 0, 16 - size);

__m128i block = aes_encrypt_x86(counter, key, ctx->nr);
__m128i tmp = _mm_xor_si128(_mm_loadu_si128((const __m128i*)full), block);
_mm_storeu_si128((__m128i*)full, tmp);

memcpy(buffer, full, size);
}
}

void aes_cmac_process_x86(const aes_context* ctx, uint8_t* block, const uint8_t* buffer, uint32_t size)
{
const __m128i* key = (__m128i*)ctx->key;
__m128i* data = (__m128i*)buffer;

__m128i tmp = _mm_loadu_si128((__m128i*)block);
for (uint32_t i = 0; i < size; i += 16)
{
__m128i input = _mm_loadu_si128(data++);
tmp = _mm_xor_si128(tmp, input);
tmp = aes_encrypt_x86(tmp, key, ctx->nr);
}
_mm_storeu_si128((__m128i*)block, tmp);
}

void aes_psp_decrypt_x86(const aes_context* ctx, const uint8_t* prev, const uint8_t* block, uint8_t* buffer, uint32_t size)
{
const __m128i* key = (__m128i*)ctx->key;
__m128i one = _mm_setr_epi32(0, 0, 0, 1);

__m128i x = _mm_load_si128((__m128i*)prev);
__m128i y = _mm_load_si128((__m128i*)block);

__m128i* data = (__m128i*)buffer;

for (uint32_t i = 0; i < size; i += 16)
{
y = _mm_add_epi32(y, one);

__m128i out = aes_decrypt_x86(y, key, ctx->nr);

out = _mm_xor_si128(out, _mm_loadu_si128(data));
out = _mm_xor_si128(out, x);
_mm_storeu_si128(data++, out);
x = y;
}
}
5 changes: 4 additions & 1 deletion deps/scrypto/sc_crc32_x86.c
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
#include "sc_crc32.h"

#ifdef __arm64__
#include "sse2neon.h"
#else
#include <wmmintrin.h> // PCLMUL
#include <tmmintrin.h> // SSSE3
#include <smmintrin.h> // SSS4

#endif
// Whitepaper: https://www.intel.com/content/dam/www/public/us/en/documents/white-papers/fast-crc-computation-generic-polynomials-pclmulqdq-paper.pdf
// ZLIB licensed code from https://github.com/jtkukunas/zlib/blob/master/crc_folding.c

Expand Down
Loading