src/mod/blowfish.mod/blowfish.c File Reference

#include "src/mod/module.h"
#include "blowfish.h"
#include "bf_tab.h"
Include dependency graph for blowfish.c:

Go to the source code of this file.

Data Structures

struct  box_t

Defines

#define MODULE_NAME   "encryption"
#define MAKING_ENCRYPTION
#define BOXES   3
#define S0(x)   (bf_S[0][x.w.byte0])
#define S1(x)   (bf_S[1][x.w.byte1])
#define S2(x)   (bf_S[2][x.w.byte2])
#define S3(x)   (bf_S[3][x.w.byte3])
#define bf_F(x)   (((S0(x) + S1(x)) ^ S2(x)) + S3(x))
#define ROUND(a, b, n)   (a.word ^= bf_F(b) ^ bf_P[n])
#define SALT1   0xdeadd061
#define SALT2   0x23f6b095

Functions

static int blowfish_expmem ()
static void blowfish_encipher (u_32bit_t *xl, u_32bit_t *xr)
static void blowfish_decipher (u_32bit_t *xl, u_32bit_t *xr)
static void blowfish_report (int idx, int details)
static void blowfish_init (u_8bit_t *key, int keybytes)
static int base64dec (char c)
static void blowfish_encrypt_pass (char *text, char *new)
static char * encrypt_string (char *key, char *str)
static char * decrypt_string (char *key, char *str)
static char * blowfish_close ()
EXPORT_SCOPE char * blowfish_start (Function *)

Variables

static Functionglobal = 0
static struct box_t box [3]
static u_32bit_t * bf_P
static u_32bit_t ** bf_S
static char * base64
static Function blowfish_table []

Define Documentation

#define bf_F (  )     (((S0(x) + S1(x)) ^ S2(x)) + S3(x))

Definition at line 47 of file blowfish.c.

#define BOXES   3

Definition at line 40 of file blowfish.c.

Referenced by blowfish_expmem(), blowfish_init(), blowfish_report(), and blowfish_start().

#define MAKING_ENCRYPTION

Definition at line 30 of file blowfish.c.

#define MODULE_NAME   "encryption"

Definition at line 29 of file blowfish.c.

#define ROUND ( a,
b,
 )     (a.word ^= bf_F(b) ^ bf_P[n])

Definition at line 48 of file blowfish.c.

Referenced by blowfish_decipher(), and blowfish_encipher().

#define S0 (  )     (bf_S[0][x.w.byte0])

Definition at line 43 of file blowfish.c.

#define S1 (  )     (bf_S[1][x.w.byte1])

Definition at line 44 of file blowfish.c.

#define S2 (  )     (bf_S[2][x.w.byte2])

Definition at line 45 of file blowfish.c.

#define S3 (  )     (bf_S[3][x.w.byte3])

Definition at line 46 of file blowfish.c.

#define SALT1   0xdeadd061

Definition at line 264 of file blowfish.c.

Referenced by blowfish_encrypt_pass().

#define SALT2   0x23f6b095

Definition at line 265 of file blowfish.c.

Referenced by blowfish_encrypt_pass().


Function Documentation

static int base64dec ( char  c  )  [static]

Definition at line 271 of file blowfish.c.

References base64.

Referenced by decrypt_string().

00272 {
00273   int i;
00274 
00275   for (i = 0; i < 64; i++)
00276     if (base64[i] == c)
00277       return i;
00278   return 0;
00279 }

Here is the caller graph for this function:

static char* blowfish_close (  )  [static]

Definition at line 440 of file blowfish.c.

00441 {
00442   return "You can't unload the encryption module";
00443 }

static void blowfish_decipher ( u_32bit_t *  xl,
u_32bit_t *  xr 
) [static]

Definition at line 108 of file blowfish.c.

References bf_P, ROUND, and aword::word.

Referenced by decrypt_string().

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 }

Here is the caller graph for this function:

static void blowfish_encipher ( u_32bit_t *  xl,
u_32bit_t *  xr 
) [static]

Definition at line 77 of file blowfish.c.

References bf_P, ROUND, and aword::word.

Referenced by blowfish_encrypt_pass(), blowfish_init(), and encrypt_string().

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 }

Here is the caller graph for this function:

static void blowfish_encrypt_pass ( char *  text,
char *  new 
) [static]

Definition at line 281 of file blowfish.c.

References base64, blowfish_encipher(), blowfish_init(), SALT1, and SALT2.

Referenced by blowfish_start().

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++ = '+';                   /* + means encrypted pass */
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 }

Here is the call graph for this function:

Here is the caller graph for this function:

