I will contribute something to.
The cryption of Kalonline was published two years ago but so far no one has done anything with it.
Anyway here ->
(c) by Bakabug..
(c) by Phantom*
Code:
DAT/Packet: Encrypt = Old: Shift + New: 128 AES/XOR, Decrypt = New: 128 AES/XOR + Old: Shift
Encrypt Key = Decrypt Key (16 bytes)
Packet Key != DAT Key
Encrypt Round Key != Decrypt Round Key
something16 = etbl0
something15 = etbl1
something14 = etbl2
something13 = etbl3
something20 = esub0
something19 = esub1
somethign18 = esub2
something17 = esub3
something1 = dtbl0
somethine2 = dtbl1
something3 = dtbl2
something4 = dtbl3
something5 = dsub0
something6 = dsub1
something7 = dsub2
something8 = dsub3
Code:
#define AES_128_KEY_ROUND_MAX 10
static const unsigned long rcon[11] = {
0x01000000, 0x02000000, 0x04000000, 0x08000000,
0x10000000, 0x20000000, 0x40000000, 0x80000000,
0x1B000000, 0x36000000, 0x00000000
};
static const unsigned long *dtbls[] = {
dtbl0, dtbl1, dtbl2, dtbl3, dsub0, dsub1, dsub2, dsub3
};
static const unsigned long *etbls[] = {
etbl0, etbl1, etbl2, etbl3, esub0, esub1, esub2, esub3
};
/* generate encryption round key */
void _cipher_128_aes_encrypt_key(const char key[16], unsigned long rk[12][4])
{
unsigned int idx = 0;
unsigned long tmp = 0L;
memcpy(&rk[0], key, 16);
do {
tmp = rk[idx][3];
rk[idx + 1][0] = rk[idx][0] ^ \
(etbl2[(tmp >> 16) & 0xff] & 0xff000000) ^ \
(etbl3[(tmp >> 8) & 0xff] & 0x00ff0000) ^ \
(etbl0[tmp & 0xff] & 0x0000ff00) ^ \
(etbl1[tmp >> 24] & 0x000000ff) ^ \
rcon[idx];
rk[idx + 1][1] = rk[idx][1] ^ rk[idx + 1][0];
rk[idx + 1][2] = rk[idx][2] ^ rk[idx + 1][1];
rk[idx + 1][3] = rk[idx][3] ^ rk[idx + 1][2];
} while (AES_128_KEY_ROUND_MAX > idx++);
}
/* generate decryption round key */
void _cipher_128_aes_decrypt_key(const char key[16], unsigned long rk[12][4])
{
unsigned int idx = 0;
if (memcmp(key, &rk[0], 16)) {
_cipher_128_aes_encrypt_key(key, rk);
}
idx = 1;
do { /* Use the decryption and encryption tables to get the mix table,
reducing the profile of the library. Sword Online statically
defines the mix table as 0x00000000, 0x00000000, 0x00000000, ... */
rk[idx][0] = dtbl0[etbl1[rk[idx][0] >> 24] & 0xff] ^
dtbl1[etbl1[(rk[idx][0] >> 16) & 0xff] & 0xff] ^
dtbl2[etbl1[(rk[idx][0] >> 8) & 0xff] & 0xff] ^
dtbl3[etbl1[rk[idx][0] & 0xff] & 0xff];
rk[idx][1] = dtbl0[etbl1[rk[idx][1] >> 24] & 0xff] ^
dtbl1[etbl1[(rk[idx][1] >> 16) & 0xff] & 0xff] ^
dtbl2[etbl1[(rk[idx][1] >> 8) & 0xff] & 0xff] ^
dtbl3[etbl1[rk[idx][1] & 0xff] & 0xff];
rk[idx][2] = dtbl0[etbl1[rk[idx][2] >> 24] & 0xff] ^
dtbl1[etbl1[(rk[idx][2] >> 16) & 0xff] & 0xff] ^
dtbl2[etbl1[(rk[idx][2] >> 8) & 0xff] & 0xff] ^
dtbl3[etbl1[rk[idx][2] & 0xff] & 0xff];
rk[idx][3] = dtbl0[etbl1[rk[idx][3] >> 24] & 0xff] ^
dtbl1[etbl1[(rk[idx][3] >> 16) & 0xff] & 0xff] ^
dtbl2[etbl1[(rk[idx][3] >> 8) & 0xff] & 0xff] ^
dtbl3[etbl1[rk[idx][3] & 0xff] & 0xff];
} while (AES_128_KEY_ROUND_MAX - 1 > idx++);
}
void _cipher_128_aes_encrypt_round(const unsigned long *tbls[],
const unsigned long *key/*[4]*/, unsigned long *st8/*[4]*/)
{
unsigned long tmp[4];
tmp[0] = tbls[0][st8[0] >> 24] ^ \
tbls[1][(st8[1] >> 16) & 0xff] ^ \
tbls[2][(st8[2] >> 8) & 0xff] ^ \
tbls[3][st8[3] & 0xff];
tmp[1] = tbls[0][st8[1] >> 24] ^ \
tbls[1][(st8[2] >> 16) & 0xff] ^ \
tbls[2][(st8[3] >> 8) & 0xff] ^ \
tbls[3][st8[0] & 0xff];
tmp[2] = tbls[0][st8[2] >> 24] ^ \
tbls[1][(st8[3] >> 16) & 0xff] ^ \
tbls[2][(st8[0] >> 8) & 0xff] ^ \
tbls[3][st8[1] & 0xff];
tmp[3] = tbls[0][st8[3] >> 24] ^ \
tbls[1][(st8[0] >> 16) & 0xff] ^ \
tbls[2][(st8[1] >> 8) & 0xff] ^ \
tbls[3][st8[2] & 0xff];
st8[0] = tmp[0] ^ key[0];
st8[1] = tmp[1] ^ key[1];
st8[2] = tmp[2] ^ key[2];
st8[3] = tmp[3] ^ key[3];
}
void _cipher_128_aes_decrypt_round(const unsigned long *tbls[],
const unsigned long *key/*[4]*/, unsigned long *st8/*[4]*/)
{
unsigned long tmp[4];
tmp[0] = tbls[0][st8[0] >> 24] ^ \
tbls[1][(st8[3] >> 16) & 0xff] ^ \
tbls[2][(st8[2] >> 8) & 0xff] ^ \
tbls[3][st8[1] & 0xff];
tmp[1] = tbls[0][st8[1] >> 24] ^ \
tbls[1][(st8[0] >> 16) & 0xff] ^ \
tbls[2][(st8[3] >> 8) & 0xff] ^ \
tbls[3][st8[2] & 0xff];
tmp[2] = tbls[0][st8[2] >> 24] ^ \
tbls[1][(st8[1] >> 16) & 0xff] ^ \
tbls[2][(st8[0] >> 8) & 0xff] ^ \
tbls[3][st8[3] & 0xff];
tmp[3] = tbls[0][st8[3] >> 24] ^ \
tbls[1][(st8[2] >> 16) & 0xff] ^ \
tbls[2][(st8[1] >> 8) & 0xff] ^ \
tbls[3][st8[0] & 0xff];
st8[0] = tmp[0] ^ key[0];
st8[1] = tmp[1] ^ key[1];
st8[2] = tmp[2] ^ key[2];
st8[3] = tmp[3] ^ key[3];
}
void _cipher_128_aes_encrypt(const unsigned long rk[12][4],
const unsigned char pt[16], unsigned char ct[16])
{
unsigned long st8[4];
st8[0] = *((unsigned long *)&pt[0]) ^ rk[0][0];
st8[1] = *((unsigned long *)&pt[4]) ^ rk[0][1];
st8[2] = *((unsigned long *)&pt[8]) ^ rk[0][2];
st8[3] = *((unsigned long *)&pt[12]) ^ rk[0][3];
_cipher_128_aes_encrypt_round(etbls, rk[1], st8);
_cipher_128_aes_encrypt_round(etbls, rk[2], st8);
_cipher_128_aes_encrypt_round(etbls, rk[3], st8);
_cipher_128_aes_encrypt_round(etbls, rk[4], st8);
_cipher_128_aes_encrypt_round(etbls, rk[5], st8);
_cipher_128_aes_encrypt_round(etbls, rk[6], st8);
_cipher_128_aes_encrypt_round(etbls, rk[7], st8);
_cipher_128_aes_encrypt_round(etbls, rk[8], st8);
_cipher_128_aes_encrypt_round(etbls, rk[9], st8);
_cipher_128_aes_encrypt_round(&etbls[4], rk[10], st8);
*((unsigned long *)&ct[0]) = st8[0];
*((unsigned long *)&ct[4]) = st8[1];
*((unsigned long *)&ct[8]) = st8[2];
*((unsigned long *)&ct[12]) = st8[3];
}
void _cipher_128_aes_decrypt(const unsigned long rk[12][4],
const unsigned char ct[16], unsigned char pt[16])
{
unsigned long st8[4];
st8[0] = *((unsigned long *)&ct[0]) ^ rk[10][0];
st8[1] = *((unsigned long *)&ct[4]) ^ rk[10][1];
st8[2] = *((unsigned long *)&ct[8]) ^ rk[10][2];
st8[3] = *((unsigned long *)&ct[12]) ^ rk[10][3];
_cipher_128_aes_decrypt_round(dtbls, rk[9], st8);
_cipher_128_aes_decrypt_round(dtbls, rk[8], st8);
_cipher_128_aes_decrypt_round(dtbls, rk[7], st8);
_cipher_128_aes_decrypt_round(dtbls, rk[6], st8);
_cipher_128_aes_decrypt_round(dtbls, rk[5], st8);
_cipher_128_aes_decrypt_round(dtbls, rk[4], st8);
_cipher_128_aes_decrypt_round(dtbls, rk[3], st8);
_cipher_128_aes_decrypt_round(dtbls, rk[2], st8);
_cipher_128_aes_decrypt_round(dtbls, rk[1], st8);
_cipher_128_aes_decrypt_round(&dtbls[4], rk[0], st8);
*((unsigned long *)&pt[0]) = st8[0];
*((unsigned long *)&pt[4]) = st8[1];
*((unsigned long *)&pt[8]) = st8[2];
*((unsigned long *)&pt[12]) = st8[3];
}
static const unsigned char xtbl[16] = { 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0x0f, 0x1e, 0x2d, 0x3c, 0x4b, 0x5a, 0x69, 0x78 };
void _cipher_xor_crypt(unsigned char *buf, unsigned int sz)
{
while (sz-- >= 0) {
buf[sz] ^= xtbl[sz % 16];
}
}
Original Thread: forum.r a g e z o n e.com/f389/cryptkalonline-c-361953/
Have fun and good succeed







