Mercurial > pidgin
annotate libpurple/ciphers/sha1.c @ 31537:6ec53e134447
bonjour: Recurse through user IP addresses instead of using the first one only
This, among other things, makes interactivity with iChat more reliable because
iChat apparently advertises an IPv6 address, but doesn't listen on it.
Fixes #13773
committer: Daniel Atallah <daniel.atallah@gmail.com>
author | Simon van der Linden <simon@vanderlinden.eu.org> |
---|---|
date | Tue, 03 May 2011 16:12:36 +0000 |
parents | ca94413ccd0e |
children |
rev | line source |
---|---|
31215 | 1 /* |
2 * purple | |
3 * | |
4 * Purple is the legal property of its developers, whose names are too numerous | |
5 * to list here. Please refer to the COPYRIGHT file distributed with this | |
6 * source distribution. | |
7 * | |
8 * This program is free software; you can redistribute it and/or modify | |
9 * it under the terms of the GNU General Public License as published by | |
10 * the Free Software Foundation; either version 2 of the License, or | |
11 * (at your option) any later version. | |
12 * | |
13 * This program is distributed in the hope that it will be useful, | |
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 * GNU General Public License for more details. | |
17 * | |
18 * You should have received a copy of the GNU General Public License | |
19 * along with this program; if not, write to the Free Software | |
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA | |
21 */ | |
22 #include <cipher.h> | |
31225
4418c97490ed
rc4.c and sha1.c needs to include libpurple/util.h as well
Gary Kramlich <grim@reaperworld.com>
parents:
31221
diff
changeset
|
23 #include <util.h> |
31215 | 24 |
31221
2b041e31b825
Removed the "new" api I added by moving it to ciphers/gchecksum.c. Moved the gchecksum implements into gchecksum.c as a preproc macro, removed them from their individual files
Gary Kramlich <grim@reaperworld.com>
parents:
31219
diff
changeset
|
25 #if !GLIB_CHECK_VERSION(2,16,0) |
31215 | 26 |
27 #define SHA1_HMAC_BLOCK_SIZE 64 | |
28 #define SHA1_ROTL(X,n) ((((X) << (n)) | ((X) >> (32-(n)))) & 0xFFFFFFFF) | |
29 | |
30 struct SHA1Context { | |
31 guint32 H[5]; | |
32 guint32 W[80]; | |
33 | |
34 gint lenW; | |
35 | |
36 guint32 sizeHi; | |
37 guint32 sizeLo; | |
38 }; | |
39 | |
31221
2b041e31b825
Removed the "new" api I added by moving it to ciphers/gchecksum.c. Moved the gchecksum implements into gchecksum.c as a preproc macro, removed them from their individual files
Gary Kramlich <grim@reaperworld.com>
parents:
31219
diff
changeset
|
40 static size_t |
2b041e31b825
Removed the "new" api I added by moving it to ciphers/gchecksum.c. Moved the gchecksum implements into gchecksum.c as a preproc macro, removed them from their individual files
Gary Kramlich <grim@reaperworld.com>
parents:
31219
diff
changeset
|
41 sha1_get_block_size(PurpleCipherContext *context) |
2b041e31b825
Removed the "new" api I added by moving it to ciphers/gchecksum.c. Moved the gchecksum implements into gchecksum.c as a preproc macro, removed them from their individual files
Gary Kramlich <grim@reaperworld.com>
parents:
31219
diff
changeset
|
42 { |
2b041e31b825
Removed the "new" api I added by moving it to ciphers/gchecksum.c. Moved the gchecksum implements into gchecksum.c as a preproc macro, removed them from their individual files
Gary Kramlich <grim@reaperworld.com>
parents:
31219
diff
changeset
|
43 /* This does not change (in this case) */ |
2b041e31b825
Removed the "new" api I added by moving it to ciphers/gchecksum.c. Moved the gchecksum implements into gchecksum.c as a preproc macro, removed them from their individual files
Gary Kramlich <grim@reaperworld.com>
parents:
31219
diff
changeset
|
44 return SHA1_HMAC_BLOCK_SIZE; |
2b041e31b825
Removed the "new" api I added by moving it to ciphers/gchecksum.c. Moved the gchecksum implements into gchecksum.c as a preproc macro, removed them from their individual files
Gary Kramlich <grim@reaperworld.com>
parents:
31219
diff
changeset
|
45 } |
2b041e31b825
Removed the "new" api I added by moving it to ciphers/gchecksum.c. Moved the gchecksum implements into gchecksum.c as a preproc macro, removed them from their individual files
Gary Kramlich <grim@reaperworld.com>
parents:
31219
diff
changeset
|
46 |
31215 | 47 static void |
48 sha1_hash_block(struct SHA1Context *sha1_ctx) { | |
49 gint i; | |
50 guint32 A, B, C, D, E, T; | |
51 | |
52 for(i = 16; i < 80; i++) { | |
53 sha1_ctx->W[i] = SHA1_ROTL(sha1_ctx->W[i - 3] ^ | |
54 sha1_ctx->W[i - 8] ^ | |
55 sha1_ctx->W[i - 14] ^ | |
56 sha1_ctx->W[i - 16], 1); | |
57 } | |
58 | |
59 A = sha1_ctx->H[0]; | |
60 B = sha1_ctx->H[1]; | |
61 C = sha1_ctx->H[2]; | |
62 D = sha1_ctx->H[3]; | |
63 E = sha1_ctx->H[4]; | |
64 | |
65 for(i = 0; i < 20; i++) { | |
66 T = (SHA1_ROTL(A, 5) + (((C ^ D) & B) ^ D) + E + sha1_ctx->W[i] + 0x5A827999) & 0xFFFFFFFF; | |
67 E = D; | |
68 D = C; | |
69 C = SHA1_ROTL(B, 30); | |
70 B = A; | |
71 A = T; | |
72 } | |
73 | |
74 for(i = 20; i < 40; i++) { | |
75 T = (SHA1_ROTL(A, 5) + (B ^ C ^ D) + E + sha1_ctx->W[i] + 0x6ED9EBA1) & 0xFFFFFFFF; | |
76 E = D; | |
77 D = C; | |
78 C = SHA1_ROTL(B, 30); | |
79 B = A; | |
80 A = T; | |
81 } | |
82 | |
83 for(i = 40; i < 60; i++) { | |
31257
4ef9165ebe45
Fix compilation on glib < 2.16. Somehow a trailing semicolon got lost.
Mark Doliner <mark@kingant.net>
parents:
31225
diff
changeset
|
84 T = (SHA1_ROTL(A, 5) + ((B & C) | (D & (B | C))) + E + sha1_ctx->W[i] + 0x8F1BBCDC) & 0xFFFFFFFF; |
4ef9165ebe45
Fix compilation on glib < 2.16. Somehow a trailing semicolon got lost.
Mark Doliner <mark@kingant.net>
parents:
31225
diff
changeset
|
85 E = D; |
31215 | 86 D = C; |
87 C = SHA1_ROTL(B, 30); | |
88 B = A; | |
89 A = T; | |
90 } | |
91 | |
92 for(i = 60; i < 80; i++) { | |
93 T = (SHA1_ROTL(A, 5) + (B ^ C ^ D) + E + sha1_ctx->W[i] + 0xCA62C1D6) & 0xFFFFFFFF; | |
94 E = D; | |
95 D = C; | |
96 C = SHA1_ROTL(B, 30); | |
97 B = A; | |
98 A = T; | |
99 } | |
100 | |
101 sha1_ctx->H[0] += A; | |
102 sha1_ctx->H[1] += B; | |
103 sha1_ctx->H[2] += C; | |
104 sha1_ctx->H[3] += D; | |
105 sha1_ctx->H[4] += E; | |
106 } | |
107 | |
108 static void | |
109 sha1_set_opt(PurpleCipherContext *context, const gchar *name, void *value) { | |
110 struct SHA1Context *ctx; | |
111 | |
112 ctx = purple_cipher_context_get_data(context); | |
113 | |
114 if(purple_strequal(name, "sizeHi")) { | |
115 ctx->sizeHi = GPOINTER_TO_INT(value); | |
116 } else if(purple_strequal(name, "sizeLo")) { | |
117 ctx->sizeLo = GPOINTER_TO_INT(value); | |
118 } else if(purple_strequal(name, "lenW")) { | |
119 ctx->lenW = GPOINTER_TO_INT(value); | |
120 } | |
121 } | |
122 | |
123 static void * | |
124 sha1_get_opt(PurpleCipherContext *context, const gchar *name) { | |
125 struct SHA1Context *ctx; | |
126 | |
127 ctx = purple_cipher_context_get_data(context); | |
128 | |
129 if(purple_strequal(name, "sizeHi")) { | |
130 return GINT_TO_POINTER(ctx->sizeHi); | |
131 } else if(purple_strequal(name, "sizeLo")) { | |
132 return GINT_TO_POINTER(ctx->sizeLo); | |
133 } else if(purple_strequal(name, "lenW")) { | |
134 return GINT_TO_POINTER(ctx->lenW); | |
135 } | |
136 | |
137 return NULL; | |
138 } | |
139 | |
140 static void | |
141 sha1_init(PurpleCipherContext *context, void *extra) { | |
142 struct SHA1Context *sha1_ctx; | |
143 | |
144 sha1_ctx = g_new0(struct SHA1Context, 1); | |
145 | |
146 purple_cipher_context_set_data(context, sha1_ctx); | |
147 | |
148 purple_cipher_context_reset(context, extra); | |
149 } | |
150 | |
151 static void | |
152 sha1_reset(PurpleCipherContext *context, void *extra) { | |
153 struct SHA1Context *sha1_ctx; | |
154 gint i; | |
155 | |
156 sha1_ctx = purple_cipher_context_get_data(context); | |
157 | |
158 g_return_if_fail(sha1_ctx); | |
159 | |
160 sha1_ctx->lenW = 0; | |
161 sha1_ctx->sizeHi = 0; | |
162 sha1_ctx->sizeLo = 0; | |
163 | |
164 sha1_ctx->H[0] = 0x67452301; | |
165 sha1_ctx->H[1] = 0xEFCDAB89; | |
166 sha1_ctx->H[2] = 0x98BADCFE; | |
167 sha1_ctx->H[3] = 0x10325476; | |
168 sha1_ctx->H[4] = 0xC3D2E1F0; | |
169 | |
170 for(i = 0; i < 80; i++) | |
171 sha1_ctx->W[i] = 0; | |
172 } | |
173 | |
174 static void | |
175 sha1_uninit(PurpleCipherContext *context) { | |
176 struct SHA1Context *sha1_ctx; | |
177 | |
178 purple_cipher_context_reset(context, NULL); | |
179 | |
180 sha1_ctx = purple_cipher_context_get_data(context); | |
181 | |
182 memset(sha1_ctx, 0, sizeof(struct SHA1Context)); | |
183 | |
184 g_free(sha1_ctx); | |
185 sha1_ctx = NULL; | |
186 } | |
187 | |
188 static void | |
189 sha1_append(PurpleCipherContext *context, const guchar *data, size_t len) { | |
190 struct SHA1Context *sha1_ctx; | |
191 gint i; | |
192 | |
193 sha1_ctx = purple_cipher_context_get_data(context); | |
194 | |
195 g_return_if_fail(sha1_ctx); | |
196 | |
197 for(i = 0; i < len; i++) { | |
198 sha1_ctx->W[sha1_ctx->lenW / 4] <<= 8; | |
199 sha1_ctx->W[sha1_ctx->lenW / 4] |= data[i]; | |
200 | |
201 if((++sha1_ctx->lenW) % 64 == 0) { | |
202 sha1_hash_block(sha1_ctx); | |
203 sha1_ctx->lenW = 0; | |
204 } | |
205 | |
206 sha1_ctx->sizeLo += 8; | |
207 sha1_ctx->sizeHi += (sha1_ctx->sizeLo < 8); | |
208 } | |
209 } | |
210 | |
211 static gboolean | |
212 sha1_digest(PurpleCipherContext *context, size_t in_len, guchar digest[20], | |
213 size_t *out_len) | |
214 { | |
215 struct SHA1Context *sha1_ctx; | |
216 guchar pad0x80 = 0x80, pad0x00 = 0x00; | |
217 guchar padlen[8]; | |
218 gint i; | |
219 | |
220 g_return_val_if_fail(in_len >= 20, FALSE); | |
221 | |
222 sha1_ctx = purple_cipher_context_get_data(context); | |
223 | |
224 g_return_val_if_fail(sha1_ctx, FALSE); | |
225 | |
226 padlen[0] = (guchar)((sha1_ctx->sizeHi >> 24) & 255); | |
227 padlen[1] = (guchar)((sha1_ctx->sizeHi >> 16) & 255); | |
228 padlen[2] = (guchar)((sha1_ctx->sizeHi >> 8) & 255); | |
229 padlen[3] = (guchar)((sha1_ctx->sizeHi >> 0) & 255); | |
230 padlen[4] = (guchar)((sha1_ctx->sizeLo >> 24) & 255); | |
231 padlen[5] = (guchar)((sha1_ctx->sizeLo >> 16) & 255); | |
232 padlen[6] = (guchar)((sha1_ctx->sizeLo >> 8) & 255); | |
233 padlen[7] = (guchar)((sha1_ctx->sizeLo >> 0) & 255); | |
234 | |
235 /* pad with a 1, then zeroes, then length */ | |
236 purple_cipher_context_append(context, &pad0x80, 1); | |
237 while(sha1_ctx->lenW != 56) | |
238 purple_cipher_context_append(context, &pad0x00, 1); | |
239 purple_cipher_context_append(context, padlen, 8); | |
240 | |
241 for(i = 0; i < 20; i++) { | |
242 digest[i] = (guchar)(sha1_ctx->H[i / 4] >> 24); | |
243 sha1_ctx->H[i / 4] <<= 8; | |
244 } | |
245 | |
246 purple_cipher_context_reset(context, NULL); | |
247 | |
248 if(out_len) | |
249 *out_len = 20; | |
250 | |
251 return TRUE; | |
252 } | |
253 | |
254 static PurpleCipherOps SHA1Ops = { | |
31353
ca94413ccd0e
Named initializers and most other C99isms don't work in Visual C++ .NET 2005 in
Florian Quèze <florian@instantbird.org>
parents:
31257
diff
changeset
|
255 sha1_set_opt, /* Set Option */ |
ca94413ccd0e
Named initializers and most other C99isms don't work in Visual C++ .NET 2005 in
Florian Quèze <florian@instantbird.org>
parents:
31257
diff
changeset
|
256 sha1_get_opt, /* Get Option */ |
ca94413ccd0e
Named initializers and most other C99isms don't work in Visual C++ .NET 2005 in
Florian Quèze <florian@instantbird.org>
parents:
31257
diff
changeset
|
257 sha1_init, /* init */ |
ca94413ccd0e
Named initializers and most other C99isms don't work in Visual C++ .NET 2005 in
Florian Quèze <florian@instantbird.org>
parents:
31257
diff
changeset
|
258 sha1_reset, /* reset */ |
ca94413ccd0e
Named initializers and most other C99isms don't work in Visual C++ .NET 2005 in
Florian Quèze <florian@instantbird.org>
parents:
31257
diff
changeset
|
259 sha1_uninit, /* uninit */ |
ca94413ccd0e
Named initializers and most other C99isms don't work in Visual C++ .NET 2005 in
Florian Quèze <florian@instantbird.org>
parents:
31257
diff
changeset
|
260 NULL, /* set iv */ |
ca94413ccd0e
Named initializers and most other C99isms don't work in Visual C++ .NET 2005 in
Florian Quèze <florian@instantbird.org>
parents:
31257
diff
changeset
|
261 sha1_append, /* append */ |
ca94413ccd0e
Named initializers and most other C99isms don't work in Visual C++ .NET 2005 in
Florian Quèze <florian@instantbird.org>
parents:
31257
diff
changeset
|
262 sha1_digest, /* digest */ |
ca94413ccd0e
Named initializers and most other C99isms don't work in Visual C++ .NET 2005 in
Florian Quèze <florian@instantbird.org>
parents:
31257
diff
changeset
|
263 NULL, /* encrypt */ |
ca94413ccd0e
Named initializers and most other C99isms don't work in Visual C++ .NET 2005 in
Florian Quèze <florian@instantbird.org>
parents:
31257
diff
changeset
|
264 NULL, /* decrypt */ |
ca94413ccd0e
Named initializers and most other C99isms don't work in Visual C++ .NET 2005 in
Florian Quèze <florian@instantbird.org>
parents:
31257
diff
changeset
|
265 NULL, /* set salt */ |
ca94413ccd0e
Named initializers and most other C99isms don't work in Visual C++ .NET 2005 in
Florian Quèze <florian@instantbird.org>
parents:
31257
diff
changeset
|
266 NULL, /* get salt size */ |
ca94413ccd0e
Named initializers and most other C99isms don't work in Visual C++ .NET 2005 in
Florian Quèze <florian@instantbird.org>
parents:
31257
diff
changeset
|
267 NULL, /* set key */ |
ca94413ccd0e
Named initializers and most other C99isms don't work in Visual C++ .NET 2005 in
Florian Quèze <florian@instantbird.org>
parents:
31257
diff
changeset
|
268 NULL, /* get key size */ |
ca94413ccd0e
Named initializers and most other C99isms don't work in Visual C++ .NET 2005 in
Florian Quèze <florian@instantbird.org>
parents:
31257
diff
changeset
|
269 NULL, /* set batch mode */ |
ca94413ccd0e
Named initializers and most other C99isms don't work in Visual C++ .NET 2005 in
Florian Quèze <florian@instantbird.org>
parents:
31257
diff
changeset
|
270 NULL, /* get batch mode */ |
ca94413ccd0e
Named initializers and most other C99isms don't work in Visual C++ .NET 2005 in
Florian Quèze <florian@instantbird.org>
parents:
31257
diff
changeset
|
271 sha1_get_block_size, /* get block size */ |
ca94413ccd0e
Named initializers and most other C99isms don't work in Visual C++ .NET 2005 in
Florian Quèze <florian@instantbird.org>
parents:
31257
diff
changeset
|
272 NULL /* set key with len */ |
31215 | 273 }; |
274 | |
275 PurpleCipherOps * | |
276 purple_sha1_cipher_get_ops(void) { | |
277 return &SHA1Ops; | |
278 } | |
279 | |
31221
2b041e31b825
Removed the "new" api I added by moving it to ciphers/gchecksum.c. Moved the gchecksum implements into gchecksum.c as a preproc macro, removed them from their individual files
Gary Kramlich <grim@reaperworld.com>
parents:
31219
diff
changeset
|
280 #endif /* !GLIB_CHECK_VERSION(2,16,0) */ |
2b041e31b825
Removed the "new" api I added by moving it to ciphers/gchecksum.c. Moved the gchecksum implements into gchecksum.c as a preproc macro, removed them from their individual files
Gary Kramlich <grim@reaperworld.com>
parents:
31219
diff
changeset
|
281 |