/* blowfish.c -- handles: encryption and decryption of passwords The first half of this is very lightly edited from public domain sourcecode. For simplicity, this entire module will remain public domain. */ #ifdef MODULES #define MODULE_NAME "blowfish" #endif #include "module.h" #include "blowfish.h" #include "bf_tab.h" /* P-box P-array, S-box */ /* each box takes up 4k so be very careful here */ #define BOXES 3 /* #define S(x,i) (bf_S[i][x.w.byte##i]) */ #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]) /* keep a set of rotating P & S boxes */ static struct box_t { UWORD_32bits *P; UWORD_32bits **S; char key[81]; char keybytes; time_t lastuse; } box[BOXES]; /* static UWORD_32bits bf_P[bf_N+2]; static UWORD_32bits bf_S[4][256]; */ static UWORD_32bits *bf_P; static UWORD_32bits **bf_S; #ifdef MODULES static int blowfish_expmem() #else int expmem_blowfish() #endif { int i,tot=0; modcontext; for (i=0; i0) { *p++ = base64[right&0x3f]; right=(right>>6); n-=6; } n=32; while (n>0) { *p++ = base64[left&0x3f]; left=(left>>6); n-=6; } *p=0; } /* returned string must be freed when done with it! */ #ifdef MODULES static #endif char *encrypt_string PROTO2(char *,key, char *,str) { UWORD_32bits left,right; char *p,*s,*dest,*d; int i; dest=(char *)modmalloc((strlen(str)+9)*2); /* pad fake string with 8 bytes to make sure there's enough */ s=(char *)modmalloc(strlen(str)+9); strcpy(s,str); p=s; while (*p) p++; for (i=0; i<8; i++) *p++=0; blowfish_init(key,strlen(key)); p=s; d=dest; while (*p) { left=((*p++)<<24); left+=((*p++)<<16); left+=((*p++)<<8); left+=(*p++); right=((*p++)<<24); right+=((*p++)<<16); right+=((*p++)<<8); right+=(*p++); blowfish_encipher(&left,&right); for (i=0; i<6; i++) { *d++ = base64[right & 0x3f]; right=(right>>6); } for (i=0; i<6; i++) { *d++ = base64[left & 0x3f]; left=(left>>6); } } *d=0; modfree(s); return dest; } /* returned string must be freed when done with it! */ #ifdef MODULES static #endif char *decrypt_string PROTO2(char *,key,char *,str) { UWORD_32bits left,right; char *p,*s,*dest,*d; int i; dest=(char *)modmalloc(strlen(str)+12); /* pad encoded string with 0 bits in case it's bogus */ s=(char *)modmalloc(strlen(str)+12); strcpy(s,str); p=s; while (*p) p++; for (i=0; i<12; i++) *p++=0; blowfish_init(key,strlen(key)); p=s; d=dest; while (*p) { right=0L; left=0L; for (i=0; i<6; i++) right |= (base64dec(*p++)) << (i*6); for (i=0; i<6; i++) left |= (base64dec(*p++)) << (i*6); blowfish_decipher(&left,&right); for (i=0; i<4; i++) *d++ = (left & (0xff << ((3-i)*8))) >> ((3-i)*8); for (i=0; i<4; i++) *d++ = (right & (0xff << ((3-i)*8))) >> ((3-i)*8); } *d=0; modfree(s); return dest; } #ifdef MODULES static #endif int tcl_encrypt STDVAR { char *p; BADARGS(3,3," key string"); p=encrypt_string(argv[1],argv[2]); Tcl_AppendResult(irp,p,NULL); modfree(p); return TCL_OK; } #ifdef MODULES static #endif int tcl_decrypt STDVAR { char *p; BADARGS(3,3," key string"); p=decrypt_string(argv[1],argv[2]); Tcl_AppendResult(irp,p,NULL); modfree(p); return TCL_OK; } #ifdef MODULES static tcl_cmds mytcls[] = { { "encrypt", tcl_encrypt } , { "decrypt", tcl_decrypt } , { 0, 0 } }; module_function * global; /* you CANT -module an encryption module , so -module just resets it */ static char * blowfish_close() { return "You can't unload an encryption module"; } char * blowfish_start PROTO((module_function *)); static module_function blowfish_table[] = { (module_function)blowfish_start, (module_function)blowfish_close, (module_function)blowfish_expmem, (module_function)blowfish_report, }; /* initialize buffered boxes */ char * blowfish_start PROTO1(module_function *,globs) { int i; global = globs; #else void init_blowfish() { int i; #endif for (i=0; i