Mercurial > pidgin
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); |