Explorar o código

* Add eggdrop's blowfish which will enable FiSH support

Bryan Drewery %!s(int64=16) %!d(string=hai) anos
pai
achega
af9def3ff4
Modificáronse 6 ficheiros con 279 adicións e 1 borrados
  1. 17 0
      src/crypt.c
  2. 3 0
      src/crypt.h
  3. 3 1
      src/crypto/Makefile.in
  4. 232 0
      src/crypto/bf_util.c
  5. 22 0
      src/crypto/bf_util.h
  6. 2 0
      src/crypto/crypto.h

+ 17 - 0
src/crypt.c

@@ -50,6 +50,23 @@ bd::String encrypt_string(const bd::String& key, const bd::String& data) {
   return encrypted;
 }
 
+#ifdef not_needed
+/**
+ * @brief Encrypt a string with Blowfish ECB
+ * @param key The key to encrypt with
+ * @param data The string to encrypt
+ * @return A new, encrypted string
+ */
+bd::String encrypt_string_bf(const bd::String& key, const bd::String& data) {
+  if (!key) return data;
+  size_t len = data.length();
+  char *bdata = (char*) bf_encrypt_ecb_binary(key.c_str(), (unsigned char*) data.c_str(), &len);
+  bd::String encrypted(bdata, len);
+  free(bdata);
+  return encrypted;
+}
+#endif
+
 /**
  * @brief Encrypt a string with AES 256 CBC
  * @param key The key to encrypt with

+ 3 - 0
src/crypt.h

@@ -31,6 +31,9 @@ int sha256cmp(const char *, const char*);
 
 char *encrypt_string(const char *, char *);
 bd::String encrypt_string(const bd::String&, const bd::String&);
+#ifdef not_needed
+bd::String encrypt_string_bf(const bd::String&, const bd::String&);
+#endif
 bd::String encrypt_string_cbc(const bd::String&, const bd::String&, unsigned char *);
 char *decrypt_string(const char *, char *);
 char *salted_sha1(const char *, const char* = NULL);

+ 3 - 1
src/crypto/Makefile.in

@@ -12,7 +12,9 @@ depcomp = /bin/sh $(top_srcdir)/autotools/depcomp
 
 @SET_MAKE@
 
-OBJS = aes_util.o
+OBJS = \
+       aes_util.o \
+       bf_util.o
 
 doofus:
 	@echo ""

+ 232 - 0
src/crypto/bf_util.c

@@ -0,0 +1,232 @@
+/* bf_util.c
+ *
+ */
+
+#include "crypto.h"
+#include "src/compat/compat.h"
+#include <bdlib/src/String.h>
+
+#define CRYPT_BLOCKSIZE BF_BLOCK
+
+BF_KEY bf_e_key, bf_d_key;
+
+static const char eggdrop_blowfish_base64[65] = "./0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
+static const char eggdrop_blowfish_base64_index[256] = {
+  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  0,  1,
+   2,  3,  4,  5,  6,  7,  8,  9, 10, 11, -1, -1, -1, -1, -1, -1,
+  -1, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
+  53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, -1, -1, -1, -1, -1,
+  -1, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
+  27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, -1, -1, -1, -1, -1,
+  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
+};
+
+union bf_data {
+  struct {
+    unsigned long left;
+    unsigned long right;
+  } lr;
+  BF_LONG bf_long;
+};
+
+/* These were adapted from eggdrop's blowfish.mod as well as dirtirc */
+
+/*
+ * @brief Encrypt a string using eggdrop's blowfish
+ * @param in The string to encrypt.
+ * @param key The key to use.
+ * @returns The encrypted string.
+ */
+bd::String egg_bf_encrypt(bd::String in, const bd::String& key)
+{
+  /* No key, no encryption */
+  if (!key.length()) return in;
+
+  bd::String out(size_t(in.length() * 1.5));
+  size_t datalen = in.length();
+  if (datalen % 8 != 0) {
+    datalen += 8 - (datalen % 8);
+    in.resize(datalen, 0);
+  }
+  BF_set_key(&bf_e_key, key.length(), (unsigned char *)key.data());
+  bf_data data;
+  size_t part;
+  unsigned char *s = (unsigned char *)in.data();
+  for (size_t i = 0; i < in.length(); i += 8) {
+    data.lr.left = *s++ << 24;
+    data.lr.left += *s++ << 16;
+    data.lr.left += *s++ << 8;
+    data.lr.left += *s++;
+    data.lr.right = *s++ << 24;
+    data.lr.right += *s++ << 16;
+    data.lr.right += *s++ << 8;
+    data.lr.right += *s++;
+    BF_encrypt(&data.bf_long, &bf_e_key);
+    for (part = 0; part < 6; part++) {
+      out += eggdrop_blowfish_base64[data.lr.right & 0x3f];
+      data.lr.right = data.lr.right >> 6;
+    }
+    for (part = 0; part < 6; part++) {
+      out += eggdrop_blowfish_base64[data.lr.left & 0x3f];
+      data.lr.left = data.lr.left >> 6;
+    }
+  }
+  return out;
+}
+
+/*
+ * @brief Decrypt a string using eggdrop's blowfish
+ * @param in The string to decrypt.
+ * @param key The key to use.
+ * @returns The decrypted string if valid. The string passed in if no key is given. A truncated decrypted string in the case of error.
+ */
+bd::String egg_bf_decrypt(bd::String in, const bd::String& key)
+{
+  bd::String out(size_t(in.length() * .9));
+  // Too small to process
+  if (in.size() < 12) return out;
+
+  // Not valid base64
+  if (eggdrop_blowfish_base64_index[in[0]] == -1) return out;
+
+  int cut_off = in.length() % 12;
+  if (cut_off > 0)
+    in.resize(in.length() - cut_off);
+
+  BF_set_key(&bf_d_key, key.length(), (unsigned char *)key.data());
+  bf_data data;
+  char val;
+  size_t part;
+  char *s = (char *)in.data();
+  for (size_t i = 0; i < in.length(); i += 12) {
+    data.lr.left = 0;
+    data.lr.right = 0;
+    for (part = 0; part < 6; part++) {
+      if ((val = eggdrop_blowfish_base64_index[int(*s++)]) == -1) return out;
+      data.lr.right |= val << part * 6;
+    }
+    for (part = 0; part < 6; part++) {
+      if ((val = eggdrop_blowfish_base64_index[int(*s++)]) == -1) return out;
+      data.lr.left |= val << part * 6;
+    }
+    BF_decrypt(&data.bf_long, &bf_d_key);
+    for (part = 0; part < 4; part++) out += char((data.lr.left & (0xff << ((3 - part) * 8))) >> ((3 - part) * 8));
+    for (part = 0; part < 4; part++) out += char((data.lr.right & (0xff << ((3 - part) * 8))) >> ((3 - part) * 8));
+  }
+
+  return out;
+}
+
+#ifdef not_needed
+unsigned char *
+bf_encrypt_ecb_binary(const char *keydata, unsigned char *in, size_t *inlen)
+{
+  size_t len = *inlen;
+  int blocks = 0, block = 0;
+  unsigned char *out = NULL;
+
+  /* First pad indata to CRYPT_BLOCKSIZE multiple */
+  if (len % CRYPT_BLOCKSIZE)             /* more than 1 block? */
+    len += (CRYPT_BLOCKSIZE - (len % CRYPT_BLOCKSIZE));
+
+  out = (unsigned char *) my_calloc(1, len + 1);
+  memcpy(out, in, *inlen);
+  *inlen = len;
+
+  if (!keydata || !*keydata) {
+    /* No key, no encryption */
+    memcpy(out, in, len);
+  } else {
+    BF_set_key(&bf_e_key, strlen(keydata), (const unsigned char*) keydata);
+    /* Now loop through the blocks and crypt them */
+    blocks = len / CRYPT_BLOCKSIZE;
+    for (block = blocks - 1; block >= 0; --block)
+      BF_ecb_encrypt(&out[block * CRYPT_BLOCKSIZE], &out[block * CRYPT_BLOCKSIZE], &bf_e_key, BF_ENCRYPT);
+    OPENSSL_cleanse(&bf_e_key, sizeof(bf_e_key));
+  }
+  out[len] = 0;
+  return out;
+}
+
+unsigned char *
+bf_decrypt_ecb_binary(const char *keydata, unsigned char *in, size_t *len)
+{
+  int blocks = 0, block = 0;
+  unsigned char *out = NULL;
+
+  *len -= *len % CRYPT_BLOCKSIZE;
+  out = (unsigned char *) my_calloc(1, *len + 1);
+  memcpy(out, in, *len);
+
+  if (!keydata || !*keydata) {
+    /* No key, no decryption */
+  } else {
+    BF_set_key(&bf_d_key, strlen(keydata), (const unsigned char*) keydata);
+    /* Now loop through the blocks and decrypt them */
+    blocks = *len / CRYPT_BLOCKSIZE;
+
+    for (block = blocks - 1; block >= 0; --block)
+      BF_ecb_encrypt(&out[block * CRYPT_BLOCKSIZE], &out[block * CRYPT_BLOCKSIZE], &bf_d_key, BF_DECRYPT);
+    OPENSSL_cleanse(&bf_d_key, sizeof(bf_d_key));
+  }
+
+  *len = strlen((char*) out);
+  out[*len] = 0;
+  return out;
+}
+
+unsigned char *
+bf_encrypt_cbc_binary(const char *keydata, unsigned char *in, size_t *inlen, unsigned char *ivec)
+{
+  size_t len = *inlen;
+  unsigned char *out = NULL;
+
+  /* First pad indata to CRYPT_BLOCKSIZE multiple */
+  if (len % CRYPT_BLOCKSIZE)             /* more than 1 block? */
+    len += (CRYPT_BLOCKSIZE - (len % CRYPT_BLOCKSIZE));
+
+  out = (unsigned char *) my_calloc(1, len + 1);
+  *inlen = len;
+
+  if (!keydata || !*keydata) {
+    /* No key, no encryption */
+    memcpy(out, in, len);
+  } else {
+    BF_set_key(&bf_e_key, strlen(keydata), (const unsigned char*) keydata);
+    BF_cbc_encrypt(in, out, len, &bf_e_key, ivec, BF_ENCRYPT);
+    OPENSSL_cleanse(&bf_e_key, sizeof(bf_e_key));
+  }
+  out[len] = 0;
+  return out;
+}
+
+unsigned char *
+bf_decrypt_cbc_binary(const char *keydata, unsigned char *in, size_t *len, unsigned char* ivec)
+{
+  unsigned char *out = NULL;
+
+  *len -= *len % CRYPT_BLOCKSIZE;
+  out = (unsigned char *) my_calloc(1, *len + 1);
+
+  if (!keydata || !*keydata) {
+    /* No key, no decryption */
+  } else {
+    BF_set_key(&bf_d_key, strlen(keydata), (const unsigned char*) keydata);
+    BF_cbc_encrypt(in, out, *len, &bf_d_key, ivec, BF_DECRYPT);
+    OPENSSL_cleanse(&bf_d_key, sizeof(bf_d_key));
+  }
+
+  *len = strlen((char*) out);
+  out[*len] = 0;
+  return out;
+}
+#endif

