annotate src/protocols/qq/crypt.c @ 13875:eb20e674ccf2

[gaim-migrate @ 16349] Three changes: 1. When you try to sign on with an oscar screen name that is not valid ("123abc" for example), the PRPL will set gc->wants_to_die to TRUE so that the account will not be auto-reconnected. 2. When we get an AIM userinfo packet about someone in our buddy list, if the person has some kind of screen name formatting set ("Mark Doliner" instead of "markdoliner") then we set the buddies server_nick to that formatted name. 3. Add a "Get AIM Info" to the context menu for ICQ buddies who are in the buddy list of an ICQ user. committer: Tailor Script <tailor@pidgin.im>
author Mark Doliner <mark@kingant.net>
date Mon, 26 Jun 2006 09:03:54 +0000
parents 983fd420e86b
children 96947ec79828
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
13870
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
1 /**
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
2 * The QQ2003C protocol plugin
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
3 *
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
4 * for gaim
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
5 *
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
6 * Copyright (C) 2004 Puzzlebird
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
7 *
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
8 * This program is free software; you can redistribute it and/or modify
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
9 * it under the terms of the GNU General Public License as published by
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
10 * the Free Software Foundation; either version 2 of the License, or
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
11 * (at your option) any later version.
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
12 *
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
13 * This program is distributed in the hope that it will be useful,
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
16 * GNU General Public License for more details.
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
17 *
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
18 * You should have received a copy of the GNU General Public License
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
19 * along with this program; if not, write to the Free Software
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
21 *
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
22 *
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
23 * OICQ encryption algorithm
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
24 * Convert from ASM code provided by PerlOICQ
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
25 *
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
26 * Puzzlebird, Nov-Dec 2002
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
27 */
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
28
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
29 // START OF FILE
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
30 /*****************************************************************************/
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
31 /*Notes: (OICQ uses 0x10 iterations, and modified something...)
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
32
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
33 IN : 64 bits of data in v[0] - v[1].
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
34 OUT: 64 bits of data in w[0] - w[1].
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
35 KEY: 128 bits of key in k[0] - k[3].
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
36
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
37 delta is chosen to be the real part of
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
38 the golden ratio: Sqrt(5/4) - 1/2 ~ 0.618034 multiplied by 2^32.
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
39
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
40 0x61C88647 is what we can track on the ASM codes.!!
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
41 */
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
42
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
43 #ifndef _WIN32
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
44 #include <arpa/inet.h>
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
45 #else
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
46 #include "win32dep.h"
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
47 #endif
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
48
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
49 #include <string.h>
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
50
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
51 #include "crypt.h"
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
52 #include "debug.h" // gaim_debug, by gfhuang
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
53
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
54 /*****************************************************************************/
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
55 static void qq_encipher(unsigned long *const v, const unsigned long *const k, unsigned long *const w)
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
56 {
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
57 register unsigned long y = ntohl(v[0]), z = ntohl(v[1]), a = ntohl(k[0]), b = ntohl(k[1]), c = ntohl(k[2]), d = ntohl(k[3]), n = 0x10, sum = 0, delta = 0x9E3779B9; /* 0x9E3779B9 - 0x100000000 = -0x61C88647 */
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
58
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
59 while (n-- > 0) {
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
60 sum += delta;
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
61 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
62 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
63 } // while
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
64
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
65 w[0] = htonl(y);
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
66 w[1] = htonl(z);
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
67 } // qq_enciper
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
68
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
69 /*****************************************************************************/
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
70 static void qq_decipher(unsigned long *const v, const unsigned long *const k, unsigned long *const w)
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
71 {
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
72 register unsigned long y = ntohl(v[0]), z = ntohl(v[1]), a = ntohl(k[0]), b = ntohl(k[1]), c = ntohl(k[2]), d = ntohl(k[3]), n = 0x10, sum = 0xE3779B90, // why this ? must be related with n value
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
73 delta = 0x9E3779B9;
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
74
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
75 /* sum = delta<<5, in general sum = delta * n */
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
76 while (n-- > 0) {
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
77 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
78 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
79 sum -= delta;
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
80 }
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
81
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
82 w[0] = htonl(y);
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
83 w[1] = htonl(z);
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
84 } // qq_decipher
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
85
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
86 /********************************************************************
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
87 * encrypt part
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
88 *******************************************************************/
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
89
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
90 static void qq_encrypt(unsigned char *instr, int instrlen, unsigned char *key, unsigned char *outstr, int *outstrlen_prt)
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
91 {
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
92 unsigned char plain[8], // plain text buffer
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
93 plain_pre_8[8], // plain text buffer, previous 8 bytes
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
94 *crypted, // crypted text
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
95 *crypted_pre_8, // crypted test, previous 8 bytes
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
96 *inp; // current position in instr
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
97 int pos_in_byte = 1, // loop in the byte
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
98 is_header = 1, // header is one byte
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
99 count = 0, // number of bytes being crypted
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
100 padding = 0; // number of padding stuff
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
101
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
102 int rand(void) { // it can be the real random seed function
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
103 return 0xdead;
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
104 } // override with number, convenient for debug
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
105
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
106 /*** we encrypt every eight byte ***/
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
107 void encrypt_every_8_byte(void) {
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
108 for (pos_in_byte = 0; pos_in_byte < 8; pos_in_byte++) {
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
109 if (is_header) {
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
110 plain[pos_in_byte] ^= plain_pre_8[pos_in_byte];
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
111 } else {
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
112 plain[pos_in_byte] ^= crypted_pre_8[pos_in_byte];
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
113 }
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
114 } // prepare plain text
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
115 qq_encipher((unsigned long *) plain, (unsigned long *) key, (unsigned long *) crypted); // encrypt it
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
116
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
117 for (pos_in_byte = 0; pos_in_byte < 8; pos_in_byte++) {
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
118 crypted[pos_in_byte] ^= plain_pre_8[pos_in_byte];
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
119 }
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
120 memcpy(plain_pre_8, plain, 8); // prepare next
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
121
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
122 crypted_pre_8 = crypted; // store position of previous 8 byte
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
123 crypted += 8; // prepare next output
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
124 count += 8; // outstrlen increase by 8
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
125 pos_in_byte = 0; // back to start
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
126 is_header = 0; // and exit header
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
127 } // encrypt_every_8_byte
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
128
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
129 pos_in_byte = (instrlen + 0x0a) % 8; // header padding decided by instrlen
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
130 if (pos_in_byte) {
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
131 pos_in_byte = 8 - pos_in_byte;
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
132 }
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
133 plain[0] = (rand() & 0xf8) | pos_in_byte;
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
134
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
135 memset(plain + 1, rand() & 0xff, pos_in_byte++);
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
136 memset(plain_pre_8, 0x00, sizeof(plain_pre_8));
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
137
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
138 crypted = crypted_pre_8 = outstr;
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
139
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
140 padding = 1; // pad some stuff in header
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
141 while (padding <= 2) { // at most two byte
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
142 if (pos_in_byte < 8) {
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
143 plain[pos_in_byte++] = rand() & 0xff;
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
144 padding++;
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
145 }
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
146 if (pos_in_byte == 8) {
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
147 encrypt_every_8_byte();
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
148 }
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
149 }
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
150
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
151 inp = instr;
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
152 while (instrlen > 0) {
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
153 if (pos_in_byte < 8) {
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
154 plain[pos_in_byte++] = *(inp++);
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
155 instrlen--;
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
156 }
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
157 if (pos_in_byte == 8) {
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
158 encrypt_every_8_byte();
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
159 }
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
160 }
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
161
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
162 padding = 1; // pad some stuff in tailer
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
163 while (padding <= 7) { // at most sever byte
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
164 if (pos_in_byte < 8) {
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
165 plain[pos_in_byte++] = 0x00;
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
166 padding++;
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
167 }
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
168 if (pos_in_byte == 8) {
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
169 encrypt_every_8_byte();
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
170 }
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
171 }
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
172
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
173 *outstrlen_prt = count;
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
174 } // qq_encrypt
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
175
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
176
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
177 /********************************************************************
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
178 * [decrypt part]
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
179 * return 0 if failed, otherwise return 1
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
180 ********************************************************************/
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
181
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
182 static int qq_decrypt(unsigned char *instr, int instrlen, unsigned char *key, unsigned char *outstr, int *outstrlen_ptr)
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
183 {
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
184 unsigned char decrypted[8], m[8], *crypt_buff, *crypt_buff_pre_8, *outp;
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
185 int count, context_start, pos_in_byte, padding;
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
186
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
187 int decrypt_every_8_byte(void) {
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
188 for (pos_in_byte = 0; pos_in_byte < 8; pos_in_byte++) {
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
189 if (context_start + pos_in_byte >= instrlen)
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
190 return 1;
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
191 decrypted[pos_in_byte] ^= crypt_buff[pos_in_byte];
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
192 }
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
193 qq_decipher((unsigned long *) decrypted, (unsigned long *) key, (unsigned long *) decrypted);
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
194
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
195 context_start += 8;
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
196 crypt_buff += 8;
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
197 pos_in_byte = 0;
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
198 return 1;
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
199 } // decrypt_every_8_byte
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
200
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
201 // at least 16 bytes and %8 == 0
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
202 if ((instrlen % 8) || (instrlen < 16)) {
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
203 //debug info by gfhuang
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
204 gaim_debug(GAIM_DEBUG_ERROR, "QQ", "Packet len is not times of 8 bytes, read %d bytes\n", instrlen);
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
205 return 0;
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
206 }
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
207 // get information from header
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
208 qq_decipher((unsigned long *) instr, (unsigned long *) key, (unsigned long *) decrypted);
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
209 pos_in_byte = decrypted[0] & 0x7;
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
210 count = instrlen - pos_in_byte - 10; // this is the plaintext length
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
211 // return if outstr buffer is not large enought or error plaintext length
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
212 if (*outstrlen_ptr < count || count < 0) {
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
213 gaim_debug(GAIM_DEBUG_ERROR, "QQ", "Buffer len %d is less than real len %d", *outstrlen_ptr, count);
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
214 return 0;
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
215 }
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
216
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
217 memset(m, 0, 8);
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
218 crypt_buff_pre_8 = m;
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
219 *outstrlen_ptr = count; // everything is ok! set return string length
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
220
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
221 crypt_buff = instr + 8; // address of real data start
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
222 context_start = 8; // context is at the second 8 byte
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
223 pos_in_byte++; // start of paddng stuff
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
224
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
225 padding = 1; // at least one in header
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
226 while (padding <= 2) { // there are 2 byte padding stuff in header
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
227 if (pos_in_byte < 8) { // bypass the padding stuff, none sense data
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
228 pos_in_byte++;
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
229 padding++;
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
230 }
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
231 if (pos_in_byte == 8) {
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
232 crypt_buff_pre_8 = instr;
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
233 if (!decrypt_every_8_byte()) {
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
234 gaim_debug(GAIM_DEBUG_ERROR, "QQ", "decrypt every 8 bytes error A");
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
235 return 0;
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
236 }
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
237 }
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
238 } // while
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
239
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
240 outp = outstr;
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
241 while (count != 0) {
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
242 if (pos_in_byte < 8) {
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
243 *outp = crypt_buff_pre_8[pos_in_byte] ^ decrypted[pos_in_byte];
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
244 outp++;
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
245 count--;
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
246 pos_in_byte++;
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
247 }
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
248 if (pos_in_byte == 8) {
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
249 crypt_buff_pre_8 = crypt_buff - 8;
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
250 if (!decrypt_every_8_byte()) {
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
251 gaim_debug(GAIM_DEBUG_ERROR, "QQ", "decrypt every 8 bytes error B");
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
252 return 0;
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
253 }
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
254 }
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
255 } // while
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
256
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
257 for (padding = 1; padding < 8; padding++) {
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
258 if (pos_in_byte < 8) {
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
259 if (crypt_buff_pre_8[pos_in_byte] ^ decrypted[pos_in_byte])
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
260 return 0;
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
261 pos_in_byte++;
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
262 }
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
263 if (pos_in_byte == 8) {
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
264 crypt_buff_pre_8 = crypt_buff;
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
265 if (!decrypt_every_8_byte()) {
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
266 gaim_debug(GAIM_DEBUG_ERROR, "QQ", "decrypt every 8 bytes error C");
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
267 return 0;
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
268 }
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
269 }
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
270 } // for
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
271 return 1;
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
272 } // qq_decrypt
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
273
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
274 /*****************************************************************************/
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
275 /* This is the Public Function */
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
276 // return 1 is succeed, otherwise return 0
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
277 int qq_crypt(unsigned char flag,
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
278 unsigned char *instr, int instrlen, unsigned char *key, unsigned char *outstr, int *outstrlen_ptr)
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
279 {
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
280 if (flag == DECRYPT)
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
281 return qq_decrypt(instr, instrlen, key, outstr, outstrlen_ptr);
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
282 else if (flag == ENCRYPT)
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
283 qq_encrypt(instr, instrlen, key, outstr, outstrlen_ptr);
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
284
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
285 return 1; // flag must be DECRYPT or ENCRYPT
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
286 } // qq_crypt
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
287
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
288 /*****************************************************************************/
983fd420e86b [gaim-migrate @ 16340]
Mark Huetsch <markhuetsch>
parents:
diff changeset
289 // END OF FILE