#include "stdafx.h" #include "aes.h" #include "sha1.h" #include "utils.h" // Endian swap auxiliary functions. u16 swap16(u16 i) { return ((i & 0xFF00) >> 8) | ((i & 0xFF) << 8); } 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); } void xor_(unsigned char *dest, unsigned char *src1, unsigned char *src2, int size) { int i; for(i = 0; i < size; i++) { dest[i] = src1[i] ^ src2[i]; } } // Hex string conversion auxiliary functions. u64 hex_to_u64(const char* hex_str) { u32 length = (u32)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; } void hex_to_bytes(unsigned char *data, const char *hex_str) { u32 str_length = (u32)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); } } // 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]; sha1_hmac(key, key_len, in, in_len, out); for (int i = 0; i < 0x10; i++) { if (out[i] != hash[i]) { delete[] out; return false; } } delete[] out; 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); aes_cmac(&ctx, in_len, in, out); for (int i = 0; i < key_len; i++) { if (out[i] != hash[i]) { delete[] out; return false; } } delete[] out; return true; } #include "lz.h" // Reverse-engineered custom Lempel–Ziv–Markov based compression (unknown variant of LZRC). int lz_decompress(unsigned char *out, unsigned char *in, unsigned int size) { return decompress(out,in,size); }