Skip to content

Commit

Permalink
Added arcade support with fixed Kbit and Kc keys.
Browse files Browse the repository at this point in the history
Adjusted Readme.
  • Loading branch information
AKuHAK committed Sep 14, 2022
1 parent c87b4a0 commit fb700c2
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 10 deletions.
31 changes: 30 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,33 @@ An open-source utility for decrypting, encrypting and signing PS2/PSX DESR KELF

## You need to bring your keys

Place them at your home directory (%USERPROFILE%) in the "PS2KEYS.dat" file as a 'KEY=HEX_VALUE' pair.
Place them in your home directory (%USERPROFILE%) in the "PS2KEYS.dat" file as a 'KEY=HEX_VALUE' pair. Or place them in your working directory.

## Usage

decrypt - decrypt and check the signature of kelf files
encrypt <headerid> - encrypt and sign kelf files <headerid>: fmcb, fhdb, mbr
fmcb - for retail PS2 memory cards
fhdb - for retail PS2 HDD (HDD OSD / BB Navigator)
mbr - for retail PS2 HDD (mbr injection).
Note: for mbr, elf should load from 0x100000 and should be without headers:
readelf -h <input_elf> should show 0x100000 or 0x100008
headerless elf creation:

$(EE_OBJCOPY) -O binary -v <input_elf> <headerless_elf>
examples:

kelftool encrypt fhdb input.elf output.kelf
kelftool decrypot input.kelf output.elf

*decrypt* command will also print useful information about kelf

## SHA256 Hashes of the keys

### THESE ARE HASHES, NOT THE ACTUAL KEYS

#### Retail

**MG_SIG_MASTER_KEY**=*e6e41172c069b752b9e88d31c70606c580b1c15ee782abd83cf34117bfc47c91*
**MG_SIG_HASH_KEY**=*0dc3a1e225d3e701cfd07c2b25e7a3cc661ded10870218f1f22f936ba350bef5*
**MG_KBIT_MASTER_KEY**=*1512f3f196d6edb723e3c2f4258f6a937c4efd6441785b02d7c9ea7c817ad8fa*
Expand All @@ -20,3 +41,11 @@ Place them at your home directory (%USERPROFILE%) in the "PS2KEYS.dat" file as a
**MG_ROOTSIG_HASH_KEY**=*5023ea32da5f595d15edf3aad08941dd96ae42a1ad32690a8ca35a024d758bd2*
**MG_CONTENT_TABLE_IV**=*3d9ac39d6e1b69b076da20a38593b2f4ccdd5f943b991c99eacbea13cb1cf0a4*
**MG_CONTENT_IV**=*4e3f5dfaf24c8016c60a23ced78af1e469522dbedb65ca7c8abfb990458f036b*

#### Arcade

Note: for arcade units (Namco System 246/256 and Konami Python 1) it is necessary to provide different keys and also additional keys: **ARCADE_KBIT** and **ARCADE_KC**

#### Dev and proto

For DTL units it is necessary to provide different keys (dev keystore). Proto keystore probably was never used.
22 changes: 19 additions & 3 deletions src/kelf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,12 @@ int Kelf::LoadKelf(const std::string filename)
for (size_t i = 0; i < 16; ++i)
printf(" %02X", (unsigned char)Kc[i]);

// arcade
if (ks.GetArcadeKbit().size() && ks.GetArcadeKc().size()) {
memcpy(Kbit.data(), ks.GetArcadeKbit().data(), 16);
memcpy(Kc.data(), ks.GetArcadeKc().data(), 16);
}

int BitTableSize = header.HeaderSize - ftell(f) - 8 - 8;
printf("\nBitTableSize = %#X\n", BitTableSize);
if (BitTableSize > sizeof(BitTable)) {
Expand Down Expand Up @@ -367,6 +373,10 @@ int Kelf::SaveKelf(const std::string filename, int headerid)
case 2:
USER_HEADER = USER_HEADER_MBR;
break;

default:
USER_HEADER = USER_HEADER_FHDB;
break;
}

memcpy(header.UserDefined, USER_HEADER, 16);
Expand Down Expand Up @@ -440,13 +450,19 @@ int Kelf::LoadContent(const std::string filename, int headerid)

Kbit.resize(16);
memcpy(Kbit.data(), USER_Kbit, 16);
// std::fill(Kbit.data(), Kbit.data() + 16, 0x00);

// TODO: encrypted Kc hold some useful data
Kc.resize(16);
// memset(Kc.data(), 0xBB, Kc.size());

// memcpy(Kbit.data(), USER_Kc_MBR, 16);
std::fill(Kc.data(), Kc.data() + 16, 0xBB);
std::fill(Kc.data(), Kc.data() + 16, 0x00);

