modules/blowfish/blowfish.c File Reference

#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
#include <eggdrop/eggdrop.h>
#include "blowfish.h"
#include "bf_tab.h"

Go to the source code of this file.

Data Structures

struct  box_t

Defines

#define start   blowfish_LTX_start
#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 void blowfish_encipher (u_int32_t *xl, u_int32_t *xr)
static void blowfish_decipher (u_int32_t *xl, u_int32_t *xr)
static void blowfish_init (u_int8_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 * script_encpass (char *pass)
static int blowfish_close (int why)
EXPORT_SCOPE int start (egg_module_t *modinfo)

Variables

static const char rcsid [] = "$Id: blowfish.c,v 1.18 2004-06-23 11:19:52 wingman Exp $"
static struct box_t box [BOXES]
static u_int32_t * bf_P
static u_int32_t ** bf_S
static char * base64 = "./0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
static script_command_t blowfish_script_cmds []


Define Documentation

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

Definition at line 46 of file blowfish.c.

#define BOXES   3

Definition at line 39 of file blowfish.c.

Referenced by blowfish_init(), and start().

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

Definition at line 47 of file blowfish.c.

Referenced by blowfish_decipher(), and blowfish_encipher().

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

Definition at line 42 of file blowfish.c.

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

Definition at line 43 of file blowfish.c.

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

Definition at line 44 of file blowfish.c.

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

Definition at line 45 of file blowfish.c.

#define SALT1   0xdeadd061

Definition at line 225 of file blowfish.c.

Referenced by blowfish_encrypt_pass().

#define SALT2   0x23f6b095

Definition at line 226 of file blowfish.c.

Referenced by blowfish_encrypt_pass().

#define start   blowfish_LTX_start


Function Documentation

static int base64dec ( char  c  )  [static]

Definition at line 231 of file blowfish.c.

References base64.

Referenced by decrypt_string().

00232 {
00233   int i;
00234 
00235   for (i = 0; i < 64; i++)
00236     if (base64[i] == c)
00237       return i;
00238   return 0;
00239 }

static int blowfish_close ( int  why  )  [static]

Definition at line 371 of file blowfish.c.

Referenced by start().

00372 {
00373   return(-1);
00374 }

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

Definition at line 94 of file blowfish.c.

References bf_P, ROUND, and aword::word.

Referenced by decrypt_string().

00095 {
00096   union aword Xl;
00097   union aword Xr;
00098 
00099   Xl.word = *xl;
00100   Xr.word = *xr;
00101 
00102   Xl.word ^= bf_P[17];
00103   ROUND(Xr, Xl, 16);
00104   ROUND(Xl, Xr, 15);
00105   ROUND(Xr, Xl, 14);
00106   ROUND(Xl, Xr, 13);
00107   ROUND(Xr, Xl, 12);
00108   ROUND(Xl, Xr, 11);
00109   ROUND(Xr, Xl, 10);
00110   ROUND(Xl, Xr, 9);
00111   ROUND(Xr, Xl, 8);
00112   ROUND(Xl, Xr, 7);
00113   ROUND(Xr, Xl, 6);
00114   ROUND(Xl, Xr, 5);
00115   ROUND(Xr, Xl, 4);
00116   ROUND(Xl, Xr, 3);
00117   ROUND(Xr, Xl, 2);
00118   ROUND(Xl, Xr, 1);
00119   Xr.word ^= bf_P[0];
00120 
00121   *xl = Xr.word;
00122   *xr = Xl.word;
00123 }

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

Definition at line 63 of file blowfish.c.

References bf_P, ROUND, and aword::word.

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

00064 {
00065   union aword Xl;
00066   union aword Xr;
00067 
00068   Xl.word = *xl;
00069   Xr.word = *xr;
00070 
00071   Xl.word ^= bf_P[0];
00072   ROUND(Xr, Xl, 1);
00073   ROUND(Xl, Xr, 2);
00074   ROUND(Xr, Xl, 3);
00075   ROUND(Xl, Xr, 4);
00076   ROUND(Xr, Xl, 5);
00077   ROUND(Xl, Xr, 6);
00078   ROUND(Xr, Xl, 7);
00079   ROUND(Xl, Xr, 8);
00080   ROUND(Xr, Xl, 9);
00081   ROUND(Xl, Xr, 10);
00082   ROUND(Xr, Xl, 11);
00083   ROUND(Xl, Xr, 12);
00084   ROUND(Xr, Xl, 13);
00085   ROUND(Xl, Xr, 14);
00086   ROUND(Xr, Xl, 15);
00087   ROUND(Xl, Xr, 16);
00088   Xr.word ^= bf_P[17];
00089 
00090   *xr = Xl.word;
00091   *xl = Xr.word;
00092 }

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

Definition at line 241 of file blowfish.c.

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

Referenced by script_encpass().

00242 {
00243   u_int32_t left, right;
00244   int n;
00245   char *p;
00246 
00247   blowfish_init((unsigned char *) text, strlen(text));
00248   left = SALT1;
00249   right = SALT2;
00250   blowfish_encipher(&left, &right);
00251   p = new;
00252   *p++ = '+';     /* + means encrypted pass */
00253   n = 32;
00254   while (n > 0) {
00255     *p++ = base64[right & 0x3f];
00256     right = (right >> 6);
00257     n -= 6;
00258   }
00259   n = 32;
00260   while (n > 0) {
00261     *p++ = base64[left & 0x3f];
00262     left = (left >> 6);
00263     n -= 6;
00264   }
00265   *p = 0;
00266 }

static void blowfish_init ( u_int8_t *  key,
int  keybytes 
) [static]

Definition at line 126 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::keybytes, box_t::lastuse, NULL, box_t::P, box_t::S, timer_get_now_sec(), aword::w, and aword::word.

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

00127 {
00128   int i, j, bx;
00129   int lowest = 0;
00130   u_int32_t data;
00131   u_int32_t datal;
00132   u_int32_t datar;
00133   union aword temp;
00134 
00135   /* drummer: Fixes crash if key is longer than 80 char. This may cause the key
00136    *          to not end with \00 but that's no problem.
00137    */
00138   if (keybytes > 80)
00139     keybytes = 80;
00140 
00141   /* Is buffer already allocated for this? */
00142   for (i = 0; i < BOXES; i++)
00143     if (box[i].P != NULL) {
00144       if ((box[i].keybytes == keybytes) &&
00145     (!strncmp((char *) (box[i].key), (char *) key, keybytes))) {
00146   /* Match! */
00147   timer_get_now_sec(&box[i].lastuse);
00148   bf_P = box[i].P;
00149   bf_S = box[i].S;
00150   return;
00151       }
00152     }
00153   /* No pre-allocated buffer: make new one */
00154   /* Set 'bx' to empty buffer */
00155   bx = (-1);
00156   for (i = 0; i < BOXES; i++) {
00157     if (box[i].P == NULL) {
00158       bx = i;
00159       i = BOXES + 1;
00160     }
00161   }
00162   if (bx < 0) {
00163     /* Find oldest */
00164     timer_get_now_sec(&lowest);
00165     for (i = 0; i < BOXES; i++)
00166       if (box[i].lastuse <= lowest) {
00167   lowest = box[i].lastuse;
00168   bx = i;
00169       }
00170     free(box[bx].P);
00171     for (i = 0; i < 4; i++)
00172       free(box[bx].S[i]);
00173     free(box[bx].S);
00174   }
00175   /* Initialize new buffer */
00176   /* uh... this is over 4k */
00177   box[bx].P = (u_int32_t *) malloc((bf_N + 2) * sizeof(u_int32_t));
00178   box[bx].S = (u_int32_t **) malloc(4 * sizeof(u_int32_t *));
00179   for (i = 0; i < 4; i++)
00180     box[bx].S[i] = (u_int32_t *) malloc(256 * sizeof(u_int32_t));
00181   bf_P = box[bx].P;
00182   bf_S = box[bx].S;
00183   box[bx].keybytes = keybytes;
00184   strlcpy(box[bx].key, key, keybytes + 1);  /* + 1 for NULL */
00185   timer_get_now_sec(&box[bx].lastuse);
00186   /* Robey: Reset blowfish boxes to initial state
00187    * (I guess normally it just keeps scrambling them, but here it's
00188    * important to get the same encrypted result each time)
00189    */
00190   for (i = 0; i < bf_N + 2; i++)
00191     bf_P[i] = initbf_P[i];
00192   for (i = 0; i < 4; i++)
00193     for (j = 0; j < 256; j++)
00194       bf_S[i][j] = initbf_S[i][j];
00195 
00196   j = 0;
00197   if (keybytes > 0) { /* drummer: fixes crash if key=="" */
00198     for (i = 0; i < bf_N + 2; ++i) {
00199       temp.word = 0;
00200       temp.w.byte0 = key[j];
00201       temp.w.byte1 = key[(j + 1) % keybytes];
00202       temp.w.byte2 = key[(j + 2) % keybytes];
00203       temp.w.byte3 = key[(j + 3) % keybytes];
00204       data = temp.word;
00205       bf_P[i] = bf_P[i] ^ data;
00206       j = (j + 4) % keybytes;
00207     }
00208   }
00209   datal = 0x00000000;
00210   datar = 0x00000000;
00211   for (i = 0; i < bf_N + 2; i += 2) {
00212     blowfish_encipher(&datal, &datar);
00213     bf_P[i] = datal;
00214     bf_P[i + 1] = datar;
00215   }
00216   for (i = 0; i < 4; ++i) {
00217     for (j = 0; j < 256; j += 2) {
00218       blowfish_encipher(&datal, &datar);
00219       bf_S[i][j] = datal;
00220       bf_S[i][j + 1] = datar;
00221     }
00222   }
00223 }

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

Definition at line 317 of file blowfish.c.

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

00318 {
00319   u_int32_t left, right;
00320   char *p, *s, *dest, *d;
00321   int i;
00322 
00323   /* Pad encoded string with 0 bits in case it's bogus */
00324   s = (char *) malloc(strlen(str) + 12);
00325   strcpy(s, str);
00326   if ((!key) || (!key[0]))
00327     return s;
00328   p = s;
00329   dest = (char *) malloc(strlen(str) + 12);
00330   while (*p)
00331     p++;
00332   for (i = 0; i < 12; i++)
00333     *p++ = 0;
00334   blowfish_init((unsigned char *) key, strlen(key));
00335   p = s;
00336   d = dest;
00337   while (*p) {
00338     right = 0L;
00339     left = 0L;
00340     for (i = 0; i < 6; i++)
00341       right |= (base64dec(*p++)) << (i * 6);
00342     for (i = 0; i < 6; i++)
00343       left |= (base64dec(*p++)) << (i * 6);
00344     blowfish_decipher(&left, &right);
00345     for (i = 0; i < 4; i++)
00346       *d++ = (left & (0xff << ((3 - i) * 8))) >> ((3 - i) * 8);
00347     for (i = 0; i < 4; i++)
00348       *d++ = (right & (0xff << ((3 - i) * 8))) >> ((3 - i) * 8);
00349   }
00350   *d = 0;
00351   free(s);
00352   return dest;
00353 }

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

Definition at line 270 of file blowfish.c.

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

00271 {
00272   u_int32_t left, right;
00273   unsigned char *p;
00274   char *s, *dest, *d;
00275   int i;
00276 
00277   /* Pad fake string with 8 bytes to make sure there's enough */
00278   s = (char *) malloc(strlen(str) + 9);
00279   strcpy(s, str);
00280   if ((!key) || (!key[0]))
00281     return s;
00282   p = s;
00283   dest = (char *) malloc((strlen(str) + 9) * 2);
00284   while (*p)
00285     p++;
00286   for (i = 0; i < 8; i++)
00287     *p++ = 0;
00288   blowfish_init((unsigned char *) key, strlen(key));
00289   p = s;
00290   d = dest;
00291   while (*p) {
00292     left = ((*p++) << 24);
00293     left += ((*p++) << 16);
00294     left += ((*p++) << 8);
00295     left += (*p++);
00296     right = ((*p++) << 24);
00297     right += ((*p++) << 16);
00298     right += ((*p++) << 8);
00299     right += (*p++);
00300     blowfish_encipher(&left, &right);
00301     for (i = 0; i < 6; i++) {
00302       *d++ = base64[right & 0x3f];
00303       right = (right >> 6);
00304     }
00305     for (i = 0; i < 6; i++) {
00306       *d++ = base64[left & 0x3f];
00307       left = (left >> 6);
00308     }
00309   }
00310   *d = 0;
00311   free(s);
00312   return dest;
00313 }

static char* script_encpass ( char *  pass  )  [static]

Definition at line 355 of file blowfish.c.

References blowfish_encrypt_pass().

00356 {
00357   char *buf;
00358 
00359   buf = (char *)malloc(17);
00360   blowfish_encrypt_pass(pass, buf);
00361   return(buf);
00362 }

int start ( egg_module_t modinfo  ) 

Definition at line 378 of file blowfish.c.

References egg_module::author, blowfish_close(), box, BOXES, egg_module::close_func, egg_module::description, box_t::key, box_t::lastuse, egg_module::name, NULL, box_t::P, box_t::S, script_create_commands(), and egg_module::version.

00379 {
00380   int i;
00381 
00382   modinfo->name = "blowfish";
00383   modinfo->author = "eggdev";
00384   modinfo->version = "1.9.0";
00385   modinfo->description = "provides blowfish encryption/decryption";
00386   modinfo->close_func = blowfish_close;
00387 
00388   /* Initialize buffered boxes */
00389   for (i = 0; i < BOXES; i++) {
00390     box[i].P = NULL;
00391     box[i].S = NULL;
00392     box[i].key[0] = 0;
00393     box[i].lastuse = 0L;
00394   }
00395   script_create_commands(blowfish_script_cmds);
00396   return(0);
00397 }


Variable Documentation

char* base64 = "./0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" [static]

Definition at line 229 of file blowfish.c.

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

u_int32_t* bf_P [static]

Definition at line 60 of file blowfish.c.

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

u_int32_t** bf_S [static]

Definition at line 61 of file blowfish.c.

Referenced by blowfish_init().

Initial value:

 {
  {"", "encpass", (Function) script_encpass, NULL, 1, "s", "string", SCRIPT_STRING | SCRIPT_FREE, 0},
  {"", "encrypt", (Function) encrypt_string, NULL, 2, "ss", "key string", SCRIPT_STRING | SCRIPT_FREE, 0},
  {"", "decrypt", (Function) decrypt_string, NULL, 2, "ss", "key string", SCRIPT_STRING | SCRIPT_FREE, 0},
  {0}
}

Definition at line 364 of file blowfish.c.

struct box_t box[BOXES] [static]

Referenced by blowfish_init(), and start().

const char rcsid[] = "$Id: blowfish.c,v 1.18 2004-06-23 11:19:52 wingman Exp $" [static]

Definition at line 24 of file blowfish.c.


Generated on Sun Nov 30 18:43:35 2008 for eggdrop1.9 by  doxygen 1.5.6