00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #define MODULE_NAME "encryption"
00030 #define MAKING_ENCRYPTION
00031
00032 #include "src/mod/module.h"
00033 #include "blowfish.h"
00034 #include "bf_tab.h"
00035
00036 #undef global
00037 static Function *global = NULL;
00038
00039
00040 #define BOXES 3
00041
00042
00043 #define S0(x) (bf_S[0][x.w.byte0])
00044 #define S1(x) (bf_S[1][x.w.byte1])
00045 #define S2(x) (bf_S[2][x.w.byte2])
00046 #define S3(x) (bf_S[3][x.w.byte3])
00047 #define bf_F(x) (((S0(x) + S1(x)) ^ S2(x)) + S3(x))
00048 #define ROUND(a,b,n) (a.word ^= bf_F(b) ^ bf_P[n])
00049
00050
00051 static struct box_t {
00052 u_32bit_t *P;
00053 u_32bit_t **S;
00054 char key[81];
00055 char keybytes;
00056 time_t lastuse;
00057 } box[BOXES];
00058
00059
00060
00061 static u_32bit_t *bf_P;
00062 static u_32bit_t **bf_S;
00063
00064 static int blowfish_expmem()
00065 {
00066 int i, tot = 0;
00067
00068 for (i = 0; i < BOXES; i++)
00069 if (box[i].P != NULL) {
00070 tot += ((bf_N + 2) * sizeof(u_32bit_t));
00071 tot += (4 * sizeof(u_32bit_t *));
00072 tot += (4 * 256 * sizeof(u_32bit_t));
00073 }
00074 return tot;
00075 }
00076
00077 static void blowfish_encipher(u_32bit_t *xl, u_32bit_t *xr)
00078 {
00079 union aword Xl;
00080 union aword Xr;
00081
00082 Xl.word = *xl;
00083 Xr.word = *xr;
00084
00085 Xl.word ^= bf_P[0];
00086 ROUND(Xr, Xl, 1);
00087 ROUND(Xl, Xr, 2);
00088 ROUND(Xr, Xl, 3);
00089 ROUND(Xl, Xr, 4);
00090 ROUND(Xr, Xl, 5);
00091 ROUND(Xl, Xr, 6);
00092 ROUND(Xr, Xl, 7);
00093 ROUND(Xl, Xr, 8);
00094 ROUND(Xr, Xl, 9);
00095 ROUND(Xl, Xr, 10);
00096 ROUND(Xr, Xl, 11);
00097 ROUND(Xl, Xr, 12);
00098 ROUND(Xr, Xl, 13);
00099 ROUND(Xl, Xr, 14);
00100 ROUND(Xr, Xl, 15);
00101 ROUND(Xl, Xr, 16);
00102 Xr.word ^= bf_P[17];
00103
00104 *xr = Xl.word;
00105 *xl = Xr.word;
00106 }
00107
00108 static void blowfish_decipher(u_32bit_t *xl, u_32bit_t *xr)
00109 {
00110 union aword Xl;
00111 union aword Xr;
00112
00113 Xl.word = *xl;
00114 Xr.word = *xr;
00115
00116 Xl.word ^= bf_P[17];
00117 ROUND(Xr, Xl, 16);
00118 ROUND(Xl, Xr, 15);
00119 ROUND(Xr, Xl, 14);
00120 ROUND(Xl, Xr, 13);
00121 ROUND(Xr, Xl, 12);
00122 ROUND(Xl, Xr, 11);
00123 ROUND(Xr, Xl, 10);
00124 ROUND(Xl, Xr, 9);
00125 ROUND(Xr, Xl, 8);
00126 ROUND(Xl, Xr, 7);
00127 ROUND(Xr, Xl, 6);
00128 ROUND(Xl, Xr, 5);
00129 ROUND(Xr, Xl, 4);
00130 ROUND(Xl, Xr, 3);
00131 ROUND(Xr, Xl, 2);
00132 ROUND(Xl, Xr, 1);
00133 Xr.word ^= bf_P[0];
00134
00135 *xl = Xr.word;
00136 *xr = Xl.word;
00137 }
00138
00139
00140 static void blowfish_report(int idx, int details)
00141 {
00142 if (details) {
00143 int i, tot = 0, size = blowfish_expmem();
00144
00145 for (i = 0; i < BOXES; i++)
00146 if (box[i].P != NULL)
00147 tot++;
00148
00149 dprintf(idx, " Blowfish encryption module:\n");
00150 dprintf(idx, " %d of %d boxes in use: ", tot, BOXES);
00151 for (i = 0; i < BOXES; i++)
00152 if (box[i].P != NULL) {
00153 dprintf(idx, "(age: %d) ", now - box[i].lastuse);
00154 }
00155 dprintf(idx, "\n");
00156 dprintf(idx, " Using %d byte%s of memory\n", size,
00157 (size != 1) ? "s" : "");
00158 }
00159 }
00160
00161 static void blowfish_init(u_8bit_t *key, int keybytes)
00162 {
00163 int i, j, bx;
00164 time_t lowest;
00165 u_32bit_t data;
00166 u_32bit_t datal;
00167 u_32bit_t datar;
00168 union aword temp;
00169
00170
00171
00172
00173 if (keybytes > 80)
00174 keybytes = 80;
00175
00176
00177 for (i = 0; i < BOXES; i++)
00178 if (box[i].P != NULL) {
00179 if ((box[i].keybytes == keybytes) &&
00180 (!strncmp((char *) (box[i].key), (char *) key, keybytes))) {
00181
00182 box[i].lastuse = now;
00183 bf_P = box[i].P;
00184 bf_S = box[i].S;
00185 return;
00186 }
00187 }
00188
00189
00190 bx = -1;
00191 for (i = 0; i < BOXES; i++) {
00192 if (box[i].P == NULL) {
00193 bx = i;
00194 i = BOXES + 1;
00195 }
00196 }
00197 if (bx < 0) {
00198
00199 lowest = now;
00200 for (i = 0; i < BOXES; i++)
00201 if (box[i].lastuse <= lowest) {
00202 lowest = box[i].lastuse;
00203 bx = i;
00204 }
00205 nfree(box[bx].P);
00206 for (i = 0; i < 4; i++)
00207 nfree(box[bx].S[i]);
00208 nfree(box[bx].S);
00209 }
00210
00211
00212 box[bx].P = nmalloc((bf_N + 2) * sizeof(u_32bit_t));
00213 box[bx].S = nmalloc(4 * sizeof(u_32bit_t *));
00214 for (i = 0; i < 4; i++)
00215 box[bx].S[i] = nmalloc(256 * sizeof(u_32bit_t));
00216 bf_P = box[bx].P;
00217 bf_S = box[bx].S;
00218 box[bx].keybytes = keybytes;
00219 strncpy(box[bx].key, (char *) key, keybytes);
00220 box[bx].key[keybytes] = 0;
00221 box[bx].lastuse = now;
00222
00223
00224
00225
00226 for (i = 0; i < bf_N + 2; i++)
00227 bf_P[i] = initbf_P[i];
00228 for (i = 0; i < 4; i++)
00229 for (j = 0; j < 256; j++)
00230 bf_S[i][j] = initbf_S[i][j];
00231
00232 j = 0;
00233 if (keybytes > 0) {
00234 for (i = 0; i < bf_N + 2; ++i) {
00235 temp.word = 0;
00236 temp.w.byte0 = key[j];
00237 temp.w.byte1 = key[(j + 1) % keybytes];
00238 temp.w.byte2 = key[(j + 2) % keybytes];
00239 temp.w.byte3 = key[(j + 3) % keybytes];
00240 data = temp.word;
00241 bf_P[i] = bf_P[i] ^ data;
00242 j = (j + 4) % keybytes;
00243 }
00244 }
00245 datal = 0x00000000;
00246 datar = 0x00000000;
00247 for (i = 0; i < bf_N + 2; i += 2) {
00248 blowfish_encipher(&datal, &datar);
00249 bf_P[i] = datal;
00250 bf_P[i + 1] = datar;
00251 }
00252 for (i = 0; i < 4; ++i) {
00253 for (j = 0; j < 256; j += 2) {
00254 blowfish_encipher(&datal, &datar);
00255 bf_S[i][j] = datal;
00256 bf_S[i][j + 1] = datar;
00257 }
00258 }
00259 }
00260
00261
00262
00263
00264 #define SALT1 0xdeadd061
00265 #define SALT2 0x23f6b095
00266
00267
00268 static char *base64 =
00269 "./0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
00270
00271 static int base64dec(char c)
00272 {
00273 int i;
00274
00275 for (i = 0; i < 64; i++)
00276 if (base64[i] == c)
00277 return i;
00278 return 0;
00279 }
00280
00281 static void blowfish_encrypt_pass(char *text, char *new)
00282 {
00283 u_32bit_t left, right;
00284 int n;
00285 char *p;
00286
00287 blowfish_init((unsigned char *) text, strlen(text));
00288 left = SALT1;
00289 right = SALT2;
00290 blowfish_encipher(&left, &right);
00291 p = new;
00292 *p++ = '+';
00293 n = 32;
00294 while (n > 0) {
00295 *p++ = base64[right & 0x3f];
00296 right = (right >> 6);
00297 n -= 6;
00298 }
00299 n = 32;
00300 while (n > 0) {
00301 *p++ = base64[left & 0x3f];
00302 left = (left >> 6);
00303 n -= 6;
00304 }
00305 *p = 0;
00306 }
00307
00308
00309
00310 static char *encrypt_string(char *key, char *str)
00311 {
00312 u_32bit_t left, right;
00313 unsigned char *p;
00314 char *s, *dest, *d;
00315 int i;
00316
00317
00318 s = nmalloc(strlen(str) + 9);
00319 strcpy(s, str);
00320 if ((!key) || (!key[0]))
00321 return s;
00322 p = (unsigned char *) s;
00323 dest = nmalloc((strlen(str) + 9) * 2);
00324 while (*p)
00325 p++;
00326 for (i = 0; i < 8; i++)
00327 *p++ = 0;
00328 blowfish_init((unsigned char *) key, strlen(key));
00329 p = (unsigned char *) s;
00330 d = dest;
00331 while (*p) {
00332 left = ((*p++) << 24);
00333 left += ((*p++) << 16);
00334 left += ((*p++) << 8);
00335 left += (*p++);
00336 right = ((*p++) << 24);
00337 right += ((*p++) << 16);
00338 right += ((*p++) << 8);
00339 right += (*p++);
00340 blowfish_encipher(&left, &right);
00341 for (i = 0; i < 6; i++) {
00342 *d++ = base64[right & 0x3f];
00343 right = (right >> 6);
00344 }
00345 for (i = 0; i < 6; i++) {
00346 *d++ = base64[left & 0x3f];
00347 left = (left >> 6);
00348 }
00349 }
00350 *d = 0;
00351 nfree(s);
00352 return dest;
00353 }
00354
00355
00356
00357 static char *decrypt_string(char *key, char *str)
00358 {
00359 u_32bit_t left, right;
00360 char *p, *s, *dest, *d;
00361 int i;
00362
00363
00364 s = nmalloc(strlen(str) + 12);
00365 strcpy(s, str);
00366 if ((!key) || (!key[0]))
00367 return s;
00368 p = s;
00369 dest = nmalloc(strlen(str) + 12);
00370 while (*p)
00371 p++;
00372 for (i = 0; i < 12; i++)
00373 *p++ = 0;
00374 blowfish_init((unsigned char *) key, strlen(key));
00375 p = s;
00376 d = dest;
00377 while (*p) {
00378 right = 0L;
00379 left = 0L;
00380 for (i = 0; i < 6; i++)
00381 right |= (base64dec(*p++)) << (i * 6);
00382 for (i = 0; i < 6; i++)
00383 left |= (base64dec(*p++)) << (i * 6);
00384 blowfish_decipher(&left, &right);
00385 for (i = 0; i < 4; i++)
00386 *d++ = (left & (0xff << ((3 - i) * 8))) >> ((3 - i) * 8);
00387 for (i = 0; i < 4; i++)
00388 *d++ = (right & (0xff << ((3 - i) * 8))) >> ((3 - i) * 8);
00389 }
00390 *d = 0;
00391 nfree(s);
00392 return dest;
00393 }
00394
00395 static int tcl_encrypt STDVAR
00396 {
00397 char *p;
00398
00399 BADARGS(3, 3, " key string");
00400
00401 p = encrypt_string(argv[1], argv[2]);
00402 Tcl_AppendResult(irp, p, NULL);
00403 nfree(p);
00404 return TCL_OK;
00405 }
00406
00407 static int tcl_decrypt STDVAR
00408 {
00409 char *p;
00410
00411 BADARGS(3, 3, " key string");
00412
00413 p = decrypt_string(argv[1], argv[2]);
00414 Tcl_AppendResult(irp, p, NULL);
00415 nfree(p);
00416 return TCL_OK;
00417 }
00418
00419 static int tcl_encpass STDVAR
00420 {
00421 BADARGS(2, 2, " string");
00422
00423 if (strlen(argv[1]) > 0) {
00424 char p[16];
00425
00426 blowfish_encrypt_pass(argv[1], p);
00427 Tcl_AppendResult(irp, p, NULL);
00428 } else
00429 Tcl_AppendResult(irp, "", NULL);
00430 return TCL_OK;
00431 }
00432
00433 static tcl_cmds mytcls[] = {
00434 {"encrypt", tcl_encrypt},
00435 {"decrypt", tcl_decrypt},
00436 {"encpass", tcl_encpass},
00437 {NULL, NULL}
00438 };
00439
00440 static char *blowfish_close()
00441 {
00442 return "You can't unload the encryption module";
00443 }
00444
00445 EXPORT_SCOPE char *blowfish_start(Function *);
00446
00447 static Function blowfish_table[] = {
00448
00449 (Function) blowfish_start,
00450 (Function) blowfish_close,
00451 (Function) blowfish_expmem,
00452 (Function) blowfish_report,
00453
00454 (Function) encrypt_string,
00455 (Function) decrypt_string,
00456 };
00457
00458 char *blowfish_start(Function *global_funcs)
00459 {
00460 int i;
00461
00462
00463
00464
00465
00466
00467 if (global_funcs) {
00468 global = global_funcs;
00469
00470 if (!module_rename("blowfish", MODULE_NAME))
00471 return "Already loaded.";
00472
00473 for (i = 0; i < BOXES; i++) {
00474 box[i].P = NULL;
00475 box[i].S = NULL;
00476 box[i].key[0] = 0;
00477 box[i].lastuse = 0L;
00478 }
00479 module_register(MODULE_NAME, blowfish_table, 2, 1);
00480 if (!module_depend(MODULE_NAME, "eggdrop", 106, 3)) {
00481 module_undepend(MODULE_NAME);
00482 return "This module requires Eggdrop 1.6.3 or later.";
00483 }
00484 add_hook(HOOK_ENCRYPT_PASS, (Function) blowfish_encrypt_pass);
00485 add_hook(HOOK_ENCRYPT_STRING, (Function) encrypt_string);
00486 add_hook(HOOK_DECRYPT_STRING, (Function) decrypt_string);
00487 }
00488 add_tcl_commands(mytcls);
00489 return NULL;
00490 }