Skip to content

Commit

Permalink
psp updates
Browse files Browse the repository at this point in the history
add ps1 vmc management
add kirk cmd5
  • Loading branch information
bucanero committed Feb 12, 2024
1 parent 54c3783 commit fd51c9f
Show file tree
Hide file tree
Showing 8 changed files with 1,388 additions and 20 deletions.
3 changes: 2 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ find_package(OpenSSL REQUIRED)

set(VITA_APP_NAME "Apollo Save Tool")
set(VITA_TITLEID "NP0APOLLO")
set(VITA_VERSION "01.24")
set(VITA_VERSION "01.40")

option(APOLLO_ENABLE_LOGGING "enables debug logging over udp multicast" OFF)

Expand Down Expand Up @@ -92,6 +92,7 @@ add_executable(${PROJECT_NAME}
source/psp_decrypter.c
source/vmp_resign.c
source/key_zrif.c
source/ps1card.c
source/ciso.c
)

Expand Down
2 changes: 1 addition & 1 deletion include/kirk_engine.h
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ typedef struct
//kirk-like funcs
int kirk_CMD0(u8* outbuff, u8* inbuff, int size, int generate_trash);
int kirk_CMD1(u8* outbuff, u8* inbuff, int size);

int kirk_CMD5(u8* outbuff, u8* inbuff, int size);
int kirk_CMD4(u8* outbuff, u8* inbuff, int size);
int kirk_CMD7(u8* outbuff, u8* inbuff, int size);
int kirk_CMD10(u8* inbuff, int insize);
Expand Down
92 changes: 92 additions & 0 deletions include/ps1card.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
#include <inttypes.h>

#define PS1CARD_MAX_SLOTS 15
#define PS1CARD_HEADER_SIZE 128
#define PS1CARD_BLOCK_SIZE 8192
#define PS1CARD_SIZE 131072

enum ps1card_type
{
PS1CARD_NULL,
PS1CARD_RAW,
PS1CARD_GME,
PS1CARD_VGS,
PS1CARD_VMP,
PS1CARD_MCX,
};

enum ps1save_type
{
PS1SAVE_NULL,
PS1SAVE_AR,
PS1SAVE_MCS,
PS1SAVE_RAW,
PS1SAVE_PSV,
};

enum ps1block_type
{
PS1BLOCK_FORMATTED,
PS1BLOCK_INITIAL,
PS1BLOCK_MIDDLELINK,
PS1BLOCK_ENDLINK,
PS1BLOCK_DELETED_INITIAL,
PS1BLOCK_DELETED_MIDDLELINK,
PS1BLOCK_DELETED_ENDLINK,
PS1BLOCK_CORRUPTED,
};

typedef struct ps1McData
{
uint8_t* headerData; //Memory Card header data (128 bytes each)
uint8_t* saveData; //Memory Card save data (8192 bytes each)
uint32_t iconPalette[16]; //Memory Card icon palette data
uint8_t iconData[3][256]; //Memory Card icon data, 3 icons per slot, (16*16px icons)
uint8_t iconFrames; //Number of icon frames
uint8_t saveType; //Type of the save (0 - formatted, 1 - initial, 2 - middle link, 3 - end link, 4 - deleted initial, 5 - deleted middle link, 6 - deleted end link, 7 - corrupted)
uint16_t saveRegion; //Region of the save (16 bit value, ASCII representation: BA - America, BE - Europe, BI - Japan)
char saveProdCode[11]; //Product code of the save
char saveIdentifier[9]; //Identifier string of the save
int saveSize; //Size of the save in Bytes
char saveName[21]; //Name of the save
char saveTitle[65]; //Title of the save data (in Shift-JIS format)
} ps1mcData_t;

//Open Memory Card from the given filename (return error message if operation is not sucessful)
int openMemoryCard(const char* fileName, int fixData);

//Open memory card from the given byte stream
int openMemoryCardStream(const uint8_t* memCardData, int dataSize, int fixData);

//Save (export) Memory Card to a given byte stream
uint8_t* saveMemoryCardStream(int fixData);

//Save Memory Card to the given filename
int saveMemoryCard(const char* fileName, int memoryCardType, int fixData);

//Format a complete Memory Card
void formatMemoryCard(void);

//Import single save to the Memory Card
int openSingleSave(const char* fileName, int* requiredSlots);

//Save single save to the given filename
int saveSingleSave(const char* fileName, int slotNumber, int singleSaveType);

//Get icon data as bytes
uint8_t* getIconRGBA(int slotNumber, int frame);

//Set icon data to saveData
void setIconBytes(int slotNumber, uint8_t* iconBytes);

//Return all bytes of the specified save
uint8_t* getSaveBytes(int slotNumber, uint32_t* saveLen);

//Toggle deleted/undeleted status
void toggleDeleteSave(int slotNumber);

//Format save
void formatSave(int slotNumber);

