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,
00055 sum = 0,
00056 delta = 0x9E3779B9;
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
00079 delta = 0x9E3779B9;
00080
00081
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],
00096 plain_pre_8[8],
00097 * crypted,
00098 * crypted_pre_8,
00099 * inp;
00100 int
00101 pos_in_byte = 1,
00102 is_header=1,
00103 count=0,
00104 padding = 0;
00105
00106
00107
00108
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 } \
00115 teaEncipher( (unsigned int *) plain,\
00116 (unsigned int *) key, \
00117 (unsigned int *) crypted); \
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); \
00123 \
00124 crypted_pre_8 = crypted; \
00125 crypted += 8; \
00126 count += 8; \
00127 pos_in_byte = 0; \
00128 is_header = 0; \
00129 }
00130
00131 pos_in_byte = (instrlen + 0x0a) % 8;
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;
00143 while (padding <= 2) {
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;
00155 while (padding <= 7) {
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
00167 return 0xdead;
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 }
00204
00205
00206 if ((instrlen % 8) || (instrlen < 16)) return 0;
00207
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;
00213
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;
00219
00220 crypt_buff = instr + 8;
00221 context_start = 8;
00222 pos_in_byte ++;
00223
00224 padding = 1;
00225 while (padding <= 2) {
00226 if (pos_in_byte < 8) {
00227 pos_in_byte ++; padding ++;
00228 }
00229 if (pos_in_byte == 8) {
00230 crypt_buff_pre_8 = instr;
00231
00232 decrypt_every_8_byte();
00233 }
00234 }
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
00247 decrypt_every_8_byte();
00248 }
00249 }
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
00259 decrypt_every_8_byte();
00260 }
00261 }
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;
00277 }