/* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. */ /* Copyright (C) 2005 Ismail Donmez */ // mc_blowfishnew.cpp //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- #include "newblowfish.h" #include "b64stuff.h" #include "BlowfishCbc.h" #include #include #include //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- void ChooseIv(char *iv) { // file the 8 byte IV with a nonce // ATTN: this is not the best nonce IV generator, we'd like to improve it later static unsigned int staticcounter=0; static int didinit=0; int i; time_t t1; int part1,part2; char *part1p,*part2p; // get current time time(&t1); // on first use, initialize random number generator to time if (didinit==0) { srand((long) t1); didinit=1; } // increment counter ++staticcounter; if (staticcounter>=65534L) staticcounter=0; // ok now the IV will be 4 bytes random and 4 bytes time_t int intsize=sizeof(int); // now part1 and part2 of the 8 byte iv // part1 is a timestamp, number of seconds past since 1970 part1=(int)t1; part1p=(char*)(&part1); // part2 is a random number, from prng initted with time, plus a counter part2=(int)(rand()+staticcounter); part2p=(char*)(&part2); // now fill IV for (i=0;i<4;++i) iv[i]=part1p[i%intsize]; for (i=0;i<4;++i) iv[4+i]=part2p[i%intsize]; } //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- // NEW CBCB METHODS char *encrypt_string_new(char *key, char *str) { char *p; char *s, *dest,*dest2; char iv[8]; int i; int len; // Pad fake string with 8 bytes to make sure there's enough PLUS add 8 bytes for IV s = new char[strlen(str) + 9+8]; if ((!key) || (!key[0])) return s; // allocate max space we will need for encrypted, base64d dest = new char[(strlen(str) + 9+8) * 2]; // choose a (random or timestamped) IV block, 8 bytes wide and stick it into first 8 bytes of s ChooseIv(iv); // load the iv into start of s for (i=0;i<8;++i) s[i]=iv[i]; // add user string after strcpy(&s[8], str); len=8+strlen(str); // pad at end of source with 0s p = s+len; for (i = 0; i < 8; i++) *p++ = 0; // modify len to be mod%8 if (len%8!=0) len+=8-(len%8); // encrypt into dest (note len does not change) CBlowFish oBlowFish((unsigned char*)key, strlen(key)); oBlowFish.ResetChain(); oBlowFish.Encrypt((unsigned char*)s,(unsigned char*)dest, len, CBlowFish::CBC); // now base 64 it, allocating new dest2 in the process dest2=(char*)(spc_base64_encode((unsigned char*)dest,len,0)); if (dest2==0) { delete s; return dest; } // now prefix a * to it while copying to dest and delete s strcpy(dest,"*"); strcat(dest,dest2); delete dest2; delete s; // return the dest (user will free) return dest; } // Returned string must be freed when done with it! char *decrypt_string_new(char *key, char *str) { char *p, *s, *dest; char *dest2,*dest3; int i; int err; size_t len; char iv[9]; // Pad encoded string with 0 bits in case it's bogus s = new char[strlen(str) + 12]; strcpy(s, str); if ((!key) || (!key[0])) return s; dest = new char[strlen(str) + 12 + 8]; // pad with 0s p = s+strlen(str); for (i = 0; i < 12; i++) *p++ = 0; // now unbase64 it, allocating new dest2 in the process len=strlen(str); dest2=(char*)(spc_base64_decode((unsigned char*)s,&len,0,&err)); if (dest2==0) { delete dest; return s; } if (err) { // FOR TESTING: // printf("ERROR IN BASE 64 decode!\n"); delete dest; return s; } // copy unbase64'd to new temp dest3 then delete dest2 // pad it to be mod%8 (this should not be necesary on decrypt but could be on a truncated transmission); dest3 = new char[strlen(str) + 12 + 8]; memcpy(dest3,dest2,len); if (len%8!=0) { int newbytes=8-(len%8); while (newbytes>0) { ++len; --newbytes; dest3[len]='\0'; } } delete dest2; // decrypt from dest3 (length len) to dest CBlowFish oBlowFish((unsigned char*)key, strlen(key)); oBlowFish.ResetChain(); oBlowFish.Decrypt((unsigned char*)dest3,(unsigned char*)dest, len, CBlowFish::CBC); // 0 terminate in case it is exactly mod 8 real characters dest[len]='\0'; // now the first block (8bytes) is just the IV so we don't want to return that strncpy(iv,dest,8); iv[8]='\0'; strcpy(dest,&dest[8]); // delete s and dest3 delete s; delete dest3; // return dest return dest; } //---------------------------------------------------------------------------