comparison libgaim/protocols/qq/crypt.c @ 14236:b7f17fdded6f

[gaim-migrate @ 16918] Const-correctness to eliminate some warnings. committer: Tailor Script <tailor@pidgin.im>
author Mark Huetsch <markhuetsch>
date Sun, 20 Aug 2006 21:37:45 +0000
parents 60b1bc8dbf37
children 516ef76d6430
comparison
equal deleted inserted replaced
14235:a54ff7cafc2a 14236:b7f17fdded6f
47 47
48 /******************************************************************** 48 /********************************************************************
49 * encryption 49 * encryption
50 *******************************************************************/ 50 *******************************************************************/
51 51
52 /* TODO: convert these data types to proper glib ones */ 52 static void qq_encipher(guint32 *const v, const guint32 *const k, guint32 *const w)
53 static void qq_encipher(unsigned long *const v, const unsigned long *const k, unsigned long *const w) 53 {
54 { 54 register guint32 y = ntohl(v[0]),
55 register unsigned long y = ntohl(v[0]),
56 z = ntohl(v[1]), 55 z = ntohl(v[1]),
57 a = ntohl(k[0]), 56 a = ntohl(k[0]),
58 b = ntohl(k[1]), 57 b = ntohl(k[1]),
59 c = ntohl(k[2]), 58 c = ntohl(k[2]),
60 d = ntohl(k[3]), 59 d = ntohl(k[3]),
70 69
71 w[0] = htonl(y); 70 w[0] = htonl(y);
72 w[1] = htonl(z); 71 w[1] = htonl(z);
73 } 72 }
74 73
75 static int rand(void) { /* it can be the real random seed function */ 74 static gint rand(void) { /* it can be the real random seed function */
76 return 0xdead; 75 return 0xdead;
77 } /* override with number, convenient for debug */ 76 } /* override with number, convenient for debug */
78 77
79 /* we encrypt every eight byte block */ 78 /* we encrypt every eight byte chunk */
80 static void encrypt_every_8_byte(unsigned char *plain, unsigned char *plain_pre_8, unsigned char **crypted, 79 static void encrypt_every_8_byte(guint8 *plain, guint8 *plain_pre_8, guint8 **crypted,
81 unsigned char **crypted_pre_8, unsigned char *key, int *count, int *pos_in_byte, int *is_header) 80 guint8 **crypted_pre_8, const guint8 *const key, gint *count,
81 gint *pos_in_byte, gint *is_header)
82 { 82 {
83 /* prepare plain text */ 83 /* prepare plain text */
84 for (*pos_in_byte = 0; *pos_in_byte < 8; (*pos_in_byte)++) { 84 for (*pos_in_byte = 0; *pos_in_byte < 8; (*pos_in_byte)++) {
85 if (*is_header) { 85 if (*is_header) {
86 plain[*pos_in_byte] ^= plain_pre_8[*pos_in_byte]; 86 plain[*pos_in_byte] ^= plain_pre_8[*pos_in_byte];
87 } else { 87 } else {
88 plain[*pos_in_byte] ^= (*crypted_pre_8)[*pos_in_byte]; 88 plain[*pos_in_byte] ^= (*crypted_pre_8)[*pos_in_byte];
89 } 89 }
90 } 90 }
91 /* encrypt it */ 91 /* encrypt it */
92 qq_encipher((unsigned long *) plain, (unsigned long *) key, (unsigned long *) *crypted); 92 qq_encipher((guint32 *) plain, (guint32 *) key, (guint32 *) *crypted);
93 93
94 for (*pos_in_byte = 0; *pos_in_byte < 8; (*pos_in_byte)++) { 94 for (*pos_in_byte = 0; *pos_in_byte < 8; (*pos_in_byte)++) {
95 (*crypted)[*pos_in_byte] ^= plain_pre_8[*pos_in_byte]; 95 (*crypted)[*pos_in_byte] ^= plain_pre_8[*pos_in_byte];
96 } 96 }
97 memcpy(plain_pre_8, plain, 8); /* prepare next */ 97 memcpy(plain_pre_8, plain, 8); /* prepare next */
102 *pos_in_byte = 0; /* back to start */ 102 *pos_in_byte = 0; /* back to start */
103 *is_header = 0; /* and exit header */ 103 *is_header = 0; /* and exit header */
104 } /* encrypt_every_8_byte */ 104 } /* encrypt_every_8_byte */
105 105
106 106
107 static void qq_encrypt(unsigned char *instr, int instrlen, unsigned char *key, 107 static void qq_encrypt(const guint8 *const instr, gint instrlen,
108 unsigned char *outstr, int *outstrlen_prt) 108 const guint8 *const key,
109 { 109 guint8 *outstr, gint *outstrlen_prt)
110 unsigned char plain[8], /* plain text buffer */ 110 {
111 guint8 plain[8], /* plain text buffer */
111 plain_pre_8[8], /* plain text buffer, previous 8 bytes */ 112 plain_pre_8[8], /* plain text buffer, previous 8 bytes */
112 *crypted, /* crypted text */ 113 *crypted, /* crypted text */
113 *crypted_pre_8, /* crypted test, previous 8 bytes */ 114 *crypted_pre_8; /* crypted test, previous 8 bytes */
114 *inp; /* current position in instr */ 115 const guint8 *inp; /* current position in instr */
115 int pos_in_byte = 1, /* loop in the byte */ 116 gint pos_in_byte = 1, /* loop in the byte */
116 is_header = 1, /* header is one byte */ 117 is_header = 1, /* header is one byte */
117 count = 0, /* number of bytes being crypted */ 118 count = 0, /* number of bytes being crypted */
118 padding = 0; /* number of padding stuff */ 119 padding = 0; /* number of padding stuff */
119 120
120 pos_in_byte = (instrlen + 0x0a) % 8; /* header padding decided by instrlen */ 121 pos_in_byte = (instrlen + 0x0a) % 8; /* header padding decided by instrlen */
133 if (pos_in_byte < 8) { 134 if (pos_in_byte < 8) {
134 plain[pos_in_byte++] = rand() & 0xff; 135 plain[pos_in_byte++] = rand() & 0xff;
135 padding++; 136 padding++;
136 } 137 }
137 if (pos_in_byte == 8) { 138 if (pos_in_byte == 8) {
138 encrypt_every_8_byte(plain, plain_pre_8, &crypted, &crypted_pre_8, key, &count, &pos_in_byte, &is_header); 139 encrypt_every_8_byte(plain, plain_pre_8, &crypted, &crypted_pre_8,
140 key, &count, &pos_in_byte, &is_header);
139 } 141 }
140 } 142 }
141 143
142 inp = instr; 144 inp = instr;
143 while (instrlen > 0) { 145 while (instrlen > 0) {
144 if (pos_in_byte < 8) { 146 if (pos_in_byte < 8) {
145 plain[pos_in_byte++] = *(inp++); 147 plain[pos_in_byte++] = *(inp++);
146 instrlen--; 148 instrlen--;
147 } 149 }
148 if (pos_in_byte == 8) { 150 if (pos_in_byte == 8) {
149 encrypt_every_8_byte(plain, plain_pre_8, &crypted, &crypted_pre_8, key, &count, &pos_in_byte, &is_header); 151 encrypt_every_8_byte(plain, plain_pre_8, &crypted, &crypted_pre_8,
152 key, &count, &pos_in_byte, &is_header);
150 } 153 }
151 } 154 }
152 155
153 padding = 1; /* pad some stuff in tail */ 156 padding = 1; /* pad some stuff in tail */
154 while (padding <= 7) { /* at most seven bytes */ 157 while (padding <= 7) { /* at most seven bytes */
155 if (pos_in_byte < 8) { 158 if (pos_in_byte < 8) {
156 plain[pos_in_byte++] = 0x00; 159 plain[pos_in_byte++] = 0x00;
157 padding++; 160 padding++;
158 } 161 }
159 if (pos_in_byte == 8) { 162 if (pos_in_byte == 8) {
160 encrypt_every_8_byte(plain, plain_pre_8, &crypted, &crypted_pre_8, key, &count, &pos_in_byte, &is_header); 163 encrypt_every_8_byte(plain, plain_pre_8, &crypted, &crypted_pre_8,
164 key, &count, &pos_in_byte, &is_header);
161 } 165 }
162 } 166 }
163 167
164 *outstrlen_prt = count; 168 *outstrlen_prt = count;
165 } 169 }
167 171
168 /******************************************************************** 172 /********************************************************************
169 * decryption 173 * decryption
170 ********************************************************************/ 174 ********************************************************************/
171 175
172 static void qq_decipher(unsigned long *const v, const unsigned long *const k, unsigned long *const w) 176 static void qq_decipher(guint32 *const v, const guint32 *const k, guint32 *const w)
173 { 177 {
174 register unsigned long y = ntohl(v[0]), 178 register guint32 y = ntohl(v[0]),
175 z = ntohl(v[1]), 179 z = ntohl(v[1]),
176 a = ntohl(k[0]), 180 a = ntohl(k[0]),
177 b = ntohl(k[1]), 181 b = ntohl(k[1]),
178 c = ntohl(k[2]), 182 c = ntohl(k[2]),
179 d = ntohl(k[3]), 183 d = ntohl(k[3]),
190 194
191 w[0] = htonl(y); 195 w[0] = htonl(y);
192 w[1] = htonl(z); 196 w[1] = htonl(z);
193 } 197 }
194 198
195 static int decrypt_every_8_byte(unsigned char **crypt_buff, const int instrlen, const unsigned char * const key, 199 static gint decrypt_every_8_byte(const guint8 **crypt_buff, const gint instrlen,
196 int *context_start, unsigned char *decrypted, int *pos_in_byte) 200 const guint8 *const key, gint *context_start,
201 guint8 *decrypted, gint *pos_in_byte)
197 { 202 {
198 for (*pos_in_byte = 0; *pos_in_byte < 8; (*pos_in_byte)++) { 203 for (*pos_in_byte = 0; *pos_in_byte < 8; (*pos_in_byte)++) {
199 if (*context_start + *pos_in_byte >= instrlen) 204 if (*context_start + *pos_in_byte >= instrlen)
200 return 1; 205 return 1;
201 decrypted[*pos_in_byte] ^= (*crypt_buff)[*pos_in_byte]; 206 decrypted[*pos_in_byte] ^= (*crypt_buff)[*pos_in_byte];
202 } 207 }
203 qq_decipher((unsigned long *) decrypted, (unsigned long *) key, (unsigned long *) decrypted); 208 qq_decipher((guint32 *) decrypted, (guint32 *) key, (guint32 *) decrypted);
204 209
205 *context_start += 8; 210 *context_start += 8;
206 *crypt_buff += 8; 211 *crypt_buff += 8;
207 *pos_in_byte = 0; 212 *pos_in_byte = 0;
208 213
209 return 1; 214 return 1;
210 } 215 }
211 216
212 /* return 0 if failed, 1 otherwise */ 217 /* return 0 if failed, 1 otherwise */
213 static int qq_decrypt(unsigned char *instr, int instrlen, unsigned char *key, 218 static gint qq_decrypt(const guint8 *const instr, gint instrlen,
214 unsigned char *outstr, int *outstrlen_ptr) 219 const guint8 *const key,
215 { 220 guint8 *outstr, gint *outstrlen_ptr)
216 unsigned char decrypted[8], m[8], *crypt_buff, *crypt_buff_pre_8, *outp; 221 {
217 int count, context_start, pos_in_byte, padding; 222 guint8 decrypted[8], m[8], *outp;
223 const guint8 *crypt_buff, *crypt_buff_pre_8;
224 gint count, context_start, pos_in_byte, padding;
218 225
219 /* at least 16 bytes and %8 == 0 */ 226 /* at least 16 bytes and %8 == 0 */
220 if ((instrlen % 8) || (instrlen < 16)) { 227 if ((instrlen % 8) || (instrlen < 16)) {
221 gaim_debug(GAIM_DEBUG_ERROR, "QQ", 228 gaim_debug(GAIM_DEBUG_ERROR, "QQ",
222 "Packet len is either too short or not a multiple of 8 bytes, read %d bytes\n", instrlen); 229 "Packet len is either too short or not a multiple of 8 bytes, read %d bytes\n",
230 instrlen);
223 return 0; 231 return 0;
224 } 232 }
225 /* get information from header */ 233 /* get information from header */
226 qq_decipher((unsigned long *) instr, (unsigned long *) key, (unsigned long *) decrypted); 234 qq_decipher((guint32 *) instr, (guint32 *) key, (guint32 *) decrypted);
227 pos_in_byte = decrypted[0] & 0x7; 235 pos_in_byte = decrypted[0] & 0x7;
228 count = instrlen - pos_in_byte - 10; /* this is the plaintext length */ 236 count = instrlen - pos_in_byte - 10; /* this is the plaintext length */
229 /* return if outstr buffer is not large enough or error plaintext length */ 237 /* return if outstr buffer is not large enough or error plaintext length */
230 if (*outstrlen_ptr < count || count < 0) { 238 if (*outstrlen_ptr < count || count < 0) {
231 gaim_debug(GAIM_DEBUG_ERROR, "QQ", "Buffer len %d is less than real len %d", *outstrlen_ptr, count); 239 gaim_debug(GAIM_DEBUG_ERROR, "QQ", "Buffer len %d is less than real len %d",
240 *outstrlen_ptr, count);
232 return 0; 241 return 0;
233 } 242 }
234 243
235 memset(m, 0, 8); 244 memset(m, 0, 8);
236 crypt_buff_pre_8 = m; 245 crypt_buff_pre_8 = m;
246 pos_in_byte++; 255 pos_in_byte++;
247 padding++; 256 padding++;
248 } 257 }
249 if (pos_in_byte == 8) { 258 if (pos_in_byte == 8) {
250 crypt_buff_pre_8 = instr; 259 crypt_buff_pre_8 = instr;
251 if (!decrypt_every_8_byte(&crypt_buff, instrlen, key, &context_start, decrypted, &pos_in_byte)) { 260 if (!decrypt_every_8_byte(&crypt_buff, instrlen, key,
261 &context_start, decrypted, &pos_in_byte)) {
252 gaim_debug(GAIM_DEBUG_ERROR, "QQ", "decrypt every 8 bytes error A"); 262 gaim_debug(GAIM_DEBUG_ERROR, "QQ", "decrypt every 8 bytes error A");
253 return 0; 263 return 0;
254 } 264 }
255 } 265 }
256 } 266 }
263 count--; 273 count--;
264 pos_in_byte++; 274 pos_in_byte++;
265 } 275 }
266 if (pos_in_byte == 8) { 276 if (pos_in_byte == 8) {
267 crypt_buff_pre_8 = crypt_buff - 8; 277 crypt_buff_pre_8 = crypt_buff - 8;
268 if (!decrypt_every_8_byte(&crypt_buff, instrlen, key, &context_start, decrypted, &pos_in_byte)) { 278 if (!decrypt_every_8_byte(&crypt_buff, instrlen, key,
279 &context_start, decrypted, &pos_in_byte)) {
269 gaim_debug(GAIM_DEBUG_ERROR, "QQ", "decrypt every 8 bytes error B"); 280 gaim_debug(GAIM_DEBUG_ERROR, "QQ", "decrypt every 8 bytes error B");
270 return 0; 281 return 0;
271 } 282 }
272 } 283 }
273 } 284 }
278 return 0; 289 return 0;
279 pos_in_byte++; 290 pos_in_byte++;
280 } 291 }
281 if (pos_in_byte == 8) { 292 if (pos_in_byte == 8) {
282 crypt_buff_pre_8 = crypt_buff; 293 crypt_buff_pre_8 = crypt_buff;
283 if (!decrypt_every_8_byte(&crypt_buff, instrlen, key, &context_start, decrypted, &pos_in_byte)) { 294 if (!decrypt_every_8_byte(&crypt_buff, instrlen, key,
295 &context_start, decrypted, &pos_in_byte)) {
284 gaim_debug(GAIM_DEBUG_ERROR, "QQ", "decrypt every 8 bytes error C"); 296 gaim_debug(GAIM_DEBUG_ERROR, "QQ", "decrypt every 8 bytes error C");
285 return 0; 297 return 0;
286 } 298 }
287 } 299 }
288 } 300 }
289 return 1; 301 return 1;
290 } 302 }
291 303
292 /* This is the Public Function */
293 /* return 1 is succeed, otherwise return 0 */ 304 /* return 1 is succeed, otherwise return 0 */
294 int qq_crypt(unsigned char flag, 305 gint qq_crypt(gint flag,
295 unsigned char *instr, int instrlen, unsigned char *key, unsigned char *outstr, int *outstrlen_ptr) 306 const guint8 *const instr, gint instrlen,
307 const guint8 *const key,
308 guint8 *outstr, gint *outstrlen_ptr)
296 { 309 {
297 if (flag == DECRYPT) 310 if (flag == DECRYPT)
298 return qq_decrypt(instr, instrlen, key, outstr, outstrlen_ptr); 311 return qq_decrypt(instr, instrlen, key, outstr, outstrlen_ptr);
299 else if (flag == ENCRYPT) 312 else if (flag == ENCRYPT)
300 qq_encrypt(instr, instrlen, key, outstr, outstrlen_ptr); 313 qq_encrypt(instr, instrlen, key, outstr, outstrlen_ptr);