Mercurial > pidgin
comparison libpurple/protocols/qq/qq_crypt.c @ 31086:a8cc50c2279f
Remove trailing whitespace
author | Richard Laager <rlaager@wiktel.com> |
---|---|
date | Tue, 04 Jan 2011 06:55:30 +0000 |
parents | 33921125348d |
children |
comparison
equal
deleted
inserted
replaced
31085:44f53d3fc54f | 31086:a8cc50c2279f |
---|---|
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA | 22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA |
23 * | 23 * |
24 * | 24 * |
25 * QQ encryption algorithm | 25 * QQ encryption algorithm |
26 * Convert from ASM code provided by PerlOICQ | 26 * Convert from ASM code provided by PerlOICQ |
27 * | 27 * |
28 * Puzzlebird, Nov-Dec 2002 | 28 * Puzzlebird, Nov-Dec 2002 |
29 */ | 29 */ |
30 | 30 |
31 /* Notes: (QQ uses 16 rounds, and modified something...) | 31 /* Notes: (QQ uses 16 rounds, and modified something...) |
32 | 32 |
33 IN : 64 bits of data in v[0] - v[1]. | 33 IN : 64 bits of data in v[0] - v[1]. |
34 OUT: 64 bits of data in w[0] - w[1]. | 34 OUT: 64 bits of data in w[0] - w[1]. |
35 KEY: 128 bits of key in k[0] - k[3]. | 35 KEY: 128 bits of key in k[0] - k[3]. |
36 | 36 |
37 delta is chosen to be the real part of | 37 delta is chosen to be the real part of |
38 the golden ratio: Sqrt(5/4) - 1/2 ~ 0.618034 multiplied by 2^32. | 38 the golden ratio: Sqrt(5/4) - 1/2 ~ 0.618034 multiplied by 2^32. |
39 | 39 |
40 0x61C88647 is what we can track on the ASM codes.!! | 40 0x61C88647 is what we can track on the ASM codes.!! |
41 */ | 41 */ |
42 | 42 |
43 #include <string.h> | 43 #include <string.h> |
51 printf("== %s %d ==\r\n", psztitle, bytes); | 51 printf("== %s %d ==\r\n", psztitle, bytes); |
52 gint i, j, ch; | 52 gint i, j, ch; |
53 for (i = 0; i < bytes; i += 16) { | 53 for (i = 0; i < bytes; i += 16) { |
54 /* length label */ | 54 /* length label */ |
55 printf("%07x: ", i); | 55 printf("%07x: ", i); |
56 | 56 |
57 /* dump hex value */ | 57 /* dump hex value */ |
58 for (j = 0; j < 16; j++) { | 58 for (j = 0; j < 16; j++) { |
59 if (j == 8) { | 59 if (j == 8) { |
60 printf(" -"); | 60 printf(" -"); |
61 } | 61 } |
62 if ((i + j) < bytes) | 62 if ((i + j) < bytes) |
63 printf(" %02x", buffer[i + j]); | 63 printf(" %02x", buffer[i + j]); |
64 else | 64 else |
65 printf(" "); | 65 printf(" "); |
66 } | 66 } |
67 | 67 |
68 printf(" "); | 68 printf(" "); |
69 | 69 |
70 | 70 |
71 /* dump ascii value */ | 71 /* dump ascii value */ |
72 for (j = 0; j < 16 && (i + j) < bytes; j++) { | 72 for (j = 0; j < 16 && (i + j) < bytes; j++) { |
73 ch = buffer[i + j] & 127; | 73 ch = buffer[i + j] & 127; |
74 if (ch < ' ' || ch == 127) | 74 if (ch < ' ' || ch == 127) |
75 printf("."); | 75 printf("."); |
85 #define show_binary(args... ) /* nothing */ | 85 #define show_binary(args... ) /* nothing */ |
86 | 86 |
87 #endif | 87 #endif |
88 | 88 |
89 /******************************************************************** | 89 /******************************************************************** |
90 * encryption | 90 * encryption |
91 *******************************************************************/ | 91 *******************************************************************/ |
92 | 92 |
93 /* Tiny Encryption Algorithm (TEA) */ | 93 /* Tiny Encryption Algorithm (TEA) */ |
94 static inline void qq_encipher(guint32 *const v, const guint32 *const k, guint32 *const w) | 94 static inline void qq_encipher(guint32 *const v, const guint32 *const k, guint32 *const w) |
95 { | 95 { |
96 register guint32 | 96 register guint32 |
97 y = g_ntohl(v[0]), | 97 y = g_ntohl(v[0]), |
98 z = g_ntohl(v[1]), | 98 z = g_ntohl(v[1]), |
99 a = g_ntohl(k[0]), | 99 a = g_ntohl(k[0]), |
100 b = g_ntohl(k[1]), | 100 b = g_ntohl(k[1]), |
101 c = g_ntohl(k[2]), | 101 c = g_ntohl(k[2]), |
102 d = g_ntohl(k[3]), | 102 d = g_ntohl(k[3]), |
103 n = 0x10, | 103 n = 0x10, |
104 sum = 0, | 104 sum = 0, |
105 delta = 0x9E3779B9; /* 0x9E3779B9 - 0x100000000 = -0x61C88647 */ | 105 delta = 0x9E3779B9; /* 0x9E3779B9 - 0x100000000 = -0x61C88647 */ |
106 | 106 |
107 while (n-- > 0) { | 107 while (n-- > 0) { |
108 sum += delta; | 108 sum += delta; |
109 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); | 109 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b); |
115 } | 115 } |
116 | 116 |
117 /* it can be the real random seed function */ | 117 /* it can be the real random seed function */ |
118 /* override with number, convenient for debug */ | 118 /* override with number, convenient for debug */ |
119 #ifdef DEBUG | 119 #ifdef DEBUG |
120 static gint crypt_rand(void) { | 120 static gint crypt_rand(void) { |
121 return 0xdead; | 121 return 0xdead; |
122 } | 122 } |
123 #else | 123 #else |
124 #include <stdlib.h> | 124 #include <stdlib.h> |
125 #define crypt_rand() rand() | 125 #define crypt_rand() rand() |
126 #endif | 126 #endif |
127 | 127 |
128 /* 64-bit blocks and some kind of feedback mode of operation */ | 128 /* 64-bit blocks and some kind of feedback mode of operation */ |
129 static inline void encrypt_out(guint8 *crypted, const gint crypted_len, const guint8 *key) | 129 static inline void encrypt_out(guint8 *crypted, const gint crypted_len, const guint8 *key) |
130 { | 130 { |
131 /* ships in encipher */ | 131 /* ships in encipher */ |
132 guint32 plain32[2]; | 132 guint32 plain32[2]; |
133 guint32 p32_prev[2]; | 133 guint32 p32_prev[2]; |
134 guint32 key32[4]; | 134 guint32 key32[4]; |
135 guint32 crypted32[2]; | 135 guint32 crypted32[2]; |
136 guint32 c32_prev[2]; | 136 guint32 c32_prev[2]; |
137 | 137 |
138 guint8 *crypted_ptr; | 138 guint8 *crypted_ptr; |
139 gint count64; | 139 gint count64; |
140 | 140 |
141 /* prepare at first */ | 141 /* prepare at first */ |
142 crypted_ptr = crypted; | 142 crypted_ptr = crypted; |
143 | 143 |
144 memcpy(crypted32, crypted_ptr, sizeof(crypted32)); | 144 memcpy(crypted32, crypted_ptr, sizeof(crypted32)); |
145 c32_prev[0] = crypted32[0]; c32_prev[1] = crypted32[1]; | 145 c32_prev[0] = crypted32[0]; c32_prev[1] = crypted32[1]; |
146 | 146 |
147 p32_prev[0] = 0; p32_prev[1] = 0; | 147 p32_prev[0] = 0; p32_prev[1] = 0; |
148 plain32[0] = crypted32[0] ^ p32_prev[0]; plain32[1] = crypted32[1] ^ p32_prev[1]; | 148 plain32[0] = crypted32[0] ^ p32_prev[0]; plain32[1] = crypted32[1] ^ p32_prev[1]; |
149 | 149 |
150 g_memmove(key32, key, 16); | 150 g_memmove(key32, key, 16); |
151 count64 = crypted_len / 8; | 151 count64 = crypted_len / 8; |
152 while (count64-- > 0){ | 152 while (count64-- > 0){ |
153 /* encrypt it */ | 153 /* encrypt it */ |
154 qq_encipher(plain32, key32, crypted32); | 154 qq_encipher(plain32, key32, crypted32); |
155 | 155 |
156 crypted32[0] ^= p32_prev[0]; crypted32[1] ^= p32_prev[1]; | 156 crypted32[0] ^= p32_prev[0]; crypted32[1] ^= p32_prev[1]; |
157 | 157 |
158 /* store curr 64 bits crypted */ | 158 /* store curr 64 bits crypted */ |
159 g_memmove(crypted_ptr, crypted32, sizeof(crypted32)); | 159 g_memmove(crypted_ptr, crypted32, sizeof(crypted32)); |
160 | 160 |
161 /* set prev */ | 161 /* set prev */ |
162 p32_prev[0] = plain32[0]; p32_prev[1] = plain32[1]; | 162 p32_prev[0] = plain32[0]; p32_prev[1] = plain32[1]; |
163 c32_prev[0] = crypted32[0]; c32_prev[1] = crypted32[1]; | 163 c32_prev[0] = crypted32[0]; c32_prev[1] = crypted32[1]; |
164 | 164 |
165 /* set next 64 bits want to crypt*/ | 165 /* set next 64 bits want to crypt*/ |
166 if (count64 > 0) { | 166 if (count64 > 0) { |
167 crypted_ptr += 8; | 167 crypted_ptr += 8; |
168 memcpy(crypted32, crypted_ptr, sizeof(crypted32)); | 168 memcpy(crypted32, crypted_ptr, sizeof(crypted32)); |
169 plain32[0] = crypted32[0] ^ c32_prev[0]; plain32[1] = crypted32[1] ^ c32_prev[1]; | 169 plain32[0] = crypted32[0] ^ c32_prev[0]; plain32[1] = crypted32[1] ^ c32_prev[1]; |
179 */ | 179 */ |
180 gint qq_encrypt(guint8* crypted, const guint8* const plain, const gint plain_len, const guint8* const key) | 180 gint qq_encrypt(guint8* crypted, const guint8* const plain, const gint plain_len, const guint8* const key) |
181 { | 181 { |
182 guint8 *crypted_ptr = crypted; /* current position of dest */ | 182 guint8 *crypted_ptr = crypted; /* current position of dest */ |
183 gint pos, padding; | 183 gint pos, padding; |
184 | 184 |
185 padding = (plain_len + 10) % 8; | 185 padding = (plain_len + 10) % 8; |
186 if (padding) { | 186 if (padding) { |
187 padding = 8 - padding; | 187 padding = 8 - padding; |
188 } | 188 } |
189 | 189 |
221 | 221 |
222 show_binary("Encrypted", crypted, pos); | 222 show_binary("Encrypted", crypted, pos); |
223 return pos; | 223 return pos; |
224 } | 224 } |
225 | 225 |
226 /******************************************************************** | 226 /******************************************************************** |
227 * decryption | 227 * decryption |
228 ********************************************************************/ | 228 ********************************************************************/ |
229 | 229 |
230 static inline void qq_decipher(guint32 *const v, const guint32 *const k, guint32 *const w) | 230 static inline void qq_decipher(guint32 *const v, const guint32 *const k, guint32 *const w) |
231 { | 231 { |
232 register guint32 | 232 register guint32 |
233 y = g_ntohl(v[0]), | 233 y = g_ntohl(v[0]), |
234 z = g_ntohl(v[1]), | 234 z = g_ntohl(v[1]), |
235 a = g_ntohl(k[0]), | 235 a = g_ntohl(k[0]), |
236 b = g_ntohl(k[1]), | 236 b = g_ntohl(k[1]), |
237 c = g_ntohl(k[2]), | 237 c = g_ntohl(k[2]), |
238 d = g_ntohl(k[3]), | 238 d = g_ntohl(k[3]), |
239 n = 0x10, | 239 n = 0x10, |
240 sum = 0xE3779B90, /* why this ? must be related with n value */ | 240 sum = 0xE3779B90, /* why this ? must be related with n value */ |
241 delta = 0x9E3779B9; | 241 delta = 0x9E3779B9; |
242 | 242 |
243 /* sum = delta<<5, in general sum = delta * n */ | 243 /* sum = delta<<5, in general sum = delta * n */ |
244 while (n-- > 0) { | 244 while (n-- > 0) { |
249 | 249 |
250 w[0] = g_htonl(y); | 250 w[0] = g_htonl(y); |
251 w[1] = g_htonl(z); | 251 w[1] = g_htonl(z); |
252 } | 252 } |
253 | 253 |
254 static inline gint decrypt_out(guint8 *dest, gint crypted_len, const guint8* const key) | 254 static inline gint decrypt_out(guint8 *dest, gint crypted_len, const guint8* const key) |
255 { | 255 { |
256 gint plain_len; | 256 gint plain_len; |
257 guint32 key32[4]; | 257 guint32 key32[4]; |
258 guint32 crypted32[2]; | 258 guint32 crypted32[2]; |
259 guint32 c32_prev[2]; | 259 guint32 c32_prev[2]; |
278 } | 278 } |
279 plain_len = crypted_len - 1 - padding - 7; | 279 plain_len = crypted_len - 1 - padding - 7; |
280 if( plain_len < 0 ) { | 280 if( plain_len < 0 ) { |
281 return -2; | 281 return -2; |
282 } | 282 } |
283 | 283 |
284 count64 = crypted_len / 8; | 284 count64 = crypted_len / 8; |
285 while (--count64 > 0){ | 285 while (--count64 > 0){ |
286 c32_prev[0] = crypted32[0]; c32_prev[1] = crypted32[1]; | 286 c32_prev[0] = crypted32[0]; c32_prev[1] = crypted32[1]; |
287 crypted_ptr += 8; | 287 crypted_ptr += 8; |
288 | 288 |
289 memcpy(crypted32, crypted_ptr, sizeof(crypted32)); | 289 memcpy(crypted32, crypted_ptr, sizeof(crypted32)); |
290 p32_prev[0] ^= crypted32[0]; p32_prev[1] ^= crypted32[1]; | 290 p32_prev[0] ^= crypted32[0]; p32_prev[1] ^= crypted32[1]; |
291 | 291 |
292 qq_decipher(p32_prev, key32, p32_prev); | 292 qq_decipher(p32_prev, key32, p32_prev); |
293 | 293 |
294 plain32[0] = p32_prev[0] ^ c32_prev[0]; plain32[1] = p32_prev[1] ^ c32_prev[1]; | 294 plain32[0] = p32_prev[0] ^ c32_prev[0]; plain32[1] = p32_prev[1] ^ c32_prev[1]; |
295 memcpy(crypted_ptr, plain32, sizeof(plain32)); | 295 memcpy(crypted_ptr, plain32, sizeof(plain32)); |
296 } | 296 } |
297 | 297 |
298 return plain_len; | 298 return plain_len; |
304 gint plain_len = 0; | 304 gint plain_len = 0; |
305 gint hdr_padding; | 305 gint hdr_padding; |
306 gint pos; | 306 gint pos; |
307 | 307 |
308 /* at least 16 bytes and %8 == 0 */ | 308 /* at least 16 bytes and %8 == 0 */ |
309 if ((crypted_len % 8) || (crypted_len < 16)) { | 309 if ((crypted_len % 8) || (crypted_len < 16)) { |
310 return -1; | 310 return -1; |
311 } | 311 } |
312 | 312 |
313 memcpy(plain, crypted, crypted_len); | 313 memcpy(plain, crypted, crypted_len); |
314 | 314 |