aboutsummaryrefslogtreecommitdiff
path: root/source/crypt.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/crypt.c')
-rw-r--r--source/crypt.c147
1 files changed, 147 insertions, 0 deletions
diff --git a/source/crypt.c b/source/crypt.c
new file mode 100644
index 0000000..0fb97b4
--- /dev/null
+++ b/source/crypt.c
@@ -0,0 +1,147 @@
+#include "compat.h"
+#include "crypt.h"
+#include "utils.h"
+
+#ifndef __MINGW32__
+#include <time.h>
+#endif
+
+
+static inline int xor32_crypt(uint32_t u32, uint32_t key)
+{
+ return u32 ^ key;
+}
+
+uint32_t xor32n_pcbc_crypt_buf(uint32_t* buf, uint32_t siz, const uint32_t* iv, const uint32_t* key, uint32_t ivkeysiz)
+{
+ uint32_t pad = siz % (ivkeysiz*sizeof(uint32_t));
+ if (pad) {
+ siz += (ivkeysiz*sizeof(uint32_t)) - pad;
+ }
+ uint32_t msiz = (uint32_t)(siz/sizeof(uint32_t));
+ uint32_t prev[ivkeysiz];
+
+ for (register uint32_t i = 0; i < ivkeysiz; ++i) {
+ prev[i] = iv[i];
+ }
+ for (register uint32_t i = 0; i < msiz; ++i) {
+ register uint32_t plain = buf[i];
+ register uint32_t arridx = i % ivkeysiz;
+ register uint32_t tmp = xor32_crypt(plain, prev[arridx]);
+ register uint32_t crypt = xor32_crypt(tmp, key[arridx]);
+ prev[arridx] = xor32_crypt(crypt, plain);
+ buf[i] = crypt;
+ }
+ return siz;
+}
+
+unsigned char* xor32_byte_crypt(unsigned char* buf, uint32_t siz, unsigned int key)
+{
+ uint32_t bsiz = siz - (siz%4);
+
+ uint32_t i;
+ for (i = 0; i < bsiz/4; ++i) {
+ unsigned int* src = (unsigned int*)buf;
+ unsigned int* dst = (unsigned int*)buf;
+ *(dst+i) = *(src+i) ^ key;
+ }
+ for (i = bsiz; i < bsiz+(siz%4); ++i) {
+ unsigned char k = (unsigned char)(key & (0xFF << i*8)) >> i*8;
+ buf[i] = buf[i] ^ k;
+ }
+
+ return buf;
+}
+
+uint32_t xor32_randomkey(void)
+{
+#ifdef __MINGW32__
+ SYSTEMTIME st;
+ volatile unsigned int seed, retval;
+
+ _GetSystemTime(&st);
+ seed = (seed*retval)+(st.wYear + st.wMonth + st.wDayOfWeek +
+ st.wDay + st.wMinute) * (st.wSecond + 1);
+ for (int i = 0; i < 100; ++i) {
+ _GetSystemTime(&st);
+ retval = (volatile unsigned int)(seed * st.wMilliseconds);
+ seed++;
+ }
+ return (volatile unsigned int)((retval * st.wMilliseconds));
+#else
+ time_t st = time(NULL);
+ volatile unsigned int seed = st * __rdtsc(), retval;
+
+ for (uint32_t i = 0; i < 100; ++i) {
+ st = time(NULL);
+ retval = (volatile unsigned int)((seed * st) % 256),
+ seed++;
+ }
+ return (volatile unsigned int)(retval * st);
+#endif
+}
+
+/* from: https://github.com/jwerle/murmurhash.c */
+uint32_t murmurhash(const char *key, uint32_t len, uint32_t seed)
+{
+ uint32_t c1 = 0xa1f3e2d1;
+ uint32_t c2 = 0x4df56a13;
+ uint32_t r1 = 15;
+ uint32_t r2 = 13;
+ uint32_t m = 5;
+ uint32_t n = 0xa24f697f;
+ register uint32_t h = 0;
+ register uint32_t k = 0;
+ uint8_t *d = (uint8_t *) key; // 32 bit extract from `key'
+ const uint32_t *chunks = NULL;
+ const uint8_t *tail = NULL; // tail - last 8 bytes
+ register int i = 0;
+ int l = len / 4; // chunk length
+
+ h = seed;
+
+ chunks = (const uint32_t *) (d + l * 4); // body
+ tail = (const uint8_t *) (d + l * 4); // last 8 byte chunk of `key'
+
+ // for each 4 byte chunk of `key'
+ for (i = -l; i != 0; ++i) {
+ // next 4 byte chunk of `key'
+ k = chunks[i];
+
+ // encode next 4 byte chunk of `key'
+ k *= c1;
+ k = (k << r1) | (k >> (32 - r1));
+ k *= c2;
+
+ // append to hash
+ h ^= k;
+ h = (h << r2) | (h >> (32 - r2));
+ h = h * m + n;
+ }
+
+ k = 0;
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+ // remainder
+ switch (len & 3) { // `len % 4'
+ case 3: k ^= (tail[2] << 16);
+ case 2: k ^= (tail[1] << 8);
+ case 1:
+ k ^= tail[0];
+ k *= c1;
+ k = (k << r1) | (k >> (32 - r1));
+ k *= c2;
+ h ^= k;
+ }
+#pragma GCC diagnostic pop
+
+ h ^= len;
+ h ^= (h >> 16);
+ h *= 0x85ebca6b;
+ h ^= (h >> 13);
+ h *= 0xc2b2ae35;
+ h ^= (h >> 16);
+
+ return h;
+}