//Get Memory Card data
ps1mcData_t* getMemoryCardData(void);
114 changes: 105 additions & 9 deletions source/kirk_engine.c
Original file line number Diff line number Diff line change
Expand Up @@ -165,11 +165,9 @@ static u8 keyvault[0x80][0x10] =
{0x5F, 0x8C, 0x17, 0x9F, 0xC1, 0xB2, 0x1D, 0xF1, 0xF6, 0x36, 0x7A, 0x9C, 0xF7, 0xD3, 0xD4, 0x7C},
};

static u8 kirk1_key[] = {0x98, 0xC9, 0x40, 0x97, 0x5C, 0x1D, 0x10, 0xE8, 0x7F, 0xE6, 0x0E, 0xA3, 0xFD, 0x03, 0xA8, 0xBA};

static u8 kirk16_key[] = {0x47, 0x5E, 0x09, 0xF4, 0xA2, 0x37, 0xDA, 0x9B, 0xEF, 0xFF, 0x3B, 0xC0, 0x77, 0x14, 0x3D, 0x8A};

static u8 const_Rb[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87};
static const u8 MASTER_KEY[] = {0x47, 0x5E, 0x09, 0xF4, 0xA2, 0x37, 0xDA, 0x9B, 0xEF, 0xFF, 0x3B, 0xC0, 0x77, 0x14, 0x3D, 0x8A};
static const u8 kirk1_key[] = {0x98, 0xC9, 0x40, 0x97, 0x5C, 0x1D, 0x10, 0xE8, 0x7F, 0xE6, 0x0E, 0xA3, 0xFD, 0x03, 0xA8, 0xBA};
static const u8 const_Rb[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87};

/* ------------------------- KEY VAULT END ------------------------- */

Expand All @@ -188,6 +186,7 @@ static u32 g_fuse94;

static aes_context aes_kirk1; //global
static u8 PRNG_DATA[0x14];
static u8 g_mesh[0x40];

static char is_kirk_initialized = 0; //"init" emulation

Expand All @@ -211,7 +210,7 @@ static void AES_cbc_decrypt(aes_context *ctx, u8 *src, u8 *dst, int size)

/* AES-CMAC Generation Function */

static void leftshift_onebit(u8 *input, u8 *output)
static void leftshift_onebit(const u8 *input, u8 *output)
{
u8 overflow = 0;

Expand All @@ -223,7 +222,7 @@ static void leftshift_onebit(u8 *input, u8 *output)
}
}

static void xor_128(u8 *a, u8 *b, u8 *out)
static void xor_128(const u8 *a, const u8 *b, u8 *out)
{
for (int i=0;i<16; i++)
out[i] = a[i] ^ b[i];
Expand Down Expand Up @@ -311,6 +310,78 @@ static void AES_CMAC(aes_context *ctx, u8 *input, int length, u8 *mac)
memcpy(mac, X, sizeof(X));
}

static void init_mesh(void)
{
u8 fuseid[8];
int i, k;
u8 subkey_1[0x10], subkey_2[0x10];
aes_context aes_ctx, aes_ctx2;
memset(g_mesh,0,0x40);

fuseid[7] = g_fuse90 &0xFF;
fuseid[6] = (g_fuse90>>8) &0xFF;
fuseid[5] = (g_fuse90>>16) &0xFF;
fuseid[4] = (g_fuse90>>24) &0xFF;
fuseid[3] = g_fuse94 &0xFF;
fuseid[2] = (g_fuse94>>8) &0xFF;
fuseid[1] = (g_fuse94>>16) &0xFF;
fuseid[0] = (g_fuse94>>24) &0xFF;
/* set encryption key */
aes_setkey_enc(&aes_ctx, MASTER_KEY, 128);
aes_setkey_dec(&aes_ctx2, MASTER_KEY, 128);

/* set the subkeys */
for (i = 0; i < 0x10; i++)
{
/* set to the fuseid */
subkey_2[i] = subkey_1[i] = fuseid[i % 8];
}

/* do aes crypto */
for (i = 0; i < 3; i++)
{
/* encrypt + decrypt */
aes_crypt_ecb(&aes_ctx, AES_ENCRYPT, subkey_1, subkey_1);
aes_crypt_ecb(&aes_ctx2, AES_DECRYPT, subkey_2, subkey_2);
}

/* set new key */
aes_setkey_enc(&aes_ctx, subkey_1, 128);

/* now lets make the key mesh */
for (i = 0; i < 3; i++)
{
/* do encryption in group of 3 */
for (k = 0; k < 3; k++)
{
/* crypto */
aes_crypt_ecb(&aes_ctx, AES_ENCRYPT, subkey_2, subkey_2);
}

/* copy to out block */
memcpy(&g_mesh[i * 0x10], subkey_2, 0x10);
}
}

static void generate_key_from_mesh(u8 * key, int param)
{
u8 genkey[0x10];
aes_context aes_ctx;
int i;
memset(genkey,0,0x10);
int rounds = (param >> 1) +1;
memcpy(genkey,&g_mesh[(param&1) * 0x10], 0x10);

aes_setkey_enc(&aes_ctx, &g_mesh[0x20], 128);
for (i = 0; i < rounds; i++)
{
/* encrypt the data */
aes_crypt_ecb(&aes_ctx, AES_ENCRYPT, genkey, genkey);
}
memcpy(key,genkey,0x10);
return;
}