+ 22 - 0
src/crypto/bf_util.h

@@ -0,0 +1,22 @@
+/* bf_util.h
+ *
+ */
+
+#ifndef _BF_UTIL_H
+#define _BF_UTIL_H 1
+
+#include <sys/types.h>
+
+namespace bd {
+  class String;
+}
+
+bd::String egg_bf_encrypt(bd::String in, const bd::String& key);
+bd::String egg_bf_decrypt(bd::String in, const bd::String& key);
+#ifdef not_needed
+unsigned char *bf_encrypt_ecb_binary(const char *, unsigned char *, size_t *);
+unsigned char *bf_decrypt_ecb_binary(const char *, unsigned char *, size_t *);
+unsigned char *bf_encrypt_cbc_binary(const char *, unsigned char *, size_t *, unsigned char *);
+unsigned char *bf_decrypt_cbc_binary(const char *, unsigned char *, size_t *, unsigned char *);
+#endif
+#endif

+ 2 - 0
src/crypto/crypto.h

@@ -2,8 +2,10 @@
 #define _CRYPTO_H
 
 #include "aes_util.h"
+#include "bf_util.h"
 #include <openssl/crypto.h>
 #include <openssl/aes.h>
+#include <openssl/blowfish.h>
 #include <openssl/md5.h>
 #include <openssl/sha.h>