From fb700c2ee9a6a5a364354f8be75f5e6c6ed05662 Mon Sep 17 00:00:00 2001 From: AKuHAK <621640+AKuHAK@users.noreply.github.com> Date: Wed, 14 Sep 2022 17:58:10 +0300 Subject: [PATCH] Added arcade support with fixed Kbit and Kc keys. Adjusted Readme. --- README.md | 31 ++++++++++++++++++++++++++++++- src/kelf.cpp | 22 +++++++++++++++++++--- src/kelf.h | 10 ++++------ src/keystore.cpp | 4 ++++ src/keystore.h | 4 ++++ 5 files changed, 61 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 1e21476..4f58e82 100644 --- a/README.md +++ b/README.md @@ -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 - encrypt and sign kelf files : 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 should show 0x100000 or 0x100008 +headerless elf creation: + + $(EE_OBJCOPY) -O binary -v +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* @@ -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. diff --git a/src/kelf.cpp b/src/kelf.cpp index 83c59fd..fef504f 100644 --- a/src/kelf.cpp +++ b/src/kelf.cpp @@ -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)) { @@ -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); @@ -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 diff --git a/src/kelf.h b/src/kelf.h index 281e020..f94211a 100644 --- a/src/kelf.h +++ b/src/kelf.h @@ -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 @@ -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. ?? diff --git a/src/keystore.cpp b/src/keystore.cpp index 1feed52..ec7ca5d 100644 --- a/src/keystore.cpp +++ b/src/keystore.cpp @@ -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 || diff --git a/src/keystore.h b/src/keystore.h index 47d157a..436a983 100644 --- a/src/keystore.h +++ b/src/keystore.h @@ -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); @@ -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); };