You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
209 lines
4.9 KiB
209 lines
4.9 KiB
/*
|
|
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 <ismail@kde.org>
|
|
*/
|
|
|
|
// mc_blowfishnew.cpp
|
|
//---------------------------------------------------------------------------
|
|
|
|
//---------------------------------------------------------------------------
|
|
#include "newblowfish.h"
|
|
#include "b64stuff.h"
|
|
#include "BlowfishCbc.h"
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
#include <time.h>
|
|
//---------------------------------------------------------------------------
|
|
|
|
|
|
//---------------------------------------------------------------------------
|
|
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;
|
|
}
|
|
//---------------------------------------------------------------------------
|