// arcade
if (ks.GetArcadeKbit().size() && ks.GetArcadeKc().size()) {
memcpy(Kbit.data(), ks.GetArcadeKbit().data(), 16);
memcpy(Kc.data(), ks.GetArcadeKc().data(), 16);
}

std::fill(bitTable.gap, bitTable.gap + 3, 0);

// You can create your own sets of files
Expand Down
10 changes: 4 additions & 6 deletions src/kelf.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,9 @@ static uint8_t USER_HEADER_FMCB[16] = {0x01, 0x00, 0x00, 0x01, 0x00, 0x03, 0x00,
static uint8_t USER_HEADER_FHDB[16] = {0x01, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x4A, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1B};
static uint8_t USER_HEADER_MBR[16] = {0x01, 0x00, 0x00, 0x04, 0x00, 0x02, 0x01, 0x57, 0x07, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A};

// static uint8_t USER_Kc_MBR[16] = {0xD2 ,0xC6 ,0x8F ,0xC2 ,0xEB ,0xA0 ,0x5B ,0x63 ,0x3F ,0x0B ,0xF8 ,0x7B ,0x46 ,0x0E ,0x0D ,0x93};
// static uint8_t USER_Kbit_MBR[16] = {0x83 ,0x1E ,0x4E ,0x4B ,0x42 ,0xCA ,0x7F ,0x39 ,0x0C ,0xB7 ,0xC5 ,0xFB ,0x81 ,0xB1 ,0x10 ,0xDA};
static uint8_t USER_Kbit_MBR[16] = {0x82, 0xf0, 0x29, 0xad, 0xe9, 0x53, 0x23, 0xf5, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa};
static uint8_t USER_Kbit_FHDB[16] = {0x40, 0xe9, 0x80, 0x4d, 0x2e, 0x92, 0xb0, 0xa8, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa};
static uint8_t USER_Kbit_FMCB[16] = {0xd9, 0x4a, 0x2e, 0x56, 0x01, 0x6e, 0xa7, 0x31, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa};
static uint8_t USER_Kbit_MBR[16] = {0x82, 0xf0, 0x29, 0xad, 0xe9, 0x53, 0x23, 0xf5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
static uint8_t USER_Kbit_FHDB[16] = {0x40, 0xe9, 0x80, 0x4d, 0x2e, 0x92, 0xb0, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
static uint8_t USER_Kbit_FMCB[16] = {0xd9, 0x4a, 0x2e, 0x56, 0x01, 0x6e, 0xa7, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

#pragma pack(push, 1)
struct KELFHeader
Expand All @@ -65,7 +63,7 @@ struct KELFHeader
#define HDR_FLAG2 0x4 // Set. ??
#define HDR_FLAG3 0x8 // Set. ??
#define HDR_FLAG4_1DES 0x10 // Set in kirx. HDR_FLAG4_3DES should be unset. Represents Single DES encryption
#define HDR_FLAG4_3DES 0x20 // Set in kelf. HDR_FLAG4_1DES should be unset. Represents Single DES encryption
#define HDR_FLAG4_3DES 0x20 // Set in kelf. HDR_FLAG4_1DES should be unset. Represents Triple DES encryption
#define HDR_FLAG6 0x40 // Unset. ??
#define HDR_FLAG7 0x80 // Unset. ??
#define HDR_FLAG8 0x100 // Unset. ??
Expand Down
4 changes: 4 additions & 0 deletions src/keystore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,10 @@ int KeyStore::Load(std::string filename)
ContentTableIV = value;
if (key == "MG_CONTENT_IV")
ContentIV = value;
if (key == "ARCADE_KBIT")
ArcadeKbit = value;
if (key == "ARCADE_KC")
ArcadeKc = value;
}

if (SignatureMasterKey.size() == 0 || SignatureHashKey.size() == 0 ||
Expand Down
4 changes: 4 additions & 0 deletions src/keystore.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ class KeyStore
std::string RootSignatureHashKey;
std::string ContentTableIV;
std::string ContentIV;
std::string ArcadeKbit;
std::string ArcadeKc;

public:
int Load(std::string filename);
Expand All @@ -50,6 +52,8 @@ class KeyStore
std::string GetRootSignatureHashKey() { return RootSignatureHashKey; }
std::string GetContentTableIV() { return ContentTableIV; }
std::string GetContentIV() { return ContentIV; }
std::string GetArcadeKbit() { return ArcadeKbit; }
std::string GetArcadeKc() { return ArcadeKc; }

static std::string getErrorString(int err);
};
Expand Down

0 comments on commit fb700c2

Please sign in to comment.