2014-04-12 11:42:20 +02:00
|
|
|
|
#include "stdafx.h"
|
|
|
|
|
|
#include "utils.h"
|
|
|
|
|
|
|
|
|
|
|
|
// Endian swap auxiliary functions.
|
2014-03-03 05:48:07 +01:00
|
|
|
|
u16 swap16(u16 i)
|
2014-04-12 11:42:20 +02:00
|
|
|
|
{
|
|
|
|
|
|
return ((i & 0xFF00) >> 8) | ((i & 0xFF) << 8);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2014-03-03 05:48:07 +01:00
|
|
|
|
u32 swap32(u32 i)
|
|
|
|
|
|
{
|
|
|
|
|
|
return ((i & 0xFF000000) >> 24) | ((i & 0xFF0000) >> 8) | ((i & 0xFF00) << 8) | ((i & 0xFF) << 24);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
u64 swap64(u64 i)
|
|
|
|
|
|
{
|
|
|
|
|
|
return ((i & 0x00000000000000ff) << 56) | ((i & 0x000000000000ff00) << 40) |
|
|
|
|
|
|
((i & 0x0000000000ff0000) << 24) | ((i & 0x00000000ff000000) << 8) |
|
|
|
|
|
|
((i & 0x000000ff00000000) >> 8) | ((i & 0x0000ff0000000000) >> 24) |
|
|
|
|
|
|
((i & 0x00ff000000000000) >> 40) | ((i & 0xff00000000000000) >> 56);
|
|
|
|
|
|
}
|
2014-03-30 22:09:49 +02:00
|
|
|
|
|
2014-03-31 09:55:27 +02:00
|
|
|
|
void xor_(unsigned char *dest, unsigned char *src1, unsigned char *src2, int size)
|
2014-03-30 22:09:49 +02:00
|
|
|
|
{
|
|
|
|
|
|
int i;
|
|
|
|
|
|
for(i = 0; i < size; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
dest[i] = src1[i] ^ src2[i];
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2014-04-12 11:42:20 +02:00
|
|
|
|
|
|
|
|
|
|
// Hex string conversion auxiliary functions.
|
|
|
|
|
|
u64 hex_to_u64(const char* hex_str)
|
|
|
|
|
|
{
|
|
|
|
|
|
u32 length = strlen(hex_str);
|
|
|
|
|
|
u64 tmp = 0;
|
|
|
|
|
|
u64 result = 0;
|
|
|
|
|
|
char c;
|
|
|
|
|
|
|
|
|
|
|
|
while (length--)
|
|
|
|
|
|
{
|
|
|
|
|
|
c = *hex_str++;
|
|
|
|
|
|
if((c >= '0') && (c <= '9'))
|
|
|
|
|
|
tmp = c - '0';
|
|
|
|
|
|
else if((c >= 'a') && (c <= 'f'))
|
|
|
|
|
|
tmp = c - 'a' + 10;
|
|
|
|
|
|
else if((c >= 'A') && (c <= 'F'))
|
|
|
|
|
|
tmp = c - 'A' + 10;
|
|
|
|
|
|
else
|
|
|
|
|
|
tmp = 0;
|
|
|
|
|
|
result |= (tmp << (length * 4));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2014-03-03 05:48:07 +01:00
|
|
|
|
void hex_to_bytes(unsigned char *data, const char *hex_str)
|
|
|
|
|
|
{
|
|
|
|
|
|
u32 str_length = strlen(hex_str);
|
|
|
|
|
|
u32 data_length = str_length / 2;
|
|
|
|
|
|
char tmp_buf[3] = {0, 0, 0};
|
|
|
|
|
|
|
|
|
|
|
|
// Don't convert if the string length is odd.
|
|
|
|
|
|
if (!(str_length % 2))
|
|
|
|
|
|
{
|
|
|
|
|
|
u8 *out = (u8 *) malloc (str_length * sizeof(u8));
|
|
|
|
|
|
u8 *pos = out;
|
|
|
|
|
|
|
|
|
|
|
|
while (str_length--)
|
|
|
|
|
|
{
|
|
|
|
|
|
tmp_buf[0] = *hex_str++;
|
|
|
|
|
|
tmp_buf[1] = *hex_str++;
|
|
|
|
|
|
|
|
|
|
|
|
*pos++ = (u8)(hex_to_u64(tmp_buf) & 0xFF);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Copy back to our array.
|
|
|
|
|
|
memcpy(data, out, data_length);
|
|
|
|
|
|
}
|
2014-03-30 22:09:49 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Crypto functions (AES128-CBC, AES128-ECB, SHA1-HMAC and AES-CMAC).
|
|
|
|
|
|
void aescbc128_decrypt(unsigned char *key, unsigned char *iv, unsigned char *in, unsigned char *out, int len)
|
|
|
|
|
|
{
|
|
|
|
|
|
aes_context ctx;
|
|
|
|
|
|
aes_setkey_dec(&ctx, key, 128);
|
|
|
|
|
|
aes_crypt_cbc(&ctx, AES_DECRYPT, len, iv, in, out);
|
|
|
|
|
|
|
|
|
|
|
|
// Reset the IV.
|
|
|
|
|
|
memset(iv, 0, 0x10);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void aesecb128_encrypt(unsigned char *key, unsigned char *in, unsigned char *out)
|
|
|
|
|
|
{
|
|
|
|
|
|
aes_context ctx;
|
|
|
|
|
|
aes_setkey_enc(&ctx, key, 128);
|
|
|
|
|
|
aes_crypt_ecb(&ctx, AES_ENCRYPT, in, out);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool hmac_hash_compare(unsigned char *key, int key_len, unsigned char *in, int in_len, unsigned char *hash)
|
|
|
|
|
|
{
|
|
|
|
|
|
unsigned char *out = new unsigned char[key_len];
|
|
|
|
|
|
|
2014-04-12 11:42:20 +02:00
|
|
|
|
sha1_hmac(key, key_len, in, in_len, out);
|
|
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < 0x10; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (out[i] != hash[i])
|
2014-03-30 22:09:49 +02:00
|
|
|
|
{
|
2014-04-12 11:42:20 +02:00
|
|
|
|
delete[] out;
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
delete[] out;
|
|
|
|
|
|
|
2014-03-30 22:09:49 +02:00
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool cmac_hash_compare(unsigned char *key, int key_len, unsigned char *in, int in_len, unsigned char *hash)
|
|
|
|
|
|
{
|
|
|
|
|
|
unsigned char *out = new unsigned char[key_len];
|
|
|
|
|
|
|
|
|
|
|
|
aes_context ctx;
|
|
|
|
|
|
aes_setkey_enc(&ctx, key, 128);
|
2014-04-12 11:42:20 +02:00
|
|
|
|
aes_cmac(&ctx, in_len, in, out);
|
|
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < key_len; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (out[i] != hash[i])
|
2014-03-30 22:09:49 +02:00
|
|
|
|
{
|
2014-04-12 11:42:20 +02:00
|
|
|
|
delete[] out;
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
delete[] out;
|
|
|
|
|
|
|
2014-03-30 22:09:49 +02:00
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2014-04-25 18:57:00 +02:00
|
|
|
|
#include "lz.h"
|
2014-03-30 22:09:49 +02:00
|
|
|
|
// Reverse-engineered custom Lempel<65>Ziv<69>Markov based compression (unknown variant of LZRC).
|
|
|
|
|
|
int lz_decompress(unsigned char *out, unsigned char *in, unsigned int size)
|
|
|
|
|
|
{
|
2014-04-25 18:57:00 +02:00
|
|
|
|
return decompress(out,in,size);
|
2014-04-12 11:42:20 +02:00
|
|
|
|
}
|