bf_util.cc 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  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 int 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. BF_LONG left;
  31. BF_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. size_t datalen = in.length();
  47. bd::String out(static_cast<size_t>(datalen * 1.5));
  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.cbegin());
  53. bf_data data;
  54. size_t part;
  55. unsigned char *s = (unsigned char *)in.cbegin();
  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(static_cast<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[int(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.cbegin());
  97. bf_data data;
  98. int val;
  99. size_t part;
  100. char *s = (char *)in.cbegin();
  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 |= (char)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 |= (char)val << part * 6;
  111. }
  112. BF_decrypt(&data.bf_long, &bf_d_key);
  113. for (part = 0; part < 4; part++) {
  114. const char decrypted_char = char((data.lr.left & (0xff << ((3 - part) * 8))) >> ((3 - part) * 8));
  115. // Don't write NULLs into the string
  116. if (decrypted_char) {
  117. out += decrypted_char;
  118. }
  119. }
  120. for (part = 0; part < 4; part++) {
  121. const char decrypted_char = char((data.lr.right & (0xff << ((3 - part) * 8))) >> ((3 - part) * 8));
  122. // Don't write NULLs into the string
  123. if (decrypted_char) {
  124. out += decrypted_char;
  125. }
  126. }
  127. }
  128. return out;
  129. }
  130. #ifdef not_needed
  131. unsigned char *
  132. bf_encrypt_ecb_binary(const char *keydata, unsigned char *in, size_t *inlen)
  133. {
  134. size_t len = *inlen;
  135. int blocks = 0, block = 0;
  136. unsigned char *out = NULL;
  137. /* First pad indata to CRYPT_BLOCKSIZE multiple */
  138. if (len % CRYPT_BLOCKSIZE) /* more than 1 block? */
  139. len += (CRYPT_BLOCKSIZE - (len % CRYPT_BLOCKSIZE));
  140. out = (unsigned char *) calloc(1, len + 1);
  141. memcpy(out, in, *inlen);
  142. *inlen = len;
  143. if (!keydata || !*keydata) {
  144. /* No key, no encryption */
  145. memcpy(out, in, len);
  146. } else {
  147. BF_set_key(&bf_e_key, strlen(keydata), (const unsigned char*) keydata);
  148. /* Now loop through the blocks and crypt them */
  149. blocks = len / CRYPT_BLOCKSIZE;
  150. for (block = blocks - 1; block >= 0; --block)
  151. BF_ecb_encrypt(&out[block * CRYPT_BLOCKSIZE], &out[block * CRYPT_BLOCKSIZE], &bf_e_key, BF_ENCRYPT);
  152. OPENSSL_cleanse(&bf_e_key, sizeof(bf_e_key));
  153. }
  154. out[len] = 0;
  155. return out;
  156. }
  157. unsigned char *
  158. bf_decrypt_ecb_binary(const char *keydata, unsigned char *in, size_t *len)
  159. {
  160. int blocks = 0, block = 0;
  161. unsigned char *out = NULL;
  162. *len -= *len % CRYPT_BLOCKSIZE;
  163. out = (unsigned char *) calloc(1, *len + 1);
  164. memcpy(out, in, *len);
  165. if (!keydata || !*keydata) {
  166. /* No key, no decryption */
  167. } else {
  168. BF_set_key(&bf_d_key, strlen(keydata), (const unsigned char*) keydata);
  169. /* Now loop through the blocks and decrypt them */
  170. blocks = *len / CRYPT_BLOCKSIZE;
  171. for (block = blocks - 1; block >= 0; --block)
  172. BF_ecb_encrypt(&out[block * CRYPT_BLOCKSIZE], &out[block * CRYPT_BLOCKSIZE], &bf_d_key, BF_DECRYPT);
  173. OPENSSL_cleanse(&bf_d_key, sizeof(bf_d_key));
  174. }
  175. *len = strlen((char*) out);
  176. out[*len] = 0;
  177. return out;
  178. }
  179. unsigned char *
  180. bf_encrypt_cbc_binary(const char *keydata, unsigned char *in, size_t *inlen, unsigned char *ivec)
  181. {
  182. size_t len = *inlen;
  183. unsigned char *out = NULL;
  184. /* First pad indata to CRYPT_BLOCKSIZE multiple */
  185. if (len % CRYPT_BLOCKSIZE) /* more than 1 block? */
  186. len += (CRYPT_BLOCKSIZE - (len % CRYPT_BLOCKSIZE));
  187. out = (unsigned char *) calloc(1, len + 1);
  188. *inlen = len;
  189. if (!keydata || !*keydata) {
  190. /* No key, no encryption */
  191. memcpy(out, in, len);
  192. } else {
  193. BF_set_key(&bf_e_key, strlen(keydata), (const unsigned char*) keydata);
  194. BF_cbc_encrypt(in, out, len, &bf_e_key, ivec, BF_ENCRYPT);
  195. OPENSSL_cleanse(&bf_e_key, sizeof(bf_e_key));
  196. }
  197. out[len] = 0;
  198. return out;
  199. }
  200. unsigned char *
  201. bf_decrypt_cbc_binary(const char *keydata, unsigned char *in, size_t *len, unsigned char* ivec)
  202. {
  203. unsigned char *out = NULL;
  204. *len -= *len % CRYPT_BLOCKSIZE;
  205. out = (unsigned char *) calloc(1, *len + 1);
  206. if (!keydata || !*keydata) {
  207. /* No key, no decryption */
  208. } else {
  209. BF_set_key(&bf_d_key, strlen(keydata), (const unsigned char*) keydata);
  210. BF_cbc_encrypt(in, out, *len, &bf_d_key, ivec, BF_DECRYPT);
  211. OPENSSL_cleanse(&bf_d_key, sizeof(bf_d_key));
  212. }
  213. *len = strlen((char*) out);
  214. out[*len] = 0;
  215. return out;
  216. }
  217. #endif
  218. /* vim: set sts=2 sw=2 ts=8 et: */