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