Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
277 lines (205 sloc) 6.11 KB
#include <stdlib.h>
#include <string.h>
#include "kidhash.h"
#include "constants.h"
#include "glib_replacement.h"
const double append_multiplicator = 4.614703357219696e-7;
const char alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789./";
const int init_variable = 0x0FE0637B1;
int init_table[31];
int init_table_size = 31;
int *init_table_ptr = NULL;
int *init_table_end = NULL;
int *init_table_idx2 = NULL;
int *init_table_idx1 = NULL;
int init_table_idx_diff = 3;
const int fixed_value_3 = 3;
int key[26];
void crazy_algorithm(int *table,int *temp_data) {
unsigned int i, temp = 0;
// Initialize the 4 temp variables
int P = table[1],
PP = table[2],
PPP = table[3],
PPPP = table[0];
// four loops made into one
for (i = 0; i < 16*4; i++) {
temp = PPPP + const_mult[i] * const_values[i]; // Common to all loops
if(i/16 == 0) temp += GUINT32_FROM_LE(temp_data[i]) + (PPP ^ (P & (PP ^ PPP))); // add this for first loop i =[0..15]
else if(i/16 == 1) temp += GUINT32_FROM_LE(temp_data[((i-16)*5 + 1)%16]) + (PP ^ (PPP & (P ^ PP))); // add for second i = [16..31]
else if(i/16 == 2) temp += GUINT32_FROM_LE(temp_data[((i-32)*3 + 5)%16]) + (P ^ (PP ^ PPP)); // add for second i = [31..47]
else if(i/16 == 3) temp += GUINT32_FROM_LE(temp_data[choose_data_idx[i-48]]) + (PP ^ ((PPP ^ 0xFFFFFFFF) | P)); // add for the last loop
PPPP = PPP; PPP = PP; PP = P;
P += (temp >> shifts_right[(i%4) + 4*(i/16)]) | (temp << shifts_left[(i%4) + 4*(i/16)]); // look for the shifts in the table
}
// store in the output variables
table[0] += PPPP;
table[1] += P;
table[2] += PP;
table[3] += PPP;
return;
}
int alter_table() {
int ret;
if (fixed_value_3 != 0 ) {
*init_table_idx2 = *init_table_idx1 + *init_table_idx2;
ret = *init_table_idx2 >> 1 & 0x7fffffff;
if (init_table_idx2 + 1 < init_table_end) {
if(init_table_idx1 + 1 >= init_table_end)
init_table_idx1 = init_table_ptr;
else
init_table_idx1++;
init_table_idx2++;
} else {
init_table_idx2 = init_table_ptr;
init_table_idx1++;
}
} else {
init_table_ptr[0] = init_table_ptr[0] % 0x1f31d * 0x41a7 -
init_table_ptr[0] / 0x1f31d * 0xb14;
if ( init_table_ptr[0] <= 0)
init_table_ptr[0] += 0x7fffffff;
init_table_ptr[0] &= 0x7fffffff;
ret = init_table_ptr[0];
}
return ret;
}
void init(int value) {
int i = 0;
*init_table_ptr = value;
if(fixed_value_3) {
for (i = 1; i < init_table_size; i++) {
init_table_ptr[i] = init_table_ptr[i-1] % 0x1f31d * 0x41a7 -
init_table_ptr[i-1] / 0x1f31d * 0xb14;
if ( init_table_ptr[i] <= 0)
init_table_ptr[i] += 0x7fffffff;
}
init_table_idx1 = init_table_ptr;
init_table_idx2 = init_table_ptr + init_table_idx_diff;
for(i = init_table_size * 10; i > 0; i--) alter_table();
}
return;
}
void set_result (int *table, char * temp_data, int * result) {
char * temp_data_ptr = temp_data;
int idx;
idx = (table[4] / 8) & 63;
temp_data_ptr = temp_data + idx;
*temp_data_ptr = 0x80;
temp_data_ptr++;
idx = 55 - idx;
if ( idx < 0) {
memset(temp_data_ptr, 0, idx + 8);
crazy_algorithm(table, (int *)temp_data);
memset(temp_data, 0, 56);
} else
memset(temp_data_ptr, 0, idx);
temp_data_ptr += idx;
// The last 2 dwords are size / 8 and a bool for if size > 64
*((int *)temp_data_ptr) = GUINT32_TO_LE(table[4]);
temp_data_ptr+=4;
*((int *)temp_data_ptr) = GUINT32_TO_LE(table[5]);
crazy_algorithm(table, (int *)temp_data);
result[0] = table[0];
result[1] = table[1];
result[2] = table[2];
result[3] = table[3];
result[4] = 0;
}
void Hash(char * a, int key_size) {
int result[5],
table[] = {0x67452301,
0x0EFCDAB89,
0x98BADCFE,
0x10325476,
8*key_size,
key_size >> 29};
char temp_data[64];
int *key_ptr = key;
char *a_ptr = a;
int i, temp;
if(key_size >= 64) {
for(i = key_size / 64; i > 0 ; i--) {
memcpy(temp_data, key_ptr, 64);
crazy_algorithm(table, (int *)temp_data);
key_ptr += 16;
}
key_size &= 63;
}
memcpy(temp_data, key_ptr, key_size);
set_result(table, temp_data, result);
result[0] = GUINT32_TO_LE(result[0]);
result[1] = GUINT32_TO_LE(result[1]);
result[2] = GUINT32_TO_LE(result[2]);
result[3] = GUINT32_TO_LE(result[3]);
result[4] = GUINT32_TO_LE(result[4]);
for (i = 0 ; i < 18; i += 3) {
temp = (0x000000ff &((char *) result)[i]) << 16 |
(0x000000ff & ((char *) result)[i+1]) << 8 |
(0x000000ff & ((char *) result)[i+2]);
a_ptr[0] = alphabet[temp >> 6 >> 6 >> 6 & 0x3F];
a_ptr[1] = alphabet[temp >> 6 >> 6 & 0x3F];
a_ptr[2] = alphabet[temp >> 6 & 0x3F];
a_ptr[3] = alphabet[temp & 0x3F];
a_ptr+=4;
}
*(a_ptr - 2) = 0;
}
int MakeKidHash(char *a, int *a_size, int kid, char * sid) {
int i;
char * sid_ptr = sid;
char *key_ptr = (char *) key;
char *append_char;
char *append_ptr;
if(kid < 0 || kid > 100) return 0;
if (*a_size < 25) return 0;
memset(key, 0, 26 * sizeof(int));
init_table_ptr = init_table;
init_table_idx1 = init_table_ptr;
init_table_idx2 = init_table_ptr + init_table_idx_diff;
init_table_end = init_table_ptr + init_table_size;
for (i = 0 ; i < 100; i++) {
if(*sid_ptr == 0) break;
*key_ptr = *sid_ptr;
key_ptr++;
sid_ptr++;
}
if (sid_ptr - sid + append_size > 100) return 0;
init(init_variable);
while(kid > 0) {
alter_table();
kid--;
}
append_char = (char *) (key_append + (long) (alter_table() * append_multiplicator) * 4);
append_ptr = append_char;
for (i = 0 ; i < append_size; i++) {
#ifdef __BIG_ENDIAN__
*key_ptr = append_char[3 - ((append_ptr - append_char)%4) + 4*((append_ptr - append_char)/4)];
#else
*key_ptr = *append_ptr;
#endif
key_ptr++;
append_ptr++;
}
Hash(a, (int) (sid_ptr - sid) + append_size);
return 1;
}
int test () {
char sid[] = "sid=aD4ENXNY3Q";
char sid2[] = "sid=KCSwrDFrVg";
char a[30];
int kid = 64;
int kid2 = 98;
int a_size = 30;
printf("\n");
if (MakeKidHash(a, &a_size, kid2, sid2)) {
printf("Computed hash is : %s\n", a);
printf("Should be : hHQbVkZ/eApiRzPiTg6jyw\n\n\n");
}
if(MakeKidHash(a, &a_size, kid, sid)) {
printf("Computed hash is : %s\n", a);
printf("Should be : HlyPs6/kiWhr0JxmMO1A4Q\n");
}
printf("\n\n");
return 0;
}