static int blowfish_expmem (  )  [static]

Definition at line 64 of file blowfish.c.

References bf_N, box, BOXES, and NULL.

Referenced by blowfish_report().

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 }

Here is the caller graph for this function:

static void blowfish_init ( u_8bit_t key,
int  keybytes 
) [static]

Definition at line 161 of file blowfish.c.

References bf_N, bf_P, bf_S, blowfish_encipher(), box, BOXES, aword::byte0, aword::byte1, aword::byte2, aword::byte3, initbf_P, initbf_S, box_t::key, box_t::keybytes, box_t::lastuse, nfree, nmalloc, now, NULL, box_t::P, box_t::S, time_t, aword::w, and aword::word.

Referenced by blowfish_encrypt_pass(), decrypt_string(), and encrypt_string().

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   /* drummer: Fixes crash if key is longer than 80 char. This may cause the key
00171    *          to not end with \00 but that's no problem.
00172    */
00173   if (keybytes > 80)
00174     keybytes = 80;
00175 
00176   /* Is buffer already allocated for this? */
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         /* Match! */
00182         box[i].lastuse = now;
00183         bf_P = box[i].P;
00184         bf_S = box[i].S;
00185         return;
00186       }
00187     }
00188   /* No pre-allocated buffer: make new one */
00189   /* Set 'bx' to empty buffer */
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     /* Find oldest */
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   /* Initialize new buffer */
00211   /* uh... this is over 4k */
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   /* Robey: Reset blowfish boxes to initial state
00223    * (I guess normally it just keeps scrambling them, but here it's
00224    * important to get the same encrypted result each time)
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) {           /* drummer: fixes crash if key=="" */
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 }

Here is the call graph for this function:

Here is the caller graph for this function:

static void blowfish_report ( int  idx,
int  details 
) [static]

Definition at line 140 of file blowfish.c.

References blowfish_expmem(), box, BOXES, dprintf, now, and NULL.

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 }

Here is the call graph for this function:

char * blowfish_start ( Function global_funcs  ) 

Definition at line 458 of file blowfish.c.

References add_hook, add_tcl_commands, blowfish_encrypt_pass(), box, BOXES, decrypt_string, encrypt_string, global, HOOK_DECRYPT_STRING, HOOK_ENCRYPT_PASS, HOOK_ENCRYPT_STRING, box_t::key, box_t::lastuse, module_depend, MODULE_NAME, module_register, module_rename, module_undepend, NULL, box_t::P, and box_t::S.

00459 {
00460   int i;
00461 
00462   /* `global_funcs' is NULL if eggdrop is recovering from a restart.
00463    *
00464    * As the encryption module is never unloaded, only initialise stuff
00465    * that got reset during restart, e.g. the tcl bindings.
00466    */
00467   if (global_funcs) {
00468     global = global_funcs;
00469 
00470     if (!module_rename("blowfish", MODULE_NAME))
00471       return "Already loaded.";
00472     /* Initialize buffered boxes */
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 }

Here is the call graph for this function:

static char* decrypt_string ( char *  key,
char *  str 
) [static]

Definition at line 357 of file blowfish.c.

References base64dec(), blowfish_decipher(), blowfish_init(), nfree, and nmalloc.

00358 {
00359   u_32bit_t left, right;
00360   char *p, *s, *dest, *d;
00361   int i;
00362 
00363   /* Pad encoded string with 0 bits in case it's bogus */
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 }

Here is the call graph for this function:

static char* encrypt_string ( char *  key,
char *  str 
) [static]

Definition at line 310 of file blowfish.c.

References base64, blowfish_encipher(), blowfish_init(), nfree, and nmalloc.

00311 {
00312   u_32bit_t left, right;
00313   unsigned char *p;
00314   char *s, *dest, *d;
00315   int i;
00316 
00317   /* Pad fake string with 8 bytes to make sure there's enough */
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 }

Here is the call graph for this function:


Variable Documentation

char* base64 [static]
Initial value:
            "./0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"

Definition at line 268 of file blowfish.c.

Referenced by base64dec(), blowfish_encrypt_pass(), and encrypt_string().

u_32bit_t* bf_P [static]

Definition at line 61 of file blowfish.c.

Referenced by blowfish_decipher(), blowfish_encipher(), and blowfish_init().

u_32bit_t** bf_S [static]

Definition at line 62 of file blowfish.c.

Referenced by blowfish_init().

struct box_t box[ 3 ] [static]
Function* global = 0 [static]

Definition at line 37 of file blowfish.c.


Generated on 7 Sep 2016 for Eggdrop by  doxygen 1.6.1