mirror of
https://github.com/pspdev/pspsdk.git
synced 2025-10-03 16:51:27 +00:00
add PrxEncrypter to tools
This commit is contained in:
@@ -23,7 +23,8 @@ AC_PROG_RANLIB
|
||||
|
||||
# Checks for header files.
|
||||
AC_HEADER_STDC
|
||||
AC_CHECK_HEADERS([fcntl.h malloc.h stdlib.h string.h unistd.h])
|
||||
AC_CHECK_HEADERS([fcntl.h malloc.h stdlib.h string.h unistd.h zlib.h])
|
||||
AC_CHECK_LIB([z], [compress])
|
||||
|
||||
# Checks for typedefs, structures, and compiler characteristics.
|
||||
AC_C_CONST
|
||||
@@ -114,5 +115,6 @@ AC_CONFIG_FILES([Makefile
|
||||
src/vsh/Makefile
|
||||
src/wlan/Makefile
|
||||
src/samples/Makefile
|
||||
tools/Makefile])
|
||||
tools/Makefile
|
||||
tools/PrxEncrypter/Makefile])
|
||||
AC_OUTPUT
|
||||
|
@@ -25,6 +25,7 @@ STRIP = psp-strip
|
||||
MKSFO = mksfo
|
||||
PACK_PBP = pack-pbp
|
||||
FIXUP = psp-fixup-imports
|
||||
ENC = PrxEncrypter
|
||||
|
||||
# Add in PSPSDK includes and libraries.
|
||||
INCDIR := $(INCDIR) . $(PSPSDK)/include
|
||||
@@ -185,11 +186,17 @@ $(PSP_EBOOT_SFO):
|
||||
|
||||
ifeq ($(BUILD_PRX),1)
|
||||
$(PSP_EBOOT): $(TARGET).prx $(PSP_EBOOT_SFO)
|
||||
ifeq ($(ENCRYPT), 1)
|
||||
- $(ENC) $(TARGET).prx $(TARGET).prx
|
||||
endif
|
||||
$(PACK_PBP) $(PSP_EBOOT) $(PSP_EBOOT_SFO) $(PSP_EBOOT_ICON) \
|
||||
$(PSP_EBOOT_ICON1) $(PSP_EBOOT_UNKPNG) $(PSP_EBOOT_PIC1) \
|
||||
$(PSP_EBOOT_SND0) $(TARGET).prx $(PSP_EBOOT_PSAR)
|
||||
else
|
||||
$(PSP_EBOOT): $(TARGET).elf $(PSP_EBOOT_SFO)
|
||||
ifeq ($(ENCRYPT), 1)
|
||||
- $(ENC) $(TARGET).prx $(TARGET).prx
|
||||
endif
|
||||
$(STRIP) $(TARGET).elf -o $(TARGET)_strip.elf
|
||||
$(PACK_PBP) $(PSP_EBOOT) $(PSP_EBOOT_SFO) $(PSP_EBOOT_ICON) \
|
||||
$(PSP_EBOOT_ICON1) $(PSP_EBOOT_UNKPNG) $(PSP_EBOOT_PIC1) \
|
||||
|
@@ -1,4 +1,4 @@
|
||||
|
||||
SUBDIRS = PrxEncrypter
|
||||
bin_PROGRAMS = bin2s bin2c bin2o pack-pbp unpack-pbp mksfo mksfoex psp-config psp-build-exports psp-prxgen psp-fixup-imports
|
||||
|
||||
bin2s_SOURCES = bin2s.c
|
||||
|
3
tools/PrxEncrypter/Makefile.am
Normal file
3
tools/PrxEncrypter/Makefile.am
Normal file
@@ -0,0 +1,3 @@
|
||||
bin_PROGRAMS = PrxEncrypter
|
||||
PrxEncrypter_SOURCES = crypto.c kirk_engine.c main.c
|
||||
noinst_HEADERS = crypto.h endian_.h kirk_engine.h psp_headers.h types.h
|
1885
tools/PrxEncrypter/crypto.c
Normal file
1885
tools/PrxEncrypter/crypto.c
Normal file
File diff suppressed because it is too large
Load Diff
73
tools/PrxEncrypter/crypto.h
Normal file
73
tools/PrxEncrypter/crypto.h
Normal file
@@ -0,0 +1,73 @@
|
||||
#ifndef __RIJNDAEL_H
|
||||
#define __RIJNDAEL_H
|
||||
|
||||
#include "kirk_engine.h"
|
||||
|
||||
#define AES_KEY_LEN_128 (128)
|
||||
#define AES_KEY_LEN_192 (192)
|
||||
#define AES_KEY_LEN_256 (256)
|
||||
|
||||
#define AES_BUFFER_SIZE (16)
|
||||
|
||||
#define AES_MAXKEYBITS (256)
|
||||
#define AES_MAXKEYBYTES (AES_MAXKEYBITS/8)
|
||||
/* for 256-bit keys, fewer for less */
|
||||
#define AES_MAXROUNDS 14
|
||||
#define pwuAESContextBuffer rijndael_ctx
|
||||
|
||||
/* The structure for key information */
|
||||
typedef struct
|
||||
{
|
||||
int enc_only; /* context contains only encrypt schedule */
|
||||
int Nr; /* key-length-dependent number of rounds */
|
||||
u32 ek[4*(AES_MAXROUNDS + 1)]; /* encrypt key schedule */
|
||||
u32 dk[4*(AES_MAXROUNDS + 1)]; /* decrypt key schedule */
|
||||
} rijndael_ctx;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int enc_only; /* context contains only encrypt schedule */
|
||||
int Nr; /* key-length-dependent number of rounds */
|
||||
u32 ek[4*(AES_MAXROUNDS + 1)]; /* encrypt key schedule */
|
||||
u32 dk[4*(AES_MAXROUNDS + 1)]; /* decrypt key schedule */
|
||||
} AES_ctx;
|
||||
|
||||
int rijndael_set_key(rijndael_ctx *, const u8 *, int);
|
||||
int rijndael_set_key_enc_only(rijndael_ctx *, const u8 *, int);
|
||||
void rijndael_decrypt(rijndael_ctx *, const u8 *, u8 *);
|
||||
void rijndael_encrypt(rijndael_ctx *, const u8 *, u8 *);
|
||||
|
||||
int AES_set_key(AES_ctx *ctx, const u8 *key, int bits);
|
||||
void AES_encrypt(AES_ctx *ctx, const u8 *src, u8 *dst);
|
||||
void AES_decrypt(AES_ctx *ctx, const u8 *src, u8 *dst);
|
||||
void AES_cbc_encrypt(AES_ctx *ctx, u8 *src, u8 *dst, int size);
|
||||
void AES_cbc_decrypt(AES_ctx *ctx, u8 *src, u8 *dst, int size);
|
||||
void AES_CMAC(AES_ctx *ctx, unsigned char *input, int length, unsigned char *mac);
|
||||
void AES_CMAC_forge (AES_ctx *ctx, unsigned char *input, int length, unsigned char * forge );
|
||||
|
||||
int rijndaelKeySetupEnc(unsigned int [], const unsigned char [], int);
|
||||
int rijndaelKeySetupDec(unsigned int [], const unsigned char [], int);
|
||||
void rijndaelEncrypt(const unsigned int [], int, const unsigned char [],
|
||||
unsigned char []);
|
||||
|
||||
typedef struct SHA1Context
|
||||
{
|
||||
unsigned Message_Digest[5]; /* Message Digest (output) */
|
||||
unsigned Length_Low; /* Message length in bits */
|
||||
unsigned Length_High; /* Message length in bits */
|
||||
unsigned char Message_Block[64]; /* 512-bit message blocks */
|
||||
int Message_Block_Index; /* Index into message block array */
|
||||
int Computed; /* Is the digest computed? */
|
||||
int Corrupted; /* Is the message digest corruped? */
|
||||
} SHA1Context;
|
||||
|
||||
/*
|
||||
* Function Prototypes
|
||||
*/
|
||||
void SHA1Reset(SHA1Context *);
|
||||
int SHA1Result(SHA1Context *);
|
||||
void SHA1Input( SHA1Context *,
|
||||
const unsigned char *,
|
||||
unsigned);
|
||||
|
||||
#endif /* __RIJNDAEL_H */
|
36
tools/PrxEncrypter/endian_.h
Normal file
36
tools/PrxEncrypter/endian_.h
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* endian.h
|
||||
*
|
||||
* Created on: Jan 4, 2011
|
||||
*/
|
||||
|
||||
#ifndef ENDIAN_H_
|
||||
#define ENDIAN_H_
|
||||
|
||||
#include "types.h"
|
||||
|
||||
static inline u16 Swap16(u16 v)
|
||||
{
|
||||
return (((v & 0x00FF) << 8) | (v & 0xFF00) >> 8);
|
||||
}
|
||||
|
||||
static inline u32 Swap32(u32 v)
|
||||
{
|
||||
return (((v & 0x000000FF) << 24) | ((v & 0x0000FF00) << 8) |
|
||||
((v & 0xFF000000) >> 24) | ((v & 0x00FF0000) >> 8));
|
||||
}
|
||||
|
||||
static inline u64 Swap64(u64 v)
|
||||
{
|
||||
return (((v & 0x00000000000000FFULL) << 56) |
|
||||
((v & 0x000000000000FF00ULL) << 40) |
|
||||
((v & 0x0000000000FF0000ULL) << 24) |
|
||||
((v & 0x00000000FF000000ULL) << 8) |
|
||||
((v & 0x000000FF00000000ULL) >> 8) |
|
||||
((v & 0x0000FF0000000000ULL) >> 24) |
|
||||
((v & 0x00FF000000000000ULL) >> 40) |
|
||||
((v & 0xFF00000000000000ULL) >> 56));
|
||||
}
|
||||
|
||||
|
||||
#endif /* ENDIAN_H_ */
|
360
tools/PrxEncrypter/kirk_engine.c
Normal file
360
tools/PrxEncrypter/kirk_engine.c
Normal file
@@ -0,0 +1,360 @@
|
||||
/*
|
||||
KIRK ENGINE CODE
|
||||
Thx for coyotebean, Davee, hitchhikr, kgsws, Mathieulh, SilverSpring
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <malloc.h>
|
||||
#include "types.h"
|
||||
#include "kirk_engine.h"
|
||||
#include "crypto.h"
|
||||
|
||||
|
||||
/* ------------------------- KEY VAULT ------------------------- */
|
||||
|
||||
u8 kirk1_key[] = {0x98, 0xC9, 0x40, 0x97, 0x5C, 0x1D, 0x10, 0xE8, 0x7F, 0xE6, 0x0E, 0xA3, 0xFD, 0x03, 0xA8, 0xBA};
|
||||
|
||||
u8 kirk7_key03[] = {0x98, 0x02, 0xC4, 0xE6, 0xEC, 0x9E, 0x9E, 0x2F, 0xFC, 0x63, 0x4C, 0xE4, 0x2F, 0xBB, 0x46, 0x68};
|
||||
u8 kirk7_key04[] = {0x99, 0x24, 0x4C, 0xD2, 0x58, 0xF5, 0x1B, 0xCB, 0xB0, 0x61, 0x9C, 0xA7, 0x38, 0x30, 0x07, 0x5F};
|
||||
u8 kirk7_key05[] = {0x02, 0x25, 0xD7, 0xBA, 0x63, 0xEC, 0xB9, 0x4A, 0x9D, 0x23, 0x76, 0x01, 0xB3, 0xF6, 0xAC, 0x17};
|
||||
u8 kirk7_key0C[] = {0x84, 0x85, 0xC8, 0x48, 0x75, 0x08, 0x43, 0xBC, 0x9B, 0x9A, 0xEC, 0xA7, 0x9C, 0x7F, 0x60, 0x18};
|
||||
u8 kirk7_key0D[] = {0xB5, 0xB1, 0x6E, 0xDE, 0x23, 0xA9, 0x7B, 0x0E, 0xA1, 0x7C, 0xDB, 0xA2, 0xDC, 0xDE, 0xC4, 0x6E};
|
||||
u8 kirk7_key0E[] = {0xC8, 0x71, 0xFD, 0xB3, 0xBC, 0xC5, 0xD2, 0xF2, 0xE2, 0xD7, 0x72, 0x9D, 0xDF, 0x82, 0x68, 0x82};
|
||||
u8 kirk7_key0F[] = {0x0A, 0xBB, 0x33, 0x6C, 0x96, 0xD4, 0xCD, 0xD8, 0xCB, 0x5F, 0x4B, 0xE0, 0xBA, 0xDB, 0x9E, 0x03};
|
||||
u8 kirk7_key10[] = {0x32, 0x29, 0x5B, 0xD5, 0xEA, 0xF7, 0xA3, 0x42, 0x16, 0xC8, 0x8E, 0x48, 0xFF, 0x50, 0xD3, 0x71};
|
||||
u8 kirk7_key11[] = {0x46, 0xF2, 0x5E, 0x8E, 0x4D, 0x2A, 0xA5, 0x40, 0x73, 0x0B, 0xC4, 0x6E, 0x47, 0xEE, 0x6F, 0x0A};
|
||||
u8 kirk7_key12[] = {0x5D, 0xC7, 0x11, 0x39, 0xD0, 0x19, 0x38, 0xBC, 0x02, 0x7F, 0xDD, 0xDC, 0xB0, 0x83, 0x7D, 0x9D};
|
||||
u8 kirk7_key38[] = {0x12, 0x46, 0x8D, 0x7E, 0x1C, 0x42, 0x20, 0x9B, 0xBA, 0x54, 0x26, 0x83, 0x5E, 0xB0, 0x33, 0x03};
|
||||
u8 kirk7_key39[] = {0xC4, 0x3B, 0xB6, 0xD6, 0x53, 0xEE, 0x67, 0x49, 0x3E, 0xA9, 0x5F, 0xBC, 0x0C, 0xED, 0x6F, 0x8A};
|
||||
u8 kirk7_key3A[] = {0x2C, 0xC3, 0xCF, 0x8C, 0x28, 0x78, 0xA5, 0xA6, 0x63, 0xE2, 0xAF, 0x2D, 0x71, 0x5E, 0x86, 0xBA};
|
||||
u8 kirk7_key4B[] = {0x0C, 0xFD, 0x67, 0x9A, 0xF9, 0xB4, 0x72, 0x4F, 0xD7, 0x8D, 0xD6, 0xE9, 0x96, 0x42, 0x28, 0x8B}; //1.xx game eboot.bin
|
||||
u8 kirk7_key53[] = {0xAF, 0xFE, 0x8E, 0xB1, 0x3D, 0xD1, 0x7E, 0xD8, 0x0A, 0x61, 0x24, 0x1C, 0x95, 0x92, 0x56, 0xB6};
|
||||
u8 kirk7_key57[] = {0x1C, 0x9B, 0xC4, 0x90, 0xE3, 0x06, 0x64, 0x81, 0xFA, 0x59, 0xFD, 0xB6, 0x00, 0xBB, 0x28, 0x70};
|
||||
u8 kirk7_key5D[] = {0x11, 0x5A, 0x5D, 0x20, 0xD5, 0x3A, 0x8D, 0xD3, 0x9C, 0xC5, 0xAF, 0x41, 0x0F, 0x0F, 0x18, 0x6F};
|
||||
u8 kirk7_key63[] = {0x9C, 0x9B, 0x13, 0x72, 0xF8, 0xC6, 0x40, 0xCF, 0x1C, 0x62, 0xF5, 0xD5, 0x92, 0xDD, 0xB5, 0x82};
|
||||
u8 kirk7_key64[] = {0x03, 0xB3, 0x02, 0xE8, 0x5F, 0xF3, 0x81, 0xB1, 0x3B, 0x8D, 0xAA, 0x2A, 0x90, 0xFF, 0x5E, 0x61};
|
||||
|
||||
/* ------------------------- KEY VAULT END ------------------------- */
|
||||
|
||||
/* ------------------------- INTERNAL STUFF ------------------------- */
|
||||
|
||||
typedef struct header_keys
|
||||
{
|
||||
u8 AES[16];
|
||||
u8 CMAC[16];
|
||||
}header_keys; //small struct for temporary keeping AES & CMAC key from CMD1 header
|
||||
|
||||
u8 fuseID[16]; //Emulate FUSEID
|
||||
|
||||
AES_ctx aes_kirk1; //global
|
||||
|
||||
char is_kirk_initialized; //"init" emulation
|
||||
|
||||
/* ------------------------- INTERNAL STUFF END ------------------------- */
|
||||
|
||||
|
||||
/* ------------------------- IMPLEMENTATION ------------------------- */
|
||||
|
||||
int kirk_CMD0(void* outbuff, void* inbuff, int size, int generate_trash)
|
||||
{
|
||||
if(is_kirk_initialized == 0) return KIRK_NOT_INITIALIZED;
|
||||
|
||||
KIRK_CMD1_HEADER* header = (KIRK_CMD1_HEADER*)outbuff;
|
||||
|
||||
memcpy(outbuff, inbuff, size);
|
||||
|
||||
if(header->mode != KIRK_MODE_CMD1) return KIRK_INVALID_MODE;
|
||||
|
||||
header_keys *keys = (header_keys *)outbuff; //0-15 AES key, 16-31 CMAC key
|
||||
|
||||
//FILL PREDATA WITH RANDOM DATA
|
||||
if(generate_trash) kirk_CMD14(outbuff+sizeof(KIRK_CMD1_HEADER), header->data_offset);
|
||||
|
||||
//Make sure data is 16 aligned
|
||||
int chk_size = header->data_size;
|
||||
if(chk_size % 16) chk_size += 16 - (chk_size % 16);
|
||||
|
||||
//ENCRYPT DATA
|
||||
AES_ctx k1;
|
||||
AES_set_key(&k1, keys->AES, 128);
|
||||
|
||||
AES_cbc_encrypt(&k1, inbuff+sizeof(KIRK_CMD1_HEADER)+header->data_offset, outbuff+sizeof(KIRK_CMD1_HEADER)+header->data_offset, chk_size);
|
||||
|
||||
//CMAC HASHES
|
||||
AES_ctx cmac_key;
|
||||
AES_set_key(&cmac_key, keys->CMAC, 128);
|
||||
|
||||
u8 cmac_header_hash[16];
|
||||
u8 cmac_data_hash[16];
|
||||
|
||||
AES_CMAC(&cmac_key, outbuff+0x60, 0x30, cmac_header_hash);
|
||||
|
||||
AES_CMAC(&cmac_key, outbuff+0x60, 0x30 + chk_size + header->data_offset, cmac_data_hash);
|
||||
|
||||
memcpy(header->CMAC_header_hash, cmac_header_hash, 16);
|
||||
memcpy(header->CMAC_data_hash, cmac_data_hash, 16);
|
||||
|
||||
//ENCRYPT KEYS
|
||||
|
||||
AES_cbc_encrypt(&aes_kirk1, inbuff, outbuff, 16*2);
|
||||
return KIRK_OPERATION_SUCCESS;
|
||||
}
|
||||
|
||||
int kirk_decrypt_keys(u8 *keys, void *inbuff)
|
||||
{
|
||||
AES_cbc_decrypt(&aes_kirk1, inbuff, (u8*)keys, 16*2); //decrypt AES & CMAC key to temp buffer
|
||||
return 0;
|
||||
}
|
||||
|
||||
int kirk_CMD1(void* outbuff, void* inbuff, int size, int do_check)
|
||||
{
|
||||
if(is_kirk_initialized == 0) return KIRK_NOT_INITIALIZED;
|
||||
|
||||
KIRK_CMD1_HEADER* header = (KIRK_CMD1_HEADER*)inbuff;
|
||||
if(header->mode != KIRK_MODE_CMD1) return KIRK_INVALID_MODE;
|
||||
|
||||
header_keys keys; //0-15 AES key, 16-31 CMAC key
|
||||
|
||||
AES_cbc_decrypt(&aes_kirk1, inbuff, (u8*)&keys, 16*2); //decrypt AES & CMAC key to temp buffer
|
||||
|
||||
// HOAX WARRING! I have no idea why the hash check on last IPL block fails, so there is an option to disable checking
|
||||
if(do_check)
|
||||
{
|
||||
int ret = kirk_CMD10(inbuff, size);
|
||||
if(ret != KIRK_OPERATION_SUCCESS) return ret;
|
||||
}
|
||||
|
||||
AES_ctx k1;
|
||||
AES_set_key(&k1, keys.AES, 128);
|
||||
|
||||
AES_cbc_decrypt(&k1, inbuff+sizeof(KIRK_CMD1_HEADER)+header->data_offset, outbuff, header->data_size);
|
||||
|
||||
return KIRK_OPERATION_SUCCESS;
|
||||
}
|
||||
|
||||
int kirk_CMD4(void* outbuff, void* inbuff, int size)
|
||||
{
|
||||
if(is_kirk_initialized == 0) return KIRK_NOT_INITIALIZED;
|
||||
|
||||
KIRK_AES128CBC_HEADER *header = (KIRK_AES128CBC_HEADER*)inbuff;
|
||||
if(header->mode != KIRK_MODE_ENCRYPT_CBC) return KIRK_INVALID_MODE;
|
||||
if(header->data_size == 0) return KIRK_DATA_SIZE_ZERO;
|
||||
|
||||
u8* key = kirk_4_7_get_key(header->keyseed);
|
||||
if(key == (u8*)KIRK_INVALID_SIZE) return KIRK_INVALID_SIZE;
|
||||
|
||||
//Set the key
|
||||
AES_ctx aesKey;
|
||||
AES_set_key(&aesKey, key, 128);
|
||||
AES_cbc_encrypt(&aesKey, inbuff+sizeof(KIRK_AES128CBC_HEADER), outbuff, size);
|
||||
|
||||
return KIRK_OPERATION_SUCCESS;
|
||||
}
|
||||
|
||||
int kirk_CMD7(void* outbuff, void* inbuff, int size)
|
||||
{
|
||||
if(is_kirk_initialized == 0) return KIRK_NOT_INITIALIZED;
|
||||
|
||||
KIRK_AES128CBC_HEADER *header = (KIRK_AES128CBC_HEADER*)inbuff;
|
||||
if(header->mode != KIRK_MODE_DECRYPT_CBC) return KIRK_INVALID_MODE;
|
||||
if(header->data_size == 0) return KIRK_DATA_SIZE_ZERO;
|
||||
|
||||
u8* key = kirk_4_7_get_key(header->keyseed);
|
||||
if(key == (u8*)KIRK_INVALID_SIZE) return KIRK_INVALID_SIZE;
|
||||
|
||||
//Set the key
|
||||
AES_ctx aesKey;
|
||||
AES_set_key(&aesKey, key, 128);
|
||||
|
||||
AES_cbc_decrypt(&aesKey, inbuff+sizeof(KIRK_AES128CBC_HEADER), outbuff, size);
|
||||
|
||||
return KIRK_OPERATION_SUCCESS;
|
||||
}
|
||||
|
||||
int kirk_CMD10(void* inbuff, int insize)
|
||||
{
|
||||
if(is_kirk_initialized == 0) return KIRK_NOT_INITIALIZED;
|
||||
|
||||
KIRK_CMD1_HEADER* header = (KIRK_CMD1_HEADER*)inbuff;
|
||||
|
||||
if(!(header->mode == KIRK_MODE_CMD1 || header->mode == KIRK_MODE_CMD2 || header->mode == KIRK_MODE_CMD3)) return KIRK_INVALID_MODE;
|
||||
if(header->data_size == 0) return KIRK_DATA_SIZE_ZERO;
|
||||
|
||||
if(header->mode == KIRK_MODE_CMD1)
|
||||
{
|
||||
header_keys keys; //0-15 AES key, 16-31 CMAC key
|
||||
|
||||
AES_cbc_decrypt(&aes_kirk1, inbuff, (u8*)&keys, 32); //decrypt AES & CMAC key to temp buffer
|
||||
|
||||
AES_ctx cmac_key;
|
||||
AES_set_key(&cmac_key, keys.CMAC, 128);
|
||||
|
||||
u8 cmac_header_hash[16];
|
||||
u8 cmac_data_hash[16];
|
||||
|
||||
AES_CMAC(&cmac_key, inbuff+0x60, 0x30, cmac_header_hash);
|
||||
|
||||
//Make sure data is 16 aligned
|
||||
int chk_size = header->data_size;
|
||||
if(chk_size % 16) chk_size += 16 - (chk_size % 16);
|
||||
AES_CMAC(&cmac_key, inbuff+0x60, 0x30 + chk_size + header->data_offset, cmac_data_hash);
|
||||
|
||||
if(memcmp(cmac_header_hash, header->CMAC_header_hash, 16) != 0)
|
||||
{
|
||||
printf("header hash invalid\n");
|
||||
return KIRK_HEADER_HASH_INVALID;
|
||||
}
|
||||
if(memcmp(cmac_data_hash, header->CMAC_data_hash, 16) != 0)
|
||||
{
|
||||
printf("data hash invalid\n");
|
||||
return KIRK_DATA_HASH_INVALID;
|
||||
}
|
||||
|
||||
return KIRK_OPERATION_SUCCESS;
|
||||
}
|
||||
return KIRK_SIG_CHECK_INVALID; //Checks for cmd 2 & 3 not included right now
|
||||
}
|
||||
|
||||
int kirk_CMD11(void* outbuff, void* inbuff, int size)
|
||||
{
|
||||
if(is_kirk_initialized == 0) return KIRK_NOT_INITIALIZED;
|
||||
KIRK_SHA1_HEADER *header = (KIRK_SHA1_HEADER *)inbuff;
|
||||
if(header->data_size == 0 || size == 0) return KIRK_DATA_SIZE_ZERO;
|
||||
|
||||
SHA1Context sha;
|
||||
SHA1Reset(&sha);
|
||||
size <<= 4;
|
||||
size >>= 4;
|
||||
size = size < header->data_size ? size : header->data_size;
|
||||
SHA1Input(&sha, inbuff+sizeof(KIRK_SHA1_HEADER), size);
|
||||
memcpy(outbuff, sha.Message_Digest, 16);
|
||||
return KIRK_OPERATION_SUCCESS;
|
||||
}
|
||||
|
||||
int kirk_CMD14(void* outbuff, int size)
|
||||
{
|
||||
if(is_kirk_initialized == 0) return KIRK_NOT_INITIALIZED;
|
||||
int i;
|
||||
u8* buf = (u8*)outbuff;
|
||||
for(i = 0; i < size; i++)
|
||||
{
|
||||
buf[i] = rand()%255;
|
||||
}
|
||||
return KIRK_OPERATION_SUCCESS;
|
||||
}
|
||||
|
||||
int kirk_init()
|
||||
{
|
||||
AES_set_key(&aes_kirk1, kirk1_key, 128);
|
||||
is_kirk_initialized = 1;
|
||||
srand(time(0));
|
||||
return KIRK_OPERATION_SUCCESS;
|
||||
}
|
||||
|
||||
u8* kirk_4_7_get_key(int key_type)
|
||||
{
|
||||
switch(key_type)
|
||||
{
|
||||
case(0x03): return kirk7_key03; break;
|
||||
case(0x04): return kirk7_key04; break;
|
||||
case(0x05): return kirk7_key05; break;
|
||||
case(0x0C): return kirk7_key0C; break;
|
||||
case(0x0D): return kirk7_key0D; break;
|
||||
case(0x0E): return kirk7_key0E; break;
|
||||
case(0x0F): return kirk7_key0F; break;
|
||||
case(0x10): return kirk7_key10; break;
|
||||
case(0x11): return kirk7_key11; break;
|
||||
case(0x12): return kirk7_key12; break;
|
||||
case(0x38): return kirk7_key38; break;
|
||||
case(0x39): return kirk7_key39; break;
|
||||
case(0x3A): return kirk7_key3A; break;
|
||||
case(0x4B): return kirk7_key4B; break;
|
||||
case(0x53): return kirk7_key53; break;
|
||||
case(0x57): return kirk7_key57; break;
|
||||
case(0x5D): return kirk7_key5D; break;
|
||||
case(0x63): return kirk7_key63; break;
|
||||
case(0x64): return kirk7_key64; break;
|
||||
default: return (u8*)KIRK_INVALID_SIZE; break; //need to get the real error code for that, placeholder now :)
|
||||
}
|
||||
}
|
||||
|
||||
int kirk_CMD1_ex(void* outbuff, void* inbuff, int size, KIRK_CMD1_HEADER* header)
|
||||
{
|
||||
u8* buffer = (u8*)malloc(size);
|
||||
memcpy(buffer, header, sizeof(KIRK_CMD1_HEADER));
|
||||
memcpy(buffer+sizeof(KIRK_CMD1_HEADER), inbuff, header->data_size);
|
||||
int ret = kirk_CMD1(outbuff, buffer, size, 1);
|
||||
free(buffer);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int sceUtilsSetFuseID(void*fuse)
|
||||
{
|
||||
memcpy(fuseID, fuse, 16);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sceUtilsBufferCopyWithRange(void* outbuff, int outsize, void* inbuff, int insize, int cmd)
|
||||
{
|
||||
switch(cmd)
|
||||
{
|
||||
case KIRK_CMD_DECRYPT_PRIVATE:
|
||||
if(insize % 16) return SUBCWR_NOT_16_ALGINED;
|
||||
int ret = kirk_CMD1(outbuff, inbuff, insize, 1);
|
||||
if(ret == KIRK_HEADER_HASH_INVALID) return SUBCWR_HEADER_HASH_INVALID;
|
||||
return ret;
|
||||
break;
|
||||
case KIRK_CMD_ENCRYPT_IV_0: return kirk_CMD4(outbuff, inbuff, insize); break;
|
||||
case KIRK_CMD_DECRYPT_IV_0: return kirk_CMD7(outbuff, inbuff, insize); break;
|
||||
case KIRK_CMD_PRIV_SIG_CHECK: return kirk_CMD10(inbuff, insize); break;
|
||||
case KIRK_CMD_SHA1_HASH: return kirk_CMD11(outbuff, inbuff, insize); break;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int kirk_forge(u8* inbuff, int insize)
|
||||
{
|
||||
KIRK_CMD1_HEADER* header = (KIRK_CMD1_HEADER*)inbuff;
|
||||
AES_ctx cmac_key;
|
||||
u8 cmac_header_hash[16];
|
||||
u8 cmac_data_hash[16];
|
||||
int chk_size;
|
||||
|
||||
if(is_kirk_initialized == 0) return KIRK_NOT_INITIALIZED;
|
||||
if(!(header->mode == KIRK_MODE_CMD1 || header->mode == KIRK_MODE_CMD2 || header->mode == KIRK_MODE_CMD3)) return KIRK_INVALID_MODE;
|
||||
if(header->data_size == 0) return KIRK_DATA_SIZE_ZERO;
|
||||
|
||||
if(header->mode == KIRK_MODE_CMD1){
|
||||
header_keys keys; //0-15 AES key, 16-31 CMAC key
|
||||
|
||||
AES_cbc_decrypt(&aes_kirk1, inbuff, (u8*)&keys, 32); //decrypt AES & CMAC key to temp buffer
|
||||
AES_set_key(&cmac_key, keys.CMAC, 128);
|
||||
AES_CMAC(&cmac_key, inbuff+0x60, 0x30, cmac_header_hash);
|
||||
if(memcmp(cmac_header_hash, header->CMAC_header_hash, 16) != 0) return KIRK_HEADER_HASH_INVALID;
|
||||
|
||||
//Make sure data is 16 aligned
|
||||
chk_size = header->data_size;
|
||||
if(chk_size % 16) chk_size += 16 - (chk_size % 16);
|
||||
AES_CMAC(&cmac_key, inbuff+0x60, 0x30 + chk_size + header->data_offset, cmac_data_hash);
|
||||
|
||||
if(memcmp(cmac_data_hash, header->CMAC_data_hash, 16) != 0) {
|
||||
//printf("data hash invalid, correcting...\n");
|
||||
} else {
|
||||
printf("data hash is already valid!\n");
|
||||
return 100;
|
||||
}
|
||||
// Forge collision for data hash
|
||||
memcpy(cmac_data_hash,header->CMAC_data_hash,0x10);
|
||||
AES_CMAC_forge(&cmac_key, inbuff+0x60, 0x30+ chk_size + header->data_offset, cmac_data_hash);
|
||||
//printf("Last row in bad file should be :\n"); for(i=0;i<0x10;i++) printf("%02x", cmac_data_hash[i]);
|
||||
//printf("\n\n");
|
||||
|
||||
return KIRK_OPERATION_SUCCESS;
|
||||
}
|
||||
return KIRK_SIG_CHECK_INVALID; //Checks for cmd 2 & 3 not included right now
|
||||
}
|
129
tools/PrxEncrypter/kirk_engine.h
Normal file
129
tools/PrxEncrypter/kirk_engine.h
Normal file
@@ -0,0 +1,129 @@
|
||||
#ifndef KIRK_ENGINE
|
||||
#define KIRK_ENGINE
|
||||
|
||||
|
||||
//Kirk return values
|
||||
#define KIRK_OPERATION_SUCCESS 0
|
||||
#define KIRK_NOT_ENABLED 1
|
||||
#define KIRK_INVALID_MODE 2
|
||||
#define KIRK_HEADER_HASH_INVALID 3
|
||||
#define KIRK_DATA_HASH_INVALID 4
|
||||
#define KIRK_SIG_CHECK_INVALID 5
|
||||
#define KIRK_UNK_1 6
|
||||
#define KIRK_UNK_2 7
|
||||
#define KIRK_UNK_3 8
|
||||
#define KIRK_UNK_4 9
|
||||
#define KIRK_UNK_5 0xA
|
||||
#define KIRK_UNK_6 0xB
|
||||
#define KIRK_NOT_INITIALIZED 0xC
|
||||
#define KIRK_INVALID_OPERATION 0xD
|
||||
#define KIRK_INVALID_SEED_CODE 0xE
|
||||
#define KIRK_INVALID_SIZE 0xF
|
||||
#define KIRK_DATA_SIZE_ZERO 0x10
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int mode; //0
|
||||
int unk_4; //4
|
||||
int unk_8; //8
|
||||
int keyseed; //C
|
||||
int data_size; //10
|
||||
} KIRK_AES128CBC_HEADER; //0x14
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 AES_key[16]; //0
|
||||
u8 CMAC_key[16]; //10
|
||||
u8 CMAC_header_hash[16]; //20
|
||||
u8 CMAC_data_hash[16]; //30
|
||||
u8 unused[32]; //40
|
||||
u32 mode; //60
|
||||
u8 unk3[12]; //64
|
||||
u32 data_size; //70
|
||||
u32 data_offset; //74
|
||||
u8 unk4[8]; //78
|
||||
u8 unk5[16]; //80
|
||||
} KIRK_CMD1_HEADER; //0x90
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32 data_size; //0
|
||||
} KIRK_SHA1_HEADER; //4
|
||||
|
||||
//mode passed to sceUtilsBufferCopyWithRange
|
||||
#define KIRK_CMD_DECRYPT_PRIVATE 1
|
||||
#define KIRK_CMD_ENCRYPT_IV_0 4
|
||||
#define KIRK_CMD_ENCRYPT_IV_FUSE 5
|
||||
#define KIRK_CMD_ENCRYPT_IV_USER 6
|
||||
#define KIRK_CMD_DECRYPT_IV_0 7
|
||||
#define KIRK_CMD_DECRYPT_IV_FUSE 8
|
||||
#define KIRK_CMD_DECRYPT_IV_USER 9
|
||||
#define KIRK_CMD_PRIV_SIG_CHECK 10
|
||||
#define KIRK_CMD_SHA1_HASH 11
|
||||
|
||||
//"mode" in header
|
||||
#define KIRK_MODE_CMD1 1
|
||||
#define KIRK_MODE_CMD2 2
|
||||
#define KIRK_MODE_CMD3 3
|
||||
#define KIRK_MODE_ENCRYPT_CBC 4
|
||||
#define KIRK_MODE_DECRYPT_CBC 5
|
||||
|
||||
//sceUtilsBufferCopyWithRange errors
|
||||
#define SUBCWR_NOT_16_ALGINED 0x90A
|
||||
#define SUBCWR_HEADER_HASH_INVALID 0x920
|
||||
#define SUBCWR_BUFFER_TOO_SMALL 0x1000
|
||||
|
||||
/*
|
||||
// Private Sig + Cipher
|
||||
0x01: Super-Duper decryption (no inverse)
|
||||
0x02: Encrypt Operation (inverse of 0x03)
|
||||
0x03: Decrypt Operation (inverse of 0x02)
|
||||
|
||||
// Cipher
|
||||
0x04: Encrypt Operation (inverse of 0x07) (IV=0)
|
||||
0x05: Encrypt Operation (inverse of 0x08) (IV=FuseID)
|
||||
0x06: Encrypt Operation (inverse of 0x09) (IV=UserDefined)
|
||||
0x07: Decrypt Operation (inverse of 0x04)
|
||||
0x08: Decrypt Operation (inverse of 0x05)
|
||||
0x09: Decrypt Operation (inverse of 0x06)
|
||||
|
||||
// Sig Gens
|
||||
0x0A: Private Signature Check (checks for private SCE sig)
|
||||
0x0B: SHA1 Hash
|
||||
0x0C: Mul1
|
||||
0x0D: Mul2
|
||||
0x0E: Random Number Gen
|
||||
0x0F: (absolutely no idea <20> could be KIRK initialization)
|
||||
0x10: Signature Gen
|
||||
// Sig Checks
|
||||
0x11: Signature Check (checks for generated sigs)
|
||||
0x12: Certificate Check (idstorage signatures)
|
||||
*/
|
||||
|
||||
//kirk-like funcs
|
||||
int kirk_CMD0(void* outbuff, void* inbuff, int size, int generate_trash);
|
||||
int kirk_CMD1(void* outbuff, void* inbuff, int size, int do_check);
|
||||
int kirk_CMD4(void* outbuff, void* inbuff, int size);
|
||||
int kirk_CMD7(void* outbuff, void* inbuff, int size);
|
||||
int kirk_CMD10(void* inbuff, int insize);
|
||||
int kirk_CMD11(void* outbuff, void* inbuff, int size);
|
||||
int kirk_CMD14(void* outbuff, int size);
|
||||
int kirk_init(); //CMD 0xF?
|
||||
|
||||
//helper funcs
|
||||
u8* kirk_4_7_get_key(int key_type);
|
||||
|
||||
//kirk "ex" functions
|
||||
int kirk_CMD1_ex(void* outbuff, void* inbuff, int size, KIRK_CMD1_HEADER* header);
|
||||
|
||||
//sce-like funcs
|
||||
int sceUtilsSetFuseID(void*fuse);
|
||||
int sceUtilsBufferCopyWithRange(void* outbuff, int outsize, void* inbuff, int insize, int cmd);
|
||||
|
||||
int kirk_forge(u8* inbuff, int insize);
|
||||
|
||||
int kirk_decrypt_keys(u8 *keys, void *inbuff);
|
||||
|
||||
#endif
|
||||
|
||||
|
367
tools/PrxEncrypter/main.c
Normal file
367
tools/PrxEncrypter/main.c
Normal file
@@ -0,0 +1,367 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <zlib.h>
|
||||
|
||||
#include "types.h"
|
||||
#include "endian_.h"
|
||||
#include "kirk_engine.h"
|
||||
#include "psp_headers.h"
|
||||
|
||||
// 5MB application
|
||||
unsigned char pspHeader_big[336] =
|
||||
{
|
||||
0x7E, 0x50, 0x53, 0x50, 0x00, 0x02, 0x00, 0x00, 0x01, 0x01, 0x22, 0x74, 0x69, 0x66, 0x70, 0x73,
|
||||
0x70, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x33, 0x55, 0x00, 0x50, 0x34, 0x55, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x40, 0x67, 0x3D, 0x00, 0x50, 0x55, 0x0A, 0x01, 0x10, 0x00, 0x40, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x6B, 0x3D, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x4C, 0x6B, 0x3D, 0x00, 0xCC, 0xBB, 0x11, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,
|
||||
0x90, 0x82, 0x4C, 0x48, 0xA3, 0x53, 0xB2, 0x1B, 0x13, 0x95, 0x2F, 0xF1, 0x0B, 0x90, 0x9C, 0x11,
|
||||
0x61, 0x40, 0x20, 0x67, 0xF8, 0xDB, 0xFC, 0x95, 0x5C, 0xBE, 0x8C, 0x80, 0xF3, 0x92, 0x03, 0x01,
|
||||
0xB0, 0xBE, 0xF5, 0xF8, 0xA1, 0xAF, 0xAF, 0xA8, 0x38, 0x26, 0x63, 0x09, 0x26, 0x0E, 0xB7, 0xD5,
|
||||
0x00, 0x33, 0x55, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x5C, 0x3E, 0x03, 0x22, 0xE5, 0x7D, 0xB9, 0xD1, 0x13, 0x67, 0x97, 0xA3, 0x5B, 0xD8, 0x77, 0x1F,
|
||||
0xF0, 0x05, 0xF3, 0xAD, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87, 0x4A, 0xD7, 0x37,
|
||||
0xC2, 0x8F, 0x15, 0x43, 0x33, 0x93, 0x4D, 0x5B, 0xC0, 0x6E, 0xE4, 0x00, 0xC6, 0x0A, 0x71, 0x11,
|
||||
0x98, 0xB6, 0xC3, 0xB7, 0x59, 0x66, 0x21, 0xA8, 0x65, 0xF6, 0x53, 0xA9, 0x7A, 0x48, 0x17, 0xB6,
|
||||
};
|
||||
|
||||
unsigned char kirkHeader_big[272] =
|
||||
{
|
||||
0x2A, 0x4F, 0x3C, 0x49, 0x8A, 0x73, 0x4E, 0xD1, 0xF4, 0x55, 0x93, 0x0B, 0x9B, 0x69, 0xDC, 0x65,
|
||||
0x73, 0x22, 0x69, 0xD3, 0x73, 0x96, 0x7A, 0x60, 0x66, 0x8C, 0x88, 0xCF, 0x2F, 0x83, 0x58, 0xBC,
|
||||
0xB2, 0x00, 0x0A, 0x11, 0x72, 0x43, 0xC5, 0xDE, 0xEF, 0xBB, 0x2C, 0xBF, 0x97, 0x79, 0x6B, 0x9C,
|
||||
0x10, 0x1E, 0x7C, 0x57, 0x0E, 0xDB, 0x1D, 0x61, 0x6E, 0xB5, 0xF9, 0x3D, 0x35, 0xE9, 0x5C, 0xD8,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x33, 0x55, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x7E, 0x50, 0x53, 0x50, 0x00, 0x02, 0x00, 0x00, 0x01, 0x01, 0x22, 0x74, 0x69, 0x66, 0x70, 0x73,
|
||||
0x70, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x33, 0x55, 0x00, 0x50, 0x34, 0x55, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x40, 0x67, 0x3D, 0x00, 0x50, 0x55, 0x0A, 0x01, 0x10, 0x00, 0x40, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x6B, 0x3D, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x4C, 0x6B, 0x3D, 0x00, 0xCC, 0xBB, 0x11, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
// Minna no Sukkiri Demo(421KB)
|
||||
unsigned char pspHeader_small[336] = {
|
||||
0x7E, 0x50, 0x53, 0x50, 0x00, 0x02, 0x01, 0x00, 0x01, 0x01, 0x6D, 0x61, 0x69, 0x6E, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x94, 0x14, 0x11, 0x00, 0x60, 0x90, 0x06, 0x00,
|
||||
0xB8, 0x80, 0x09, 0x00, 0x18, 0xA6, 0x0B, 0x00, 0x70, 0xA1, 0x05, 0x00, 0x10, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x80, 0xAC, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x05, 0x0D, 0x00, 0x00, 0x00,
|
||||
0x8A, 0x42, 0xAA, 0x13, 0xAE, 0x02, 0x9C, 0x16, 0x99, 0x19, 0x3E, 0xEF, 0xE1, 0xCD, 0xFB, 0xBC,
|
||||
0xDA, 0x28, 0x6E, 0xA5, 0x62, 0x67, 0x71, 0xB2, 0x14, 0x12, 0xAB, 0x7E, 0x1C, 0x69, 0x3A, 0x7A,
|
||||
0xB7, 0x40, 0x8E, 0x91, 0xB1, 0x4F, 0x36, 0xE7, 0x82, 0xF1, 0xFD, 0xB1, 0x50, 0x6D, 0x33, 0xB4,
|
||||
0x09, 0x8F, 0x06, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xCB, 0x8D, 0xC7, 0x1B, 0x2A, 0xAF, 0x3B, 0x09, 0x2A, 0x5B, 0x4F, 0x9E, 0xE8, 0xE2, 0xCA, 0x66,
|
||||
0xF0, 0x05, 0xF3, 0xAD, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x12, 0xE3, 0x40,
|
||||
0x6E, 0x14, 0x13, 0xEA, 0xA1, 0x81, 0x64, 0x54, 0x57, 0xBE, 0xA2, 0x43, 0x26, 0x7E, 0x4D, 0x0C,
|
||||
0x4F, 0xA6, 0x87, 0x6A, 0xEA, 0x0D, 0xEF, 0xBE, 0x27, 0xE8, 0x78, 0x2D, 0x10, 0x40, 0x05, 0x96
|
||||
};
|
||||
|
||||
unsigned char kirkHeader_small[272] = {
|
||||
0x9D, 0xC4, 0x48, 0xA6, 0x0E, 0x3C, 0xB7, 0x40, 0x4F, 0x93, 0xFF, 0x56, 0x15, 0x08, 0x28, 0x71,
|
||||
0x3E, 0x52, 0xB5, 0x89, 0xA0, 0x1C, 0xC9, 0xEF, 0x6E, 0x11, 0x0A, 0xC8, 0x28, 0x67, 0x77, 0x66,
|
||||
0xF2, 0xB2, 0x69, 0xCC, 0x08, 0x8C, 0x53, 0xA7, 0xA7, 0x25, 0xF7, 0x2B, 0x84, 0x53, 0x15, 0x54,
|
||||
0x2D, 0x4A, 0xAD, 0xB6, 0x52, 0x40, 0x17, 0xD7, 0xA7, 0xF4, 0xB9, 0x11, 0x17, 0xB7, 0x13, 0x9B,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x09, 0x8F, 0x06, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x7E, 0x50, 0x53, 0x50, 0x00, 0x02, 0x01, 0x00, 0x01, 0x01, 0x6D, 0x61, 0x69, 0x6E, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x94, 0x14, 0x11, 0x00, 0x60, 0x90, 0x06, 0x00,
|
||||
0xB8, 0x80, 0x09, 0x00, 0x18, 0xA6, 0x0B, 0x00, 0x70, 0xA1, 0x05, 0x00, 0x10, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x80, 0xAC, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x05, 0x0D, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
// astonishia story 2(368KB)
|
||||
unsigned char pspHeader_small2[336] = {
|
||||
0x7e, 0x50, 0x53, 0x50, 0x00, 0x02, 0x01, 0x00, 0x01, 0x01, 0x61, 0x73, 0x74, 0x6f, 0x6e, 0x69,
|
||||
0x73, 0x68, 0x69, 0x61, 0x5f, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x5f, 0x32, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x08, 0xf0, 0x0e, 0x00, 0xa0, 0x9f, 0x05, 0x00,
|
||||
0xc8, 0x1f, 0x08, 0x00, 0x24, 0x20, 0x0a, 0x00, 0xec, 0x81, 0x28, 0x00, 0x04, 0x00, 0x08, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0xe9, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x68, 0xe9, 0x0b, 0x00, 0x8c, 0x84, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x07, 0x03, 0x0d, 0x00, 0x00, 0x00,
|
||||
0x4e, 0x98, 0x4a, 0xdf, 0x2d, 0x13, 0x3c, 0x79, 0x1b, 0x16, 0xaf, 0x76, 0xcb, 0x74, 0x8b, 0xa0,
|
||||
0x24, 0x1c, 0xf0, 0x79, 0x22, 0x2a, 0x01, 0x73, 0xc0, 0xbc, 0xf1, 0x51, 0x66, 0x9d, 0x01, 0xc9,
|
||||
0xb1, 0xbb, 0x2e, 0xd8, 0x09, 0xbc, 0xbf, 0x68, 0xe7, 0x86, 0x80, 0xd7, 0x45, 0x8c, 0x58, 0xd2,
|
||||
0x44, 0x9e, 0x05, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x1f, 0x98, 0x28, 0x63, 0x73, 0x50, 0x94, 0x0e, 0xd6, 0x13, 0xfa, 0x0f, 0x50, 0xf8, 0xbf, 0xe8,
|
||||
0xf0, 0x05, 0xf3, 0xad, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x99, 0x35, 0x43, 0xa6,
|
||||
0x62, 0xd4, 0x81, 0xea, 0x75, 0xca, 0x13, 0xe1, 0x27, 0x7e, 0xa3, 0xb8, 0xc1, 0x21, 0xba, 0xcb,
|
||||
0x5d, 0x32, 0x90, 0x80, 0x91, 0x52, 0x0a, 0x08, 0x3f, 0x3b, 0x26, 0x36, 0xd8, 0xb1, 0xd4, 0x8e,
|
||||
};
|
||||
|
||||
unsigned char kirkHeader_small2[272] = {
|
||||
0xa7, 0xa2, 0xd7, 0xe2, 0x21, 0xe8, 0xf8, 0x9d, 0x4f, 0x84, 0x28, 0x94, 0xeb, 0xae, 0xf1, 0x97,
|
||||
0xc2, 0x3d, 0x20, 0xc5, 0xc7, 0x81, 0x0d, 0x74, 0xc5, 0x98, 0x01, 0xb6, 0x2d, 0x81, 0x1a, 0xc1,
|
||||
0x91, 0x13, 0x07, 0x32, 0xf0, 0xb2, 0x44, 0x05, 0xfa, 0x89, 0x0e, 0xf4, 0x0c, 0x63, 0x68, 0x94,
|
||||
0xc3, 0x98, 0xaa, 0xd2, 0x35, 0xe9, 0xd9, 0xc8, 0xa2, 0xed, 0xbf, 0xbc, 0x4b, 0x68, 0x3f, 0x87,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x44, 0x9e, 0x05, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x7e, 0x50, 0x53, 0x50, 0x00, 0x02, 0x01, 0x00, 0x01, 0x01, 0x61, 0x73, 0x74, 0x6f, 0x6e, 0x69,
|
||||
0x73, 0x68, 0x69, 0x61, 0x5f, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x5f, 0x32, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x08, 0xf0, 0x0e, 0x00, 0xa0, 0x9f, 0x05, 0x00,
|
||||
0xc8, 0x1f, 0x08, 0x00, 0x24, 0x20, 0x0a, 0x00, 0xec, 0x81, 0x28, 0x00, 0x04, 0x00, 0x08, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0xe9, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x68, 0xe9, 0x0b, 0x00, 0x8c, 0x84, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x07, 0x03, 0x0d, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
typedef struct Header_List {
|
||||
unsigned char *pspHeader;
|
||||
unsigned char *kirkHeader;
|
||||
} Header_List;
|
||||
|
||||
Header_List header_list[] = {
|
||||
{ pspHeader_small2, kirkHeader_small2 },
|
||||
{ pspHeader_small , kirkHeader_small },
|
||||
{ pspHeader_big , kirkHeader_big },
|
||||
};
|
||||
|
||||
u8 in_buffer[1024*1024*10];
|
||||
u8 out_buffer[1024*1024*10];
|
||||
|
||||
u8 kirk_raw[1024*1024*10];
|
||||
u8 kirk_enc[1024*1024*10];
|
||||
u8 elf[1024*1024*10];
|
||||
|
||||
typedef struct header_keys
|
||||
{
|
||||
u8 AES[16];
|
||||
u8 CMAC[16];
|
||||
}header_keys;
|
||||
|
||||
int load_elf(char *elff)
|
||||
{
|
||||
FILE *fp = fopen(elff, "rb");
|
||||
|
||||
if(fp == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
fseek(fp, 0, SEEK_END);
|
||||
int size = ftell(fp);
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
fread(elf, 1, size, fp);
|
||||
fclose(fp);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
int dumpFile(char *name, void *in, int size)
|
||||
{
|
||||
FILE *fp = fopen(name, "wb");
|
||||
|
||||
if(fp == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
fwrite(in, 1, size, fp);
|
||||
fclose(fp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int get_kirk_size(u8 *key_hdr)
|
||||
{
|
||||
int krawSize = *(u32*)(key_hdr+0x70);
|
||||
|
||||
if(krawSize % 0x10) {
|
||||
krawSize += 0x10 - (krawSize % 0x10); // 16 bytes aligned
|
||||
}
|
||||
|
||||
krawSize += 0x110;
|
||||
|
||||
return krawSize;
|
||||
}
|
||||
|
||||
Header_List *get_header_list(int size)
|
||||
{
|
||||
int i;
|
||||
int h_size;
|
||||
|
||||
for(i=0; i<sizeof(header_list)/sizeof(header_list[i]); i++) {
|
||||
h_size = get_kirk_size(header_list[i].kirkHeader);
|
||||
h_size -= 0x150;
|
||||
|
||||
if( h_size >= size ) {
|
||||
return &header_list[i];
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int is_compressed(u8 *psp_header)
|
||||
{
|
||||
if (*(u16*)(psp_header+6) == 1) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int get_elf_size(u8 *psp_header)
|
||||
{
|
||||
return *(u32*)(psp_header+0x28);
|
||||
}
|
||||
|
||||
int gzip_compress(u8 *dst, const u8 *src, int size)
|
||||
{
|
||||
int ret;
|
||||
z_stream strm;
|
||||
u8 *elf_compress;
|
||||
const int compress_max_size = 10 * 1024 * 1024;
|
||||
|
||||
strm.zalloc = Z_NULL;
|
||||
strm.zfree = Z_NULL;
|
||||
strm.opaque = Z_NULL;
|
||||
|
||||
elf_compress = malloc(compress_max_size);
|
||||
|
||||
if(elf_compress == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = deflateInit2(&strm, 9, Z_DEFLATED, 15+16, 8, Z_DEFAULT_STRATEGY);
|
||||
|
||||
if(ret != Z_OK) {
|
||||
printf("%s: compress error\n", __func__);
|
||||
free(elf_compress);
|
||||
|
||||
return -2;
|
||||
}
|
||||
|
||||
strm.avail_in = size;
|
||||
strm.next_in = (void*)src;
|
||||
strm.avail_out = compress_max_size;
|
||||
strm.next_out = elf_compress;
|
||||
|
||||
ret = deflate(&strm, Z_FINISH);
|
||||
|
||||
if(ret == Z_STREAM_ERROR) {
|
||||
deflateEnd(&strm);
|
||||
printf("%s: compress error\n", __func__);
|
||||
free(elf_compress);
|
||||
|
||||
return -3;
|
||||
}
|
||||
|
||||
memcpy(dst, elf_compress, strm.total_out);
|
||||
deflateEnd(&strm);
|
||||
free(elf_compress);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
header_keys keys;
|
||||
u8 rawkheaderBk[0x90];
|
||||
char *out_fname = NULL;
|
||||
if(argc != 3)
|
||||
{
|
||||
printf("USAGE: %s [input_prx] [output_prx]\n", argv[0]);
|
||||
return 0;
|
||||
}
|
||||
out_fname = argv[2];
|
||||
|
||||
memset(in_buffer, 0, sizeof(in_buffer));
|
||||
memset(out_buffer, 0, sizeof(out_buffer));
|
||||
memset(kirk_raw, 0, sizeof(kirk_raw));
|
||||
memset(kirk_enc, 0, sizeof(kirk_enc));
|
||||
memset(elf, 0, sizeof(elf));
|
||||
|
||||
kirk_init();
|
||||
|
||||
int elfSize = load_elf(argv[1]);
|
||||
|
||||
if(elfSize < 0) {
|
||||
printf("Cannot open %s\n", argv[1]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Header_List *target_header = get_header_list( elfSize );
|
||||
|
||||
if( target_header == NULL ) {
|
||||
printf("PRX SIGNER: Elf is to big\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
u8 *kirkHeader = target_header->kirkHeader;
|
||||
u8 *pspHeader = target_header->pspHeader;
|
||||
int krawSize = get_kirk_size(kirkHeader);
|
||||
|
||||
if (is_compressed(pspHeader)) {
|
||||
elfSize = get_elf_size(pspHeader);
|
||||
gzip_compress(elf, elf, elfSize);
|
||||
}
|
||||
|
||||
memcpy(kirk_raw, kirkHeader, 0x110);
|
||||
memcpy(rawkheaderBk, kirk_raw, sizeof(rawkheaderBk));
|
||||
|
||||
kirk_decrypt_keys((u8*)&keys, kirk_raw);
|
||||
memcpy(kirk_raw, &keys, sizeof(header_keys));
|
||||
memcpy(kirk_raw+0x110, elf, elfSize);
|
||||
|
||||
if(kirk_CMD0(kirk_enc, kirk_raw, sizeof(kirk_enc), 0) != 0)
|
||||
{
|
||||
printf("PRX SIGNER: Could not encrypt elf\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(kirk_enc, rawkheaderBk, sizeof(rawkheaderBk));
|
||||
|
||||
if(kirk_forge(kirk_enc, sizeof(kirk_enc)) != 0)
|
||||
{
|
||||
printf("PRX SIGNER: Could not forge cmac block\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(out_buffer, pspHeader, 0x150);
|
||||
memcpy(out_buffer+0x150, kirk_enc+0x110, krawSize-0x110);
|
||||
|
||||
return dumpFile(out_fname, out_buffer, (krawSize-0x110)+0x150);
|
||||
}
|
158
tools/PrxEncrypter/psp_headers.h
Normal file
158
tools/PrxEncrypter/psp_headers.h
Normal file
@@ -0,0 +1,158 @@
|
||||
typedef struct
|
||||
{
|
||||
u32 e_magic;
|
||||
u8 e_class;
|
||||
u8 e_data;
|
||||
u8 e_idver;
|
||||
u8 e_pad[9];
|
||||
u16 e_type;
|
||||
u16 e_machine;
|
||||
u32 e_version;
|
||||
u32 e_entry;
|
||||
u32 e_phoff;
|
||||
u32 e_shoff;
|
||||
u32 e_flags;
|
||||
u16 e_ehsize;
|
||||
u16 e_phentsize;
|
||||
u16 e_phnum;
|
||||
u16 e_shentsize;
|
||||
u16 e_shnum;
|
||||
u16 e_shstrndx;
|
||||
} __attribute__((packed)) Elf32_Ehdr;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32 p_type;
|
||||
u32 p_offset;
|
||||
u32 p_vaddr;
|
||||
u32 p_paddr;
|
||||
u32 p_filesz;
|
||||
u32 p_memsz;
|
||||
u32 p_flags;
|
||||
u32 p_align;
|
||||
} __attribute__((packed)) Elf32_Phdr;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32 sh_name;
|
||||
u32 sh_type;
|
||||
u32 sh_flags;
|
||||
u32 sh_addr;
|
||||
u32 sh_offset;
|
||||
u32 sh_size;
|
||||
u32 sh_link;
|
||||
u32 sh_info;
|
||||
u32 sh_addralign;
|
||||
u32 sh_entsize;
|
||||
} __attribute__((packed)) Elf32_Shdr;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u16 attribute;
|
||||
u8 module_ver_lo;
|
||||
u8 module_ver_hi;
|
||||
char modname[28];
|
||||
} __attribute__((packed)) PspModuleInfo;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32 signature; //0
|
||||
u16 mod_attribute; //4
|
||||
u16 comp_attribute; //6
|
||||
u8 module_ver_lo; //8
|
||||
u8 module_ver_hi; //9
|
||||
char modname[28]; //0xA
|
||||
u8 mod_version; //0x26
|
||||
u8 nsegments; //0x27
|
||||
u32 elf_size; //0x28
|
||||
u32 psp_size; //0x2C
|
||||
u32 boot_entry; //0x30
|
||||
u32 modinfo_offset; //0x34
|
||||
int bss_size; //0x38
|
||||
u32 seg_align[4]; //0x3C
|
||||
u32 seg_address[4]; //0x44
|
||||
int seg_size[4]; //0x54
|
||||
u32 reserved[5]; //0x64
|
||||
u32 devkit_version; //0x78
|
||||
u8 decrypt_mode; //0x7C
|
||||
u8 padding; //0x7D
|
||||
u8 overlap_size; //0x7E
|
||||
u8 key_data[0x30]; //0x80
|
||||
u32 comp_size; //0xB0
|
||||
int _80; //0xB4
|
||||
u32 unk_B8; //0xB8
|
||||
u32 unk_BC; //0xBC
|
||||
u8 key_data2[0x10]; //0xC0
|
||||
u32 tag; //0xD0
|
||||
u8 scheck[0x58]; //0xD4
|
||||
u8 sha1_hash[0x14]; //0x12C
|
||||
u8 key_data4[0x10]; //0x140
|
||||
} PSP_Header2; //0x150
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32 signature; // 0
|
||||
PspModuleInfo mod_info; //4
|
||||
u8 version; // 26
|
||||
u8 nsegments; // 27
|
||||
int elf_size; // 28
|
||||
int psp_size; // 2C
|
||||
u32 entry; // 30
|
||||
u32 modinfo_offset; // 34
|
||||
int bss_size; // 38
|
||||
u16 seg_align[4]; // 3C
|
||||
u32 seg_address[4]; // 44
|
||||
int seg_size[4]; // 54
|
||||
u32 reserved[5]; // 64
|
||||
u32 devkitversion; // 78
|
||||
u32 decrypt_mode; // 7C
|
||||
u8 key_data0[0x30]; // 80
|
||||
int comp_size; // B0
|
||||
int _80; // B4
|
||||
int reserved2[2]; // B8
|
||||
u8 key_data1[0x10]; // C0
|
||||
u32 tag; // D0
|
||||
u8 scheck[0x58]; // D4
|
||||
u32 key_data2; // 12C
|
||||
u32 oe_tag; // 130
|
||||
u8 key_data3[0x1C]; // 134
|
||||
} __attribute__((packed)) PSP_Header;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u8 signature[4]; //0
|
||||
u16 mod_attribute; //4
|
||||
u16 comp_attribute; //6
|
||||
u8 module_ver_lo; //8
|
||||
u8 module_ver_hi; //9
|
||||
char modname[28]; //A
|
||||
u8 mod_version; //26
|
||||
u8 nsegments; //27
|
||||
u32 elf_size; //28
|
||||
u32 psp_size; //2C
|
||||
u32 boot_entry; //30
|
||||
u32 modinfo_offset; //34
|
||||
u32 bss_size; //38
|
||||
u16 seg_align[4]; //3C
|
||||
u32 seg_address[4]; //44
|
||||
u32 seg_size[4]; //54
|
||||
u32 reserved[5]; //64
|
||||
u32 devkit_version; //78
|
||||
u8 decrypt_mode; //7C
|
||||
u8 padding; //7D
|
||||
u16 overlap_size; //7E
|
||||
u8 aes_key[0x10]; //80
|
||||
u8 cmac_key[0x10]; //90
|
||||
u8 cmac_header_hash[0x10]; //A0
|
||||
u32 comp_size; //B0
|
||||
u32 _80; //B4
|
||||
u32 unk_B8; //B8
|
||||
u32 unk_BC; //BC
|
||||
u8 cmac_data_hash[0x10]; //C0
|
||||
u32 tag; //D0
|
||||
u8 scheck[0x58]; //D4
|
||||
u8 sha1_hash[0x14]; //12C
|
||||
u8 key_data4[0x10]; //140
|
||||
} PSP_HEADER, *LPPSP_HEADER;
|
20
tools/PrxEncrypter/types.h
Normal file
20
tools/PrxEncrypter/types.h
Normal file
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* types.h
|
||||
*
|
||||
* Created on: Jan 4, 2011
|
||||
*/
|
||||
|
||||
#ifndef TYPES_H_
|
||||
#define TYPES_H_
|
||||
|
||||
typedef char s8;
|
||||
typedef short s16;
|
||||
typedef int s32;
|
||||
typedef long long s64;
|
||||
|
||||
typedef unsigned char u8;
|
||||
typedef unsigned short u16;
|
||||
typedef unsigned int u32;
|
||||
typedef unsigned long long u64;
|
||||
|
||||
#endif /* TYPES_H_ */
|
Reference in New Issue
Block a user