Update code
This commit is contained in:
parent
59b7224db4
commit
851182ce7a
|
@ -11,7 +11,10 @@
|
|||
#include "crypto/aes_cbc.h"
|
||||
#include "crypto/aes_cmac.h"
|
||||
|
||||
// game specific keys, (From .vci header)
|
||||
// game specific keys, used to derive the rif key,
|
||||
// which is used to decrypt the game klicensee.
|
||||
|
||||
// example is from "Smart As."
|
||||
static char RIF_KEY_BUF[0x20] = { 0x12, 0x53, 0x56, 0x29, 0x00, 0x31, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x00, 0x42, 0x21, 0x00, 0x00, 0x00, 0x42, 0x02, 0x00, 0x56, 0x29, 0x05, 0x03, 0x31, 0x3D, 0x20, 0x11, 0x00, 0x00, 0x00, 0x00 };
|
||||
static char KLIC_KEY_BUF[0x20] = { 0x7B, 0x2B, 0xA1, 0xF1, 0xB7, 0x57, 0xF0, 0x35, 0xFA, 0x93, 0x94, 0x0D, 0x1A, 0xB4, 0xD9, 0x1A, 0x18, 0x54, 0xD6, 0xC3, 0xCD, 0xCD, 0x5B, 0x67, 0xE1, 0x07, 0x70, 0xA4, 0x2B, 0x4F, 0xA9, 0x0A };
|
||||
|
||||
|
@ -19,12 +22,23 @@ static char KLIC_KEY_BUF[0x20] = { 0x7B, 0x2B, 0xA1, 0xF1, 0xB7, 0x57, 0xF0, 0x3
|
|||
static char CMD56_PACKET[0x200];
|
||||
static char CMD56_PACKET_RESPONSE[0x200];
|
||||
|
||||
// cmd56 state
|
||||
// CART_RANDOM is used to derive the master_key using bbmac 0x305
|
||||
// and 0x308 (only on RETAIL_KEY_ID)
|
||||
static char VITA_AUTHENTICITY_KEY[0x30];
|
||||
static char CART_RANDOM[0x20];
|
||||
|
||||
// cart lock status
|
||||
// cart lock status, unlocked after successful VITA_AUTHENTICITY_CHECK
|
||||
static uint8_t CART_STATUS = READ_WRITE_LOCK;
|
||||
|
||||
// KEY_ID to use, every gc ive ever seen uses RETAIL_KEY_ID (0x1).
|
||||
// however a PROTOTYPE_KEY_ID1 0x8001 is also allowed,
|
||||
|
||||
// PROTOTYPE_KEY_ID actually has worse security in place,
|
||||
// however sony could easily check for this in a future update
|
||||
// and can use RETAIL_KEY_ID thanks to the racoon exploit anyway.
|
||||
|
||||
// There also exists a PROTOTYPE_KEY_ID2 and 3,0x8002 and 0x8003,
|
||||
// however these are blacklisted as of fw 1.04.
|
||||
static uint16_t KEY_ID = RETAIL_KEY_ID;
|
||||
|
||||
#define PACKET_RESPONSE_START(resp, pack) \
|
||||
|
@ -188,7 +202,7 @@ void handle_vita_random(src_packet_header* packet) {
|
|||
LOG_BUFFER(vita_random, sizeof(vita_random));
|
||||
|
||||
char master_key[0x10];
|
||||
derive_master_key(master_key, KEY_ID);
|
||||
derive_master_key(master_key, CART_RANDOM, KEY_ID);
|
||||
|
||||
LOG("Master Key: ");
|
||||
LOG_BUFFER(master_key, sizeof(master_key));
|
||||
|
@ -243,6 +257,32 @@ void handle_packet(src_packet_header* packet) {
|
|||
}
|
||||
}
|
||||
|
||||
// exposed functions :
|
||||
|
||||
void cmd56_reset() {
|
||||
// lock cart for reading/writing
|
||||
CART_STATUS = READ_WRITE_LOCK;
|
||||
|
||||
// set default key id
|
||||
KEY_ID = RETAIL_KEY_ID;
|
||||
|
||||
// reset keys derived from CMD56 algorithm
|
||||
memset(VITA_AUTHENTICITY_KEY, 0x00, sizeof(VITA_AUTHENTICITY_KEY));
|
||||
memset(CART_RANDOM, 0x00, sizeof(CART_RANDOM));
|
||||
|
||||
// reset packet data
|
||||
memset(CMD56_PACKET, 0x00, sizeof(CMD56_PACKET));
|
||||
memset(CMD56_PACKET_RESPONSE, 0x00, sizeof(CMD56_PACKET_RESPONSE));
|
||||
|
||||
// reset cart specific keys
|
||||
memset(RIF_KEY_BUF, 0x00, sizeof(RIF_KEY_BUF));
|
||||
memset(KLIC_KEY_BUF, 0x00, sizeof(KLIC_KEY_BUF));
|
||||
}
|
||||
|
||||
void cmd56_update_keyid(uint16_t key_id) {
|
||||
KEY_ID = key_id;
|
||||
}
|
||||
|
||||
void cmd56_set_keys(char* rif_part, char* klic_part) {
|
||||
memcpy(RIF_KEY_BUF, rif_part, sizeof(RIF_KEY_BUF));
|
||||
memcpy(KLIC_KEY_BUF, klic_part, sizeof(KLIC_KEY_BUF));
|
||||
|
|
|
@ -39,7 +39,8 @@ enum PACKET_SUB_COMMANDS {
|
|||
};
|
||||
|
||||
// exposed functions:
|
||||
|
||||
void cmd56_reset();
|
||||
void cmd56_update_keyid(uint16_t key_id);
|
||||
void cmd56_set_keys(char* rif_part, char* klic_part);
|
||||
void cmd56_run(char* buffer);
|
||||
|
||||
|
|
|
@ -17,23 +17,34 @@ void encrypt_with_master_key(char* masterKey, char* output, char* data, size_t d
|
|||
AES_CBC_encrypt(data, output, dataLen, masterKey, 0x10, iv);
|
||||
}
|
||||
|
||||
void derive_master_key(char* out, int key_id) {
|
||||
void derive_master_key(char* masterKey, char* cart_random, int key_id) {
|
||||
|
||||
// CART_RANDOM is used to derive the master_key
|
||||
// it is done by first decrypting bbmac 0x305 with a static key based on the key_id into bbmac 0x21.
|
||||
// then the resulting 0x21 key is used to create a AES_128_CMAC hash of the CART_RANDOM
|
||||
// -- on RETAIL_KEY_ID only, the AES_128_CMAC hash is then decrypted using bbmac 0x308 into 0x24,
|
||||
//
|
||||
// this is not possible to implement as the bbmac keys are not yet known.
|
||||
// so instead we have implemented a "replay attack" where we will always use the same VITA_RANDOM every time
|
||||
// this will mean the vita will derive the same 'master key' every time, and can just use it.
|
||||
// NOTE: extracting the key RETAIL_KEY_ID requires using the racoon exploit.
|
||||
|
||||
switch(key_id) {
|
||||
case PROTOTYPE_KEY_ID:
|
||||
memcpy(out, MASTER_KEY_0x8001, sizeof(MASTER_KEY_0x8001));
|
||||
case PROTOTYPE_KEY_ID1:
|
||||
memcpy(masterKey, MASTER_KEY_0x8001, sizeof(MASTER_KEY_0x8001));
|
||||
break;
|
||||
case PROTOTYPE_KEY_ID2:
|
||||
break;
|
||||
case PROTOTYPE_KEY_ID3:
|
||||
break;
|
||||
case RETAIL_KEY_ID:
|
||||
memcpy(out, MASTER_KEY_0x1, sizeof(MASTER_KEY_0x1));
|
||||
memcpy(masterKey, MASTER_KEY_0x1, sizeof(MASTER_KEY_0x1));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void decrypt_secondary_key0(char* cart_random, int key_id, char* vita_authenticity_key, char* secondary_key0) {
|
||||
char master_key[0x10];
|
||||
derive_master_key(master_key, key_id);
|
||||
derive_master_key(master_key, cart_random, key_id);
|
||||
decrypt_with_master_key(master_key, secondary_key0, vita_authenticity_key, 0x10);
|
||||
}
|
|
@ -5,7 +5,7 @@ static char MASTER_KEY_0x8001[0x10] = { 0x39, 0x07, 0xA9, 0x3E, 0x6B, 0x68, 0x8C
|
|||
static char MASTER_KEY_0x1[0x10] = { 0x16, 0x20, 0x5F, 0xA6, 0x71, 0x35, 0xD6, 0x2B, 0x29, 0x08, 0xE7, 0xEC, 0x78, 0x04, 0x1A, 0xE8 }; // keyid = 0x1
|
||||
|
||||
enum KEY_IDS {
|
||||
PROTOTYPE_KEY_ID = 0x8001,
|
||||
PROTOTYPE_KEY_ID1 = 0x8001,
|
||||
|
||||
// on CEX 1.04+ 8002 and 8003 are hardcoded blocked in gcauthmgr.skprx
|
||||
PROTOTYPE_KEY_ID2 = 0x8002,
|
||||
|
@ -17,7 +17,7 @@ enum KEY_IDS {
|
|||
|
||||
void decrypt_with_master_key(char* masterKey, char* output, char* data, size_t dataLen);
|
||||
void encrypt_with_master_key(char* masterKey, char* output, char* data, size_t dataLen);
|
||||
void derive_master_key(char* out, int key_id);
|
||||
void derive_master_key(char* masterKey, char* cart_random, int key_id);
|
||||
void decrypt_secondary_key0(char* cart_random, int key_id, char* vita_authenticity_key, char* secondary_key0);
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue