Main Page | Class Hierarchy | Class List | Directories | File List | Class Members | File Members

evacrypt.cpp

Go to the documentation of this file.
00001 
00027 #include "evacrypt.h"
00028 
00029 #include <string.h>
00030 #ifdef _WIN32
00031 #include <winsock.h>
00032 #else
00033 #include <arpa/inet.h>
00034 #endif
00035 
00036 EvaCrypt::EvaCrypt()
00037 {
00038 }
00039 
00040 EvaCrypt::~EvaCrypt()
00041 {
00042 }
00043 
00044 void EvaCrypt::teaEncipher(unsigned int *const v, const unsigned int *const k, 
00045                         unsigned int *const w)
00046 {
00047         register unsigned int 
00048                 y     = ntohl(v[0]),
00049                 z     = ntohl(v[1]),
00050                 a     = ntohl(k[0]),
00051                 b     = ntohl(k[1]),
00052                 c     = ntohl(k[2]),
00053                 d     = ntohl(k[3]),
00054                 n     = 0x10,       /* do encrypt 16 (0x10) times */
00055                 sum   = 0,
00056                 delta = 0x9E3779B9; /*  0x9E3779B9 - 0x100000000 = -0x61C88647 */
00057 
00058         while (n-- > 0) {
00059                 sum += delta;
00060                 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
00061                 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
00062         }
00063 
00064         w[0] = htonl(y); w[1] = htonl(z);
00065 }
00066 void EvaCrypt::teaDecipher(unsigned int *const v, const unsigned int *const k, 
00067                         unsigned int *const w)
00068 {
00069         register unsigned int
00070                 y     = ntohl(v[0]),
00071                 z     = ntohl(v[1]),
00072                 a     = ntohl(k[0]),
00073                 b     = ntohl(k[1]),
00074                 c     = ntohl(k[2]),
00075                 d     = ntohl(k[3]),
00076                 n     = 0x10,
00077                 sum   = 0xE3779B90, 
00078                 /* why this ? must be related with n value*/
00079                 delta = 0x9E3779B9;
00080 
00081         /* sum = delta<<5, in general sum = delta * n */
00082         while (n-- > 0) {
00083                 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
00084                 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
00085                 sum -= delta;
00086         }
00087 
00088         w[0] = htonl(y); w[1] = htonl(z);
00089 }
00090 
00091 void EvaCrypt::encrypt( unsigned char* instr, int instrlen, unsigned char* key,
00092                         unsigned char*  outstr, int* outstrlen_ptr)
00093 {
00094         unsigned char 
00095                 plain[8],         /* plain text buffer*/
00096                 plain_pre_8[8],   /* plain text buffer, previous 8 bytes*/
00097                 * crypted,        /* crypted text*/
00098                 * crypted_pre_8,  /* crypted test, previous 8 bytes*/
00099                 * inp;            /* current position in instr*/
00100         int 
00101                 pos_in_byte = 1,  /* loop in the byte */
00102                 is_header=1,      /* header is one byte*/
00103                 count=0,          /* number of bytes being crypted*/
00104                 padding = 0;      /* number of padding stuff*/
00105 
00106         //void encrypt_every_8_byte (void);    
00107 
00108         /*** we encrypt every eight byte ***/
00109 #define encrypt_every_8_byte()  \
00110         {\
00111         for(pos_in_byte=0; pos_in_byte<8; pos_in_byte++) {\
00112         if(is_header) { plain[pos_in_byte] ^= plain_pre_8[pos_in_byte]; }\
00113                         else { plain[pos_in_byte] ^= crypted_pre_8[pos_in_byte]; }\
00114         } /* prepare plain text*/\
00115         teaEncipher( (unsigned int *) plain,\
00116         (unsigned int *) key, \
00117         (unsigned int *) crypted);   /* encrypt it*/\
00118         \
00119         for(pos_in_byte=0; pos_in_byte<8; pos_in_byte++) {\
00120         crypted[pos_in_byte] ^= plain_pre_8[pos_in_byte]; \
00121         } \
00122         memcpy(plain_pre_8, plain, 8);     /* prepare next*/\
00123         \
00124         crypted_pre_8   =   crypted;       /* store position of previous 8 byte*/\
00125         crypted         +=  8;             /* prepare next output*/\
00126         count           +=  8;             /* outstrlen increase by 8*/\
00127         pos_in_byte     =   0;             /* back to start*/\
00128         is_header       =   0;             /* and exit header*/\
00129         }/* encrypt_every_8_byte*/
00130 
00131         pos_in_byte = (instrlen + 0x0a) % 8; /* header padding decided by instrlen*/
00132         if (pos_in_byte) { 
00133                 pos_in_byte = 8 - pos_in_byte; 
00134         }
00135         plain[0] = (rand() & 0xf8) | pos_in_byte;
00136         
00137         memset(plain+1, rand()&0xff, pos_in_byte++);
00138         memset(plain_pre_8, 0x00, sizeof(plain_pre_8));
00139 
00140         crypted = crypted_pre_8 = outstr;
00141 
00142         padding = 1; /* pad some stuff in header*/
00143         while (padding <= 2) { /* at most two byte */
00144                 if(pos_in_byte < 8) { plain[pos_in_byte++] = rand() & 0xff; padding ++; } 
00145                 if(pos_in_byte == 8){ encrypt_every_8_byte(); } 
00146         }
00147 
00148         inp = instr;
00149         while (instrlen > 0) {
00150                 if (pos_in_byte < 8) { plain[pos_in_byte++] = *(inp++); instrlen --; }
00151                 if (pos_in_byte == 8){ encrypt_every_8_byte(); }
00152         }
00153 
00154         padding = 1; /* pad some stuff in tailer*/
00155         while (padding <= 7) { /* at most sever byte*/
00156                 if (pos_in_byte < 8) { plain[pos_in_byte++] = 0x00; padding ++; }
00157                 if (pos_in_byte == 8){ encrypt_every_8_byte(); }
00158         } 
00159 
00160         *outstrlen_ptr = count;
00161 
00162 }
00163 
00164 int EvaCrypt::rand(void)
00165 {
00166         /* it can be the real random seed function*/
00167         return 0xdead; /* override with number, convenient for debug*/  
00168 }
00169 
00170 int EvaCrypt::decrypt( unsigned char* instr, int instrlen, unsigned char* key,
00171                         unsigned char*  outstr, int* outstrlen_ptr)
00172 {
00173         unsigned char 
00174                 decrypted[8], m[8],
00175                 * crypt_buff, 
00176                 * crypt_buff_pre_8, 
00177                 * outp;
00178         int 
00179                 count, 
00180                 context_start, 
00181                 pos_in_byte, 
00182                 padding;
00183 
00184 #define decrypt_every_8_byte()  {\
00185         bool bNeedRet = false;\
00186         for (pos_in_byte = 0; pos_in_byte < 8; pos_in_byte ++ ) {\
00187         if (context_start + pos_in_byte >= instrlen) \
00188         {\
00189         bNeedRet = true;\
00190         break;\
00191         }\
00192         decrypted[pos_in_byte] ^= crypt_buff[pos_in_byte];\
00193         }\
00194         if( !bNeedRet ) { \
00195         teaDecipher( (unsigned int *) decrypted, \
00196         (unsigned int *) key, \
00197         (unsigned int *) decrypted);\
00198         \
00199         context_start +=  8;\
00200         crypt_buff    +=  8;\
00201         pos_in_byte   =   0;\
00202         }\
00203 }/* decrypt_every_8_byte*/
00204 
00205         /* at least 16 bytes and %8 == 0*/
00206         if ((instrlen % 8) || (instrlen < 16)) return 0; 
00207         /* get information from header*/
00208         teaDecipher( (unsigned int *) instr, 
00209                 (unsigned int *) key, 
00210                 (unsigned int *) decrypted);
00211         pos_in_byte = decrypted[0] & 0x7;
00212         count = instrlen - pos_in_byte - 10; /* this is the plaintext length*/
00213         /* return if outstr buffer is not large enought or error plaintext length*/
00214         if (*outstrlen_ptr < count || count < 0) return 0;
00215 
00216         memset(m, 0, 8);
00217         crypt_buff_pre_8 = m;
00218         *outstrlen_ptr = count;   /* everything is ok! set return string length*/
00219 
00220         crypt_buff = instr + 8;   /* address of real data start */
00221         context_start = 8;        /* context is at the second 8 byte*/
00222         pos_in_byte ++;           /* start of paddng stuffv*/
00223 
00224         padding = 1;              /* at least one in header*/
00225         while (padding <= 2) {    /* there are 2 byte padding stuff in header*/
00226                 if (pos_in_byte < 8) {  /* bypass the padding stuff, none sense data*/
00227                         pos_in_byte ++; padding ++;
00228                 }
00229                 if (pos_in_byte == 8) {
00230                         crypt_buff_pre_8 = instr;
00231                         //if (! decrypt_every_8_byte()) return 0; 
00232                         decrypt_every_8_byte();
00233                 }
00234         }/* while*/
00235 
00236         outp = outstr;
00237         while(count !=0) {
00238                 if (pos_in_byte < 8) {
00239                         *outp = crypt_buff_pre_8[pos_in_byte] ^ decrypted[pos_in_byte];
00240                         outp ++;
00241                         count --;
00242                         pos_in_byte ++;
00243                 }
00244                 if (pos_in_byte == 8) {
00245                         crypt_buff_pre_8 = crypt_buff - 8;
00246                         //if (! decrypt_every_8_byte()) return 0;
00247                         decrypt_every_8_byte();
00248                 }
00249         }/* while*/
00250 
00251         for (padding = 1; padding < 8; padding ++) {
00252                 if (pos_in_byte < 8) {
00253                         if (crypt_buff_pre_8[pos_in_byte] ^ decrypted[pos_in_byte]) return 0;
00254                         pos_in_byte ++; 
00255                 }
00256                 if (pos_in_byte == 8 ) {
00257                         crypt_buff_pre_8 = crypt_buff;
00258                         //if (! decrypt_every_8_byte()) return 0; 
00259                         decrypt_every_8_byte();
00260                 }
00261         }/* for*/
00262         return 1;
00263 
00264 }
00265 
00266 
00267 int EvaCrypt::qq_crypt ( unsigned char   flag,  unsigned char*  instr,  int  instrlen,
00268                         unsigned char*  key, unsigned char*  outstr, int* outstrlen_ptr)
00269 {
00270         if (flag == DECRYPT)
00271                 return decrypt(instr, instrlen, key, outstr, outstrlen_ptr);
00272         else 
00273                 if (flag == ENCRYPT)
00274                         encrypt(instr, instrlen, key, outstr, outstrlen_ptr);
00275 
00276         return 1; /* flag must be DECRYPT or ENCRYPT*/
00277 }/* qq_crypt*/

Generated on Mon May 15 20:48:40 2006 for libeva by  doxygen 1.4.4