summaryrefslogtreecommitdiff
path: root/tools/4/source/src/util.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/4/source/src/util.cpp')
-rw-r--r--tools/4/source/src/util.cpp522
1 files changed, 522 insertions, 0 deletions
diff --git a/tools/4/source/src/util.cpp b/tools/4/source/src/util.cpp
new file mode 100644
index 0000000..adcd5a8
--- /dev/null
+++ b/tools/4/source/src/util.cpp
@@ -0,0 +1,522 @@
+/*
+* Copyright (c) 2011-2013 by naehrwert
+* This file is released under the GPLv2.
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <time.h>
+
+#include "types.h"
+#include "util.h"
+
+u8 *_read_buffer(const s8 *file, u32 *length)
+{
+ FILE *fp;
+ u32 size;
+
+ if((fp = fopen(file, "rb")) == NULL)
+ return NULL;
+
+ fseek(fp, 0, SEEK_END);
+ size = ftell(fp);
+ fseek(fp, 0, SEEK_SET);
+
+ u8 *buffer = (u8 *)malloc(sizeof(u8) * size);
+ fread(buffer, sizeof(u8), size, fp);
+
+ if(length != NULL)
+ *length = size;
+
+ fclose(fp);
+
+ return buffer;
+}
+
+int _write_buffer(const s8 *file, u8 *buffer, u32 length)
+{
+ FILE *fp;
+
+ if((fp = fopen(file, "wb")) == NULL)
+ return 0;
+
+ /**/
+ while(length > 0)
+ {
+ u32 wrlen = 1024;
+ if(length < 1024)
+ wrlen = length;
+ fwrite(buffer, sizeof(u8), wrlen, fp);
+ length -= wrlen;
+ buffer += 1024;
+ }
+ /**/
+
+ //fwrite(buffer, sizeof(u8), length, fp);
+
+ fclose(fp);
+
+ return 1;
+}
+
+#include "aes.h"
+// 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 aescbc128_encrypt(unsigned char *key, unsigned char *iv, unsigned char *in, unsigned char *out, int len)
+{
+ aes_context ctx;
+ aes_setkey_enc(&ctx, key, 128);
+ aes_crypt_cbc(&ctx, AES_ENCRYPT, 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);
+}
+
+int aes128ctr(u8 *key, u8 *iv, u8 *in, u64 len, u8 *out)
+{
+ aes_context aes_ctx = {0};
+ size_t nc_off = 0;
+ unsigned char stream_block[0x10] = {0};
+ int retval = -1;
+
+
+ // validate input params
+ if ( (key == NULL) || (iv == NULL) || (in == NULL) || (out == NULL) )
+ goto exit;
+
+ // set the AES key context
+ if (aes_setkey_enc(&aes_ctx, key, 128) != 0)
+ goto exit;
+
+ // do the AES-CTR crypt
+ if (aes_crypt_ctr(&aes_ctx, (size_t)len, &nc_off, iv, stream_block, in, out) != 0)
+ goto exit;
+ // status success
+ retval = 0;
+
+exit:
+ // return status
+ return retval;
+}
+
+int aes128ctrxor(u8 *key, u8 *iv, u8 *in, u64 len, u8 *out, size_t len_start_from)
+{
+ aes_context aes_ctx = {0};
+ size_t nc_off = 0;
+ unsigned char stream_block[0x10] = {0};
+ int retval = -1;
+
+
+ // validate input params
+ if ( (key == NULL) || (iv == NULL) || (in == NULL) || (out == NULL) )
+ goto exit;
+
+ // set the AES key context
+ if (aes_setkey_enc(&aes_ctx, key, 128) != 0)
+ goto exit;
+
+ // do the AES-CTR crypt
+ if (aes_crypt_ctr_xor(&aes_ctx, (size_t)len, &nc_off, iv, stream_block, in, out, len_start_from) != 0)
+ goto exit;
+ // status success
+ retval = 0;
+
+exit:
+ // return status
+ return retval;
+}
+
+unsigned char RAP_KEY[] = {0x86, 0x9F, 0x77, 0x45, 0xC1, 0x3F, 0xD8, 0x90, 0xCC, 0xF2, 0x91, 0x88, 0xE3, 0xCC, 0x3E, 0xDF};
+unsigned char RAP_PBOX[] = {0x0C, 0x03, 0x06, 0x04, 0x01, 0x0B, 0x0F, 0x08, 0x02, 0x07, 0x00, 0x05, 0x0A, 0x0E, 0x0D, 0x09};
+unsigned char RAP_E1[] = {0xA9, 0x3E, 0x1F, 0xD6, 0x7C, 0x55, 0xA3, 0x29, 0xB7, 0x5F, 0xDD, 0xA6, 0x2A, 0x95, 0xC7, 0xA5};
+unsigned char RAP_E2[] = {0x67, 0xD4, 0x5D, 0xA3, 0x29, 0x6D, 0x00, 0x6A, 0x4E, 0x7C, 0x53, 0x7B, 0xF5, 0x53, 0x8C, 0x74};
+
+void get_rif_key(unsigned char* rap, unsigned char* rif)
+{
+ int i;
+ int round;
+
+ unsigned char key[0x10];
+ unsigned char iv[0x10];
+ memset(key, 0, 0x10);
+ memset(iv, 0, 0x10);
+
+ // Initial decrypt.
+ aescbc128_decrypt(RAP_KEY, iv, rap, key, 0x10);
+
+ // rap2rifkey round.
+ for (round = 0; round < 5; ++round)
+ {
+ for (i = 0; i < 16; ++i)
+ {
+ int p = RAP_PBOX[i];
+ key[p] ^= RAP_E1[p];
+ }
+ for (i = 15; i >= 1; --i)
+ {
+ int p = RAP_PBOX[i];
+ int pp = RAP_PBOX[i - 1];
+ key[p] ^= key[pp];
+ }
+ int o = 0;
+ for (i = 0; i < 16; ++i)
+ {
+ int p = RAP_PBOX[i];
+ unsigned char kc = key[p] - o;
+ unsigned char ec2 = RAP_E2[p];
+ if (o != 1 || kc != 0xFF)
+ {
+ o = kc < ec2 ? 1 : 0;
+ key[p] = kc - ec2;
+ }
+ else if (kc == 0xFF)
+ {
+ key[p] = kc - ec2;
+ }
+ else
+ {
+ key[p] = kc;
+ }
+ }
+ }
+
+ memcpy(rif, key, 0x10);
+}
+
+bool hmac_hash_compare(unsigned char *key, int key_len, unsigned char *in, int in_len, unsigned char *hash, int hash_len)
+
+{
+
+ unsigned char *out = new unsigned char[key_len];
+
+
+
+ sha1_hmac(key, key_len, in, in_len, out);
+
+
+
+ for (int i = 0; i < hash_len; i++)
+
+ {
+
+ if (out[i] != hash[i])
+
+ {
+
+ delete[] out;
+
+ return false;
+
+ }
+
+ }
+
+
+
+ delete[] out;
+
+
+
+ return true;
+
+}
+
+
+// Auxiliary functions (endian swap, xor and prng).
+
+short se16(short i)
+
+{
+
+ return (((i & 0xFF00) >> 8) | ((i & 0xFF) << 8));
+
+}
+
+
+
+int se32(int i)
+
+{
+
+ return ((i & 0xFF000000) >> 24) | ((i & 0xFF0000) >> 8) | ((i & 0xFF00) << 8) | ((i & 0xFF) << 24);
+
+}
+
+
+
+u64 se64(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 xor1(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];
+
+ }
+
+}
+
+
+
+void prng(unsigned char *dest, int size)
+
+{
+
+ unsigned char *buffer = new unsigned char[size];
+
+ srand((u32)time(0));
+
+
+
+ int i;
+
+ for(i = 0; i < size; i++)
+
+ buffer[i] = (unsigned char)(rand() & 0xFF);
+
+
+
+ memcpy(dest, buffer, size);
+
+
+
+ delete[] buffer;
+
+}
+
+
+
+// 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;
+
+}
+
+
+
+void hex_to_bytes(unsigned char *data, const char *hex_str, unsigned int str_length)
+
+{
+
+ 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);
+
+ }
+
+}
+
+
+
+bool is_hex(const char* hex_str, unsigned int str_length)
+
+{
+
+ static const char hex_chars[] = "0123456789abcdefABCDEF";
+
+
+
+ if (hex_str == NULL)
+
+ return false;
+
+
+
+ unsigned int i;
+
+ for (i = 0; i < str_length; i++)
+
+ {
+
+ if (strchr(hex_chars, hex_str[i]) == 0)
+
+ return false;
+
+ }
+
+
+
+ return true;
+
+}
+
+
+
+void hmac_hash_forge(unsigned char *key, int key_len, unsigned char *in, int in_len, unsigned char *hash)
+
+{
+
+ sha1_hmac(key, key_len, in, in_len, hash);
+
+}
+
+
+
+bool cmac_hash_compare(unsigned char *key, int key_len, unsigned char *in, int in_len, unsigned char *hash, int hash_len)
+
+{
+
+ 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 < hash_len; i++)
+
+ {
+
+ if (out[i] != hash[i])
+
+ {
+
+ delete[] out;
+
+ return false;
+
+ }
+
+ }
+
+
+
+ delete[] out;
+
+
+
+ return true;
+
+}
+
+
+
+void cmac_hash_forge(unsigned char *key, int key_len, unsigned char *in, uint64_t in_len, unsigned char *hash)
+
+{
+
+ aes_context ctx;
+
+ aes_setkey_enc(&ctx, key, 128);
+
+ aes_cmac(&ctx, in_len, in, hash);
+
+}