#define BLOCKLEN 8
int hex2bin(char* hexstr,unsigned char* outb)
{
int len = strlen(hexstr);
int i=0;
for(;i<len;i+=2)
{
unsigned char v = 0;
unsigned char c1 = hexstr[i];
unsigned char c2 = hexstr[i+1];
if( c1>='0' && c1 <='9')
{
v = (c1-'0')<<4;
}else{
v = ((c1-'a')+10)<<4;
}
if( c2>='0' && c2 <='9')
{
v += (c2-'0');
}else{
v += ((c2-'a')+10);
}
outb[0]=v;
outb++;
}
return len/2;
}
void bin2hex(unsigned char* inb,int len,char* hexstr)
{
int i=0;
for(;i<len;i++)
{
unsigned char v = inb[i];
unsigned char vh = (v&0xf0)>>4;
unsigned char vl = v&0x0f;
if(vh>9)
{
hexstr[i*2] = vh-10+'a';
}else{
hexstr[i*2] = vh+'0';
}
if(vl>9)
{
hexstr[i*2+1] = vl-10+'a';
}else{
hexstr[i*2+1] = vl+'0';
}
}
hexstr[i*2]=0;
}
void b2ws(unsigned char* bs,unsigned int* ws)
{
int v = 0;
v |= bs[0]<<24;
v |= bs[1]<<16;
v |= bs[2]<<8;
v |= bs[3];
ws[0] = v;
}
void w2bs(unsigned int ws,unsigned char* bs)
{
bs[0] = (unsigned char)(ws>>24);
bs[1] = (unsigned char)(ws>>16);
bs[2] = (unsigned char)(ws>>8);
bs[3] = (unsigned char)ws;
}
void iXor(unsigned char * deced, unsigned char const* keyd)
{
int i=0;
for(i=0;i<BLOCKLEN;i++)
{
deced[i] = deced[i]^keyd[i];
}
}
void DecryptBlock(unsigned char * ind, unsigned char * oud,unsigned char * kd)
{
unsigned int delta=0x9e3779b9;
unsigned int sum=0xC6EF3720, i=0;
unsigned int v0 = 0;
unsigned int v1 = 0;
unsigned int tv1=0,tv2=0;
b2ws(ind,&v0);
b2ws(ind+4,&v1);
for(i=0;i<32;i++)
{
tv1 = (v0<<4) ^ (v0>>5);
tv2 = *(int*)(kd+ ((sum>>11)&3)*4);
v1 = v1 - ( (sum + tv2) ^ ( tv1 + v0) );
sum -= delta;
tv1 = (v1<<4) ^ (v1>>5);
tv2 = *(int*)(kd+ (sum&3)*4);
v0 = v0 - ( (sum + tv2) ^ ( tv1 + v1) );
}
w2bs(v0,oud);
w2bs(v1,oud+4);
}
void EncryptBlock(unsigned char * ind, unsigned char * oud,unsigned char * kd)
{
unsigned int delta=0x9e3779b9;
unsigned int sum=0, i=0;
unsigned int v0 = 0;
unsigned int v1 = 0;
unsigned int tv1=0,tv2=0;
b2ws(ind,&v0);
b2ws(ind+4,&v1);
for(i=0;i<32;i++)
{
tv1 = (v1<<4) ^ (v1>>5);
tv2 = *(int*)(kd+ (sum&3)*4);
v0 = v0 + ( (sum + tv2) ^ ( tv1 + v1) );
sum += delta;
tv1 = (v0<<4) ^ (v0>>5);
tv2 = *(int*)(kd+ ((sum>>11)&3)*4);
v1 = v1 + ( (sum + tv2) ^ ( tv1 + v0) );
}
w2bs(v0,oud);
w2bs(v1,oud+4);
}
void CTEA_Decrypt(char* inputstr, char * outstr, char* keystr)
{
unsigned char cachedat[64];
unsigned char inputbytes[24];
unsigned char outbytes[24];
unsigned char keybytes[16];
int iblock=0;
int inputlen = strlen(inputstr)/2;
hex2bin(inputstr,inputbytes);
hex2bin(keystr,keybytes);
unsigned char* pIn=inputbytes;
unsigned char* pOu=outbytes;
memset(cachedat,0x0,64);
while(iblock *BLOCKLEN < inputlen)
{
DecryptBlock(pIn,pOu,keybytes);
iXor(pOu,cachedat);
pOu[BLOCKLEN]=0;
memcpy(cachedat,inputbytes,BLOCKLEN);
pIn += BLOCKLEN;
pOu += BLOCKLEN;
iblock++;
}
strcpy(outstr,(char*)outbytes);
}
void CTEA_Encrypt(char* plain,char* outstr,char* keystr)
{
unsigned char cachedat[64];
unsigned char outbytes[24];
unsigned char keybytes[16];
hex2bin(keystr,keybytes);
int iblock=0;
int inputlen = strlen(plain);
unsigned char* pIn=(unsigned char*)plain;
unsigned char* pOu=outbytes;
memset(cachedat,0x0,64);
while(iblock *BLOCKLEN < inputlen)
{
iXor(cachedat,pIn);
EncryptBlock(cachedat,pOu,keybytes);
memcpy(cachedat,pOu,BLOCKLEN);
pIn += BLOCKLEN;
pOu += BLOCKLEN;
iblock++;
}
bin2hex(outbytes,inputlen,outstr);
}