/* ------------------------- IMPLEMENTATION ------------------------- */

int kirk_CMD0(u8* outbuff, u8* inbuff, int size, int generate_trash)
Expand Down Expand Up @@ -401,6 +472,26 @@ int kirk_CMD4(u8* outbuff, u8* inbuff, int size)
return KIRK_OPERATION_SUCCESS;
}

int kirk_CMD5(u8* outbuff, u8* inbuff, int size)
{
KIRK_AES128CBC_HEADER *header = (KIRK_AES128CBC_HEADER*)inbuff;
u8 key[0x10];
aes_context aesKey;

if(is_kirk_initialized == 0) return KIRK_NOT_INITIALIZED;
if(header->mode != KIRK_MODE_ENCRYPT_CBC) return KIRK_INVALID_MODE;
if(header->keyseed != 0x100) return KIRK_INVALID_MODE;
if(header->data_size == 0) return KIRK_DATA_SIZE_ZERO;

generate_key_from_mesh(key,1);

//Set the key
aes_setkey_enc(&aesKey, key, 128);
AES_cbc_encrypt(&aesKey, inbuff+sizeof(KIRK_AES128CBC_HEADER), outbuff+sizeof(KIRK_AES128CBC_HEADER), header->data_size);

return KIRK_OPERATION_SUCCESS;
}

int kirk_CMD7(u8* outbuff, u8* inbuff, int size)
{
KIRK_AES128CBC_HEADER *header = (KIRK_AES128CBC_HEADER*)inbuff;
Expand Down Expand Up @@ -543,6 +634,7 @@ static int kirk_init2(u8 * rnd_seed, u32 seed_size, u32 fuseid_90, u32 fuseid_94
//Set Fuse ID
g_fuse90=fuseid_90;
g_fuse94=fuseid_94;
init_mesh();

//Set KIRK1 main key
aes_setkey_enc(&aes_kirk1, kirk1_key, 128);
Expand All @@ -552,12 +644,15 @@ static int kirk_init2(u8 * rnd_seed, u32 seed_size, u32 fuseid_90, u32 fuseid_94
return 0;
}

int kirk_init()
int kirk_init(void)
{
if (is_kirk_initialized)
return 0;

return kirk_init2((u8*)"Lazy Dev should have initialized!", 33, 0xBABEF00D, 0xDEADBEEF);
// Get device Fuse ID
uint64_t fuseId = (0xBC100090);

return kirk_init2((u8*)"Lazy Dev should have initialized!", 33, (fuseId & 0xFFFFFFFF), (fuseId >> 32));
}

static u8* kirk_4_7_get_key(int key_type)
Expand All @@ -574,6 +669,7 @@ int sceUtilsBufferCopyWithRange(u8* outbuff, int outsize, u8* inbuff, int insize
case KIRK_CMD_ENCRYPT_PRIVATE: return kirk_CMD0(outbuff, inbuff, insize, 1); break;
case KIRK_CMD_DECRYPT_PRIVATE: return kirk_CMD1(outbuff, inbuff, insize); break;
case KIRK_CMD_ENCRYPT_IV_0: return kirk_CMD4(outbuff, inbuff, insize); break;
case KIRK_CMD_ENCRYPT_IV_FUSE: return kirk_CMD5(outbuff, inbuff, insize); break;
case KIRK_CMD_DECRYPT_IV_0: return kirk_CMD7(outbuff, inbuff, insize); break;
case KIRK_CMD_PRIV_SIGN_CHECK: return kirk_CMD10(inbuff, insize); break;
case KIRK_CMD_SHA1_HASH: return kirk_CMD11(outbuff, inbuff, insize); break;
Expand Down
3 changes: 2 additions & 1 deletion source/menu_options.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "menu.h"
#include "menu_gui.h"
#include "libfont.h"
#include "vitapad.h"

static void _draw_OptionsMenu(u8 alpha)
{
Expand All @@ -32,7 +33,7 @@ static void _draw_OptionsMenu(u8 alpha)
DrawTextureCenteredX(&menu_textures[c], OPTION_ITEM_OFF-2, y_off-4, 0, menu_textures[c].width, menu_textures[c].height, 0xFFFFFF00 | alpha);
break;
case APP_OPTION_CALL:
DrawTextureCenteredX(&menu_textures[footer_ico_cross_png_index], OPTION_ITEM_OFF, y_off+4, 0, menu_textures[footer_ico_cross_png_index].width * 3/4, menu_textures[footer_ico_cross_png_index].height * 3/4, 0xFFFFFF00 | alpha);
DrawTextureCenteredX(&menu_textures[vitaPadGetConf()->crossButtonOK ? footer_ico_cross_png_index : footer_ico_circle_png_index], OPTION_ITEM_OFF, y_off+4, 0, menu_textures[footer_ico_cross_png_index].width * 3/4, menu_textures[footer_ico_cross_png_index].height * 3/4, 0xFFFFFF00 | alpha);
break;
case APP_OPTION_LIST:
SetFontAlign(FONT_ALIGN_CENTER);
Expand Down
Loading

0 comments on commit fd51c9f

Please sign in to comment.