Bemanitools v5.26 release

This commit is contained in:
icex2
2019-09-27 22:36:50 +02:00
commit cbd7720349
718 changed files with 62731 additions and 0 deletions
+14
View File
@@ -0,0 +1,14 @@
libs += security
libs_security := \
util \
src_security := \
id.c \
mcode.c \
rp-blowfish.c \
rp-sign-key.c \
rp.c \
rp2.c \
rp3.c \
util.c \
+142
View File
@@ -0,0 +1,142 @@
#include <string.h>
#include "security/id.h"
#include "util/hex.h"
#include "util/log.h"
#include "util/mem.h"
const struct security_id security_id_default = {
.header = SECURITY_ID_HEADER,
.id = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08},
.checksum = 0x6F,
};
static uint8_t security_id_checksum_calc(uint8_t initseed,
const uint8_t* inbuf, size_t length)
{
const uint8_t *v3; // edi@1
int v4; // ebp@2
uint8_t result; // al@2
unsigned int v6; // esi@3
signed int v7; // ebx@3
int v8; // edx@4
uint8_t v9; // al@4
int v10; // edx@6
uint8_t v11; // al@6
int v12; // edx@8
uint8_t v13; // al@8
int v14; // edx@10
v3 = inbuf;
if (length <= 0) {
result = initseed;
} else {
v4 = length;
result = initseed;
do {
v6 = *v3;
v7 = 0;
do {
v8 = (result ^ (uint8_t) (v6 >> v7)) & 1;
v9 = result >> 1;
if (v8) {
v9 ^= 0x8Cu;
}
v10 = (v9 ^ (uint8_t) (v6 >> (v7 + 1))) & 1;
v11 = v9 >> 1;
if (v10) {
v11 ^= 0x8Cu;
}
v12 = (v11 ^ (uint8_t) (v6 >> (v7 + 2))) & 1;
v13 = v11 >> 1;
if (v12) {
v13 ^= 0x8Cu;
}
v14 = (v13 ^ (uint8_t) (v6 >> (v7 + 3))) & 1;
result = v13 >> 1;
if (v14) {
result ^= 0x8Cu;
}
v7 += 4;
} while (v7 < 8);
v3 = (v3 + 1);
--v4;
} while (v4);
}
return result;
}
static uint8_t security_id_checksum_buffer(const uint8_t* inbuf)
{
uint8_t bufcheck[7];
bufcheck[0] = inbuf[1];
bufcheck[1] = inbuf[7];
bufcheck[2] = inbuf[6];
bufcheck[3] = inbuf[5];
bufcheck[4] = inbuf[4];
bufcheck[5] = inbuf[3];
bufcheck[6] = inbuf[2];
return security_id_checksum_calc(0, bufcheck, sizeof(bufcheck));
}
bool security_id_parse(const char* str, struct security_id* id)
{
log_assert(str);
log_assert(id);
return hex_decode(id, sizeof(struct security_id), str, strlen(str));
}
char* security_id_to_str(const struct security_id* id, bool id_only)
{
char* str;
size_t len;
log_assert(id);
if (id_only) {
len = sizeof(id->id) * 2 + 1;
str = xmalloc(len);
hex_encode_uc(id->id, sizeof(id->id), str, len);
} else {
len = sizeof(struct security_id) * 2 + 1;
str = xmalloc(len);
hex_encode_uc(id, sizeof(*id), str, len);
}
str[len - 1] = '\0';
return str;
}
void security_id_prepare(struct security_id* id)
{
log_assert(id);
id->header = SECURITY_ID_HEADER;
id->checksum = security_id_checksum_buffer(id->id);
}
bool security_id_verify(const struct security_id* id)
{
log_assert(id);
return id->header == SECURITY_ID_HEADER &&
id->checksum == security_id_checksum_buffer(id->id);
}
+58
View File
@@ -0,0 +1,58 @@
#ifndef SECURITY_ID
#define SECURITY_ID
#include <stdbool.h>
#include <stdint.h>
#define SECURITY_ID_HEADER 0x01
/**
* Structure of a security id, e.g. PCBID or EAMID.
*/
struct security_id {
uint8_t header;
uint8_t id[8];
uint8_t checksum;
};
/**
* "Default" security id with updated header and cheacksum ready for use.
*/
extern const struct security_id security_id_default;
/**
* Parse a stringified security id, e.g. PCBID, EAMID.
*
* @param str String representation of id.
* @param id Pointer to a security_id struct to write the result to.
* @return True on successf, false on parsing error.
*/
bool security_id_parse(const char* str, struct security_id* id);
/**
* Stringify a security_id struct.
*
* @param id Id to stringify.
* @param id_only True to stringify id only, false stringify header, id and
* checksum.
* @return Allocated string with stringified data. Caller must manage memory.
*/
char* security_id_to_str(const struct security_id* id, bool id_only);
/**
* Prepare a security id, i.e. update header and checksum.
*
* @param id Id to prepare.
*/
void security_id_prepare(struct security_id* id);
/**
* Verify a provided security id, i.e. check header and checksum.
*
* @param id Id to verify.
* @return True if verification is successful, false on header or checksum
* mismatch.
*/
bool security_id_verify(const struct security_id* id);
#endif
+48
View File
@@ -0,0 +1,48 @@
#include <string.h>
#include "security/mcode.h"
#include "util/log.h"
#include "util/mem.h"
const struct security_mcode security_mcode_eamuse = {
.header = '@',
.unkn = '@',
.game = "@@@",
.region = '@',
.cabinet = '@',
.revision = '@',
};
bool security_mcode_parse(const char* str, struct security_mcode* mcode)
{
size_t len;
log_assert(str);
log_assert(mcode);
memset(mcode, ' ', sizeof(struct security_mcode));
len = strlen(str);
if (len > sizeof(struct security_mcode)) {
return false;
}
memcpy(mcode, str, len);
return true;
}
char* security_mcode_to_str(const struct security_mcode* mcode)
{
char* str;
log_assert(mcode);
str = xmalloc(sizeof(struct security_mcode) + 1);
memcpy(str, mcode, sizeof(struct security_mcode));
str[sizeof(struct security_mcode)] = '\0';
return str;
}
+107
View File
@@ -0,0 +1,107 @@
#ifndef SECURITY_MCODE_H
#define SECURITY_MCODE_H
#include <stdbool.h>
/* Used to fill up empty spaces */
#define SECURITY_MCODE_FIELD_BLANK ' '
#define SECURITY_MCODE_FIELD_NULL '\0'
/* Header */
#define SECURITY_MCODE_HEADER 'G'
/* Unkn */
#define SECURITY_MCODE_UNKN_C 'C'
#define SECURITY_MCODE_UNKN_E 'E'
#define SECURITY_MCODE_UNKN_K 'K'
#define SECURITY_MCODE_UNKN_N 'N'
#define SECURITY_MCODE_UNKN_Q 'Q'
/* Games */
#define SECURITY_MCODE_GAME_LEN 3
/* IIDX */
#define SECURITY_MCODE_GAME_IIDX_1 "863"
#define SECURITY_MCODE_GAME_IIDX_1_CLUB "896"
#define SECURITY_MCODE_GAME_IIDX_SUB "983"
#define SECURITY_MCODE_GAME_IIDX_CLUB_2 "984"
#define SECURITY_MCODE_GAME_IIDX_2 "985"
#define SECURITY_MCODE_GAME_IIDX_3 "992"
#define SECURITY_MCODE_GAME_IIDX_4 "A03"
#define SECURITY_MCODE_GAME_IIDX_5 "A17"
#define SECURITY_MCODE_GAME_IIDX_6 "B4U"
#define SECURITY_MCODE_GAME_IIDX_7 "B44"
#define SECURITY_MCODE_GAME_IIDX_8 "C44"
#define SECURITY_MCODE_GAME_IIDX_9 "C02"
#define SECURITY_MCODE_GAME_IIDX_10 "D01"
#define SECURITY_MCODE_GAME_IIDX_11 "E11"
#define SECURITY_MCODE_GAME_IIDX_12 "ECO"
#define SECURITY_MCODE_GAME_IIDX_13 "FDD"
#define SECURITY_MCODE_GAME_IIDX_14 "GLD"
#define SECURITY_MCODE_GAME_IIDX_15 "HDD"
#define SECURITY_MCODE_GAME_IIDX_16 "I00"
#define SECURITY_MCODE_GAME_IIDX_17 "JDJ"
#define SECURITY_MCODE_GAME_IIDX_18 "JDZ"
#define SECURITY_MCODE_GAME_IIDX_19 "KDZ"
#define SECURITY_MCODE_GAME_IIDX_20 "LDJ"
#define SECURITY_MCODE_GAME_IIDX_21 "LDJ"
#define SECURITY_MCODE_GAME_IIDX_22 "LDJ"
#define SECURITY_MCODE_GAME_IIDX_23 "LDJ"
#define SECURITY_MCODE_GAME_IIDX_24 "LDJ"
/* Jubeat */
#define SECURITY_MCODE_GAME_JB_1 "H44"
/* Region */
#define SECURITY_MCODE_REGION_ASIA 'A'
#define SECURITY_MCODE_REGION_JAPAN 'J'
/* Cabinet */
#define SECURITY_MCODE_CABINET_A 'A'
/* Revision */
#define SECURITY_MCODE_REVISION_A 'A'
#define SECURITY_MCODE_REVISION_B 'B'
#define SECURITY_MCODE_REVISION_C 'C'
#define SECURITY_MCODE_REVISION_D 'D'
#define SECURITY_MCODE_REVISION_E 'E'
#define SECURITY_MCODE_REVISION_F 'F'
#define SECURITY_MCODE_REVISION_G 'G'
/**
* Structure to represent a Konami mcode which is used to identify games and
* different hardware/software revisions.
*/
struct security_mcode {
char header;
char unkn;
/* Identify the game and version, e.g. IIDX 12 */
char game[3];
char region;
char cabinet;
char revision;
};
/**
* Default mcode used to identify white eamuse roundplugs.
*/
extern const struct security_mcode security_mcode_eamuse;
/**
* Parse an mcode from a string representation.
*
* @param str String to parse.
* @param mcode Pointer to a security_mcode struct to write the result to.
* @return True on success, false on parsing error.
*/
bool security_mcode_parse(const char* str, struct security_mcode* mcode);
/**
* Stringify an mcode.
*
* @param mcode Mcode to stringify.
* @return String containing the stringified mcode. Caller has to manage memory.
*/
char* security_mcode_to_str(const struct security_mcode* mcode);
#endif
+228
View File
@@ -0,0 +1,228 @@
#ifndef SECURITY_RP_BLOWFISH_TABLE_H
#define SECURITY_RP_BLOWFISH_TABLE_H
#include <stdint.h>
/**
* Custom pbox for blowfish used by the roundplug module.
*/
static const uint32_t security_rp_blowfish_table_custom_pbox[16 + 2] = {
0x79F4182B, 0x0B4B1751, 0x170170D8, 0x4C0F65E3,
0x24F05558, 0x1E46FA6, 0x61E35AB, 0x579903BE,
0x1E6D3235, 0x47D05ED6, 0x722F4F14, 0x53031912,
0x2C4771B1, 0x56C43044, 0x4F8A5C95, 0x6A490262,
0x176C1D7F, 0x64274C38
};
/**
* Custom sbox for blowfish used by the roundplug module.
*/
static const uint32_t security_rp_blowfish_table_custom_sbox[4 * 256] = {
0x4BD821B3, 0x6D5E005A, 0x0C5F6494, 0x45960A5D, 0x56956C75,
0x1CA85246, 0x4BB809AD, 0x25601443, 0x79930BE9, 0x45826099,
0x2AA261C7, 0x70A57DE, 0x17756A0, 0x2EB87768, 0x635C62A4,
0x1BCC0A05, 0x763A412D, 0x550F10EC, 0x35BA414D, 0x671238F4,
0x63A904A9, 0x77BA3004, 0x57A1208B, 0x32FC6ECB, 0x71E65532,
0x74E64AB1, 0x358E4F6D, 0x54DF640D, 0x4DE52868, 0x762F4498,
0x30F17C5, 0x41C24222, 0x61EF0BEE, 0x6D287983, 0x1B481CAA,
0x72E175D5, 0x5E220BEF, 0x5FD857E0, 0x317048F8, 0x1A2D11D6,
0x10EF2996, 0x5370B41, 0x51514DCB, 0x26CA4139, 0x0F9B6195,
0x31B536DA, 0x2FCC3108, 0x198F49F5, 0x2EBF429F, 0x13B44006,
0x4B526BD4, 0x298A1F66, 0x4AC813EE, 0x400928C2, 0x5C6C191B,
0x387A04CC, 0x60770BBE, 0x0E7E7A30, 0x1634340A, 0x17533FCA,
0x756215D0, 0x46533F16, 0x36DA6695, 0x1ABD5AE8, 0x507229E8,
0x1AB80E5D, 0x682067F3, 0x7F957811, 0x263324F, 0x77552592,
0x6FDE6B1D, 0x1F6B3315, 0x3E460252, 0x1CC31368, 0x307F1D52,
0x75021428, 0x2025CC1, 0x0D107234, 0x79823495, 0x70D41261,
0x0ECF0A70, 0x483E3270, 0x27FA0E2E, 0x1D8B263D, 0x31BA00B9,
0x58C47538, 0x170E5D25, 0x14886C19, 0x5C2417F9, 0x300C76D0,
0x607A68CA, 0x426056BB, 0x0C43520F, 0x52F4091C, 0x6D0C5B30,
0x7B5A71CA, 0x59F30E0, 0x564D1E27, 0x55281FAD, 0x5FF33451,
0x59961CD5, 0x2B5F629D, 0x1144515C, 0x115A6341, 0x3FD95B5B,
0x3C636850, 0x7A6D399B, 0x35F403EC, 0x3EED1562, 0x590760B7,
0x1AC05E8D, 0x4DD95E8A, 0x24AA6DDF, 0x72EE676A, 0x4DF12199,
0x575510B7, 0x4EBF284B, 0x2A2D5CA7, 0x31C86DE9, 0x43682FF3,
0x432C5F21, 0x29CF4FD0, 0x669F76EC, 0x3A467C21, 0x18C74A64,
0x545279EB, 0x1FE506D5, 0x2FD82209, 0x2FB81616, 0x40284821,
0x49F5D1A, 0x48390DD6, 0x39FD48C2, 0x436763F, 0x5FE11CF5,
0x0C3A4D98, 0x13E739F3, 0x54593938, 0x21594BE6, 0x6DDF03C3,
0x6C9A18BB, 0x6DDC79A1, 0x2DC5602F, 0x1CE069AF, 0x3E91022D,
0x54031E34, 0x7F785F57, 0x2B286216, 0x181827E3, 0x5C83664E,
0x16D90CA8, 0x1591B99, 0x33D00678, 0x0C075470, 0x3AE327B1,
0x2346433B, 0x612E2C0F, 0x42AD28C2, 0x9A63AC4, 0x447846E4,
0x3CFC0ECB, 0x38876B8B, 0x58C57979, 0x2CAA27DF, 0x39D77355,
0x4A1B07BA, 0x65F62F29, 0x6C4C5D5C, 0x78B06359, 0x14E37561,
0x57853D74, 0x610346F0, 0x714B3409, 0x63CE7434, 0x0CD12ABC,
0x0A282F10, 0x6AC31C98, 0x6BBD560E, 0x3ECD40A7, 0x2D455D99,
0x44035CC0, 0x5807596D, 0x70813AA1, 0x4A9B3A4B, 0x0C4E733E,
0x26F513F1, 0x2F870458, 0x619F7F49, 0x6BB96450, 0x56466CE1,
0x248E083E, 0x5787B9B, 0x5BAC103E, 0x5FAC27A6, 0x73DA0E0A,
0x418365AC, 0x2F6419CE, 0x54D7E4D, 0x6DC12937, 0x4DCF3DCD,
0x6C745CCD, 0x6E444C09, 0x0F303784, 0x13A140B0, 0x733F748D,
0x131D47AF, 0x52256F72, 0x1F169ED, 0x77805262, 0x7A5C4E39,
0x4E327ECA, 0x31EB0681, 0x48C26425, 0x44F73D44, 0x29003914,
0x5B6F5749, 0x6AE84AB1, 0x0AD85D92, 0x56C95620, 0x1991438C,
0x7EA72068, 0x75C5D88, 0x2ADD4081, 0x7F1A1B6E, 0x7A064FAF,
0x15D65BB0, 0x381E740E, 0x7B056A7E, 0x30E5796D, 0x7E0C0139,
0x1846C5F, 0x0D035A29, 0x2D736B90, 0x10B92C72, 0x7A9A2356,
0x49F82444, 0x58B72788, 0x140A2B53, 0x57FF1F93, 0x307B1587,
0x730878CA, 0x2105F4, 0x2FE612FE, 0x4D5A200C, 0x5C951B4F,
0x0B955913, 0x6A970941, 0x30147DD4, 0x2DDD7213, 0x7F04093,
0x2EB264C, 0x2F5D6342, 0x20384D96, 0x0E2F51F8, 0x16D374CF,
0x7D9D419E, 0x464C425E, 0x7B4526EC, 0x47D244C3, 0x0D711994,
0x14990F72, 0x3C9977BC, 0x6B7F19E2, 0x46295DB2, 0x39EE14E1,
0x6C8345DB, 0x0C042A2A, 0x84864ED, 0x47F15A39, 0x3ED4165E,
0x38A16C5E, 0x2076D1D, 0x2B9C2511, 0x3D4B3C7F, 0x262A3685,
0x53D22D7C, 0x75BA1F80, 0x5420341B, 0x1F846C69, 0x4CA792B,
0x736E0EA3, 0x2E7D0C34, 0x462C3E19, 0x474171AD, 0x16AC191A,
0x62FF616F, 0x22B17668, 0x0D41496A, 0x2EBE1D8B, 0x703A6897,
0x535596B, 0x6D06162D, 0x70C0191E, 0x9330918, 0x35F012FF,
0x557F33A7, 0x50241E00, 0x31E30785, 0x75AD3541, 0x12D135EA,
0x272F59E1, 0x2BBB4012, 0x4E4A4714, 0x22D46BEF, 0x2F7A2C75,
0x321A711B, 0x333C629E, 0x59947210, 0x4A734DF6, 0x6D8159B,
0x720963CB, 0x55D1548E, 0x19D905A1, 0x4EBF4FB6, 0x72CD26C9,
0x457F420C, 0x68437035, 0x3E0D632F, 0x48B6568A, 0x7A474E12,
0x619A5677, 0x14F43FF2, 0x12874B46, 0x4E04438C, 0x1B9A13B0,
0x6C191C8C, 0x2B1978F6, 0x57470748, 0x6E550C2D, 0x511820AE,
0x29D56DD9, 0x6DD40A7B, 0x1CB033BE, 0x32FF1FAF, 0x333B60F3,
0x7F224D3D, 0x4CE42438, 0x1ECF6306, 0x195E5089, 0x32DF7108,
0x50FF43F4, 0x4BFE04D3, 0x4C6630A7, 0x5F6A5B3D, 0x3F607C4D,
0x78F75A57, 0x1B0D299B, 0x4E5767A0, 0x5B3E0025, 0x17986E78,
0x43226677, 0x50EE2AD7, 0x4D222261, 0x49B30C3E, 0x52097392,
0x24AC44EE, 0x2B683C68, 0x2D8E5959, 0x55392D07, 0x27C043D6,
0x52C224A9, 0x7A630098, 0x5ABC3D35, 0x5D9015E1, 0x0EB53512,
0x6CE06C73, 0x41B32B3D, 0x43320C48, 0x121A6199, 0x3A81182,
0x5ACF7987, 0x73F36DA5, 0x3F9E5EB7, 0x0BD14904, 0x58D9543E,
0x1DD31879, 0x424257E8, 0x7D643B59, 0x112B4FCF, 0x460735A7,
0x75DC362C, 0x27E05A88, 0x0C35376E, 0x5D767AF7, 0x1F957689,
0x2EB76CBA, 0x65FA6B91, 0x253D7D95, 0x76691087, 0x55CF26BD,
0x7E905073, 0x632B148F, 0x7BAA6CB2, 0x1E025682, 0x7AA34C92,
0x66454B5B, 0x237C6B1C, 0x319F1DA0, 0x13F25731, 0x5B43644E,
0x4D5A79D9, 0x20E73BCE, 0x39D016D7, 0x71106B26, 0x0C903B81,
0x6E91696D, 0x1A40FCE, 0x4D4E5781, 0x40C03DB1, 0x6C4641FC,
0x676A62A5, 0x50D13F63, 0x7E5D3F89, 0x67253EA1, 0x5E301AAF,
0x2C1F19B4, 0x47330830, 0x244140A7, 0x309A0C82, 0x43F710C0,
0x12DD4D4C, 0x2D1E2BFA, 0x315E4478, 0x65C664B5, 0x274D298A,
0x6C3711AD, 0x3BC80531, 0x4C335E29, 0x4147231C, 0x197B6A75,
0x438560F, 0x73955091, 0x0CE64236, 0x76CB612B, 0x389F21B9,
0x3E772CCB, 0x6E163790, 0x5C7E2D4E, 0x71066499, 0x6A1B2395,
0x191812E8, 0x15DE7D7E, 0x70076B5E, 0x52F45813, 0x7B02097D,
0x0DA87202, 0x3352217A, 0x92A224E, 0x723C4C94, 0x4A8F2743,
0x54296FA5, 0x351A61AF, 0x57046FF7, 0x3BBA504F, 0x37E42A58,
0x4BD35F88, 0x53EB6071, 0x55416157, 0x106E1053, 0x139B418B,
0x0E556A53, 0x7CB44A32, 0x2CC55918, 0x78680C51, 0x1EFD4FF2,
0x459540D8, 0x197E536D, 0x306735D4, 0x5A6F7027, 0x7DD91BE7,
0x113F13DE, 0x307847F5, 0x698C7CCD, 0x0A6A3D21, 0x3D443339,
0x70B012F8, 0x320A4147, 0x13A80BEB, 0x45DB1D10, 0x0D67003,
0x0EF178F7, 0x1E37FD0, 0x32E76E3B, 0x6CE613A3, 0x591F35C8,
0x49E33AFD, 0x1C616353, 0x71917046, 0x3FC456A5, 0x96134C2,
0x2AD25737, 0x0BB28C2, 0x70E70E00, 0x738B7417, 0x67DA518B,
0x15FC12CC, 0x11DF784C, 0x0D835A15, 0x5EAC2534, 0x5B204982,
0x7DB4283, 0x3AE17C78, 0x0C901EDE, 0x1CA74FE2, 0x105B60A1,
0x1A2C1024, 0x21604376, 0x0E454350, 0x29B55427, 0x3165639D,
0x100B1EB0, 0x5F631E15, 0x4B910299, 0x6A7D698D, 0x6F152182,
0x1F9C09DA, 0x6F6C1C00, 0x5FDA5342, 0x291510A7, 0x73414231,
0x69191168, 0x78D53B2D, 0x7D35031E, 0x17D5070C, 0x0F3B1B63,
0x563F5F65, 0x4FB670A8, 0x38921F44, 0x33CD5085, 0x0ED76C22,
0x4A6A504D, 0x12E26B14, 0x6C9B4BE6, 0x3BD65642, 0x4D3846D7,
0x6AE7069B, 0x2BC663A3, 0x556445C7, 0x2E9B6556, 0x4FF47C5D,
0x28436F5D, 0x5F201057, 0x4C23779A, 0x311107C3, 0x165C1EB8,
0x649B43BB, 0x6AF262BC, 0x417B6796, 0x302E5FDD, 0x45DD4060,
0x68401396, 0x2D224088, 0x0E2955F9, 0x53DF63D9, 0x39D87D46,
0x1D290FAB, 0x4F935FBC, 0x3D10435B, 0x3E9927AF, 0x0C692CF8,
0x13062DDB, 0x49D1763F, 0x5EF64DF8, 0x6BEE5DCA, 0x3EED698F,
0x68F87084, 0x7D770D0B, 0x17787760, 0x1A0B6B13, 0x0C506D4B,
0x37352217, 0x19FC115F, 0x33F50029, 0x55176959, 0x7462390F,
0x4221484D, 0x1D924296, 0x107F2D98, 0x48BE4B29, 0x6C31017,
0x71A27EA1, 0x42E6996, 0x24230D5F, 0x3B73168B, 0x2D342998,
0x0ABE5E05, 0x52FA6EF1, 0x14F535DF, 0x582E684C, 0x3E1739,
0x4EC427E1, 0x7DC17728, 0x7DCA2590, 0x7EAF37AD, 0x5E925775,
0x3A8324E4, 0x751338BE, 0x6A88527E, 0x78D32B9, 0x5E9B6D71,
0x796C1C31, 0x4F3255EE, 0x4D6F42FB, 0x109D1594, 0x130933CC,
0x0B8C05E3, 0x4308344E, 0x1ED23AF3, 0x4F742372, 0x4E680666,
0x6ABA3407, 0x63B5269B, 0x4A09358C, 0x630C7624, 0x66FD5F42,
0x7A772F7B, 0x47B5186, 0x4DB318F0, 0x7ADC415E, 0x437B2CE6,
0x0F4D0252, 0x380A123F, 0x5A75627D, 0x38DB7915, 0x2590CE3,
0x2DB32FAB, 0x4B7D6605, 0x12E103A3, 0x454C16B3, 0x28C44371,
0x15BA3922, 0x3C8F740F, 0x28285C3E, 0x6E490EF2, 0x43885141,
0x18185C3E, 0x4BC17785, 0x3ABE3D36, 0x32557A96, 0x13647AF6,
0x5A41368C, 0x3E976D64, 0x73253698, 0x0C900E64, 0x0FA401DC,
0x6AB84D4B, 0x7B0E2A80, 0x66B3697, 0x123C5302, 0x0CFC43DD,
0x23BC1DCD, 0x2CFA6802, 0x1B2F3B0E, 0x3CB22BAE, 0x7BEE08C3,
0x29F56DFE, 0x6EF47914, 0x171C1D79, 0x67F832E7, 0x49487D46,
0x25D920AF, 0x4BEF4A9C, 0x123F6184, 0x6D945679, 0x44805079,
0x79D56797, 0x2BC0162A, 0x54AB789C, 0x245D7894, 0x5AEE2690,
0x7C8A5D2A, 0x2C176395, 0x2C393125, 0x414A41D2, 0x443F2C1B,
0x75946AB1, 0x58B220D3, 0x6371164A, 0x6A965058, 0x3B91171F,
0x14B9734C, 0x78DB4E09, 0x7FDC6D7F, 0x15B31A72, 0x62135FC0,
0x26781AC5, 0x0D6F0BF3, 0x7D515123, 0x51D93F64, 0x3B2A0058,
0x3641375B, 0x71F9550D, 0x4CF933F1, 0x3C462F3E, 0x275B2D21,
0x6DEA1FEF, 0x2CB25E22, 0x42176F1B, 0x58581AF4, 0x2A983DEE,
0x231B243A, 0x245A1934, 0x1BE56D47, 0x352C1010, 0x739D087B,
0x76C322F1, 0x482DD0, 0x53011EC2, 0x7B740FB0, 0x55773861,
0x7FD6720A, 0x36287C53, 0x0A3237A4, 0x18F66B6, 0x17B59B3,
0x1E43776, 0x0A3C7DA9, 0x4D9C56C4, 0x29361D4E, 0x1F2F5DC4,
0x794A7512, 0x5A1D1786, 0x789A2CA1, 0x61330E38, 0x30EC6DB9,
0x220A789A, 0x3F4F5D38, 0x79D21BB2, 0x7F002A7A, 0x574D74C0,
0x5B8E28E1, 0x3E1E3F74, 0x0E3D27B5, 0x0F442C5F, 0x4AA87C2F,
0x3AE25BA8, 0x1EAB71D0, 0x3F417000, 0x98014F7, 0x19174DD7,
0x0E280BB3, 0x90A5AD0, 0x450D70D6, 0x52705173, 0x30E5654B,
0x57597D23, 0x5AD94BA9, 0x35CF724F, 0x79E76207, 0x4A5C16EC,
0x29852E13, 0x3BCD0F22, 0x73876F5E, 0x74366245, 0x31420BFA,
0x2B366C08, 0x7F22B47, 0x657C6DED, 0x459730A, 0x0D8A5500,
0x19A91ABF, 0x9B907C5, 0x7A44931, 0x737E506F, 0x6C027047,
0x53EB3752, 0x3131B21, 0x979619B, 0x5BA56263, 0x3B04483F,
0x2287AD1, 0x7C175B31, 0x6710121D, 0x66A64D8, 0x47B6DFC,
0x2CA941C0, 0x714017F, 0x6A774090, 0x7E376CA1, 0x35B33E3C,
0x57561A1D, 0x74FA527B, 0x289B6F82, 0x3F6D207C, 0x0ECE4388,
0x49B41FD4, 0x227A0EA5, 0x244371BC, 0x484B09DC, 0x2EDB1679,
0x60BB2FD6, 0x6554171B, 0x1AED5433, 0x699B776A, 0x6ED94522,
0x6EF7041E, 0x2AA2B2F, 0x6A90514E, 0x7F641B5D, 0x2D317D2B,
0x18CA0F75, 0x4A4D0AEE, 0x4C7F389D, 0x70406A0F, 0x1C6B602C,
0x15D87DB8, 0x48604ABD, 0x21143879, 0x4AFE5183, 0x6B2B203D,
0x1DD425DC, 0x45D04E7D, 0x8C77328, 0x65B540B3, 0x0B852DB,
0x564E0D12, 0x596146D1, 0x5AD74F74, 0x4E802DE2, 0x60986294,
0x283866B7, 0x6668397D, 0x7EB414DB, 0x7D706D42, 0x610D3C15,
0x473152F0, 0x636E25F6, 0x14C92DC1, 0x587645AE, 0x0B715192,
0x39DD0E24, 0x724B4997, 0x45B6E45, 0x0D5B574E, 0x0AC5679B,
0x29D25DB1, 0x47A7322, 0x3F930CB0, 0x5AFD2858, 0x4BF060DE,
0x7AE35A94, 0x49B44B6B, 0x2BF02098, 0x6A671652, 0x347D7A69,
0x74CD58D3, 0x4C1C095F, 0x6CB01024, 0x217F0E78, 0x67DF3064,
0x779622F1, 0x347741D0, 0x1DF85F18, 0x34615E39, 0x4884635C,
0x121C22B6, 0x0A4877A6, 0x32BD6996, 0x77A234EC, 0x9346098,
0x33A46D03, 0x2ED04F5F, 0x6CBD44B4, 0x65062220, 0x0C963413,
0x646E0C9E, 0x1F3B610C, 0x1D0E5958, 0x357B083F, 0x4BDB3900,
0x4691680E, 0x97D2630, 0x550461F3, 0x36533159, 0x5ACB4617,
0x67B748FC, 0x40B57D21, 0x3A83521C, 0x6508044C, 0x2ED324F3,
0x75686FBD, 0x710D41E4, 0x1FFB6713, 0x341F52B1, 0x5FCB503F,
0x1084BEE, 0x686C1C96, 0x1F9A42B5, 0x74DE6C24, 0x7C7E4A9C,
0x7DB47B44, 0x30786FE4, 0x1A760E6E, 0x0CEC21F3, 0x1245504F,
0x51A22204, 0x5FBD561F, 0x6FC64A1E, 0x2C203E2F, 0x7E334042,
0x5B01CC1, 0x42F169E9, 0x555C2B1D, 0x75FB33AE, 0x579F6CE1,
0x21460147, 0x1CA63F99, 0x420059B9, 0x53B1088F, 0x0F1523CC,
0x65BB74E5, 0x8F806BD, 0x235D7FE0, 0x36A04334, 0x9F03387,
0x33D11875, 0x63F2576D, 0x749C09DA, 0x48AA01CB, 0x62291881,
0x3F0F3ED1, 0x34B44542, 0x7E7423E, 0x2ED66EE4, 0x532C572F,
0x1E066090, 0x64B30234, 0x445F2485, 0x6C1009A9, 0x0FA46F0E,
0x13B45844, 0x418135B1, 0x0B586DEA, 0x6D1346AA, 0x119F52C7,
0x6DAB7498, 0x40F6409D, 0x3ACF2A75, 0x23BF765C, 0x3D827BCB,
0x53B069F4, 0x0AC60525, 0x28754C67, 0x275E30C4, 0x399D1422,
0x38D83394, 0x37B3018D, 0x47CB565F, 0x60AB51E1, 0x775E5F3F,
0x1381143A, 0x56092F59, 0x471C54ED, 0x2BA068C8, 0x6878131B,
0x688D30D8, 0x64043486, 0x1A5C6275, 0x5E496BA4, 0x97E44E3,
0x5FCD43F2, 0x64461AAF, 0x7837488B, 0x1B381CE5, 0x1CB378F9,
0x52833683, 0x4598004B, 0x0CCC142E, 0x0F496267, 0x732D5C24,
0x625913A2, 0x5E7E2272, 0x66F22E8E, 0x5D36D67, 0x47773C13,
0x76455E48, 0x66841C2, 0x37F65245, 0x6B860A65, 0x444F0FAC,
0x4C385CDB, 0x318C535D, 0x332E1523, 0x377B527E, 0x2B4453B6,
0x7180046F, 0x31A9371A, 0x1DD4900, 0x134053B4, 0x7A303EE2,
0x39465DDE, 0x2D3D5E5C, 0x29363A39, 0x4DEE2C3F, 0x3BE96844,
0x7F98191C, 0x50027B2E, 0x3B8060B4, 0x7B8914E9, 0x2F9E7DB0,
0x0D61780, 0x7AA10593, 0x0AB100AA, 0x693300EC, 0x73B7239F,
0x187D13D0, 0x1D00352A, 0x21EE0A87, 0x17FE5E00, 0x34381E86,
0x27A84750, 0x3D9C079D, 0x5CD8559B, 0x0B682D72, 0x51F205C6,
0x2BE0D2E, 0x49C7206E, 0x56962776, 0x35B9377B, 0x5F060A9D,
0x671F21F8, 0x75C24D18, 0x6FEB6A22, 0x7BDF0C32
};
#endif
+159
View File
@@ -0,0 +1,159 @@
#include <stdbool.h>
#include "security/rp-blowfish.h"
#include "security/rp-blowfish-table.h"
#include "util/log.h"
static int security_rp_blowfish_enc_sub(int a1)
{
int result; // eax@1
result = a1;
if ( a1 & 7 ) {
result = a1 - (a1 & 7) + 8;
}
return result;
}
void security_rp_blowfish_init(struct blowfish* ctx, const uint8_t* key,
size_t key_length, uint32_t seed)
{
log_assert(ctx);
log_assert(key);
memcpy(ctx->S, security_rp_blowfish_table_custom_sbox, sizeof(ctx->S));
memcpy(ctx->P, security_rp_blowfish_table_custom_pbox, sizeof(ctx->P));
blowfish_init(ctx, &key[seed], 14);
}
int security_rp_blowfish_enc(struct blowfish* ctx, const uint8_t* input,
uint8_t* output, int length)
{
int v4; // ebx@1
int v5; // ebp@1
int v6; // esi@1
int result; // eax@1
unsigned __int8 *v9; // edx@1
int v10; // ecx@4
int v11; // eax@11
signed int v12; // edi@11
void *v13; // edi@14
int v14; // eax@14
int v15; // edx@14
int v16; // ecx@15
int v17; // eax@18
unsigned int v18; // ecx@18
int v19; // eax@21
bool v20; // cf@21
int v22; // [sp+14h] [bp-8h]@1
int v23; // [sp+18h] [bp-4h]@1
int a2a; // [sp+20h] [bp+4h]@2
unsigned __int8 *outputa; // [sp+24h] [bp+8h]@1
log_assert(ctx);
log_assert(input);
log_assert(output);
v4 = length;
v5 = (int) output;
v6 = (int) input;
v23 = input == output;
result = security_rp_blowfish_enc_sub(length);
v9 = 0;
v22 = result;
outputa = 0;
if (result) {
a2a = v5 + 4;
while (1) {
v10 = v4 - 7;
if (v23) {
if ((unsigned int) v9 >= v10) {
if ( result - v4 > 0 ) {
memset((void *)(v6 + v4), 0, result - v4);
}
blowfish_encrypt(ctx, (uint32_t*) v6, (uint32_t*) v6 + 4);
v6 += 8;
} else {
blowfish_encrypt(ctx, (uint32_t *)v6, (uint32_t *)v6 + 1);
v6 += 8;
}
} else {
if ((unsigned int) v9 >= v10) {
v13 = (void*) v5;
v14 = v4 - (int) v9;
v15 = 0;
if ( v14 <= 0 )
goto LABEL_24;
v16 = v14;
v15 = v14;
do {
*(uint8_t *)v13 = *(uint8_t *)v6;
v13 = (char *) v13 + 1;
++v6;
--v16;
} while ( v16 );
if ( v14 < 8 ) {
LABEL_24:
((uint8_t*)v4)[0] = 8 - v15;
((uint8_t*)v4)[1] = 8 - v15;
v17 = v4 << 16;
((uint16_t*)v17)[0] = v4;
v18 = (unsigned int)(8 - v15) >> 2;
// poor man's version of memset32
//memset32(v13, v17, v18);
for (size_t i = 0; i < v18; i ++) {
*(((uint32_t*)v13) + i) = v17;
}
memset((char *)v13 + 4 * v18, 8 - v15,
(8 - (uint8_t)v15) & 3);
}
v4 = length;
} else {
v11 = v5;
v12 = 8;
do {
*(uint8_t *)v11 = *(uint8_t *)(v6 - v5 + v11);
++v11;
--v12;
} while ( v12 );
}
blowfish_encrypt(ctx, (uint32_t*) v5, (uint32_t*) a2a);
v6 += 8;
v5 += 8;
a2a += 8;
}
v19 = (int)(outputa + 8);
outputa = (unsigned __int8 *) v19;
v20 = v19 < (unsigned int) v22;
result = v22;
if ( !v20 ) {
break;
}
v9 = outputa;
}
}
return result;
}
+32
View File
@@ -0,0 +1,32 @@
#ifndef SECURITY_RP_BLOWFISH_H
#define SECURITY_RP_BLOWFISH_H
#include <stdint.h>
#include <stdlib.h>
#include "util/crypto.h"
/**
* Initializes a blowfish context for use with a modified version of the
* algorithm used by the roundplug module.
*
* @param ctx Pointer to a context to initialize.
* @param key Key to use for encryption.
* @param key_length Length of the key.
* @param seed A seed value.
*/
void security_rp_blowfish_init(struct blowfish* ctx, const uint8_t* key,
size_t key_length, uint32_t seed);
/**
* Encrypt some data with the modified version of blowfish.
*
* @param ctx Initialized context to use for the operation.
* @param input Buffer with input data to encrypt.
* @param output Pointer to a buffer to write the encrypted output data to.
* @param length Length of the input data (output buffer must have min size).
*/
int security_rp_blowfish_enc(struct blowfish* ctx, const uint8_t* input,
uint8_t* output, int length);
#endif
File diff suppressed because it is too large Load Diff
+13
View File
@@ -0,0 +1,13 @@
#include "security/rp-sign-key.h"
const struct security_rp_sign_key security_rp_sign_key_white_eamuse = {
.data = "E-AMUSE3"
};
const struct security_rp_sign_key security_rp_sign_key_black_ps2 = {
.data = "GENTAKAH"
};
const struct security_rp_sign_key security_rp_sign_key_black_gfdmv4 = {
.data = "UDONHRKI"
};
+33
View File
@@ -0,0 +1,33 @@
#ifndef SECURITY_RP_SIGN_KEY_H
#define SECURITY_RP_SIGN_KEY_H
#include <stdint.h>
/**
* Sign keys used to sign roundplug data.
*/
struct security_rp_sign_key {
char data[8];
};
/**
* Signing key used to create eeprom signitures for all white eamuse dongles.
*/
extern const struct security_rp_sign_key security_rp_sign_key_white_eamuse;
/**
* Signing key used to create eeprom signitures for all black dongles used
* on PS2 games (as far as we are aware of).
*/
extern const struct security_rp_sign_key security_rp_sign_key_black_ps2;
/**
* Signing key used to create eeprom signitures for all black dongles used
* on the following games:
*
* - GF & DM V4 to V8 (TODO needs verification)
* - jubeat (1)
*/
extern const struct security_rp_sign_key security_rp_sign_key_black_gfdmv4;
#endif
+12
View File
@@ -0,0 +1,12 @@
#ifndef SECURITY_RP_UTIL_H
#define SECURITY_RP_UTIL_H
/**
* Enum for available roundplug types
*/
enum security_rp_util_rp_type {
SECURITY_RP_UTIL_RP_TYPE_BLACK = 0,
SECURITY_RP_UTIL_RP_TYPE_WHITE = 1,
};
#endif
+84
View File
@@ -0,0 +1,84 @@
#include "security/rp.h"
#include "security/rp-blowfish.h"
#include "security/rp-enc-table.h"
#include "security/util.h"
#include "util/crypto.h"
#include "util/log.h"
static uint32_t security_rp_get_len_mcode(const struct security_mcode* mcode)
{
uint32_t len;
len = 0;
while (len < sizeof(struct security_mcode) &&
((const char*) mcode)[len] != ' ') {
len++;
}
return len;
}
void security_rp_generate_signed_eeprom_data(
const struct security_mcode* boot_version, const uint32_t* boot_seeds,
const struct security_mcode* plug_mcode,
const struct security_id* plug_id, struct security_rp_eeprom* out)
{
uint8_t encryption_key[sizeof(security_rp_enc_table_key_base)];
uint32_t boot_version_len;
uint32_t idx;
uint32_t seed;
uint8_t* enc_key_section1;
uint8_t* enc_key_section2;
uint8_t data[32];
struct blowfish ctx;
log_assert(boot_version);
log_assert(boot_seeds);
log_assert(plug_mcode);
log_assert(plug_id);
log_assert(out);
log_assert(boot_seeds[0] <= 16);
log_assert(boot_seeds[1] <= 16);
log_assert(boot_seeds[2] >= boot_seeds[1]);
memcpy(encryption_key, security_rp_enc_table_key_base,
sizeof(security_rp_enc_table_key_base));
boot_version_len = security_rp_get_len_mcode(boot_version);
idx = 0;
for (uint32_t i = 0; i < sizeof(encryption_key); i++) {
encryption_key[i] ^= ((const char*) boot_version)[idx];
idx = (idx + 1) % boot_version_len;
}
seed = 16 * (boot_seeds[2] + 16 * (boot_seeds[1] + 16 * boot_seeds[0]));
enc_key_section1 = (uint8_t*) encryption_key;
enc_key_section2 = (uint8_t*) (((uint8_t*) encryption_key) + 14);
memset(data, 0, sizeof(data));
data[0] = enc_key_section2[seed];
data[1] = enc_key_section2[seed + 1];
data[2] = plug_id->id[7];
data[3] = plug_id->id[6];
data[4] = plug_id->id[5];
data[5] = plug_id->id[4];
data[6] = plug_id->id[3];
data[7] = plug_id->id[2];
security_rp_blowfish_init(&ctx, enc_key_section1, 14, seed);
security_rp_blowfish_enc(&ctx, data, &data[16], 8);
for (uint8_t i = 0; i < sizeof(out->signature); i++) {
out->signature[i] = data[i + 16] ^ data[i + 22];
}
security_util_8_to_6_encode_reverse((const uint8_t*) plug_mcode,
out->packed_payload);
}
+44
View File
@@ -0,0 +1,44 @@
#ifndef SECURITY_RP_H
#define SECURITY_RP_H
#include <stdbool.h>
#include <stdint.h>
#include "security/id.h"
#include "security/mcode.h"
#include "security/rp-util.h"
/**
* Structure for data which is usually stored in the eeprom section of the
* dongle. This contains a signiture to verify the ROM's contents as well as
* the game this dongle is signed for.
*/
struct security_rp_eeprom {
uint8_t signature[6];
uint8_t packed_payload[6];
};
/**
* Generate signed eeprom data from non encrypted and unobfuscated data required
* to pass security checks on games using black (game specific) roundplugs.
*
* This implementation (rp (1)) is used by the following games
* - iidx 09 to 13
*
* @param boot_version The boot version mcode that is used for bootstrapping
* the security backend (of the ezusb.dll).
* @param boot_seeds Boot seeds (three numbers >= 0) set when the game is
* bootstrapping the security backend (of the ezusb.dll).
* @param plug_mcode The mcode of the game to boot. Typically, this code is
* printed onto the housing of the black dongle.
* @param plug_id The id stored of the plug. This data is normally stored in the
* ROM area of the black dongle is is often refered to as the
* "PCBID" or "EAMID" when stored on the white dongle.
* @param out Pointer to the eeprom data struct for the resulting data.
*/
void security_rp_generate_signed_eeprom_data(
const struct security_mcode* boot_version, const uint32_t* boot_seeds,
const struct security_mcode* plug_mcode,
const struct security_id* plug_id, struct security_rp_eeprom* out);
#endif
+113
View File
@@ -0,0 +1,113 @@
#include "security/rp2.h"
#include "security/util.h"
#include "util/crypto.h"
#include "util/log.h"
static const uint8_t security_rp2_sign_key_base_black[] = {
0x32, 0x44, 0x58, 0x47, 0x4C, 0x44, 0x41, 0x43
};
static const uint8_t security_rp2_sign_key_base_white[] = {
0x45, 0x2D, 0x41, 0x4D, 0x55, 0x53, 0x45, 0x33
};
static uint8_t security_rp2_signature_scramble_table[16] = {
0x0C, 0x02, 0x0F, 0x01,
0x07, 0x09, 0x04, 0x0A,
0x00, 0x0E, 0x03, 0x0D,
0x0B, 0x05, 0x08, 0x06
};
static void security_rp2_create_signiture(const uint8_t *plug_id_enc,
const uint8_t *sign_key_packed, uint8_t *out)
{
uint8_t data[14];
uint8_t md5[16];
uint8_t buffer[18];
memcpy(data, plug_id_enc, 8);
memcpy(data + 8, sign_key_packed, 6);
crypto_init();
md5_compute(data, 14, md5, sizeof(md5));
crypto_fini();
for (int i = 0; i < 16; i++) {
buffer[i] = md5[security_rp2_signature_scramble_table[i]];
}
buffer[16] = 0xDE;
buffer[17] = 0xAD;
for (int i = 0; i < 6; i++) {
out[i] = buffer[i + 12] ^ buffer[i + 6] ^ buffer[i];
}
}
void security_rp2_generate_signed_eeprom_data(
enum security_rp_util_rp_type type,
const struct security_mcode* boot_version,
const struct security_mcode* plug_mcode,
const struct security_id* plug_id, struct security_rp2_eeprom* out)
{
uint8_t sign_key[8];
uint8_t plug_id_enc[8];
char* boot_version_str;
log_assert(boot_version);
log_assert(plug_mcode);
log_assert(plug_id);
log_assert(out);
boot_version_str = (char*) boot_version;
/* -------------------------------- */
switch (type) {
case SECURITY_RP_UTIL_RP_TYPE_BLACK:
memcpy(sign_key, security_rp2_sign_key_base_black,
sizeof(sign_key));
sign_key[0] = boot_version_str[0] ^ sign_key[0];
sign_key[1] ^= boot_version_str[1];
sign_key[2] = boot_version_str[2] ^ sign_key[2];
sign_key[3] = boot_version_str[3] ^ sign_key[3];
sign_key[4] = boot_version_str[4] ^ sign_key[4];
sign_key[5] ^= boot_version_str[5];
sign_key[6] = boot_version_str[6] ^ sign_key[6];
sign_key[7] = boot_version_str[7] ^ sign_key[7];
break;
case SECURITY_RP_UTIL_RP_TYPE_WHITE:
memcpy(sign_key, security_rp2_sign_key_base_white,
sizeof(sign_key));
break;
default:
log_assert(false);
break;
}
for (uint8_t i = 0; i < sizeof(sign_key); i++) {
sign_key[i] ^= 0x40;
}
security_util_8_to_6_encode(sign_key, sign_key);
plug_id_enc[0] = plug_id->checksum;
plug_id_enc[1] = plug_id->id[2];
plug_id_enc[2] = plug_id->id[3];
plug_id_enc[3] = plug_id->id[4];
plug_id_enc[4] = plug_id->id[5];
plug_id_enc[5] = plug_id->id[6];
plug_id_enc[6] = plug_id->id[7];
plug_id_enc[7] = plug_id->id[1];
security_rp2_create_signiture(plug_id_enc, sign_key, (uint8_t*) out);
security_util_8_to_6_encode((const uint8_t*) plug_mcode,
out->packed_payload);
}
+46
View File
@@ -0,0 +1,46 @@
#ifndef SECURITY_RP2_H
#define SECURITY_RP2_H
#include <stdbool.h>
#include <stdint.h>
#include "security/id.h"
#include "security/mcode.h"
#include "security/rp-util.h"
/**
* Structure for data which is usually stored in the eeprom section of the
* dongle. This contains a signiture to verify the ROM's contents as well as
* the game this dongle is signed for.
*/
struct security_rp2_eeprom {
uint8_t signature[6];
uint8_t packed_payload[6];
};
/**
* Generate signed eeprom data from non encrypted and unobfuscated data required
* to pass security checks on games using black (game specific) and white
* (eamuse) roundplugs.
*
* This implementation (rp 2) is used by the following games
* - iidx 14 to 17
*
* @param type Type of plug to sign eeprom data for (black or white).
* @param boot_version The boot version mcode that is used for bootstrapping
* the security backend (of the ezusb.dll).
* @param plug_mcode The mcode of the game to boot. Typically, this code is
* printed onto the housing of the black dongle. For white
* dongles, the "mcode" @@@@@@@@ is used.
* @param plug_id The id stored on the plug. This data is normally stored in the
* ROM area of the black dongle is is often refered to as the
* "PCBID" or "EAMID" when stored on the white dongle.
* @param out Pointer to the eeprom data struct for the resulting data.
*/
void security_rp2_generate_signed_eeprom_data(
enum security_rp_util_rp_type type,
const struct security_mcode* boot_version,
const struct security_mcode* plug_mcode,
const struct security_id* plug_id, struct security_rp2_eeprom* out);
#endif
+78
View File
@@ -0,0 +1,78 @@
#include "security/rp3.h"
#include "security/rp-util.h"
#include "security/util.h"
#include "util/crc.h"
#include "util/crypto.h"
#include "util/log.h"
static uint8_t security_rp3_signature_scramble_table[] = {
0x0C, 0x02, 0x0F, 0x01,
0x07, 0x09, 0x04, 0x0A,
0x00, 0x0E, 0x03, 0x0D,
0x0B, 0x05, 0x08, 0x06
};
static void security_rp3_create_signature(const uint8_t *plug_id,
const uint8_t *sign_key_packed, uint8_t *out)
{
uint8_t data[14];
uint8_t md5[16];
uint8_t buffer[18];
memcpy(data, plug_id, 8);
memcpy(data + 8, sign_key_packed, 6);
crypto_init();
md5_compute(data, 14, md5, sizeof(md5));
crypto_fini();
for (int i = 0; i < 16; i++) {
buffer[i] = md5[security_rp3_signature_scramble_table[i]];
}
buffer[16] = 0xDE;
buffer[17] = 0xAD;
for (int i = 0; i < 6; i++) {
out[i] = buffer[i + 12] ^ buffer[i + 6] ^ buffer[i];
}
}
void security_rp3_generate_signed_eeprom_data(
enum security_rp_util_rp_type type,
const struct security_rp_sign_key* sign_key,
const struct security_mcode* plug_mcode,
const struct security_id* plug_id, struct security_rp3_eeprom* out)
{
uint8_t sign_key_tmp[8];
uint8_t sign_key_packed[6];
uint8_t plug_id_reversed[8];
log_assert(sign_key);
log_assert(plug_mcode);
log_assert(plug_id);
log_assert(out);
memcpy(sign_key_tmp, sign_key, sizeof(sign_key_tmp));
if (type == SECURITY_RP_UTIL_RP_TYPE_BLACK) {
for (int i = 0 ; i < sizeof(sign_key_tmp); i++) {
sign_key_tmp[i] ^= ((const uint8_t*) plug_mcode)[i];
}
}
security_util_8_to_6_encode(sign_key_tmp, sign_key_packed);
for (int i = 0; i < sizeof(plug_id_reversed); i++) {
plug_id_reversed[i] = plug_id->id[7 - i];
}
security_util_8_to_6_encode((const uint8_t*) plug_mcode,
out->packed_payload);
memset(out->zeros, 0, sizeof(out->zeros));
security_rp3_create_signature(plug_id_reversed, sign_key_packed,
out->signature);
out->crc = crc8((uint8_t *) out, sizeof(*out) - 1, 0);
}
+50
View File
@@ -0,0 +1,50 @@
#ifndef SECURITY_RP3_H
#define SECURITY_RP3_H
#include <stdbool.h>
#include <stdint.h>
#include "security/id.h"
#include "security/mcode.h"
#include "security/rp-sign-key.h"
#include "security/rp-util.h"
/**
* Structure for data which is usually stored in the eeprom section of the
* dongle. This contains a signiture to verify the ROM's contents as well as
* the game this dongle is signed for.
*/
struct security_rp3_eeprom {
uint8_t signature[6];
uint8_t packed_payload[6];
uint8_t zeros[19];
uint8_t crc;
};
/**
* Generate signed eeprom data from non encrypted and unobfuscated data required
* to pass security checks on games using black (game specific) and white
* (eamuse) roundplugs.
*
* Used on the following games:
* - jubeat
*
* @param type Type of plug to sign eeprom data for (black or white).
* @param sign_key The key to use for generating the signiture.
* This key can be extracted from the executables of the games and might
* be re-used for multiple games of the same series or generation.
* @param plug_mcode The mcode of the game to boot. Typically, this code is
* printed onto the housing of the black dongle. For white
* dongles, the "mcode" @@@@@@@@ is used.
* @param plug_id The id stored on the plug. This data is normally stored in the
* ROM area of the black dongle is is often refered to as the
* "PCBID" or "EAMID" when stored on the white dongle.
* @param out Pointer to the eeprom data struct for the resulting data.
*/
void security_rp3_generate_signed_eeprom_data(
enum security_rp_util_rp_type type,
const struct security_rp_sign_key* sign_key,
const struct security_mcode* plug_mcode,
const struct security_id* plug_id, struct security_rp3_eeprom* out);
#endif
+60
View File
@@ -0,0 +1,60 @@
#include "security/util.h"
void security_util_8_to_6_encode(const uint8_t *in, uint8_t *out)
{
uint8_t tmp[8];
int i;
for (i = 0 ; i < 8 ; i++) {
tmp[i] = (in[i] - 0x20) & 0x3F;
}
out[0] = (tmp[0] >> 0) | (tmp[1] << 6);
out[1] = (tmp[1] >> 2) | (tmp[2] << 4);
out[2] = (tmp[2] >> 4) | (tmp[3] << 2);
out[3] = (tmp[4] >> 0) | (tmp[5] << 6);
out[4] = (tmp[5] >> 2) | (tmp[6] << 4);
out[5] = (tmp[6] >> 4) | (tmp[7] << 2);
}
void security_util_6_to_8_decode(const uint8_t *in, uint8_t *out)
{
int i;
out[0] = ((in[0] >> 0) & 0x3F);
out[1] = ((in[0] >> 6) & 0x03) | ((in[1] << 2) & 0x3C);
out[2] = ((in[1] >> 4) & 0x0F) | ((in[2] << 4) & 0x30);
out[3] = ((in[2] >> 2) & 0x3F);
out[4] = ((in[3] >> 0) & 0x3F);
out[5] = ((in[3] >> 6) & 0x03) | ((in[4] << 2) & 0x3C);
out[6] = ((in[4] >> 4) & 0x0F) | ((in[5] << 4) & 0x30);
out[7] = ((in[5] >> 2) & 0x3F);
for (i = 0 ; i < 8 ; i++) {
out[i] += 0x20;
}
}
void security_util_8_to_6_encode_reverse(const uint8_t *in, uint8_t *out)
{
out[0] = ((in[7] - 0x20) << 2) | (((in[6] - 0x20) >> 4) & 0x03);
out[1] = ((in[6] - 0x20) << 4) | (((in[5] - 0x20) >> 2) & 0x0F);
out[2] = ((in[5] - 0x20) << 6) | ((in[4] - 0x20) & 0x3F);
out[3] = ((in[3] - 0x20) << 2) | (((in[2] - 0x20) >> 4) & 0x03);
out[4] = ((in[2] - 0x20) << 4) | (((in[1] - 0x20) >> 2) & 0x0F);
out[5] = ((in[1] - 0x20) << 6) | ((in[0] - 0x20) & 0x3F);
}
void security_util_6_to_8_decode_reverse(const uint8_t *in, uint8_t *out)
{
out[0] = (in[5] & 0x3F) + 0x20;
out[1] = ((in[5] >> 6) | (((in[4] & 0xF) << 2) + 0x20));
out[2] = ((in[4] >> 4) | (((in[3] & 0x03) << 4) + 0x20));
out[3] = (in[3] >> 2) + 0x20;
out[4] = (in[2] & 0x3F) + 0x20;
out[5] = (in[2] >> 6) | (((in[1] & 0x0F) << 2) + 0x20);
out[6] = (in[1] >> 4) | (((in[0] & 0x03) << 4) + 0x20);
out[7] = (in[0] >> 2) + 0x20;
}
+40
View File
@@ -0,0 +1,40 @@
#ifndef SECURITY_UTIL_H
#define SECURITY_UTIL_H
#include <stdint.h>
/**
* Pack 8 bytes of input data into 6 bytes payload output data. This is used to
* pack/encode mcodes from roundplug dongles, e.g. GCH44JAA.
*
* @param in Input data of 8 bytes length, e.g. mcode.
* @param out Target buffer for encoded data with at least 6 bytes capacity.
*/
void security_util_8_to_6_encode(const uint8_t *in, uint8_t *out);
/**
* Decode/unpack 6 bytes of encoded roundplug data, e.g. encoded mcode, to
* the full 8 bytes width.
*
* @param in Input encoded payload of 6 bytes length.
* @param out Target buffer for decoded data with at least 8 bytes capacity.
*/
void security_util_6_to_8_decode(const uint8_t *in, uint8_t *out);
/**
* Same as security_util_8_to_6_encode but in reversed byte order.
*
* @param in Input data of 8 bytes length, e.g. mcode.
* @param out Target buffer for encoded data with at least 6 bytes capacity.
*/
void security_util_8_to_6_encode_reverse(const uint8_t *in, uint8_t *out);
/**
* Same as security_util_6_to_8_decode but in reversed byte order.
*
* @param in Input encoded payload of 6 bytes length.
* @param out Target buffer for decoded data with at least 8 bytes capacity.
*/
void security_util_6_to_8_decode_reverse(const uint8_t *in, uint8_t *out);
#endif