bf_util.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. /* bf_util.c
  2. *
  3. */
  4. #include "src/libcrypto.h"
  5. #include "src/compat/compat.h"
  6. #include <bdlib/src/String.h>
  7. #define CRYPT_BLOCKSIZE BF_BLOCK
  8. BF_KEY bf_e_key, bf_d_key;
  9. static const char eggdrop_blowfish_base64[65] = "./0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
  10. static const char eggdrop_blowfish_base64_index[256] = {
  11. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  12. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  13. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1,
  14. 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, -1, -1, -1, -1, -1, -1,
  15. -1, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
  16. 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, -1, -1, -1, -1, -1,
  17. -1, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
  18. 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, -1, -1, -1, -1, -1,
  19. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  20. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  21. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  22. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  23. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  24. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  25. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  26. -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
  27. };
  28. union bf_data {
  29. struct {
  30. unsigned long left;
  31. unsigned long right;
  32. } lr;
  33. BF_LONG bf_long;
  34. };
  35. /* These were adapted from eggdrop's blowfish.mod as well as dirtirc */
  36. /*
  37. * @brief Encrypt a string using eggdrop's blowfish
  38. * @param in The string to encrypt.
  39. * @param key The key to use.
  40. * @returns The encrypted string.
  41. */
  42. bd::String egg_bf_encrypt(bd::String in, const bd::String& key)
  43. {
  44. /* No key, no encryption */
  45. if (!key.length()) return in;
  46. bd::String out(size_t(in.length() * 1.5));
  47. size_t datalen = in.length();
  48. if (datalen % 8 != 0) {
  49. datalen += 8 - (datalen % 8);
  50. in.resize(datalen, 0);
  51. }
  52. BF_set_key(&bf_e_key, key.length(), (unsigned char *)key.data());
  53. bf_data data;
  54. size_t part;
  55. unsigned char *s = (unsigned char *)in.data();
  56. for (size_t i = 0; i < in.length(); i += 8) {
  57. data.lr.left = *s++ << 24;
  58. data.lr.left += *s++ << 16;
  59. data.lr.left += *s++ << 8;
  60. data.lr.left += *s++;
  61. data.lr.right = *s++ << 24;
  62. data.lr.right += *s++ << 16;
  63. data.lr.right += *s++ << 8;
  64. data.lr.right += *s++;
  65. BF_encrypt(&data.bf_long, &bf_e_key);
  66. for (part = 0; part < 6; part++) {
  67. out += eggdrop_blowfish_base64[data.lr.right & 0x3f];
  68. data.lr.right = data.lr.right >> 6;
  69. }
  70. for (part = 0; part < 6; part++) {
  71. out += eggdrop_blowfish_base64[data.lr.left & 0x3f];
  72. data.lr.left = data.lr.left >> 6;
  73. }
  74. }
  75. return out;
  76. }
  77. /*
  78. * @brief Decrypt a string using eggdrop's blowfish
  79. * @param in The string to decrypt.
  80. * @param key The key to use.
  81. * @returns The decrypted string if valid. The string passed in if no key is given. A truncated decrypted string in the case of error.
  82. */
  83. bd::String egg_bf_decrypt(bd::String in, const bd::String& key)
  84. {
  85. // Skip over '+OK '
  86. if (in(0, 4) == "+OK ")
  87. in += static_cast<size_t>(4);
  88. bd::String out(size_t(in.length() * .9));
  89. // Too small to process
  90. if (in.size() < 12) return out;
  91. // Not valid base64
  92. if (eggdrop_blowfish_base64_index[in[0]] == -1) return out;
  93. int cut_off = in.length() % 12;
  94. if (cut_off > 0)
  95. in.resize(in.length() - cut_off);
  96. BF_set_key(&bf_d_key, key.length(), (unsigned char *)key.data());
  97. bf_data data;
  98. char val;
  99. size_t part;
  100. char *s = (char *)in.data();
  101. for (size_t i = 0; i < in.length(); i += 12) {
  102. data.lr.left = 0;
  103. data.lr.right = 0;
  104. for (part = 0; part < 6; part++) {
  105. if ((val = eggdrop_blowfish_base64_index[int(*s++)]) == -1) return out;
  106. data.lr.right |= val << part * 6;
  107. }
  108. for (part = 0; part < 6; part++) {
  109. if ((val = eggdrop_blowfish_base64_index[int(*s++)]) == -1) return out;
  110. data.lr.left |= val << part * 6;
  111. }
  112. BF_decrypt(&data.bf_long, &bf_d_key);
  113. for (part = 0; part < 4; part++) out += char((data.lr.left & (0xff << ((3 - part) * 8))) >> ((3 - part) * 8));
  114. for (part = 0; part < 4; part++) out += char((data.lr.right & (0xff << ((3 - part) * 8))) >> ((3 - part) * 8));
  115. }
  116. return out;
  117. }
  118. #ifdef not_needed
  119. unsigned char *
  120. bf_encrypt_ecb_binary(const char *keydata, unsigned char *in, size_t *inlen)
  121. {
  122. size_t len = *inlen;
  123. int blocks = 0, block = 0;
  124. unsigned char *out = NULL;
  125. /* First pad indata to CRYPT_BLOCKSIZE multiple */
  126. if (len % CRYPT_BLOCKSIZE) /* more than 1 block? */
  127. len += (CRYPT_BLOCKSIZE - (len % CRYPT_BLOCKSIZE));
  128. out = (unsigned char *) my_calloc(1, len + 1);
  129. memcpy(out, in, *inlen);
  130. *inlen = len;
  131. if (!keydata || !*keydata) {
  132. /* No key, no encryption */
  133. memcpy(out, in, len);
  134. } else {
  135. BF_set_key(&bf_e_key, strlen(keydata), (const unsigned char*) keydata);
  136. /* Now loop through the blocks and crypt them */
  137. blocks = len / CRYPT_BLOCKSIZE;
  138. for (block = blocks - 1; block >= 0; --block)
  139. BF_ecb_encrypt(&out[block * CRYPT_BLOCKSIZE], &out[block * CRYPT_BLOCKSIZE], &bf_e_key, BF_ENCRYPT);
  140. OPENSSL_cleanse(&bf_e_key, sizeof(bf_e_key));
  141. }
  142. out[len] = 0;
  143. return out;
  144. }
  145. unsigned char *
  146. bf_decrypt_ecb_binary(const char *keydata, unsigned char *in, size_t *len)
  147. {
  148. int blocks = 0, block = 0;
  149. unsigned char *out = NULL;
  150. *len -= *len % CRYPT_BLOCKSIZE;
  151. out = (unsigned char *) my_calloc(1, *len + 1);
  152. memcpy(out, in, *len);
  153. if (!keydata || !*keydata) {
  154. /* No key, no decryption */
  155. } else {
  156. BF_set_key(&bf_d_key, strlen(keydata), (const unsigned char*) keydata);
  157. /* Now loop through the blocks and decrypt them */
  158. blocks = *len / CRYPT_BLOCKSIZE;
  159. for (block = blocks - 1; block >= 0; --block)
  160. BF_ecb_encrypt(&out[block * CRYPT_BLOCKSIZE], &out[block * CRYPT_BLOCKSIZE], &bf_d_key, BF_DECRYPT);
  161. OPENSSL_cleanse(&bf_d_key, sizeof(bf_d_key));
  162. }
  163. *len = strlen((char*) out);
  164. out[*len] = 0;
  165. return out;
  166. }
  167. unsigned char *
  168. bf_encrypt_cbc_binary(const char *keydata, unsigned char *in, size_t *inlen, unsigned char *ivec)
  169. {
  170. size_t len = *inlen;
  171. unsigned char *out = NULL;
  172. /* First pad indata to CRYPT_BLOCKSIZE multiple */
  173. if (len % CRYPT_BLOCKSIZE) /* more than 1 block? */
  174. len += (CRYPT_BLOCKSIZE - (len % CRYPT_BLOCKSIZE));
  175. out = (unsigned char *) my_calloc(1, len + 1);
  176. *inlen = len;
  177. if (!keydata || !*keydata) {
  178. /* No key, no encryption */
  179. memcpy(out, in, len);
  180. } else {
  181. BF_set_key(&bf_e_key, strlen(keydata), (const unsigned char*) keydata);
  182. BF_cbc_encrypt(in, out, len, &bf_e_key, ivec, BF_ENCRYPT);
  183. OPENSSL_cleanse(&bf_e_key, sizeof(bf_e_key));
  184. }
  185. out[len] = 0;
  186. return out;
  187. }
  188. unsigned char *
  189. bf_decrypt_cbc_binary(const char *keydata, unsigned char *in, size_t *len, unsigned char* ivec)
  190. {
  191. unsigned char *out = NULL;
  192. *len -= *len % CRYPT_BLOCKSIZE;
  193. out = (unsigned char *) my_calloc(1, *len + 1);
  194. if (!keydata || !*keydata) {
  195. /* No key, no decryption */
  196. } else {
  197. BF_set_key(&bf_d_key, strlen(keydata), (const unsigned char*) keydata);
  198. BF_cbc_encrypt(in, out, *len, &bf_d_key, ivec, BF_DECRYPT);
  199. OPENSSL_cleanse(&bf_d_key, sizeof(bf_d_key));
  200. }
  201. *len = strlen((char*) out);
  202. out[*len] = 0;
  203. return out;
  204. }
  205. #endif